diff options
-rw-r--r-- | pykolab/xml/event.py | 3 | ||||
-rw-r--r-- | tests/functional/test_wallace/test_007_invitationpolicy.py | 30 | ||||
-rw-r--r-- | wallace/module_invitationpolicy.py | 9 |
3 files changed, 40 insertions, 2 deletions
diff --git a/pykolab/xml/event.py b/pykolab/xml/event.py index 2d9a424..dbe938c 100644 --- a/pykolab/xml/event.py +++ b/pykolab/xml/event.py @@ -702,6 +702,9 @@ class Event(object): def get_transparency(self): return self.event.transparency() + def get_recurrence(self): + return RecurrenceRule(self.event.recurrenceRule()) + def set_attendees(self, _attendees, recursive=False): if recursive: self._attendees = [] diff --git a/tests/functional/test_wallace/test_007_invitationpolicy.py b/tests/functional/test_wallace/test_007_invitationpolicy.py index 4507dd1..cc99c73 100644 --- a/tests/functional/test_wallace/test_007_invitationpolicy.py +++ b/tests/functional/test_wallace/test_007_invitationpolicy.py @@ -445,11 +445,14 @@ class TestWallaceInvitationpolicy(unittest.TestCase): return uid - def send_itip_cancel(self, attendee_email, uid, template=None, summary="test", sequence=1, instance=None): + def send_itip_cancel(self, attendee_email, uid, template=None, summary="test", sequence=1, instance=None, thisandfuture=False): recurrence_id = '' if instance is not None: - recurrence_id = "\nRECURRENCE-ID;TZID=Europe/Berlin:" + instance.strftime('%Y%m%dT%H%M%S') + recurrence_id = "\nRECURRENCE-ID;TZID=Europe/Berlin%s:%s" % ( + ';RANGE=THISANDFUTURE' if thisandfuture else '', + instance.strftime('%Y%m%dT%H%M%S') + ) self.send_message((template if template is not None else itip_cancellation) % { 'uid': uid, @@ -1226,6 +1229,29 @@ class TestWallaceInvitationpolicy(unittest.TestCase): response = self.check_message_received(self.itip_reply_subject % { 'summary':'new booking', 'status':participant_status_label('ACCEPTED') }, self.jane['mail']) self.assertIsInstance(response, email.message.Message) + def test_017_cancel_thisandfuture(self): + self.purge_mailbox(self.john['mailbox']) + + start = datetime.datetime(2015,5,4, 6,30,0) + uid = self.send_itip_invitation(self.mark['mail'], summary="recurring", start=start, template=itip_recurring) + + response = self.check_message_received(self.itip_reply_subject % { 'summary':'recurring', 'status':participant_status_label('ACCEPTED') }, self.mark['mail']) + self.assertIsInstance(response, email.message.Message) + + event = self.check_user_calendar_event(self.mark['kolabcalendarfolder'], uid) + self.assertIsInstance(event, pykolab.xml.Event) + + exdate = start + datetime.timedelta(days=14) + self.send_itip_cancel(self.mark['mail'], uid, summary="recurring ended", instance=exdate, thisandfuture=True) + + time.sleep(10) + event = self.check_user_calendar_event(self.mark['kolabcalendarfolder'], uid) + self.assertIsInstance(event, pykolab.xml.Event) + + rrule = event.get_recurrence().to_dict() + self.assertIsInstance(rrule['until'], datetime.datetime) + self.assertEqual(rrule['until'].strftime('%Y%m%d'), (exdate - datetime.timedelta(days=1)).strftime('%Y%m%d')) + def test_018_invite_individual_occurrences(self): self.purge_mailbox(self.john['mailbox']) diff --git a/wallace/module_invitationpolicy.py b/wallace/module_invitationpolicy.py index 4ac7eef..993cd5e 100644 --- a/wallace/module_invitationpolicy.py +++ b/wallace/module_invitationpolicy.py @@ -18,6 +18,7 @@ # import datetime +import pytz import os import tempfile import time @@ -656,6 +657,14 @@ def process_itip_cancel(itip_event, policy, recipient_email, sender_email, recei )) return MESSAGE_FORWARD + # on this-and-future cancel requests, set the recurrence until date on the master event + if itip_event['recurrence-id'] and master and itip_event['xml'].get_thisandfuture(): + rrule = master.get_recurrence() + rrule.set_count(0) + rrule.set_until(existing.get_start().astimezone(pytz.utc) + datetime.timedelta(days=-1)) + master.set_recurrence(rrule) + existing.set_recurrence_id(existing.get_recurrence_id(), True) + existing.set_status('CANCELLED') existing.set_transparency(True) if update_object(existing, receiving_user, master): |