pykolab/xml tests/functional wallace/module_invitationpolicy.py

Thomas Brüderli bruederli at kolabsys.com
Fri Feb 20 10:44:27 CET 2015


 pykolab/xml/event.py                                       |    3 +
 tests/functional/test_wallace/test_007_invitationpolicy.py |   30 ++++++++++++-
 wallace/module_invitationpolicy.py                         |    9 +++
 3 files changed, 40 insertions(+), 2 deletions(-)

New commits:
commit 05f1d4e5787acde1835337ca5dff4b86470fe53e
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Fri Feb 20 10:44:22 2015 +0100

    Support iTip CANCEL requests with THISANDFUTRE range

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):




More information about the commits mailing list