Changeset View
Changeset View
Standalone View
Standalone View
tests/functional/test_wallace/test_007_invitationpolicy.py
Show First 20 Lines • Show All 215 Lines • ▼ Show 20 Lines | |||||
Content-Type: text/calendar; charset=UTF-8; method=%s; name=event.ics | Content-Type: text/calendar; charset=UTF-8; method=%s; name=event.ics | ||||
Content-Disposition: attachment; filename=event.ics | Content-Disposition: attachment; filename=event.ics | ||||
Content-Transfer-Encoding: 8bit | Content-Transfer-Encoding: 8bit | ||||
%s | %s | ||||
--=_c8894dbdb8baeedacae836230e3436fd-- | --=_c8894dbdb8baeedacae836230e3436fd-- | ||||
""" | """ | ||||
class TestWallaceInvitationpolicy(unittest.TestCase): | class TestWallaceInvitationpolicy(unittest.TestCase): | ||||
john = None | john = None | ||||
itip_reply_subject = None | itip_reply_subject = None | ||||
@classmethod | @classmethod | ||||
def setUp(self): | def setUp(self): | ||||
""" Compatibility for twisted.trial.unittest | """ Compatibility for twisted.trial.unittest | ||||
""" | """ | ||||
if not self.john: | if not self.john: | ||||
self.setup_class() | self.setup_class() | ||||
@classmethod | @classmethod | ||||
def setup_class(self, *args, **kw): | def setup_class(self, *args, **kw): | ||||
# set language to default | # set language to default | ||||
pykolab.translate.setUserLanguage(conf.get('kolab','default_locale')) | pykolab.translate.setUserLanguage(conf.get('kolab', 'default_locale')) | ||||
self.itip_reply_subject = _('"%(summary)s" has been %(status)s') | self.itip_reply_subject = _('"%(summary)s" has been %(status)s') | ||||
from tests.functional.purge_users import purge_users | from tests.functional.purge_users import purge_users | ||||
purge_users() | purge_users() | ||||
self.john = { | self.john = { | ||||
'displayname': 'John Doe', | 'displayname': 'John Doe', | ||||
'mail': 'john.doe@example.org', | 'mail': 'john.doe@example.org', | ||||
'dn': 'uid=doe,ou=People,dc=example,dc=org', | 'dn': 'uid=doe,ou=People,dc=example,dc=org', | ||||
'preferredlanguage': 'en_US', | 'preferredlanguage': 'en_US', | ||||
'mailbox': 'user/john.doe@example.org', | 'mailbox': 'user/john.doe@example.org', | ||||
'kolabcalendarfolder': 'user/john.doe/Calendar@example.org', | 'kolabcalendarfolder': 'user/john.doe/Calendar@example.org', | ||||
'kolabtasksfolder': 'user/john.doe/Tasks@example.org', | 'kolabtasksfolder': 'user/john.doe/Tasks@example.org', | ||||
'kolabinvitationpolicy': ['ACT_UPDATE_AND_NOTIFY','ACT_MANUAL'] | 'kolabinvitationpolicy': ['ACT_UPDATE_AND_NOTIFY', 'ACT_MANUAL'] | ||||
} | } | ||||
self.jane = { | self.jane = { | ||||
'displayname': 'Jane Manager', | 'displayname': 'Jane Manager', | ||||
'mail': 'jane.manager@example.org', | 'mail': 'jane.manager@example.org', | ||||
'dn': 'uid=manager,ou=People,dc=example,dc=org', | 'dn': 'uid=manager,ou=People,dc=example,dc=org', | ||||
'preferredlanguage': 'en_US', | 'preferredlanguage': 'en_US', | ||||
'mailbox': 'user/jane.manager@example.org', | 'mailbox': 'user/jane.manager@example.org', | ||||
'kolabcalendarfolder': 'user/jane.manager/Calendar@example.org', | 'kolabcalendarfolder': 'user/jane.manager/Calendar@example.org', | ||||
'kolabtasksfolder': 'user/jane.manager/Tasks@example.org', | 'kolabtasksfolder': 'user/jane.manager/Tasks@example.org', | ||||
'kolabconfidentialcalendar': 'user/jane.manager/Calendar/Confidential@example.org', | 'kolabconfidentialcalendar': 'user/jane.manager/Calendar/Confidential@example.org', | ||||
'kolabinvitationpolicy': ['ACT_ACCEPT_IF_NO_CONFLICT','ACT_REJECT_IF_CONFLICT','TASK_ACCEPT','TASK_UPDATE_AND_NOTIFY','ACT_UPDATE'] | 'kolabinvitationpolicy': ['ACT_ACCEPT_IF_NO_CONFLICT', 'ACT_REJECT_IF_CONFLICT', 'TASK_ACCEPT', 'TASK_UPDATE_AND_NOTIFY', 'ACT_UPDATE'] | ||||
} | } | ||||
self.jack = { | self.jack = { | ||||
'displayname': 'Jack Tentative', | 'displayname': 'Jack Tentative', | ||||
'mail': 'jack.tentative@example.org', | 'mail': 'jack.tentative@example.org', | ||||
'dn': 'uid=tentative,ou=People,dc=example,dc=org', | 'dn': 'uid=tentative,ou=People,dc=example,dc=org', | ||||
'preferredlanguage': 'en_US', | 'preferredlanguage': 'en_US', | ||||
'mailbox': 'user/jack.tentative@example.org', | 'mailbox': 'user/jack.tentative@example.org', | ||||
'kolabcalendarfolder': 'user/jack.tentative/Calendar@example.org', | 'kolabcalendarfolder': 'user/jack.tentative/Calendar@example.org', | ||||
'kolabtasksfolder': 'user/jack.tentative/Tasks@example.org', | 'kolabtasksfolder': 'user/jack.tentative/Tasks@example.org', | ||||
'kolabinvitationpolicy': ['ACT_TENTATIVE_IF_NO_CONFLICT','ALL_SAVE_TO_FOLDER','ACT_UPDATE'] | 'kolabinvitationpolicy': ['ACT_TENTATIVE_IF_NO_CONFLICT', 'ALL_SAVE_TO_FOLDER', 'ACT_UPDATE'] | ||||
} | } | ||||
self.mark = { | self.mark = { | ||||
'displayname': 'Mark German', | 'displayname': 'Mark German', | ||||
'mail': 'mark.german@example.org', | 'mail': 'mark.german@example.org', | ||||
'dn': 'uid=german,ou=People,dc=example,dc=org', | 'dn': 'uid=german,ou=People,dc=example,dc=org', | ||||
'preferredlanguage': 'de_DE', | 'preferredlanguage': 'de_DE', | ||||
'mailbox': 'user/mark.german@example.org', | 'mailbox': 'user/mark.german@example.org', | ||||
'kolabcalendarfolder': 'user/mark.german/Calendar@example.org', | 'kolabcalendarfolder': 'user/mark.german/Calendar@example.org', | ||||
'kolabtasksfolder': 'user/mark.german/Tasks@example.org', | 'kolabtasksfolder': 'user/mark.german/Tasks@example.org', | ||||
'kolabinvitationpolicy': ['ACT_ACCEPT','ACT_UPDATE_AND_NOTIFY'] | 'kolabinvitationpolicy': ['ACT_ACCEPT', 'ACT_UPDATE_AND_NOTIFY'] | ||||
} | } | ||||
self.lucy = { | self.lucy = { | ||||
'displayname': 'Lucy Meyer', | 'displayname': 'Lucy Meyer', | ||||
'mail': 'lucy.meyer@example.org', | 'mail': 'lucy.meyer@example.org', | ||||
'dn': 'uid=meyer,ou=People,dc=example,dc=org', | 'dn': 'uid=meyer,ou=People,dc=example,dc=org', | ||||
'preferredlanguage': 'en_US', | 'preferredlanguage': 'en_US', | ||||
'mailbox': 'user/lucy.meyer@example.org', | 'mailbox': 'user/lucy.meyer@example.org', | ||||
'kolabcalendarfolder': 'user/lucy.meyer/Calendar@example.org', | 'kolabcalendarfolder': 'user/lucy.meyer/Calendar@example.org', | ||||
'kolabtasksfolder': 'user/lucy.meyer/Tasks@example.org', | 'kolabtasksfolder': 'user/lucy.meyer/Tasks@example.org', | ||||
'kolabinvitationpolicy': ['ALL_SAVE_AND_FORWARD','ACT_CANCEL_DELETE_AND_NOTIFY','ACT_UPDATE_AND_NOTIFY'] | 'kolabinvitationpolicy': ['ALL_SAVE_AND_FORWARD', 'ACT_CANCEL_DELETE_AND_NOTIFY', 'ACT_UPDATE_AND_NOTIFY'] | ||||
} | } | ||||
self.bill = { | self.bill = { | ||||
'displayname': 'Bill Mayor', | 'displayname': 'Bill Mayor', | ||||
'mail': 'bill.mayor@example.org', | 'mail': 'bill.mayor@example.org', | ||||
'dn': 'uid=mayor,ou=People,dc=example,dc=org', | 'dn': 'uid=mayor,ou=People,dc=example,dc=org', | ||||
'preferredlanguage': 'en_US', | 'preferredlanguage': 'en_US', | ||||
'mailbox': 'user/bill.mayor@example.org', | 'mailbox': 'user/bill.mayor@example.org', | ||||
'kolabcalendarfolder': 'user/bill.mayor/Calendar@example.org', | 'kolabcalendarfolder': 'user/bill.mayor/Calendar@example.org', | ||||
'kolabtasksfolder': 'user/bill.mayor/Tasks@example.org', | 'kolabtasksfolder': 'user/bill.mayor/Tasks@example.org', | ||||
'kolabinvitationpolicy': ['ALL_SAVE_TO_FOLDER:lucy.meyer@example.org','ALL_REJECT'] | 'kolabinvitationpolicy': ['ALL_SAVE_TO_FOLDER:lucy.meyer@example.org', 'ALL_REJECT'] | ||||
} | } | ||||
self.external = { | self.external = { | ||||
'displayname': 'Bob External', | 'displayname': 'Bob External', | ||||
'mail': 'bob.external@gmail.com' | 'mail': 'bob.external@gmail.com' | ||||
} | } | ||||
from tests.functional.user_add import user_add | from tests.functional.user_add import user_add | ||||
user_add("John", "Doe", kolabinvitationpolicy=self.john['kolabinvitationpolicy'], preferredlanguage=self.john['preferredlanguage']) | user_add("John", "Doe", kolabinvitationpolicy=self.john['kolabinvitationpolicy'], preferredlanguage=self.john['preferredlanguage']) | ||||
user_add("Jane", "Manager", kolabinvitationpolicy=self.jane['kolabinvitationpolicy'], preferredlanguage=self.jane['preferredlanguage'], kolabdelegate=[self.mark['dn']]) | user_add("Jane", "Manager", kolabinvitationpolicy=self.jane['kolabinvitationpolicy'], preferredlanguage=self.jane['preferredlanguage'], kolabdelegate=[self.mark['dn']]) | ||||
user_add("Jack", "Tentative", kolabinvitationpolicy=self.jack['kolabinvitationpolicy'], preferredlanguage=self.jack['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("Mark", "German", kolabinvitationpolicy=self.mark['kolabinvitationpolicy'], preferredlanguage=self.mark['preferredlanguage']) | ||||
user_add("Lucy", "Meyer", kolabinvitationpolicy=self.lucy['kolabinvitationpolicy'], preferredlanguage=self.lucy['preferredlanguage']) | user_add("Lucy", "Meyer", kolabinvitationpolicy=self.lucy['kolabinvitationpolicy'], preferredlanguage=self.lucy['preferredlanguage']) | ||||
user_add("Bill", "Mayor", kolabinvitationpolicy=self.bill['kolabinvitationpolicy'], preferredlanguage=self.bill['preferredlanguage']) | user_add("Bill", "Mayor", kolabinvitationpolicy=self.bill['kolabinvitationpolicy'], preferredlanguage=self.bill['preferredlanguage']) | ||||
time.sleep(1) | time.sleep(1) | ||||
from tests.functional.synchronize import synchronize_once | from tests.functional.synchronize import synchronize_once | ||||
synchronize_once() | synchronize_once() | ||||
time.sleep(4) | time.sleep(4) | ||||
# create confidential calendar folder for jane | # create confidential calendar folder for jane | ||||
imap = IMAP() | imap = IMAP() | ||||
imap.connect(domain='example.org') # sets self.domain | imap.connect(domain='example.org') # sets self.domain | ||||
imap.user_mailbox_create_additional_folders(self.jane['mail'], { | imap.user_mailbox_create_additional_folders(self.jane['mail'], { | ||||
'Calendar/Confidential': { | 'Calendar/Confidential': { | ||||
'annotations': { | 'annotations': { | ||||
'/shared/vendor/kolab/folder-type': "event", | '/shared/vendor/kolab/folder-type': "event", | ||||
'/private/vendor/kolab/folder-type': "event.confidential" | '/private/vendor/kolab/folder-type': "event.confidential" | ||||
} | } | ||||
} | } | ||||
}) | }) | ||||
# grant full access for Mark to Jane's calendar | # grant full access for Mark to Jane's calendar | ||||
imap.set_acl(imap.folder_quote(self.jane['kolabcalendarfolder']), self.mark['mail'], "lrswipkxtecda") | imap.set_acl(imap.folder_quote(self.jane['kolabcalendarfolder']), self.mark['mail'], "lrswipkxtecda") | ||||
imap.disconnect() | imap.disconnect() | ||||
def send_message(self, itip_payload, to_addr, from_addr=None, method="REQUEST"): | def send_message(self, itip_payload, to_addr, from_addr=None, method="REQUEST"): | ||||
if from_addr is None: | if from_addr is None: | ||||
from_addr = self.john['mail'] | from_addr = self.john['mail'] | ||||
smtp = smtplib.SMTP('localhost', 10026) | smtp = smtplib.SMTP('localhost', 10026) | ||||
smtp.sendmail(from_addr, to_addr, mime_message % (to_addr, method, itip_payload)) | smtp.sendmail(from_addr, to_addr, mime_message % (to_addr, method, itip_payload)) | ||||
def send_itip_invitation(self, attendee_email, start=None, allday=False, template=None, summary="test", sequence=0, partstat='NEEDS-ACTION', from_addr=None, uid=None, instance=None): | def send_itip_invitation(self, attendee_email, start=None, allday=False, template=None, summary="test", sequence=0, partstat='NEEDS-ACTION', from_addr=None, uid=None, instance=None): | ||||
▲ Show 20 Lines • Show All 312 Lines • ▼ Show 20 Lines | def purge_mailbox(self, mailbox): | ||||
typ, data = imap.imap.m.search(None, 'ALL') | typ, data = imap.imap.m.search(None, 'ALL') | ||||
for num in data[0].split(): | for num in data[0].split(): | ||||
imap.imap.m.store(num, '+FLAGS', '\\Deleted') | imap.imap.m.store(num, '+FLAGS', '\\Deleted') | ||||
imap.imap.m.expunge() | imap.imap.m.expunge() | ||||
imap.disconnect() | imap.disconnect() | ||||
def test_001_invite_accept_udate(self): | def test_001_invite_accept_udate(self): | ||||
start = datetime.datetime(2014,8,13, 10,0,0) | start = datetime.datetime(2014, 8, 13, 10, 0, 0) | ||||
uid = self.send_itip_invitation(self.jane['mail'], start) | uid = self.send_itip_invitation(self.jane['mail'], start) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }, self.jane['mail']) | 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) | self.assertIsInstance(response, email.message.Message) | ||||
event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(event.get_summary(), "test") | self.assertEqual(event.get_summary(), "test") | ||||
# send update with the same sequence: no re-scheduling | # send update with the same sequence: no re-scheduling | ||||
self.send_itip_update(self.jane['mail'], uid, start, summary="test updated", sequence=0, partstat='ACCEPTED') | self.send_itip_update(self.jane['mail'], uid, start, summary="test updated", sequence=0, partstat='ACCEPTED') | ||||
time.sleep(10) | time.sleep(10) | ||||
event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(event.get_summary(), "test updated") | self.assertEqual(event.get_summary(), "test updated") | ||||
self.assertEqual(event.get_attendee(self.jane['mail']).get_participant_status(), kolabformat.PartAccepted) | self.assertEqual(event.get_attendee(self.jane['mail']).get_participant_status(), kolabformat.PartAccepted) | ||||
# @depends on test_001_invite_user | # @depends on test_001_invite_user | ||||
def test_002_invite_conflict_reject(self): | def test_002_invite_conflict_reject(self): | ||||
uid = self.send_itip_invitation(self.jane['mail'], datetime.datetime(2014,8,13, 11,0,0), summary="test2") | uid = self.send_itip_invitation(self.jane['mail'], datetime.datetime(2014, 8, 13, 11, 0, 0), summary="test2") | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test2', 'status':participant_status_label('DECLINED') }, self.jane['mail']) | 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) | self.assertIsInstance(response, email.message.Message) | ||||
event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(event.get_summary(), "test2") | self.assertEqual(event.get_summary(), "test2") | ||||
def test_003_invite_accept_tentative(self): | def test_003_invite_accept_tentative(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
uid = self.send_itip_invitation(self.jack['mail'], datetime.datetime(2014,7,24, 8,0,0)) | uid = self.send_itip_invitation(self.jack['mail'], datetime.datetime(2014, 7, 24, 8, 0, 0)) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('TENTATIVE') }, self.jack['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('TENTATIVE')}, self.jack['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
def test_004_copy_to_calendar(self): | def test_004_copy_to_calendar(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
self.send_itip_invitation(self.jack['mail'], datetime.datetime(2014,7,29, 8,0,0)) | self.send_itip_invitation(self.jack['mail'], datetime.datetime(2014, 7, 29, 8, 0, 0)) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('TENTATIVE') }, self.jack['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('TENTATIVE')}, self.jack['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
# send conflicting request to jack | # send conflicting request to jack | ||||
uid = self.send_itip_invitation(self.jack['mail'], datetime.datetime(2014,7,29, 10,0,0), summary="test2") | uid = self.send_itip_invitation(self.jack['mail'], datetime.datetime(2014, 7, 29, 10, 0, 0), summary="test2") | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test2', 'status':participant_status_label('DECLINED') }, self.jack['mail']) | 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") | self.assertEqual(response, None, "No reply expected") | ||||
event = self.check_user_calendar_event(self.jack['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jack['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(event.get_summary(), "test2") | self.assertEqual(event.get_summary(), "test2") | ||||
self.assertEqual(event.get_attendee(self.jack['mail']).get_participant_status(), kolabformat.PartNeedsAction) | self.assertEqual(event.get_attendee(self.jack['mail']).get_participant_status(), kolabformat.PartNeedsAction) | ||||
def test_004_copy_to_calendar_and_forward(self): | 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") | 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']) | 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") | self.assertEqual(response, None, "No reply expected") | ||||
event = self.check_user_calendar_event(self.lucy['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.lucy['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(event.get_summary(), "test forward") | self.assertEqual(event.get_summary(), "test forward") | ||||
self.assertEqual(event.get_attendee(self.lucy['mail']).get_participant_status(), kolabformat.PartNeedsAction) | self.assertEqual(event.get_attendee(self.lucy['mail']).get_participant_status(), kolabformat.PartNeedsAction) | ||||
# find original itip invitation in user's inbox | # find original itip invitation in user's inbox | ||||
message = self.check_message_received('"test"', 'john.doe@example.org', self.lucy['mailbox']) | message = self.check_message_received('"test"', 'john.doe@example.org', self.lucy['mailbox']) | ||||
self.assertIsInstance(message, email.message.Message) | self.assertIsInstance(message, email.message.Message) | ||||
itips = events_from_message(message) | itips = events_from_message(message) | ||||
self.assertEqual(len(itips), 1); | self.assertEqual(len(itips), 1) | ||||
self.assertEqual(itips[0]['method'], 'REQUEST'); | self.assertEqual(itips[0]['method'], 'REQUEST') | ||||
self.assertEqual(itips[0]['uid'], uid); | self.assertEqual(itips[0]['uid'], uid) | ||||
def test_005_invite_rescheduling_accept(self): | def test_005_invite_rescheduling_accept(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
start = datetime.datetime(2014,8,14, 9,0,0, tzinfo=pytz.timezone("Europe/Berlin")) | start = datetime.datetime(2014, 8, 14, 9, 0, 0, tzinfo=pytz.timezone("Europe/Berlin")) | ||||
uid = self.send_itip_invitation(self.jane['mail'], start) | uid = self.send_itip_invitation(self.jane['mail'], start) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }, self.jane['mail']) | 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) | self.assertIsInstance(response, email.message.Message) | ||||
event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(event.get_summary(), "test") | self.assertEqual(event.get_summary(), "test") | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
# send update with new date and incremented sequence | # send update with new date and incremented sequence | ||||
new_start = pytz.timezone("Europe/Berlin").localize(datetime.datetime(2014,8,15, 15,0,0)) | new_start = pytz.timezone("Europe/Berlin").localize(datetime.datetime(2014, 8, 15, 15, 0, 0)) | ||||
self.send_itip_update(self.jane['mail'], uid, new_start, summary="test", sequence=1) | self.send_itip_update(self.jane['mail'], uid, new_start, summary="test", sequence=1) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }, self.jane['mail']) | 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) | self.assertIsInstance(response, email.message.Message) | ||||
event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(event.get_start(), new_start) | self.assertEqual(event.get_start(), new_start) | ||||
self.assertEqual(event.get_sequence(), 1) | self.assertEqual(event.get_sequence(), 1) | ||||
def test_005_invite_rescheduling_reject(self): | def test_005_invite_rescheduling_reject(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
self.purge_mailbox(self.jack['kolabcalendarfolder']) | self.purge_mailbox(self.jack['kolabcalendarfolder']) | ||||
start = datetime.datetime(2014,8,9, 17,0,0, tzinfo=pytz.timezone("Europe/Berlin")) | start = datetime.datetime(2014, 8, 9, 17, 0, 0, tzinfo=pytz.timezone("Europe/Berlin")) | ||||
uid = self.send_itip_invitation(self.jack['mail'], start) | uid = self.send_itip_invitation(self.jack['mail'], start) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('TENTATIVE') }, self.jack['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('TENTATIVE')}, self.jack['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
# send update with new but conflicting date and incremented sequence | # send update with new but conflicting date and incremented sequence | ||||
self.create_calendar_event(datetime.datetime(2014,8,10, 10,30,0, tzinfo=pytz.timezone("Europe/Berlin")), user=self.jack) | self.create_calendar_event(datetime.datetime(2014, 8, 10, 10, 30, 0, tzinfo=pytz.timezone("Europe/Berlin")), user=self.jack) | ||||
new_start = pytz.timezone("Europe/Berlin").localize(datetime.datetime(2014,8,10, 9,30,0)) | new_start = pytz.timezone("Europe/Berlin").localize(datetime.datetime(2014, 8, 10, 9, 30, 0)) | ||||
self.send_itip_update(self.jack['mail'], uid, new_start, summary="test (updated)", sequence=1) | self.send_itip_update(self.jack['mail'], uid, new_start, summary="test (updated)", sequence=1) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('DECLINED') }, self.jack['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('DECLINED')}, self.jack['mail']) | ||||
self.assertEqual(response, None) | self.assertEqual(response, None) | ||||
# verify re-scheduled copy in jack's calendar with NEEDS-ACTION | # verify re-scheduled copy in jack's calendar with NEEDS-ACTION | ||||
event = self.check_user_calendar_event(self.jack['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jack['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(event.get_start(), new_start) | self.assertEqual(event.get_start(), new_start) | ||||
self.assertEqual(event.get_sequence(), 1) | self.assertEqual(event.get_sequence(), 1) | ||||
attendee = event.get_attendee(self.jack['mail']) | attendee = event.get_attendee(self.jack['mail']) | ||||
self.assertTrue(attendee.get_rsvp()) | self.assertTrue(attendee.get_rsvp()) | ||||
self.assertEqual(attendee.get_participant_status(), kolabformat.PartNeedsAction) | self.assertEqual(attendee.get_participant_status(), kolabformat.PartNeedsAction) | ||||
def test_006_invitation_reply(self): | def test_006_invitation_reply(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
start = datetime.datetime(2014,8,18, 14,30,0, tzinfo=pytz.timezone("Europe/Berlin")) | start = datetime.datetime(2014, 8, 18, 14, 30, 0, tzinfo=pytz.timezone("Europe/Berlin")) | ||||
uid = self.create_calendar_event(start, user=self.john) | uid = self.create_calendar_event(start, user=self.john) | ||||
event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
# send a reply from jane to john | # send a reply from jane to john | ||||
self.send_itip_reply(uid, self.jane['mail'], self.john['mail'], start=start) | self.send_itip_reply(uid, self.jane['mail'], self.john['mail'], start=start) | ||||
# check for the updated event in john's calendar | # check for the updated event in john's calendar | ||||
time.sleep(10) | time.sleep(10) | ||||
event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
attendee = event.get_attendee(self.jane['mail']) | attendee = event.get_attendee(self.jane['mail']) | ||||
self.assertIsInstance(attendee, pykolab.xml.Attendee) | self.assertIsInstance(attendee, pykolab.xml.Attendee) | ||||
self.assertEqual(attendee.get_participant_status(), kolabformat.PartAccepted) | self.assertEqual(attendee.get_participant_status(), kolabformat.PartAccepted) | ||||
# check attachments in update event | # check attachments in update event | ||||
attachments = event.get_attachments() | attachments = event.get_attachments() | ||||
self.assertEqual(len(attachments), 1) | self.assertEqual(len(attachments), 1) | ||||
self.assertEqual(event.get_attachment_data(0), 'This is a text attachment') | self.assertEqual(event.get_attachment_data(0), 'This is a text attachment') | ||||
def test_006_invitation_reply_delegated(self): | def test_006_invitation_reply_delegated(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
start = datetime.datetime(2014,8,28, 14,30,0, tzinfo=pytz.timezone("Europe/Berlin")) | start = datetime.datetime(2014, 8, 28, 14, 30, 0, tzinfo=pytz.timezone("Europe/Berlin")) | ||||
uid = self.create_calendar_event(start, user=self.john) | uid = self.create_calendar_event(start, user=self.john) | ||||
event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
# send a reply from jane to john | # send a reply from jane to john | ||||
self.send_itip_reply(uid, self.jane['mail'], self.john['mail'], start=start, template=itip_delegated, partstat='NEEDS-ACTION') | self.send_itip_reply(uid, self.jane['mail'], self.john['mail'], start=start, template=itip_delegated, partstat='NEEDS-ACTION') | ||||
Show All 9 Lines | def test_006_invitation_reply_delegated(self): | ||||
self.assertEqual(attendee.get_delegated_to(True)[0], 'jack@ripper.com') | self.assertEqual(attendee.get_delegated_to(True)[0], 'jack@ripper.com') | ||||
delegatee = event.get_attendee('jack@ripper.com') | delegatee = event.get_attendee('jack@ripper.com') | ||||
self.assertIsInstance(delegatee, pykolab.xml.Attendee) | self.assertIsInstance(delegatee, pykolab.xml.Attendee) | ||||
self.assertEqual(delegatee.get_participant_status(), kolabformat.PartNeedsAction) | self.assertEqual(delegatee.get_participant_status(), kolabformat.PartNeedsAction) | ||||
self.assertEqual(len(delegatee.get_delegated_from()), 1) | self.assertEqual(len(delegatee.get_delegated_from()), 1) | ||||
self.assertEqual(delegatee.get_delegated_from(True)[0], self.jane['mail']) | self.assertEqual(delegatee.get_delegated_from(True)[0], self.jane['mail']) | ||||
def test_007_invitation_cancel(self): | def test_007_invitation_cancel(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
uid = self.send_itip_invitation(self.jane['mail'], summary="cancelled") | uid = self.send_itip_invitation(self.jane['mail'], summary="cancelled") | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'cancelled', 'status':participant_status_label('ACCEPTED') }, self.jane['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'cancelled', 'status': participant_status_label('ACCEPTED')}, self.jane['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
self.send_itip_cancel(self.jane['mail'], uid, summary="cancelled") | self.send_itip_cancel(self.jane['mail'], uid, summary="cancelled") | ||||
time.sleep(10) | time.sleep(10) | ||||
event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(event.get_summary(), "cancelled") | self.assertEqual(event.get_summary(), "cancelled") | ||||
self.assertEqual(event.get_status(True), 'CANCELLED') | self.assertEqual(event.get_status(True), 'CANCELLED') | ||||
self.assertTrue(event.get_transparency()) | self.assertTrue(event.get_transparency()) | ||||
def test_007_invitation_cancel_and_delete(self): | def test_007_invitation_cancel_and_delete(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
uid = self.send_itip_invitation(self.lucy['mail'], summary="cancel-delete") | uid = self.send_itip_invitation(self.lucy['mail'], summary="cancel-delete") | ||||
event = self.check_user_calendar_event(self.lucy['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.lucy['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.send_itip_cancel(self.lucy['mail'], uid, summary="cancel-delete") | self.send_itip_cancel(self.lucy['mail'], uid, summary="cancel-delete") | ||||
response = self.check_message_received(_('"%s" has been cancelled') % ('cancel-delete'), self.john['mail'], mailbox=self.lucy['mailbox']) | response = self.check_message_received(_('"%s" has been cancelled') % ('cancel-delete'), self.john['mail'], mailbox=self.lucy['mailbox']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
# verify event was removed from the user's calendar | # verify event was removed from the user's calendar | ||||
self.assertEqual(self.check_user_calendar_event(self.lucy['kolabcalendarfolder'], uid), None) | self.assertEqual(self.check_user_calendar_event(self.lucy['kolabcalendarfolder'], uid), None) | ||||
def test_008_inivtation_reply_notify(self): | def test_008_inivtation_reply_notify(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
start = datetime.datetime(2014,8,12, 16,0,0, tzinfo=pytz.timezone("Europe/Berlin")) | start = datetime.datetime(2014, 8, 12, 16, 0, 0, tzinfo=pytz.timezone("Europe/Berlin")) | ||||
uid = self.create_calendar_event(start, user=self.john, attendees=[self.jane, self.mark, self.jack]) | uid = self.create_calendar_event(start, user=self.john, attendees=[self.jane, self.mark, self.jack]) | ||||
# send a reply from jane to john | # send a reply from jane to john | ||||
self.send_itip_reply(uid, self.jane['mail'], self.john['mail'], start=start) | self.send_itip_reply(uid, self.jane['mail'], self.john['mail'], start=start) | ||||
# check for notification message | # check for notification message | ||||
# this notification should be suppressed until mark has replied, too | # this notification should be suppressed until mark has replied, too | ||||
notification = self.check_message_received(_('"%s" has been updated') % ('test'), self.john['mail']) | notification = self.check_message_received(_('"%s" has been updated') % ('test'), self.john['mail']) | ||||
self.assertEqual(notification, None) | self.assertEqual(notification, None) | ||||
# send a reply from mark to john | # send a reply from mark to john | ||||
self.send_itip_reply(uid, self.mark['mail'], self.john['mail'], start=start, partstat='ACCEPTED') | self.send_itip_reply(uid, self.mark['mail'], self.john['mail'], start=start, partstat='ACCEPTED') | ||||
notification = self.check_message_received(_('"%s" has been updated') % ('test'), self.john['mail']) | notification = self.check_message_received(_('"%s" has been updated') % ('test'), self.john['mail']) | ||||
self.assertIsInstance(notification, email.message.Message) | self.assertIsInstance(notification, email.message.Message) | ||||
notification_text = str(notification.get_payload()); | notification_text = str(notification.get_payload()) | ||||
self.assertIn(self.jane['mail'], notification_text) | self.assertIn(self.jane['mail'], notification_text) | ||||
self.assertIn(_("PENDING"), notification_text) | self.assertIn(_("PENDING"), notification_text) | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
# send a reply from mark to john | # send a reply from mark to john | ||||
self.send_itip_reply(uid, self.jack['mail'], self.john['mail'], start=start, partstat='ACCEPTED') | self.send_itip_reply(uid, self.jack['mail'], self.john['mail'], start=start, partstat='ACCEPTED') | ||||
# this triggers an additional notification | # this triggers an additional notification | ||||
notification = self.check_message_received(_('"%s" has been updated') % ('test'), self.john['mail']) | notification = self.check_message_received(_('"%s" has been updated') % ('test'), self.john['mail']) | ||||
self.assertIsInstance(notification, email.message.Message) | self.assertIsInstance(notification, email.message.Message) | ||||
notification_text = str(notification.get_payload()); | notification_text = str(notification.get_payload()) | ||||
self.assertNotIn(_("PENDING"), notification_text) | self.assertNotIn(_("PENDING"), notification_text) | ||||
def test_008_notify_translated(self): | def test_008_notify_translated(self): | ||||
self.purge_mailbox(self.mark['mailbox']) | self.purge_mailbox(self.mark['mailbox']) | ||||
start = datetime.datetime(2014,8,12, 16,0,0, tzinfo=pytz.timezone("Europe/Berlin")) | start = datetime.datetime(2014, 8, 12, 16, 0, 0, tzinfo=pytz.timezone("Europe/Berlin")) | ||||
uid = self.create_calendar_event(start, user=self.mark, attendees=[self.jane]) | uid = self.create_calendar_event(start, user=self.mark, attendees=[self.jane]) | ||||
# send a reply from jane to mark | # send a reply from jane to mark | ||||
self.send_itip_reply(uid, self.jane['mail'], self.mark['mail'], start=start) | self.send_itip_reply(uid, self.jane['mail'], self.mark['mail'], start=start) | ||||
# change translations to de_DE | # change translations to de_DE | ||||
pykolab.translate.setUserLanguage(self.mark['preferredlanguage']) | pykolab.translate.setUserLanguage(self.mark['preferredlanguage']) | ||||
notification = self.check_message_received(_('"%s" has been updated') % ('test'), self.mark['mail'], self.mark['mailbox']) | notification = self.check_message_received(_('"%s" has been updated') % ('test'), self.mark['mail'], self.mark['mailbox']) | ||||
self.assertIsInstance(notification, email.message.Message) | self.assertIsInstance(notification, email.message.Message) | ||||
notification_text = str(notification.get_payload()); | notification_text = str(notification.get_payload()) | ||||
self.assertIn(self.jane['mail'], notification_text) | self.assertIn(self.jane['mail'], notification_text) | ||||
self.assertIn(participant_status_label("ACCEPTED")+":", notification_text) | self.assertIn(participant_status_label("ACCEPTED")+":", notification_text) | ||||
# reset localization | # reset localization | ||||
pykolab.translate.setUserLanguage(conf.get('kolab','default_locale')) | pykolab.translate.setUserLanguage(conf.get('kolab', 'default_locale')) | ||||
def test_009_outdated_reply(self): | def test_009_outdated_reply(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
start = datetime.datetime(2014,9,2, 11,0,0, tzinfo=pytz.timezone("Europe/Berlin")) | start = datetime.datetime(2014, 9, 2, 11, 0, 0, tzinfo=pytz.timezone("Europe/Berlin")) | ||||
uid = self.create_calendar_event(start, user=self.john, sequence=2) | uid = self.create_calendar_event(start, user=self.john, sequence=2) | ||||
# send a reply from jane to john | # send a reply from jane to john | ||||
self.send_itip_reply(uid, self.jane['mail'], self.john['mail'], start=start, sequence=1) | self.send_itip_reply(uid, self.jane['mail'], self.john['mail'], start=start, sequence=1) | ||||
# verify jane's attendee status was not updated | # verify jane's attendee status was not updated | ||||
time.sleep(10) | time.sleep(10) | ||||
event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(event.get_sequence(), 2) | self.assertEqual(event.get_sequence(), 2) | ||||
self.assertEqual(event.get_attendee(self.jane['mail']).get_participant_status(), kolabformat.PartNeedsAction) | self.assertEqual(event.get_attendee(self.jane['mail']).get_participant_status(), kolabformat.PartNeedsAction) | ||||
def test_010_partstat_update_propagation(self): | def test_010_partstat_update_propagation(self): | ||||
# ATTENTION: this test requires wallace.invitationpolicy_autoupdate_other_attendees_on_reply to be enabled in config | # ATTENTION: this test requires wallace.invitationpolicy_autoupdate_other_attendees_on_reply to be enabled in config | ||||
start = datetime.datetime(2014,8,21, 13,0,0, tzinfo=pytz.timezone("Europe/Berlin")) | 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]) | uid = self.create_calendar_event(start, user=self.john, attendees=[self.jane, self.jack, self.external]) | ||||
event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
# send invitations to jack and jane | # send invitations to jack and jane | ||||
event_itip = event.as_string_itip() | event_itip = event.as_string_itip() | ||||
self.send_itip_invitation(self.jane['mail'], start, template=event_itip) | self.send_itip_invitation(self.jane['mail'], start, template=event_itip) | ||||
Show All 14 Lines | def test_010_partstat_update_propagation(self): | ||||
self.assertEqual(janes.get_attendee(self.jack['mail']).get_participant_status(), kolabformat.PartTentative) | self.assertEqual(janes.get_attendee(self.jack['mail']).get_participant_status(), kolabformat.PartTentative) | ||||
# check updated partstats in jack's calendar | # check updated partstats in jack's calendar | ||||
jacks = self.check_user_calendar_event(self.jack['kolabcalendarfolder'], 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.jane['mail']).get_participant_status(), kolabformat.PartAccepted) | ||||
self.assertEqual(jacks.get_attendee(self.jack['mail']).get_participant_status(), kolabformat.PartTentative) | self.assertEqual(jacks.get_attendee(self.jack['mail']).get_participant_status(), kolabformat.PartTentative) | ||||
# PART 2: create conflicting event in jack's calendar | # PART 2: create conflicting event in jack's calendar | ||||
new_start = datetime.datetime(2014,8,21, 6,0,0, tzinfo=pytz.timezone("Europe/Berlin")) | new_start = datetime.datetime(2014, 8, 21, 6, 0, 0, tzinfo=pytz.timezone("Europe/Berlin")) | ||||
self.create_calendar_event(new_start, user=self.jack, attendees=[], summary="blocker") | self.create_calendar_event(new_start, user=self.jack, attendees=[], summary="blocker") | ||||
# re-schedule initial event to new date | # re-schedule initial event to new date | ||||
self.update_calendar_event(uid, start=new_start, sequence=1, user=self.john) | self.update_calendar_event(uid, start=new_start, sequence=1, user=self.john) | ||||
self.send_itip_update(self.jane['mail'], uid, new_start, summary="test (updated)", sequence=1) | self.send_itip_update(self.jane['mail'], uid, new_start, summary="test (updated)", sequence=1) | ||||
self.send_itip_update(self.jack['mail'], uid, new_start, summary="test (updated)", sequence=1) | self.send_itip_update(self.jack['mail'], uid, new_start, summary="test (updated)", sequence=1) | ||||
# wait for replies to be processed and propagated | # wait for replies to be processed and propagated | ||||
time.sleep(10) | time.sleep(10) | ||||
event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
# check updated event in organizer's calendar (jack didn't reply yet) | # check updated event in organizer's calendar (jack didn't reply yet) | ||||
self.assertEqual(event.get_attendee(self.jane['mail']).get_participant_status(), kolabformat.PartAccepted) | self.assertEqual(event.get_attendee(self.jane['mail']).get_participant_status(), kolabformat.PartAccepted) | ||||
self.assertEqual(event.get_attendee(self.jack['mail']).get_participant_status(), kolabformat.PartTentative) | 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 | # check partstats in jack's calendar: jack's status should remain needs-action | ||||
jacks = self.check_user_calendar_event(self.jack['kolabcalendarfolder'], 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.jane['mail']).get_participant_status(), kolabformat.PartAccepted) | ||||
self.assertEqual(jacks.get_attendee(self.jack['mail']).get_participant_status(), kolabformat.PartNeedsAction) | self.assertEqual(jacks.get_attendee(self.jack['mail']).get_participant_status(), kolabformat.PartNeedsAction) | ||||
def test_011_manual_schedule_auto_update(self): | def test_011_manual_schedule_auto_update(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
# create an event in john's calendar as it was manually accepted | # create an event in john's calendar as it was manually accepted | ||||
start = datetime.datetime(2014,9,2, 11,0,0, tzinfo=pytz.timezone("Europe/Berlin")) | start = datetime.datetime(2014, 9, 2, 11, 0, 0, tzinfo=pytz.timezone("Europe/Berlin")) | ||||
uid = self.create_calendar_event(start, user=self.jane, sequence=1, folder=self.john['kolabcalendarfolder']) | uid = self.create_calendar_event(start, user=self.jane, sequence=1, folder=self.john['kolabcalendarfolder']) | ||||
# send update with the same sequence: no re-scheduling | # send update with the same sequence: no re-scheduling | ||||
templ = itip_invitation.replace("RSVP=TRUE", "RSVP=FALSE").replace("Doe, John", self.jane['displayname']).replace("john.doe@example.org", self.jane['mail']) | templ = itip_invitation.replace("RSVP=TRUE", "RSVP=FALSE").replace("Doe, John", self.jane['displayname']).replace("john.doe@example.org", self.jane['mail']) | ||||
self.send_itip_update(self.john['mail'], uid, start, summary="test updated", sequence=1, partstat='ACCEPTED', template=templ) | self.send_itip_update(self.john['mail'], uid, start, summary="test updated", sequence=1, partstat='ACCEPTED', template=templ) | ||||
time.sleep(10) | time.sleep(10) | ||||
event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(event.get_summary(), "test updated") | self.assertEqual(event.get_summary(), "test updated") | ||||
self.assertEqual(event.get_attendee(self.john['mail']).get_participant_status(), kolabformat.PartAccepted) | self.assertEqual(event.get_attendee(self.john['mail']).get_participant_status(), kolabformat.PartAccepted) | ||||
# this should also trigger an update notification | # this should also trigger an update notification | ||||
notification = self.check_message_received(_('"%s" has been updated') % ('test updated'), self.jane['mail'], mailbox=self.john['mailbox']) | notification = self.check_message_received(_('"%s" has been updated') % ('test updated'), self.jane['mail'], mailbox=self.john['mailbox']) | ||||
self.assertIsInstance(notification, email.message.Message) | self.assertIsInstance(notification, email.message.Message) | ||||
# send outdated update: should not be saved | # send outdated update: should not be saved | ||||
self.send_itip_update(self.john['mail'], uid, start, summary="old test", sequence=0, partstat='NEEDS-ACTION', template=templ) | self.send_itip_update(self.john['mail'], uid, start, summary="old test", sequence=0, partstat='NEEDS-ACTION', template=templ) | ||||
notification = self.check_message_received(_('"%s" has been updated') % ('old test'), self.jane['mail'], mailbox=self.john['mailbox']) | notification = self.check_message_received(_('"%s" has been updated') % ('old test'), self.jane['mail'], mailbox=self.john['mailbox']) | ||||
self.assertEqual(notification, None) | self.assertEqual(notification, None) | ||||
def test_012_confidential_invitation(self): | def test_012_confidential_invitation(self): | ||||
start = datetime.datetime(2014,9,21, 9,30,0) | start = datetime.datetime(2014, 9, 21, 9, 30, 0) | ||||
uid = self.send_itip_invitation(self.jane['mail'], start, summary='confidential', template=itip_invitation.replace("DESCRIPTION:test", "CLASS:CONFIDENTIAL")) | uid = self.send_itip_invitation(self.jane['mail'], start, summary='confidential', template=itip_invitation.replace("DESCRIPTION:test", "CLASS:CONFIDENTIAL")) | ||||
# check event being stored in the folder annotared with event.confidential | # check event being stored in the folder annotared with event.confidential | ||||
event = self.check_user_calendar_event(self.jane['kolabconfidentialcalendar'], uid) | event = self.check_user_calendar_event(self.jane['kolabconfidentialcalendar'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(event.get_summary(), "confidential") | self.assertEqual(event.get_summary(), "confidential") | ||||
def test_013_update_shared_folder(self): | def test_013_update_shared_folder(self): | ||||
# create an event organized by Mark (a delegate of Jane) into Jane's calendar | # create an event organized by Mark (a delegate of Jane) into Jane's calendar | ||||
start = datetime.datetime(2015,3,10, 9,30,0, tzinfo=pytz.timezone("Europe/Berlin")) | start = datetime.datetime(2015, 3, 10, 9, 30, 0, tzinfo=pytz.timezone("Europe/Berlin")) | ||||
uid = self.create_calendar_event(start, user=self.mark, attendees=[self.jane, self.john], folder=self.jane['kolabcalendarfolder']) | uid = self.create_calendar_event(start, user=self.mark, attendees=[self.jane, self.john], folder=self.jane['kolabcalendarfolder']) | ||||
event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
# send a reply from john to mark | # send a reply from john to mark | ||||
self.send_itip_reply(uid, self.john['mail'], self.mark['mail'], start=start) | self.send_itip_reply(uid, self.john['mail'], self.mark['mail'], start=start) | ||||
# check for the updated event in jane's calendar | # check for the updated event in jane's calendar | ||||
time.sleep(10) | time.sleep(10) | ||||
event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(event.get_attendee(self.john['mail']).get_participant_status(), kolabformat.PartAccepted) | self.assertEqual(event.get_attendee(self.john['mail']).get_participant_status(), kolabformat.PartAccepted) | ||||
def test_014_per_sender_policy(self): | def test_014_per_sender_policy(self): | ||||
# send invitation from john => REJECT | # send invitation from john => REJECT | ||||
start = datetime.datetime(2015,2,28, 14,0,0) | start = datetime.datetime(2015, 2, 28, 14, 0, 0) | ||||
uid = self.send_itip_invitation(self.bill['mail'], start) | uid = self.send_itip_invitation(self.bill['mail'], start) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('DECLINED') }, self.bill['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('DECLINED')}, self.bill['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
# send invitation from lucy => SAVE | # send invitation from lucy => SAVE | ||||
start = datetime.datetime(2015,3,11, 10,0,0) | start = datetime.datetime(2015, 3, 11, 10, 0, 0) | ||||
templ = itip_invitation.replace("Doe, John", self.lucy['displayname']) | templ = itip_invitation.replace("Doe, John", self.lucy['displayname']) | ||||
uid = self.send_itip_invitation(self.bill['mail'], start, template=templ, from_addr=self.lucy['mail']) | uid = self.send_itip_invitation(self.bill['mail'], start, template=templ, from_addr=self.lucy['mail']) | ||||
event = self.check_user_calendar_event(self.bill['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.bill['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
def test_015_update_single_occurrence(self): | def test_015_update_single_occurrence(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
start = datetime.datetime(2015,4,2, 14,0,0) | start = datetime.datetime(2015, 4, 2, 14, 0, 0) | ||||
uid = self.send_itip_invitation(self.jane['mail'], start, template=itip_recurring) | uid = self.send_itip_invitation(self.jane['mail'], start, template=itip_recurring) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }, self.jane['mail']) | 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) | self.assertIsInstance(response, email.message.Message) | ||||
event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertTrue(event.is_recurring()) | self.assertTrue(event.is_recurring()) | ||||
# send update to a single instance with the same sequence: no re-scheduling | # send update to a single instance with the same sequence: no re-scheduling | ||||
exdate = start + datetime.timedelta(days=14) | exdate = start + datetime.timedelta(days=14) | ||||
self.send_itip_update(self.jane['mail'], uid, exdate, summary="test exception", sequence=0, partstat='ACCEPTED', instance=exdate) | self.send_itip_update(self.jane['mail'], uid, exdate, summary="test exception", sequence=0, partstat='ACCEPTED', instance=exdate) | ||||
time.sleep(10) | time.sleep(10) | ||||
event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(len(event.get_exceptions()), 1) | self.assertEqual(len(event.get_exceptions()), 1) | ||||
exception = event.get_instance(exdate) | exception = event.get_instance(exdate) | ||||
self.assertEqual(exception.get_summary(), "test exception") | self.assertEqual(exception.get_summary(), "test exception") | ||||
self.assertEqual(exception.get_attendee(self.jane['mail']).get_participant_status(), kolabformat.PartAccepted) | self.assertEqual(exception.get_attendee(self.jane['mail']).get_participant_status(), kolabformat.PartAccepted) | ||||
def test_015_reschedule_single_occurrence(self): | def test_015_reschedule_single_occurrence(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
start = datetime.datetime(2015,4,10, 9,0,0) | start = datetime.datetime(2015, 4, 10, 9, 0, 0) | ||||
uid = self.send_itip_invitation(self.jane['mail'], start, template=itip_recurring) | uid = self.send_itip_invitation(self.jane['mail'], start, template=itip_recurring) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }, self.jane['mail']) | 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) | self.assertIsInstance(response, email.message.Message) | ||||
# send update to a single instance with the same sequence: no re-scheduling | # send update to a single instance with the same sequence: no re-scheduling | ||||
exdate = start + datetime.timedelta(days=14) | exdate = start + datetime.timedelta(days=14) | ||||
exstart = exdate + datetime.timedelta(hours=5) | exstart = exdate + datetime.timedelta(hours=5) | ||||
self.send_itip_update(self.jane['mail'], uid, exstart, summary="test resceduled", sequence=1, partstat='NEEDS-ACTION', instance=exdate) | self.send_itip_update(self.jane['mail'], uid, exstart, summary="test resceduled", sequence=1, partstat='NEEDS-ACTION', instance=exdate) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test resceduled', 'status':participant_status_label('ACCEPTED') }, self.jane['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test resceduled', 'status': participant_status_label('ACCEPTED')}, self.jane['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
time.sleep(10) | time.sleep(10) | ||||
event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(len(event.get_exceptions()), 1) | self.assertEqual(len(event.get_exceptions()), 1) | ||||
# re-schedule again, conflicts with itself | # re-schedule again, conflicts with itself | ||||
exstart = exdate + datetime.timedelta(hours=6) | exstart = exdate + datetime.timedelta(hours=6) | ||||
self.send_itip_update(self.jane['mail'], uid, exstart, summary="test new", sequence=2, partstat='NEEDS-ACTION', instance=exdate) | self.send_itip_update(self.jane['mail'], uid, exstart, summary="test new", sequence=2, partstat='NEEDS-ACTION', instance=exdate) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test new', 'status':participant_status_label('ACCEPTED') }, self.jane['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test new', 'status': participant_status_label('ACCEPTED')}, self.jane['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
# check for updated excaption | # check for updated excaption | ||||
time.sleep(10) | time.sleep(10) | ||||
event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(len(event.get_exceptions()), 1) | self.assertEqual(len(event.get_exceptions()), 1) | ||||
exception = event.get_instance(exdate) | exception = event.get_instance(exdate) | ||||
self.assertIsInstance(exception, pykolab.xml.Event) | self.assertIsInstance(exception, pykolab.xml.Event) | ||||
self.assertEqual(exception.get_start().strftime('%Y%m%dT%H%M%S'), exstart.strftime('%Y%m%dT%H%M%S')) | self.assertEqual(exception.get_start().strftime('%Y%m%dT%H%M%S'), exstart.strftime('%Y%m%dT%H%M%S')) | ||||
def test_016_reply_single_occurrence(self): | def test_016_reply_single_occurrence(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
start = datetime.datetime(2015,3,7, 10,0,0, tzinfo=pytz.timezone("Europe/Zurich")) | start = datetime.datetime(2015, 3, 7, 10, 0, 0, tzinfo=pytz.timezone("Europe/Zurich")) | ||||
uid = self.create_calendar_event(start, attendees=[self.jane, self.mark], recurring=True) | uid = self.create_calendar_event(start, attendees=[self.jane, self.mark], recurring=True) | ||||
event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.john['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
# store a copy in mark's calendar, too | # store a copy in mark's calendar, too | ||||
self.create_calendar_event(start, attendees=[self.jane, self.mark], recurring=True, folder=self.mark['kolabcalendarfolder'], uid=uid) | self.create_calendar_event(start, attendees=[self.jane, self.mark], recurring=True, folder=self.mark['kolabcalendarfolder'], uid=uid) | ||||
Show All 28 Lines | def test_016_reply_single_occurrence(self): | ||||
self.assertEqual(len(event.get_exceptions()), 1) | self.assertEqual(len(event.get_exceptions()), 1) | ||||
exception = event.get_instance(exdate) | exception = event.get_instance(exdate) | ||||
self.assertEqual(exception.get_attendee(self.mark['mail']).get_participant_status(), kolabformat.PartAccepted) | self.assertEqual(exception.get_attendee(self.mark['mail']).get_participant_status(), kolabformat.PartAccepted) | ||||
def test_017_cancel_single_occurrence(self): | def test_017_cancel_single_occurrence(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
start = datetime.datetime(2015,3,20, 19,0,0, tzinfo=pytz.timezone("Europe/Zurich")) | start = datetime.datetime(2015, 3, 20, 19, 0, 0, tzinfo=pytz.timezone("Europe/Zurich")) | ||||
uid = self.send_itip_invitation(self.jane['mail'], summary="recurring", start=start, template=itip_recurring) | uid = self.send_itip_invitation(self.jane['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.jane['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'recurring', 'status': participant_status_label('ACCEPTED')}, self.jane['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
exdate = start + datetime.timedelta(days=14) | exdate = start + datetime.timedelta(days=14) | ||||
self.send_itip_cancel(self.jane['mail'], uid, summary="recurring cancelled", instance=exdate) | self.send_itip_cancel(self.jane['mail'], uid, summary="recurring cancelled", instance=exdate) | ||||
time.sleep(10) | time.sleep(10) | ||||
event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(len(event.get_exceptions()), 1) | self.assertEqual(len(event.get_exceptions()), 1) | ||||
exception = event.get_instance(exdate) | exception = event.get_instance(exdate) | ||||
self.assertEqual(exception.get_status(True), 'CANCELLED') | self.assertEqual(exception.get_status(True), 'CANCELLED') | ||||
self.assertTrue(exception.get_transparency()) | self.assertTrue(exception.get_transparency()) | ||||
# send a new invitation for the cancelled slot | # send a new invitation for the cancelled slot | ||||
uid = self.send_itip_invitation(self.jane['mail'], summary="new booking", start=exdate) | uid = self.send_itip_invitation(self.jane['mail'], summary="new booking", start=exdate) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'new booking', 'status':participant_status_label('ACCEPTED') }, self.jane['mail']) | 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) | self.assertIsInstance(response, email.message.Message) | ||||
def test_017_cancel_delete_single_occurrence(self): | def test_017_cancel_delete_single_occurrence(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
start = datetime.datetime(2015,3,24, 13,0,0, tzinfo=pytz.timezone("Europe/Zurich")) | start = datetime.datetime(2015, 3, 24, 13, 0, 0, tzinfo=pytz.timezone("Europe/Zurich")) | ||||
uid = self.send_itip_invitation(self.lucy['mail'], summary="recurring cancel-delete", start=start, template=itip_recurring) | uid = self.send_itip_invitation(self.lucy['mail'], summary="recurring cancel-delete", start=start, template=itip_recurring) | ||||
event = self.check_user_calendar_event(self.lucy['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.lucy['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
# send update to a single instance with the same sequence: no re-scheduling | # send update to a single instance with the same sequence: no re-scheduling | ||||
exdate = start + datetime.timedelta(days=14) | exdate = start + datetime.timedelta(days=14) | ||||
exstart = exdate + datetime.timedelta(hours=5) | exstart = exdate + datetime.timedelta(hours=5) | ||||
Show All 14 Lines | def test_017_cancel_delete_single_occurrence(self): | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(len(event.get_exception_dates()), 1) | self.assertEqual(len(event.get_exception_dates()), 1) | ||||
self.assertEqual(event.get_exception_dates()[0].strftime("%Y-%m-%d"), exdate.strftime("%Y-%m-%d")) | self.assertEqual(event.get_exception_dates()[0].strftime("%Y-%m-%d"), exdate.strftime("%Y-%m-%d")) | ||||
self.assertEqual(len(event.get_exceptions()), 0) | self.assertEqual(len(event.get_exceptions()), 0) | ||||
def test_017_cancel_thisandfuture(self): | def test_017_cancel_thisandfuture(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
start = datetime.datetime(2015,5,4, 6,30,0) | start = datetime.datetime(2015, 5, 4, 6, 30, 0) | ||||
uid = self.send_itip_invitation(self.mark['mail'], summary="recurring", start=start, template=itip_recurring) | uid = self.send_itip_invitation(self.mark['mail'], summary="recurring", start=start, template=itip_recurring) | ||||
pykolab.translate.setUserLanguage(self.mark['preferredlanguage']) | pykolab.translate.setUserLanguage(self.mark['preferredlanguage']) | ||||
response = self.check_message_received(_('"%(summary)s" has been %(status)s') % { 'summary':'recurring', 'status':participant_status_label('ACCEPTED') }, self.mark['mail']) | response = self.check_message_received(_('"%(summary)s" has been %(status)s') % {'summary': 'recurring', 'status': participant_status_label('ACCEPTED')}, self.mark['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
pykolab.translate.setUserLanguage(conf.get('kolab','default_locale')) | pykolab.translate.setUserLanguage(conf.get('kolab','default_locale')) | ||||
event = self.check_user_calendar_event(self.mark['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.mark['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
exdate = start + datetime.timedelta(days=14) | exdate = start + datetime.timedelta(days=14) | ||||
self.send_itip_cancel(self.mark['mail'], uid, summary="recurring ended", instance=exdate, thisandfuture=True) | self.send_itip_cancel(self.mark['mail'], uid, summary="recurring ended", instance=exdate, thisandfuture=True) | ||||
time.sleep(10) | time.sleep(10) | ||||
event = self.check_user_calendar_event(self.mark['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.mark['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
rrule = event.get_recurrence().to_dict() | rrule = event.get_recurrence().to_dict() | ||||
self.assertIsInstance(rrule['until'], datetime.datetime) | self.assertIsInstance(rrule['until'], datetime.datetime) | ||||
self.assertEqual(rrule['until'].strftime('%Y%m%d'), (exdate - datetime.timedelta(days=1)).strftime('%Y%m%d')) | self.assertEqual(rrule['until'].strftime('%Y%m%d'), (exdate - datetime.timedelta(days=1)).strftime('%Y%m%d')) | ||||
def test_018_invite_individual_occurrences(self): | def test_018_invite_individual_occurrences(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
start = datetime.datetime(2015,1,30, 17,0,0, tzinfo=pytz.timezone("Europe/Zurich")) | start = datetime.datetime(2015, 1, 30, 17, 0, 0, tzinfo=pytz.timezone("Europe/Zurich")) | ||||
uid = self.send_itip_invitation(self.jane['mail'], summary="single", start=start, instance=start) | uid = self.send_itip_invitation(self.jane['mail'], summary="single", start=start, instance=start) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'single', 'status':participant_status_label('ACCEPTED') }, self.jane['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'single', 'status': participant_status_label('ACCEPTED')}, self.jane['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
self.assertIn("RECURRENCE-ID", str(response)) | self.assertIn("RECURRENCE-ID", str(response)) | ||||
event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertIsInstance(event.get_recurrence_id(), datetime.datetime) | self.assertIsInstance(event.get_recurrence_id(), datetime.datetime) | ||||
# send another invitation with the same UID for different RECURRENCE-ID | # send another invitation with the same UID for different RECURRENCE-ID | ||||
newstart = datetime.datetime(2015,2,6, 17,0,0, tzinfo=pytz.timezone("Europe/Zurich")) | newstart = datetime.datetime(2015, 2, 6, 17, 0, 0, tzinfo=pytz.timezone("Europe/Zurich")) | ||||
self.send_itip_invitation(self.jane['mail'], summary="single #2", uid=uid, start=newstart, instance=newstart) | self.send_itip_invitation(self.jane['mail'], summary="single #2", uid=uid, start=newstart, instance=newstart) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'single #2', 'status':participant_status_label('ACCEPTED') }, self.jane['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'single #2', 'status': participant_status_label('ACCEPTED')}, self.jane['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
self.assertIn("RECURRENCE-ID", str(response)) | self.assertIn("RECURRENCE-ID", str(response)) | ||||
event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(len(event.get_exceptions()), 1) | self.assertEqual(len(event.get_exceptions()), 1) | ||||
exception = event.get_instance(newstart) | exception = event.get_instance(newstart) | ||||
Show All 10 Lines | def test_018_invite_individual_occurrences(self): | ||||
time.sleep(10) | time.sleep(10) | ||||
event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | event = self.check_user_calendar_event(self.jane['kolabcalendarfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(event.get_summary(), "updated #1") | self.assertEqual(event.get_summary(), "updated #1") | ||||
exception = event.get_instance(newstart) | exception = event.get_instance(newstart) | ||||
self.assertEqual(exception.get_summary(), "updated #2") | self.assertEqual(exception.get_summary(), "updated #2") | ||||
def test_020_task_assignment_accept(self): | def test_020_task_assignment_accept(self): | ||||
start = datetime.datetime(2014,9,10, 19,0,0) | start = datetime.datetime(2014, 9, 10, 19, 0, 0) | ||||
uid = self.send_itip_invitation(self.jane['mail'], start, summary='work', template=itip_todo) | 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']) | 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) | self.assertIsInstance(response, email.message.Message) | ||||
todo = self.check_user_imap_object(self.jane['kolabtasksfolder'], uid, 'task') | todo = self.check_user_imap_object(self.jane['kolabtasksfolder'], uid, 'task') | ||||
self.assertIsInstance(todo, pykolab.xml.Todo) | self.assertIsInstance(todo, pykolab.xml.Todo) | ||||
self.assertEqual(todo.get_summary(), "work") | self.assertEqual(todo.get_summary(), "work") | ||||
# send update with the same sequence: no re-scheduling | # 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') | 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']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'work updated', 'status': participant_status_label('ACCEPTED')}, self.jane['mail']) | ||||
self.assertEqual(response, None) | self.assertEqual(response, None) | ||||
time.sleep(10) | time.sleep(10) | ||||
todo = self.check_user_imap_object(self.jane['kolabtasksfolder'], uid, 'task') | todo = self.check_user_imap_object(self.jane['kolabtasksfolder'], uid, 'task') | ||||
self.assertIsInstance(todo, pykolab.xml.Todo) | self.assertIsInstance(todo, pykolab.xml.Todo) | ||||
self.assertEqual(todo.get_summary(), "work updated") | self.assertEqual(todo.get_summary(), "work updated") | ||||
self.assertEqual(todo.get_attendee(self.jane['mail']).get_participant_status(), kolabformat.PartAccepted) | self.assertEqual(todo.get_attendee(self.jane['mail']).get_participant_status(), kolabformat.PartAccepted) | ||||
def test_021_task_assignment_reply(self): | def test_021_task_assignment_reply(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
due = datetime.datetime(2014,9,12, 14,0,0, tzinfo=pytz.timezone("Europe/Berlin")) | due = datetime.datetime(2014, 9, 12, 14, 0, 0, tzinfo=pytz.timezone("Europe/Berlin")) | ||||
uid = self.create_task_assignment(due, user=self.john) | uid = self.create_task_assignment(due, user=self.john) | ||||
todo = self.check_user_imap_object(self.john['kolabtasksfolder'], uid, 'task') | todo = self.check_user_imap_object(self.john['kolabtasksfolder'], uid, 'task') | ||||
self.assertIsInstance(todo, pykolab.xml.Todo) | self.assertIsInstance(todo, pykolab.xml.Todo) | ||||
# send a reply from jane to john | # send a reply from jane to john | ||||
partstat = 'COMPLETED' | partstat = 'COMPLETED' | ||||
self.send_itip_reply(uid, self.jane['mail'], self.john['mail'], start=due, template=itip_todo_reply, partstat=partstat) | 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 | # check for the updated task in john's tasklist | ||||
time.sleep(10) | time.sleep(10) | ||||
todo = self.check_user_imap_object(self.john['kolabtasksfolder'], uid, 'task') | todo = self.check_user_imap_object(self.john['kolabtasksfolder'], uid, 'task') | ||||
self.assertIsInstance(todo, pykolab.xml.Todo) | self.assertIsInstance(todo, pykolab.xml.Todo) | ||||
attendee = todo.get_attendee(self.jane['mail']) | attendee = todo.get_attendee(self.jane['mail']) | ||||
self.assertIsInstance(attendee, pykolab.xml.Attendee) | self.assertIsInstance(attendee, pykolab.xml.Attendee) | ||||
self.assertEqual(attendee.get_participant_status(True), partstat) | self.assertEqual(attendee.get_participant_status(True), partstat) | ||||
# this should trigger an update notification | # this should trigger an update notification | ||||
notification = self.check_message_received(_('"%s" has been updated') % ('test'), self.john['mail']) | notification = self.check_message_received(_('"%s" has been updated') % ('test'), self.john['mail']) | ||||
self.assertIsInstance(notification, email.message.Message) | self.assertIsInstance(notification, email.message.Message) | ||||
notification_text = str(notification.get_payload()); | notification_text = str(notification.get_payload()) | ||||
self.assertIn(participant_status_label(partstat), notification_text) | self.assertIn(participant_status_label(partstat), notification_text) | ||||
def test_022_task_cancellation(self): | def test_022_task_cancellation(self): | ||||
uid = self.send_itip_invitation(self.jane['mail'], summary='more work', template=itip_todo) | uid = self.send_itip_invitation(self.jane['mail'], summary='more work', template=itip_todo) | ||||
time.sleep(10) | time.sleep(10) | ||||
self.send_itip_cancel(self.jane['mail'], uid, template=itip_todo_cancel, summary="cancelled") | self.send_itip_cancel(self.jane['mail'], uid, template=itip_todo_cancel, summary="cancelled") | ||||
time.sleep(10) | time.sleep(10) | ||||
todo = self.check_user_imap_object(self.jane['kolabtasksfolder'], uid, 'task') | todo = self.check_user_imap_object(self.jane['kolabtasksfolder'], uid, 'task') | ||||
self.assertIsInstance(todo, pykolab.xml.Todo) | self.assertIsInstance(todo, pykolab.xml.Todo) | ||||
self.assertEqual(todo.get_summary(), "more work") | self.assertEqual(todo.get_summary(), "more work") | ||||
self.assertEqual(todo.get_status(True), 'CANCELLED') | self.assertEqual(todo.get_status(True), 'CANCELLED') | ||||
# this should trigger a notification message | # this should trigger a notification message | ||||
notification = self.check_message_received(_('"%s" has been cancelled') % ('more work'), self.john['mail'], mailbox=self.jane['mailbox']) | notification = self.check_message_received(_('"%s" has been cancelled') % ('more work'), self.john['mail'], mailbox=self.jane['mailbox']) | ||||
self.assertIsInstance(notification, email.message.Message) | self.assertIsInstance(notification, email.message.Message) | ||||