tests/functional wallace/module_invitationpolicy.py

Thomas Brüderli bruederli at kolabsys.com
Mon Feb 2 18:32:40 CET 2015


 tests/functional/test_wallace/test_007_invitationpolicy.py |   32 +++++++++++++
 wallace/module_invitationpolicy.py                         |   12 ++++
 2 files changed, 43 insertions(+), 1 deletion(-)

New commits:
commit 8bd5f266bcb6a230274984e085260795c052919d
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Mon Feb 2 18:31:41 2015 +0100

    Implement additional policy value *_SAVE_AND_FORWARD to still pass through the original iTip message after saving it to the invitation calendar (#4269)

diff --git a/tests/functional/test_wallace/test_007_invitationpolicy.py b/tests/functional/test_wallace/test_007_invitationpolicy.py
index d18e1f3..dee15bf 100644
--- a/tests/functional/test_wallace/test_007_invitationpolicy.py
+++ b/tests/functional/test_wallace/test_007_invitationpolicy.py
@@ -14,6 +14,7 @@ from pykolab.translate import _
 from pykolab.xml import event_from_message
 from pykolab.xml import todo_from_message
 from pykolab.xml import participant_status_label
+from pykolab.itip import events_from_message
 from email import message_from_string
 from twisted.trial import unittest
 
@@ -287,6 +288,17 @@ class TestWallaceInvitationpolicy(unittest.TestCase):
             'kolabinvitationpolicy': ['ACT_ACCEPT','ACT_UPDATE_AND_NOTIFY']
         }
 
+        self.lucy = {
+            'displayname': 'Lucy Meyer',
+            'mail': 'lucy.meyer at example.org',
+            'dn': 'uid=meyer,ou=People,dc=example,dc=org',
+            'preferredlanguage': 'en_US',
+            'mailbox': 'user/lucy.meyer at example.org',
+            'kolabcalendarfolder': 'user/lucy.meyer/Calendar at example.org',
+            'kolabtasksfolder': 'user/lucy.meyer/Tasks at example.org',
+            'kolabinvitationpolicy': ['ALL_SAVE_AND_FORWARD','ACT_UPDATE_AND_NOTIFY']
+        }
+
         self.external = {
             'displayname': 'Bob External',
             'mail': 'bob.external at gmail.com'
@@ -297,6 +309,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase):
         user_add("Jane", "Manager", kolabinvitationpolicy=self.jane['kolabinvitationpolicy'], preferredlanguage=self.jane['preferredlanguage'])
         user_add("Jack", "Tentative", kolabinvitationpolicy=self.jack['kolabinvitationpolicy'], preferredlanguage=self.jack['preferredlanguage'])
         user_add("Mark", "German", kolabinvitationpolicy=self.mark['kolabinvitationpolicy'], preferredlanguage=self.mark['preferredlanguage'])
+        user_add("Lucy", "Meyer", kolabinvitationpolicy=self.lucy['kolabinvitationpolicy'], preferredlanguage=self.lucy['preferredlanguage'])
 
         time.sleep(1)
         from tests.functional.synchronize import synchronize_once
@@ -655,6 +668,25 @@ class TestWallaceInvitationpolicy(unittest.TestCase):
         self.assertEqual(event.get_summary(), "test2")
         self.assertEqual(event.get_attendee(self.jack['mail']).get_participant_status(), kolabformat.PartNeedsAction)
 
+    def test_004_copy_to_calendar_and_forward(self):
+        uid = self.send_itip_invitation(self.lucy['mail'], datetime.datetime(2015,2,11, 14,0,0), summary="test forward")
+        response = self.check_message_received(self.itip_reply_subject % { 'summary':'test forward', 'status':participant_status_label('ACCEPTED') }, self.lucy['mail'], self.lucy['mailbox'])
+        self.assertEqual(response, None, "No reply expected")
+
+        event = self.check_user_calendar_event(self.lucy['kolabcalendarfolder'], uid)
+        self.assertIsInstance(event, pykolab.xml.Event)
+        self.assertEqual(event.get_summary(), "test forward")
+        self.assertEqual(event.get_attendee(self.lucy['mail']).get_participant_status(), kolabformat.PartNeedsAction)
+
+        # find original itip invitation in user's inbox
+        message = self.check_message_received('"test"', 'john.doe at example.org', self.lucy['mailbox'])
+        self.assertIsInstance(message, email.message.Message)
+
+        itips = events_from_message(message)
+        self.assertEqual(len(itips), 1);
+        self.assertEqual(itips[0]['method'], 'REQUEST');
+        self.assertEqual(itips[0]['uid'], uid);
+
 
     def test_005_invite_rescheduling_accept(self):
         self.purge_mailbox(self.john['mailbox'])
