diff options
Diffstat (limited to 'tests/functional')
-rw-r--r-- | tests/functional/test_wallace/test_005_resource_invitation.py | 3 | ||||
-rw-r--r-- | tests/functional/test_wallace/test_007_invitationpolicy.py | 258 |
2 files changed, 226 insertions, 35 deletions
diff --git a/tests/functional/test_wallace/test_005_resource_invitation.py b/tests/functional/test_wallace/test_005_resource_invitation.py index a4e1ebe..4e69f2f 100644 --- a/tests/functional/test_wallace/test_005_resource_invitation.py +++ b/tests/functional/test_wallace/test_005_resource_invitation.py @@ -189,6 +189,9 @@ class TestResourceInvitation(unittest.TestCase): @classmethod def setup_class(self, *args, **kw): + # set language to default + pykolab.translate.setUserLanguage(conf.get('kolab','default_locale')) + self.itip_reply_subject = _("Reservation Request for %(summary)s was %(status)s") from tests.functional.purge_users import purge_users diff --git a/tests/functional/test_wallace/test_007_invitationpolicy.py b/tests/functional/test_wallace/test_007_invitationpolicy.py index bdbfc98..dffc9df 100644 --- a/tests/functional/test_wallace/test_007_invitationpolicy.py +++ b/tests/functional/test_wallace/test_007_invitationpolicy.py @@ -12,6 +12,7 @@ from wallace import module_resources 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 email import message_from_string from twisted.trial import unittest @@ -126,6 +127,75 @@ END:VEVENT END:VCALENDAR """ +itip_todo = """ +BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//Roundcube//Roundcube libcalendaring 1.1-git//Sabre//Sabre VObject + 2.1.3//EN +CALSCALE:GREGORIAN +METHOD:REQUEST +BEGIN:VTODO +UID:%(uid)s +CREATED;VALUE=DATE-TIME:20140731T100704Z +DTSTAMP;VALUE=DATE-TIME:20140820T101333Z +DTSTART;VALUE=DATE-TIME;TZID=Europe/Berlin:%(start)s +DUE;VALUE=DATE-TIME;TZID=Europe/Berlin:%(end)s +SUMMARY:%(summary)s +SEQUENCE:%(sequence)d +PRIORITY:1 +STATUS:NEEDS-ACTION +PERCENT-COMPLETE:0 +ORGANIZER;CN="Doe, John":mailto:john.doe@example.org +ATTENDEE;PARTSTAT=%(partstat)s;ROLE=REQ-PARTICIPANT:mailto:%(mailto)s +END:VTODO +END:VCALENDAR +""" + +itip_todo_reply = """ +BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//Roundcube//Roundcube libcalendaring 1.1-git//Sabre//Sabre VObject + 2.1.3//EN +CALSCALE:GREGORIAN +METHOD:REPLY +BEGIN:VTODO +UID:%(uid)s +CREATED;VALUE=DATE-TIME:20140731T100704Z +DTSTAMP;VALUE=DATE-TIME:20140821T085424Z +DTSTART;VALUE=DATE-TIME;TZID=Europe/Berlin:%(start)s +DUE;VALUE=DATE-TIME;TZID=Europe/Berlin:%(end)s +SUMMARY:%(summary)s +SEQUENCE:%(sequence)d +PRIORITY:1 +STATUS:NEEDS-ACTION +PERCENT-COMPLETE:40 +ATTENDEE;PARTSTAT=%(partstat)s;ROLE=REQ-PARTICIPANT;CUTYPE=INDIVIDUAL:mailto:%(mailto)s +ORGANIZER;CN="Doe, John":mailto:%(organizer)s +END:VTODO +END:VCALENDAR +""" + +itip_todo_cancel = """ +BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//Roundcube//Roundcube libcalendaring 1.1-git//Sabre//Sabre VObject + 2.1.3//EN +CALSCALE:GREGORIAN +METHOD:CANCEL +BEGIN:VTODO +UID:%(uid)s +CREATED;VALUE=DATE-TIME:20140731T100704Z +DTSTAMP;VALUE=DATE-TIME:20140820T101333Z +SUMMARY:%(summary)s +SEQUENCE:%(sequence)d +PRIORITY:1 +STATUS:CANCELLED +ORGANIZER;CN="Doe, John":mailto:john.doe@example.org +ATTENDEE;PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT:mailto:%(mailto)s +END:VTODO +END:VCALENDAR +""" + mime_message = """MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=_c8894dbdb8baeedacae836230e3436fd" @@ -164,6 +234,9 @@ class TestWallaceInvitationpolicy(unittest.TestCase): @classmethod def setup_class(self, *args, **kw): + # set language to default + pykolab.translate.setUserLanguage(conf.get('kolab','default_locale')) + self.itip_reply_subject = _('"%(summary)s" has been %(status)s') from tests.functional.purge_users import purge_users @@ -175,7 +248,8 @@ class TestWallaceInvitationpolicy(unittest.TestCase): 'dn': 'uid=doe,ou=People,dc=example,dc=org', 'preferredlanguage': 'en_US', 'mailbox': 'user/john.doe@example.org', - 'kolabtargetfolder': 'user/john.doe/Calendar@example.org', + 'kolabcalendarfolder': 'user/john.doe/Calendar@example.org', + 'kolabtasksfolder': 'user/john.doe/Tasks@example.org', 'kolabinvitationpolicy': ['ACT_UPDATE_AND_NOTIFY','ACT_MANUAL'] } @@ -185,8 +259,9 @@ class TestWallaceInvitationpolicy(unittest.TestCase): 'dn': 'uid=manager,ou=People,dc=example,dc=org', 'preferredlanguage': 'en_US', 'mailbox': 'user/jane.manager@example.org', - 'kolabtargetfolder': 'user/jane.manager/Calendar@example.org', - 'kolabinvitationpolicy': ['ACT_ACCEPT_IF_NO_CONFLICT','ACT_REJECT_IF_CONFLICT','ACT_UPDATE'] + 'kolabcalendarfolder': 'user/jane.manager/Calendar@example.org', + 'kolabtasksfolder': 'user/jane.manager/Tasks@example.org', + 'kolabinvitationpolicy': ['ACT_ACCEPT_IF_NO_CONFLICT','ACT_REJECT_IF_CONFLICT','TASK_ACCEPT','ACT_UPDATE'] } self.jack = { @@ -195,8 +270,9 @@ class TestWallaceInvitationpolicy(unittest.TestCase): 'dn': 'uid=tentative,ou=People,dc=example,dc=org', 'preferredlanguage': 'en_US', 'mailbox': 'user/jack.tentative@example.org', - 'kolabtargetfolder': 'user/jack.tentative/Calendar@example.org', - 'kolabinvitationpolicy': ['ACT_TENTATIVE_IF_NO_CONFLICT','ACT_SAVE_TO_CALENDAR','ACT_UPDATE'] + 'kolabcalendarfolder': 'user/jack.tentative/Calendar@example.org', + 'kolabtasksfolder': 'user/jack.tentative/Tasks@example.org', + 'kolabinvitationpolicy': ['ACT_TENTATIVE_IF_NO_CONFLICT','ALL_SAVE_TO_FOLDER','ACT_UPDATE'] } self.mark = { @@ -205,7 +281,8 @@ class TestWallaceInvitationpolicy(unittest.TestCase): 'dn': 'uid=german,ou=People,dc=example,dc=org', 'preferredlanguage': 'de_DE', 'mailbox': 'user/mark.german@example.org', - 'kolabtargetfolder': 'user/mark.german/Calendar@example.org', + 'kolabcalendarfolder': 'user/mark.german/Calendar@example.org', + 'kolabtasksfolder': 'user/mark.german/Tasks@example.org', 'kolabinvitationpolicy': ['ACT_ACCEPT','ACT_UPDATE_AND_NOTIFY'] } @@ -298,8 +375,8 @@ class TestWallaceInvitationpolicy(unittest.TestCase): return uid - def send_itip_cancel(self, attendee_email, uid, summary="test", sequence=1): - self.send_message(itip_cancellation % { + def send_itip_cancel(self, attendee_email, uid, template=None, summary="test", sequence=1): + self.send_message((template if template is not None else itip_cancellation) % { 'uid': uid, 'mailto': attendee_email, 'summary': summary, @@ -342,7 +419,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): imap = IMAP() imap.connect() - mailbox = imap.folder_quote(user['kolabtargetfolder']) + mailbox = imap.folder_quote(user['kolabcalendarfolder']) imap.set_acl(mailbox, "cyrus-admin", "lrswipkxtecda") imap.imap.m.select(mailbox) @@ -355,11 +432,45 @@ class TestWallaceInvitationpolicy(unittest.TestCase): return event.get_uid() + def create_task_assignment(self, due=None, summary="test", sequence=0, user=None, attendees=None): + if due is None: + due = datetime.datetime.now(pytz.timezone("Europe/Berlin")) + datetime.timedelta(days=2) + if user is None: + user = self.john + if attendees is None: + attendees = [self.jane] + + todo = pykolab.xml.Todo() + todo.set_due(due) + todo.set_organizer(user['mail'], user['displayname']) + + for attendee in attendees: + todo.add_attendee(attendee['mail'], attendee['displayname'], role="REQ-PARTICIPANT", participant_status="NEEDS-ACTION", rsvp=True) + + todo.set_summary(summary) + todo.set_sequence(sequence) + + imap = IMAP() + imap.connect() + + mailbox = imap.folder_quote(user['kolabtasksfolder']) + imap.set_acl(mailbox, "cyrus-admin", "lrswipkxtecda") + imap.imap.m.select(mailbox) + + result = imap.imap.m.append( + mailbox, + None, + None, + todo.to_message().as_string() + ) + + return todo.get_uid() + def update_calendar_event(self, uid, start=None, summary=None, sequence=0, user=None): if user is None: user = self.john - event = self.check_user_calendar_event(user['kolabtargetfolder'], uid) + event = self.check_user_calendar_event(user['kolabcalendarfolder'], uid) if event: if start is not None: event.set_start(start) @@ -371,7 +482,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): imap = IMAP() imap.connect() - mailbox = imap.folder_quote(user['kolabtargetfolder']) + mailbox = imap.folder_quote(user['kolabcalendarfolder']) imap.set_acl(mailbox, "cyrus-admin", "lrswipkxtecda") imap.imap.m.select(mailbox) @@ -416,6 +527,9 @@ class TestWallaceInvitationpolicy(unittest.TestCase): return found def check_user_calendar_event(self, mailbox, uid=None): + return self.check_user_imap_object(mailbox, uid) + + def check_user_imap_object(self, mailbox, uid=None, type='event'): imap = IMAP() imap.connect() @@ -429,16 +543,20 @@ class TestWallaceInvitationpolicy(unittest.TestCase): while not found and retries > 0: retries -= 1 - typ, data = imap.imap.m.search(None, '(UNDELETED HEADER SUBJECT "%s")' % (uid) if uid else '(UNDELETED HEADER X-Kolab-Type "application/x-vnd.kolab.event")') + typ, data = imap.imap.m.search(None, '(UNDELETED HEADER SUBJECT "%s")' % (uid) if uid else '(UNDELETED HEADER X-Kolab-Type "application/x-vnd.kolab.' + type + '")') for num in data[0].split(): typ, data = imap.imap.m.fetch(num, '(RFC822)') - event_message = message_from_string(data[0][1]) + object_message = message_from_string(data[0][1]) # return matching UID or first event found - if uid and event_message['subject'] != uid: + if uid and object_message['subject'] != uid: continue - found = event_from_message(event_message) + if type == 'task': + found = todo_from_message(object_message) + else: + found = event_from_message(object_message) + if found: break @@ -468,7 +586,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }, self.jane['mail']) self.assertIsInstance(response, email.message.Message) - event = self.check_user_calendar_event(self.jane['kolabtargetfolder'], uid) + event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) self.assertIsInstance(event, pykolab.xml.Event) self.assertEqual(event.get_summary(), "test") @@ -476,7 +594,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): self.send_itip_update(self.jane['mail'], uid, start, summary="test updated", sequence=0, partstat='ACCEPTED') time.sleep(10) - event = self.check_user_calendar_event(self.jane['kolabtargetfolder'], uid) + event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) self.assertIsInstance(event, pykolab.xml.Event) self.assertEqual(event.get_summary(), "test updated") self.assertEqual(event.get_attendee(self.jane['mail']).get_participant_status(), kolabformat.PartAccepted) @@ -489,7 +607,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): response = self.check_message_received(self.itip_reply_subject % { 'summary':'test2', 'status':participant_status_label('DECLINED') }, self.jane['mail']) self.assertIsInstance(response, email.message.Message) - event = self.check_user_calendar_event(self.jane['kolabtargetfolder'], uid) + event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) self.assertIsInstance(event, pykolab.xml.Event) self.assertEqual(event.get_summary(), "test2") @@ -515,7 +633,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): response = self.check_message_received(self.itip_reply_subject % { 'summary':'test2', 'status':participant_status_label('DECLINED') }, self.jack['mail']) self.assertEqual(response, None, "No reply expected") - event = self.check_user_calendar_event(self.jack['kolabtargetfolder'], uid) + event = self.check_user_calendar_event(self.jack['kolabcalendarfolder'], uid) self.assertIsInstance(event, pykolab.xml.Event) self.assertEqual(event.get_summary(), "test2") self.assertEqual(event.get_attendee(self.jack['mail']).get_participant_status(), kolabformat.PartNeedsAction) @@ -530,7 +648,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }, self.jane['mail']) self.assertIsInstance(response, email.message.Message) - event = self.check_user_calendar_event(self.jane['kolabtargetfolder'], uid) + event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) self.assertIsInstance(event, pykolab.xml.Event) self.assertEqual(event.get_summary(), "test") @@ -543,7 +661,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }, self.jane['mail']) self.assertIsInstance(response, email.message.Message) - event = self.check_user_calendar_event(self.jane['kolabtargetfolder'], uid) + event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) self.assertIsInstance(event, pykolab.xml.Event) self.assertEqual(event.get_start(), new_start) self.assertEqual(event.get_sequence(), 1) @@ -551,7 +669,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): def test_005_invite_rescheduling_reject(self): self.purge_mailbox(self.john['mailbox']) - self.purge_mailbox(self.jack['kolabtargetfolder']) + self.purge_mailbox(self.jack['kolabcalendarfolder']) start = datetime.datetime(2014,8,9, 17,0,0, tzinfo=pytz.timezone("Europe/Berlin")) uid = self.send_itip_invitation(self.jack['mail'], start) @@ -568,7 +686,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): self.assertEqual(response, None) # verify re-scheduled copy in jack's calendar with NEEDS-ACTION - event = self.check_user_calendar_event(self.jack['kolabtargetfolder'], uid) + event = self.check_user_calendar_event(self.jack['kolabcalendarfolder'], uid) self.assertIsInstance(event, pykolab.xml.Event) self.assertEqual(event.get_start(), new_start) self.assertEqual(event.get_sequence(), 1) @@ -584,7 +702,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): start = datetime.datetime(2014,8,18, 14,30,0, tzinfo=pytz.timezone("Europe/Berlin")) uid = self.create_calendar_event(start, user=self.john) - event = self.check_user_calendar_event(self.john['kolabtargetfolder'], uid) + event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) self.assertIsInstance(event, pykolab.xml.Event) # send a reply from jane to john @@ -592,7 +710,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): # check for the updated event in john's calendar time.sleep(10) - event = self.check_user_calendar_event(self.john['kolabtargetfolder'], uid) + event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) self.assertIsInstance(event, pykolab.xml.Event) attendee = event.get_attendee(self.jane['mail']) @@ -611,7 +729,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): start = datetime.datetime(2014,8,28, 14,30,0, tzinfo=pytz.timezone("Europe/Berlin")) uid = self.create_calendar_event(start, user=self.john) - event = self.check_user_calendar_event(self.john['kolabtargetfolder'], uid) + event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) self.assertIsInstance(event, pykolab.xml.Event) # send a reply from jane to john @@ -619,7 +737,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): # check for the updated event in john's calendar time.sleep(10) - event = self.check_user_calendar_event(self.john['kolabtargetfolder'], uid) + event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) self.assertIsInstance(event, pykolab.xml.Event) attendee = event.get_attendee(self.jane['mail']) @@ -646,7 +764,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): self.send_itip_cancel(self.jane['mail'], uid, summary="cancelled") time.sleep(10) - event = self.check_user_calendar_event(self.jane['kolabtargetfolder'], uid) + event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) self.assertIsInstance(event, pykolab.xml.Event) self.assertEqual(event.get_summary(), "cancelled") self.assertEqual(event.get_status(True), 'CANCELLED') @@ -723,7 +841,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): # verify jane's attendee status was not updated time.sleep(10) - event = self.check_user_calendar_event(self.john['kolabtargetfolder'], uid) + event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) self.assertIsInstance(event, pykolab.xml.Event) self.assertEqual(event.get_sequence(), 2) self.assertEqual(event.get_attendee(self.jane['mail']).get_participant_status(), kolabformat.PartNeedsAction) @@ -735,7 +853,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): start = datetime.datetime(2014,8,21, 13,0,0, tzinfo=pytz.timezone("Europe/Berlin")) uid = self.create_calendar_event(start, user=self.john, attendees=[self.jane, self.jack, self.external]) - event = self.check_user_calendar_event(self.john['kolabtargetfolder'], uid) + event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) self.assertIsInstance(event, pykolab.xml.Event) # send invitations to jack and jane @@ -745,7 +863,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): # wait for replies from jack and jane to be processed and propagated time.sleep(10) - event = self.check_user_calendar_event(self.john['kolabtargetfolder'], uid) + event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) self.assertIsInstance(event, pykolab.xml.Event) # check updated event in organizer's calendar @@ -753,12 +871,12 @@ class TestWallaceInvitationpolicy(unittest.TestCase): self.assertEqual(event.get_attendee(self.jack['mail']).get_participant_status(), kolabformat.PartTentative) # check updated partstats in jane's calendar - janes = self.check_user_calendar_event(self.jane['kolabtargetfolder'], uid) + janes = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) self.assertEqual(janes.get_attendee(self.jane['mail']).get_participant_status(), kolabformat.PartAccepted) self.assertEqual(janes.get_attendee(self.jack['mail']).get_participant_status(), kolabformat.PartTentative) # check updated partstats in jack's calendar - jacks = self.check_user_calendar_event(self.jack['kolabtargetfolder'], uid) + jacks = self.check_user_calendar_event(self.jack['kolabcalendarfolder'], uid) self.assertEqual(jacks.get_attendee(self.jane['mail']).get_participant_status(), kolabformat.PartAccepted) self.assertEqual(jacks.get_attendee(self.jack['mail']).get_participant_status(), kolabformat.PartTentative) @@ -773,7 +891,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase): # wait for replies to be processed and propagated time.sleep(10) - event = self.check_user_calendar_event(self.john['kolabtargetfolder'], uid) + event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) self.assertIsInstance(event, pykolab.xml.Event) # check updated event in organizer's calendar (jack didn't reply yet) @@ -781,8 +899,78 @@ class TestWallaceInvitationpolicy(unittest.TestCase): self.assertEqual(event.get_attendee(self.jack['mail']).get_participant_status(), kolabformat.PartTentative) # check partstats in jack's calendar: jack's status should remain needs-action - jacks = self.check_user_calendar_event(self.jack['kolabtargetfolder'], uid) + jacks = self.check_user_calendar_event(self.jack['kolabcalendarfolder'], uid) self.assertEqual(jacks.get_attendee(self.jane['mail']).get_participant_status(), kolabformat.PartAccepted) self.assertEqual(jacks.get_attendee(self.jack['mail']).get_participant_status(), kolabformat.PartNeedsAction) + def test_011_task_assignment_accept(self): + start = datetime.datetime(2014,9,10, 19,0,0) + uid = self.send_itip_invitation(self.jane['mail'], start, summary='work', template=itip_todo) + + response = self.check_message_received(self.itip_reply_subject % { 'summary':'work', 'status':participant_status_label('ACCEPTED') }, self.jane['mail']) + self.assertIsInstance(response, email.message.Message) + + todo = self.check_user_imap_object(self.jane['kolabtasksfolder'], uid, 'task') + self.assertIsInstance(todo, pykolab.xml.Todo) + self.assertEqual(todo.get_summary(), "work") + + # send update with the same sequence: no re-scheduling + self.send_itip_update(self.jane['mail'], uid, start, summary='work updated', template=itip_todo, sequence=0, partstat='ACCEPTED') + + response = self.check_message_received(self.itip_reply_subject % { 'summary':'work updated', 'status':participant_status_label('ACCEPTED') }, self.jane['mail']) + self.assertEqual(response, None) + + time.sleep(10) + todo = self.check_user_imap_object(self.jane['kolabtasksfolder'], uid, 'task') + self.assertIsInstance(todo, pykolab.xml.Todo) + self.assertEqual(todo.get_summary(), "work updated") + self.assertEqual(todo.get_attendee(self.jane['mail']).get_participant_status(), kolabformat.PartAccepted) + + + def test_012_task_assignment_reply(self): + self.purge_mailbox(self.john['mailbox']) + + due = datetime.datetime(2014,9,12, 14,0,0, tzinfo=pytz.timezone("Europe/Berlin")) + uid = self.create_task_assignment(due, user=self.john) + + todo = self.check_user_imap_object(self.john['kolabtasksfolder'], uid, 'task') + self.assertIsInstance(todo, pykolab.xml.Todo) + + # send a reply from jane to john + partstat = 'DECLINED' + self.send_itip_reply(uid, self.jane['mail'], self.john['mail'], start=due, template=itip_todo_reply, partstat=partstat) + + # check for the updated task in john's tasklist + time.sleep(10) + todo = self.check_user_imap_object(self.john['kolabtasksfolder'], uid, 'task') + self.assertIsInstance(todo, pykolab.xml.Todo) + + attendee = todo.get_attendee(self.jane['mail']) + self.assertIsInstance(attendee, pykolab.xml.Attendee) + self.assertEqual(attendee.get_participant_status(True), partstat) + + # this should trigger an update notification + notification = self.check_message_received(_('"%s" has been updated') % ('test'), self.john['mail']) + self.assertIsInstance(notification, email.message.Message) + + notification_text = str(notification.get_payload()); + self.assertIn(participant_status_label(partstat), notification_text) + + + def test_013_task_cancellation(self): + uid = self.send_itip_invitation(self.jane['mail'], summary='more work', template=itip_todo) + + time.sleep(10) + self.send_itip_cancel(self.jane['mail'], uid, template=itip_todo_cancel, summary="cancelled") + + time.sleep(10) + todo = self.check_user_imap_object(self.jane['kolabtasksfolder'], uid, 'task') + self.assertIsInstance(todo, pykolab.xml.Todo) + self.assertEqual(todo.get_summary(), "more work") + self.assertEqual(todo.get_status(True), 'CANCELLED') + + # this should trigger a notification message + notification = self.check_message_received(_('"%s" has been cancelled') % ('more work'), self.john['mail'], mailbox=self.jane['mailbox']) + self.assertIsInstance(notification, email.message.Message) + |