caldav: add SEQUENCE field when missing on event update (#88417)
gitea/passerelle/pipeline/head This commit looks good
Details
gitea/passerelle/pipeline/head This commit looks good
Details
This commit is contained in:
parent
4a243f72e5
commit
923125e786
|
@ -162,6 +162,7 @@ class CalDAV(BaseResource):
|
|||
cal = self.get_calendar(username)
|
||||
self._process_event_properties(post_data)
|
||||
|
||||
post_data['SEQUENCE'] = 0 # RFC 5545 3.8.7.4
|
||||
try:
|
||||
evt = cal.save_event(**post_data)
|
||||
except requests.exceptions.RequestException as expt:
|
||||
|
@ -207,6 +208,10 @@ class CalDAV(BaseResource):
|
|||
for k, v in post_data.items():
|
||||
vevent.pop(k)
|
||||
vevent.add(k, v)
|
||||
if 'SEQUENCE' not in vevent:
|
||||
# SEQUENCE is auto-incremented when present
|
||||
# here after a 1st modification the SEQUENCE will be 1 (not 0)
|
||||
vevent['SEQUENCE'] = 0
|
||||
try:
|
||||
# do not use ical.save(no_create=True) : no_create fails on some calDAV
|
||||
ical.save()
|
||||
|
|
|
@ -260,6 +260,7 @@ def test_caldav_event_create_allday_ok(app, caldav_conn):
|
|||
k: v if k not in ('DTSTART', 'DTEND') else datetime.date.fromisoformat(v)
|
||||
for k, v in event.items()
|
||||
}
|
||||
event_conv['SEQUENCE'] = 0
|
||||
cal_mock.save_event.assert_called_once_with(**event_conv)
|
||||
|
||||
|
||||
|
@ -284,6 +285,7 @@ def test_caldav_event_categories(app, caldav_conn):
|
|||
for k, v in event.items()
|
||||
}
|
||||
event_conv['CATEGORIES'] = [event_conv.pop('CATEGORY')]
|
||||
event_conv['SEQUENCE'] = 0
|
||||
cal_mock.save_event.assert_called_once_with(**event_conv)
|
||||
|
||||
|
||||
|
@ -308,6 +310,7 @@ def test_caldav_event_create_ok(app, caldav_conn, event):
|
|||
|
||||
save_args = event.copy()
|
||||
caldav_conn._process_event_properties(save_args)
|
||||
save_args['SEQUENCE'] = 0
|
||||
cal_mock.save_event.assert_called_once_with(**save_args)
|
||||
|
||||
|
||||
|
@ -360,7 +363,7 @@ def test_caldav_event_create_bad_dates(app, caldav_conn, dtstart, dtend, until):
|
|||
'DTSTART': dtstart,
|
||||
'DTEND': dtend,
|
||||
'SUMMARY': 'hello',
|
||||
'RRULE': {'FREQ': 'WEEKLY', 'BYDAY': 'FR', 'UNTIL': until},
|
||||
'RRULE': {'FREQ': 'WEEKLY', 'BYDAY': ['FR'], 'UNTIL': until},
|
||||
}
|
||||
qs_params = {'username': username}
|
||||
|
||||
|
@ -368,6 +371,7 @@ def test_caldav_event_create_bad_dates(app, caldav_conn, dtstart, dtend, until):
|
|||
|
||||
assert resp.status_code == 400
|
||||
assert resp.json['err'] != 0
|
||||
assert resp.json['err_desc'].startswith('Unable to convert field')
|
||||
|
||||
|
||||
@pytest.mark.parametrize('transp', [True, False])
|
||||
|
@ -420,8 +424,17 @@ def test_caldav_event_update_ok(app, transp, caldav_conn):
|
|||
assert str(evt[k]) == v
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'event_update',
|
||||
(
|
||||
{'DTSTART': '2020-02-20', 'DTEND': '2020-03-30', 'SUMMARY': 'Foobar'},
|
||||
{'TRANSP': True},
|
||||
{'RRULE/FREQ': 'MONTHLY', 'RRULE/BYDAY': ['TU'], 'RRULE/UNTIL': '2020-10-01'},
|
||||
{'DTSTART': '2020-02-20', 'TRANSP': True},
|
||||
),
|
||||
)
|
||||
@responses.activate
|
||||
def test_caldav_event_update_ok_nomock(app, caldav_conn):
|
||||
def test_caldav_event_update_ok_nomock(app, caldav_conn, event_update):
|
||||
"""This test let the caldav lib think it is able to retrieve
|
||||
an event in order to modify it.
|
||||
This can trigger errors from icalendar lib when caldav
|
||||
|
@ -432,22 +445,59 @@ def test_caldav_event_update_ok_nomock(app, caldav_conn):
|
|||
evt_id = '01234567-abcd'
|
||||
evt_url = DAV_URL + get_event_path(caldav_conn, username, evt_id)
|
||||
|
||||
event = {
|
||||
'DTSTART': '2020-02-20',
|
||||
'DTEND': '2020-03-30',
|
||||
'SUMMARY': 'foobar',
|
||||
'TRANSP': True,
|
||||
'RRULE': {'FREQ': 'MONTHLY', 'BYDAY': ['FR'], 'UNTIL': '2020-10-01'},
|
||||
}
|
||||
qs_params = {'username': username, 'event_id': evt_id}
|
||||
|
||||
responses.add(responses.GET, evt_url, body=FAKE_ICS)
|
||||
responses.add(responses.PUT, evt_url, status=201)
|
||||
responses.add(responses.PUT, evt_url, status=204, body='')
|
||||
|
||||
resp = app_post(app, url, qs_params, event)
|
||||
resp = app_post(app, url, qs_params, event_update)
|
||||
assert resp.json['err'] == 0
|
||||
assert resp.json['data']['event_id'] == evt_id
|
||||
|
||||
assert len(responses.calls) == 2
|
||||
assert responses.calls[1].request.method == 'PUT'
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_caldav_event_update_sequence_ok(app, caldav_conn):
|
||||
url = tests.utils.generic_endpoint_url('caldav', 'event/update')
|
||||
username = 'foobar'
|
||||
evt_id = '1234567890'
|
||||
evt_url = DAV_URL + get_event_path(caldav_conn, username, evt_id)
|
||||
|
||||
qs_params = {'username': username, 'event_id': evt_id}
|
||||
|
||||
responses.add(responses.GET, evt_url, body=FAKE_ICS)
|
||||
responses.add(responses.PUT, evt_url, status=204, body='')
|
||||
|
||||
# testing SEQUENCE initialization : if missing we add it
|
||||
dtend = datetime.date.fromisoformat('2024-02-29')
|
||||
resp = app_post(app, url, qs_params, {'DTEND': dtend.isoformat()})
|
||||
assert resp.json['err'] == 0
|
||||
assert len(responses.calls) == 2
|
||||
put_mock = responses.calls[1]
|
||||
assert put_mock.request.method == 'PUT'
|
||||
raw_ics = put_mock.request.body
|
||||
calendar = icalendar.Calendar.from_ical(raw_ics)
|
||||
vevent = calendar.walk('VEVENT')[0]
|
||||
assert vevent['SEQUENCE'] == 1
|
||||
|
||||
for expt_sequence in range(2, 10):
|
||||
# testing SEQUENCE incrementation on modification
|
||||
responses.reset()
|
||||
responses.add(responses.GET, evt_url, body=raw_ics)
|
||||
responses.add(responses.PUT, evt_url, status=204, body='')
|
||||
|
||||
dtend += datetime.timedelta(days=1)
|
||||
resp = app_post(app, url, qs_params, {'DTEND': dtend.isoformat()})
|
||||
assert resp.json['err'] == 0
|
||||
assert len(responses.calls) == 2
|
||||
assert responses.calls[1].request.method == 'PUT'
|
||||
raw_ics = responses.calls[1].request.body
|
||||
calendar = icalendar.Calendar.from_ical(raw_ics)
|
||||
vevent = calendar.walk('VEVENT')[0]
|
||||
assert vevent['SEQUENCE'] == expt_sequence
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_caldav_event_update_notfound(app, caldav_conn):
|
||||
|
|
Loading…
Reference in New Issue