diff --git a/wallace/module_invitationpolicy.py b/wallace/module_invitationpolicy.py
index d473d52..0a38fcc 100644
--- a/wallace/module_invitationpolicy.py
+++ b/wallace/module_invitationpolicy.py
@@ -62,12 +62,14 @@ COND_IF_AVAILABLE  = 64
 COND_IF_CONFLICT   = 128
 COND_TENTATIVE     = 256
 COND_NOTIFY        = 512
+COND_FORWARD       = 4096
 COND_TYPE_EVENT    = 1024
 COND_TYPE_TASK     = 2048
 COND_TYPE_ALL      = COND_TYPE_EVENT + COND_TYPE_TASK
 
 ACT_TENTATIVE         = ACT_ACCEPT + COND_TENTATIVE
 ACT_UPDATE_AND_NOTIFY = ACT_UPDATE + COND_NOTIFY
+ACT_SAVE_AND_FORWARD  = ACT_SAVE_TO_FOLDER + COND_FORWARD
 
 FOLDER_TYPE_ANNOTATION = '/vendor/kolab/folder-type'
 
@@ -83,6 +85,7 @@ policy_name_map = {
     'ALL_UPDATE':                     ACT_UPDATE + COND_TYPE_ALL,
     'ALL_UPDATE_AND_NOTIFY':          ACT_UPDATE_AND_NOTIFY + COND_TYPE_ALL,
     'ALL_SAVE_TO_FOLDER':             ACT_SAVE_TO_FOLDER + COND_TYPE_ALL,
+    'ALL_SAVE_AND_FORWARD':           ACT_SAVE_AND_FORWARD + COND_TYPE_ALL,
     # event related policy values
     'EVENT_MANUAL':                   ACT_MANUAL + COND_TYPE_EVENT,
     'EVENT_ACCEPT':                   ACT_ACCEPT + COND_TYPE_EVENT,
@@ -96,6 +99,7 @@ policy_name_map = {
     'EVENT_DELEGATE_IF_CONFLICT':     ACT_DELEGATE + COND_IF_CONFLICT + COND_TYPE_EVENT,
     'EVENT_REJECT_IF_CONFLICT':       ACT_REJECT + COND_IF_CONFLICT + COND_TYPE_EVENT,
     'EVENT_SAVE_TO_FOLDER':           ACT_SAVE_TO_FOLDER + COND_TYPE_EVENT,
+    'EVENT_SAVE_AND_FORWARD':         ACT_SAVE_AND_FORWARD + COND_TYPE_EVENT,
     # task related policy values
     'TASK_MANUAL':                    ACT_MANUAL + COND_TYPE_TASK,
     'TASK_ACCEPT':                    ACT_ACCEPT + COND_TYPE_TASK,
@@ -104,6 +108,7 @@ policy_name_map = {
     'TASK_UPDATE':                    ACT_UPDATE + COND_TYPE_TASK,
     'TASK_UPDATE_AND_NOTIFY':         ACT_UPDATE_AND_NOTIFY + COND_TYPE_TASK,
     'TASK_SAVE_TO_FOLDER':            ACT_SAVE_TO_FOLDER + COND_TYPE_TASK,
+    'TASK_SAVE_AND_FORWARD':          ACT_SAVE_AND_FORWARD + COND_TYPE_TASK,
     # legacy values
     'ACT_MANUAL':                     ACT_MANUAL + COND_TYPE_ALL,
     'ACT_ACCEPT':                     ACT_ACCEPT + COND_TYPE_ALL,
@@ -117,6 +122,7 @@ policy_name_map = {
     'ACT_UPDATE':                     ACT_UPDATE + COND_TYPE_ALL,
     'ACT_UPDATE_AND_NOTIFY':          ACT_UPDATE_AND_NOTIFY + COND_TYPE_ALL,
     'ACT_SAVE_TO_CALENDAR':           ACT_SAVE_TO_FOLDER + COND_TYPE_EVENT,
+    'ACT_SAVE_AND_FORWARD':           ACT_SAVE_AND_FORWARD + COND_TYPE_EVENT,
 }
 
 policy_value_map = dict([(v &~ COND_TYPE_ALL, k) for (k, v) in policy_name_map.iteritems()])
@@ -467,7 +473,11 @@ def process_itip_request(itip_event, policy, recipient_email, sender_email, rece
         if not nonpart or existing:
             # save new copy from iTip
             if store_object(itip_event['xml'], receiving_user, targetfolder):
-                return MESSAGE_PROCESSED
+                if policy & COND_FORWARD:
+                    log.debug(_("Forward invitation for notification"), level=5)
+                    return MESSAGE_FORWARD
+                else:
+                    return MESSAGE_PROCESSED
 
     return None
 




More information about the commits mailing list