summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorThomas Bruederli <bruederli@kolabsys.com>2014-08-21 10:31:16 -0400
committerThomas Bruederli <bruederli@kolabsys.com>2014-08-21 10:31:16 -0400
commitb05296d7d41c7a42620d996641db9054e9da2f23 (patch)
treeea9fe059d07a142a67cbcb3f8be7c9ce21d13582 /tests
parentc5978eb22295fea9a09066dc177a5d167c58fb2c (diff)
downloadpykolab-b05296d7d41c7a42620d996641db9054e9da2f23.tar.gz
Refactored the wallace invitationpolicy module to work for automated task iTip processing as well + add functional tests for task assignments (#3240)
Diffstat (limited to 'tests')
-rw-r--r--tests/functional/test_wallace/test_005_resource_invitation.py3
-rw-r--r--tests/functional/test_wallace/test_007_invitationpolicy.py258
-rw-r--r--tests/unit/test-012-wallace_invitationpolicy.py32
-rw-r--r--tests/unit/test-016-todo.py1
4 files changed, 243 insertions, 51 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)
+
diff --git a/tests/unit/test-012-wallace_invitationpolicy.py b/tests/unit/test-012-wallace_invitationpolicy.py
index aabf676..3366950 100644
--- a/tests/unit/test-012-wallace_invitationpolicy.py
+++ b/tests/unit/test-012-wallace_invitationpolicy.py
@@ -117,16 +117,18 @@ class TestWallaceInvitationpolicy(unittest.TestCase):
def test_003_get_matching_invitation_policy(self):
user = { 'kolabinvitationpolicy': [
- 'ACT_ACCEPT:example.org',
- 'ACT_REJECT:gmail.com',
- 'ACT_MANUAL:*'
+ 'TASK_REJECT:*',
+ 'EVENT_ACCEPT:example.org',
+ 'EVENT_REJECT:gmail.com',
+ 'ALL_MANUAL:*'
] }
- self.assertEqual(MIP.get_matching_invitation_policies(user, 'a@fastmail.net'), [MIP.ACT_MANUAL])
- self.assertEqual(MIP.get_matching_invitation_policies(user, 'b@example.org'), [MIP.ACT_ACCEPT,MIP.ACT_MANUAL])
- self.assertEqual(MIP.get_matching_invitation_policies(user, 'c@gmail.com'), [MIP.ACT_REJECT,MIP.ACT_MANUAL])
+ self.assertEqual(MIP.get_matching_invitation_policies(user, 'a@fastmail.net', MIP.COND_TYPE_EVENT), [MIP.ACT_MANUAL])
+ self.assertEqual(MIP.get_matching_invitation_policies(user, 'b@example.org', MIP.COND_TYPE_EVENT), [MIP.ACT_ACCEPT, MIP.ACT_MANUAL])
+ self.assertEqual(MIP.get_matching_invitation_policies(user, 'c@gmail.com', MIP.COND_TYPE_EVENT), [MIP.ACT_REJECT, MIP.ACT_MANUAL])
+ self.assertEqual(MIP.get_matching_invitation_policies(user, 'd@somedomain.net', MIP.COND_TYPE_TASK), [MIP.ACT_REJECT, MIP.ACT_MANUAL])
user = { 'kolabinvitationpolicy': ['ACT_ACCEPT:example.org', 'ACT_MANUAL:others'] }
- self.assertEqual(MIP.get_matching_invitation_policies(user, 'd@somedomain.net'), [MIP.ACT_MANUAL])
+ self.assertEqual(MIP.get_matching_invitation_policies(user, 'd@somedomain.net', MIP.COND_TYPE_ALL), [MIP.ACT_MANUAL])
def test_004_write_locks(self):
user = { 'cn': 'John Doe', 'mail': "doe@example.org" }
@@ -150,12 +152,12 @@ class TestWallaceInvitationpolicy(unittest.TestCase):
accept_some = [ 'ACT_ACCEPT_IF_NO_CONFLICT', 'ACT_SAVE_TO_CALENDAR:example.org', 'ACT_REJECT_IF_CONFLICT' ]
accept_avail = [ 'ACT_ACCEPT_IF_NO_CONFLICT', 'ACT_REJECT_IF_CONFLICT:example.org' ]
- self.assertFalse( MIP.is_auto_reply({ 'kolabinvitationpolicy':all_manual }, 'user@domain.org'))
- self.assertTrue( MIP.is_auto_reply({ 'kolabinvitationpolicy':accept_none }, 'user@domain.org'))
- self.assertTrue( MIP.is_auto_reply({ 'kolabinvitationpolicy':accept_all }, 'user@domain.com'))
- self.assertTrue( MIP.is_auto_reply({ 'kolabinvitationpolicy':accept_cond }, 'user@domain.com'))
- self.assertTrue( MIP.is_auto_reply({ 'kolabinvitationpolicy':accept_some }, 'user@domain.com'))
- self.assertFalse( MIP.is_auto_reply({ 'kolabinvitationpolicy':accept_some }, 'sam@example.org'))
- self.assertFalse( MIP.is_auto_reply({ 'kolabinvitationpolicy':accept_avail }, 'user@domain.com'))
- self.assertTrue( MIP.is_auto_reply({ 'kolabinvitationpolicy':accept_avail }, 'john@example.org'))
+ self.assertFalse( MIP.is_auto_reply({ 'kolabinvitationpolicy':all_manual }, 'user@domain.org', 'event'))
+ self.assertTrue( MIP.is_auto_reply({ 'kolabinvitationpolicy':accept_none }, 'user@domain.org', 'event'))
+ self.assertTrue( MIP.is_auto_reply({ 'kolabinvitationpolicy':accept_all }, 'user@domain.com', 'event'))
+ self.assertTrue( MIP.is_auto_reply({ 'kolabinvitationpolicy':accept_cond }, 'user@domain.com', 'event'))
+ self.assertTrue( MIP.is_auto_reply({ 'kolabinvitationpolicy':accept_some }, 'user@domain.com', 'event'))
+ self.assertFalse( MIP.is_auto_reply({ 'kolabinvitationpolicy':accept_some }, 'sam@example.org', 'event'))
+ self.assertFalse( MIP.is_auto_reply({ 'kolabinvitationpolicy':accept_avail }, 'user@domain.com', 'event'))
+ self.assertTrue( MIP.is_auto_reply({ 'kolabinvitationpolicy':accept_avail }, 'john@example.org', 'event'))
\ No newline at end of file
diff --git a/tests/unit/test-016-todo.py b/tests/unit/test-016-todo.py
index a7e9394..c6a1178 100644
--- a/tests/unit/test-016-todo.py
+++ b/tests/unit/test-016-todo.py
@@ -18,7 +18,6 @@ VERSION:2.0
PRODID:-//Roundcube//Roundcube libcalendaring 1.1-git//Sabre//Sabre VObject
2.1.3//EN
CALSCALE:GREGORIAN
-METHOD:REQUEST
BEGIN:VTODO
UID:18C2EBBD8B31D99F7AA578EDFDFB1AC0-FCBB6C4091F28CA0
DTSTAMP;VALUE=DATE-TIME:20140820T101333Z