agendas: treat remote ICS as UTF-8 if it looks like it (#38510)

This commit is contained in:
Frédéric Péters 2020-01-11 12:10:19 +01:00
parent 464fc474e1
commit 47829f9d76
2 changed files with 25 additions and 2 deletions

View File

@ -578,6 +578,13 @@ class Desk(models.Model):
if source is None:
source = TimePeriodExceptionSource(desk=self, ics_url=ics_url)
try:
# override response encoding received in HTTP headers as it may
# often be missing and defaults to iso-8859-15.
response.content.decode('utf-8')
response.encoding = 'utf-8'
except UnicodeDecodeError as e:
pass
return self._import_timeperiod_exceptions_from_ics(source=source, data=response.text)
def import_timeperiod_exceptions_from_ics_file(self, ics_file, source=None):

View File

@ -30,7 +30,7 @@ DTSTAMP:20170824T082855Z
DTSTART:20170831T170800Z
DTEND:20170831T203400Z
SEQUENCE:1
SUMMARY:Event 1
SUMMARY:Événement 1
END:VEVENT
BEGIN:VEVENT
DTSTAMP:20170824T092855Z
@ -211,7 +211,7 @@ def test_timeperiodexception_creation_from_ics_without_startdt():
ics_sample = ContentFile("\n".join(lines), name='sample.ics')
with pytest.raises(ICSError) as e:
desk.import_timeperiod_exceptions_from_ics_file(ics_sample)
assert 'Event "Event 1" has no start date.' == str(e.value)
assert 'Event "Événement 1" has no start date.' == str(e.value)
def test_timeperiodexception_creation_from_ics_without_enddt():
@ -299,6 +299,7 @@ def test_timeperiodexception_creation_from_remote_ics(mocked_get):
mocked_get.return_value = mocked_response
exceptions_count = desk.import_timeperiod_exceptions_from_remote_ics('http://example.com/sample.ics')
assert exceptions_count == 2
assert 'Événement 1' in [x.label for x in desk.timeperiodexception_set.all()]
mocked_response.text = ICS_SAMPLE_WITH_NO_EVENTS
mocked_get.return_value = mocked_response
@ -307,6 +308,21 @@ def test_timeperiodexception_creation_from_remote_ics(mocked_get):
assert str(e.value) == "The file doesn't contain any events."
@mock.patch('chrono.agendas.models.requests.get')
def test_timeperiodexception_remote_ics_encoding(mocked_get):
agenda = Agenda(label=u'Test 8 agenda')
agenda.save()
desk = Desk(label='Test 8 desk', agenda=agenda)
desk.save()
mocked_response = mock.Mock()
mocked_response.content = ICS_SAMPLE.encode('iso-8859-15')
mocked_response.text = ICS_SAMPLE
mocked_get.return_value = mocked_response
exceptions_count = desk.import_timeperiod_exceptions_from_remote_ics('http://example.com/sample.ics')
assert exceptions_count == 2
assert 'Événement 1' in [x.label for x in desk.timeperiodexception_set.all()]
@mock.patch('chrono.agendas.models.requests.get')
def test_timeperiodexception_creation_from_unreachable_remote_ics(mocked_get):
agenda = Agenda(label=u'Test 9 agenda')