Changeset View
Changeset View
Standalone View
Standalone View
tests/functional/test_wallace/test_005_resource_invitation.py
Show First 20 Lines • Show All 125 Lines • ▼ Show 20 Lines | |||||
DESCRIPTION:test | DESCRIPTION:test | ||||
ORGANIZER;CN="Doe, John":mailto:john.doe@example.org | ORGANIZER;CN="Doe, John":mailto:john.doe@example.org | ||||
ATTENDEE;ROLE=REQ-PARTICIPANT;CUTYPE=RESOURCE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:mailto:%s | ATTENDEE;ROLE=REQ-PARTICIPANT;CUTYPE=RESOURCE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:mailto:%s | ||||
TRANSP:OPAQUE | TRANSP:OPAQUE | ||||
END:VEVENT | END:VEVENT | ||||
END:VCALENDAR | END:VCALENDAR | ||||
""" | """ | ||||
itip_recurring = """ | itip_recurring = """ | ||||
BEGIN:VCALENDAR | BEGIN:VCALENDAR | ||||
VERSION:2.0 | VERSION:2.0 | ||||
PRODID:-//Apple Inc.//Mac OS X 10.9.2//EN | PRODID:-//Apple Inc.//Mac OS X 10.9.2//EN | ||||
CALSCALE:GREGORIAN | CALSCALE:GREGORIAN | ||||
METHOD:REQUEST | METHOD:REQUEST | ||||
BEGIN:VEVENT | BEGIN:VEVENT | ||||
UID:%s%s | UID:%s%s | ||||
Show All 30 Lines | |||||
Content-Type: text/calendar; charset=UTF-8; method=REQUEST; name=event.ics | Content-Type: text/calendar; charset=UTF-8; method=REQUEST; 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 TestResourceInvitation(unittest.TestCase): | |||||
class TestResourceInvitation(unittest.TestCase): | |||||
john = None | john = 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 = _("Reservation Request for %(summary)s was %(status)s") | self.itip_reply_subject = _("Reservation Request for %(summary)s was %(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', | ||||
Show All 14 Lines | def setup_class(self, *args, **kw): | ||||
from tests.functional.user_add import user_add | from tests.functional.user_add import user_add | ||||
user_add("John", "Doe", kolabinvitationpolicy='ALL_MANUAL') | user_add("John", "Doe", kolabinvitationpolicy='ALL_MANUAL') | ||||
user_add("Jane", "Manager", kolabinvitationpolicy='ALL_MANUAL') | user_add("Jane", "Manager", kolabinvitationpolicy='ALL_MANUAL') | ||||
funcs.purge_resources() | funcs.purge_resources() | ||||
self.audi = funcs.resource_add("car", "Audi A4") | self.audi = funcs.resource_add("car", "Audi A4") | ||||
self.passat = funcs.resource_add("car", "VW Passat") | self.passat = funcs.resource_add("car", "VW Passat") | ||||
self.boxter = funcs.resource_add("car", "Porsche Boxter S") | self.boxter = funcs.resource_add("car", "Porsche Boxter S") | ||||
self.cars = funcs.resource_add("collection", "Company Cars", [ self.audi['dn'], self.passat['dn'], self.boxter['dn'] ]) | self.cars = funcs.resource_add("collection", "Company Cars", [self.audi['dn'], self.passat['dn'], self.boxter['dn']]) | ||||
self.room1 = funcs.resource_add("confroom", "Room 101", owner=self.jane['dn'], kolabinvitationpolicy='ACT_ACCEPT_AND_NOTIFY') | self.room1 = funcs.resource_add("confroom", "Room 101", owner=self.jane['dn'], kolabinvitationpolicy='ACT_ACCEPT_AND_NOTIFY') | ||||
self.room2 = funcs.resource_add("confroom", "Conference Room B-222") | self.room2 = funcs.resource_add("confroom", "Conference Room B-222") | ||||
self.rooms = funcs.resource_add("collection", "Rooms", [ self.room1['dn'], self.room2['dn'] ], self.jane['dn'], kolabinvitationpolicy='ACT_ACCEPT_AND_NOTIFY') | self.rooms = funcs.resource_add("collection", "Rooms", [self.room1['dn'], self.room2['dn']], self.jane['dn'], kolabinvitationpolicy='ACT_ACCEPT_AND_NOTIFY') | ||||
self.room3 = funcs.resource_add("confroom", "CEOs Office 303") | self.room3 = funcs.resource_add("confroom", "CEOs Office 303") | ||||
self.viprooms = funcs.resource_add("collection", "VIP Rooms", [ self.room3['dn'] ], self.jane['dn'], kolabinvitationpolicy='ACT_MANUAL') | self.viprooms = funcs.resource_add("collection", "VIP Rooms", [self.room3['dn']], self.jane['dn'], kolabinvitationpolicy='ACT_MANUAL') | ||||
time.sleep(1) | time.sleep(1) | ||||
from tests.functional.synchronize import synchronize_once | from tests.functional.synchronize import synchronize_once | ||||
synchronize_once() | synchronize_once() | ||||
def send_message(self, itip_payload, to_addr, from_addr=None): | def send_message(self, itip_payload, to_addr, from_addr=None): | ||||
if from_addr is None: | if from_addr is None: | ||||
from_addr = self.john['mail'] | from_addr = self.john['mail'] | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | def send_itip_cancel(self, resource_email, uid, instance=None): | ||||
uid, | uid, | ||||
recurrence_id, | recurrence_id, | ||||
resource_email | resource_email | ||||
), | ), | ||||
resource_email) | resource_email) | ||||
return uid | return uid | ||||
def send_owner_response(self, event, partstat, from_addr=None): | def send_owner_response(self, event, partstat, from_addr=None): | ||||
if from_addr is None: | if from_addr is None: | ||||
from_addr = self.jane['mail'] | from_addr = self.jane['mail'] | ||||
itip_reply = event.to_message_itip(from_addr, | itip_reply = event.to_message_itip( | ||||
from_addr, | |||||
method="REPLY", | method="REPLY", | ||||
participant_status=partstat, | participant_status=partstat, | ||||
message_text="Request " + partstat, | message_text="Request " + partstat, | ||||
subject="Booking has been %s" % (partstat) | subject="Booking has been %s" % (partstat) | ||||
) | ) | ||||
smtp = smtplib.SMTP('localhost', 10026) | smtp = smtplib.SMTP('localhost', 10026) | ||||
smtp.sendmail(from_addr, str(event.get_organizer().email()), str(itip_reply)) | smtp.sendmail(from_addr, str(event.get_organizer().email()), str(itip_reply)) | ||||
smtp.quit() | smtp.quit() | ||||
def check_message_received(self, subject, from_addr=None, mailbox=None): | def check_message_received(self, subject, from_addr=None, mailbox=None): | ||||
if mailbox is None: | if mailbox is None: | ||||
▲ Show 20 Lines • Show All 64 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 find_resource_by_email(self, email): | def find_resource_by_email(self, email): | ||||
resource = None | resource = None | ||||
for r in [self.audi, self.passat, self.boxter, self.room1, self.room2]: | for r in [self.audi, self.passat, self.boxter, self.room1, self.room2]: | ||||
if (email.find(r['mail']) >= 0): | if (email.find(r['mail']) >= 0): | ||||
resource = r | resource = r | ||||
break | break | ||||
return resource | return resource | ||||
def test_001_resource_from_email_address(self): | def test_001_resource_from_email_address(self): | ||||
resource = module_resources.resource_record_from_email_address(self.audi['mail']) | resource = module_resources.resource_record_from_email_address(self.audi['mail']) | ||||
self.assertEqual(len(resource), 1) | self.assertEqual(len(resource), 1) | ||||
self.assertEqual(resource[0], self.audi['dn']) | self.assertEqual(resource[0], self.audi['dn']) | ||||
collection = module_resources.resource_record_from_email_address(self.cars['mail']) | collection = module_resources.resource_record_from_email_address(self.cars['mail']) | ||||
self.assertEqual(len(collection), 1) | self.assertEqual(len(collection), 1) | ||||
self.assertEqual(collection[0], self.cars['dn']) | self.assertEqual(collection[0], self.cars['dn']) | ||||
def test_002_invite_resource(self): | def test_002_invite_resource(self): | ||||
uid = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014,7,13, 10,0,0)) | uid = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014, 7, 13, 10, 0, 0)) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }, self.audi['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}, self.audi['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
event = self.check_resource_calendar_event(self.audi['kolabtargetfolder'], uid) | event = self.check_resource_calendar_event(self.audi['kolabtargetfolder'], 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") | ||||
# @depends test_002_invite_resource | # @depends test_002_invite_resource | ||||
def test_003_invite_resource_conflict(self): | def test_003_invite_resource_conflict(self): | ||||
uid = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014,7,13, 12,0,0)) | uid = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014, 7, 13, 12, 0, 0)) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('DECLINED') }, self.audi['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('DECLINED')}, self.audi['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
self.assertEqual(self.check_resource_calendar_event(self.audi['kolabtargetfolder'], uid), None) | self.assertEqual(self.check_resource_calendar_event(self.audi['kolabtargetfolder'], uid), None) | ||||
def test_004_invite_resource_collection(self): | def test_004_invite_resource_collection(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
uid = self.send_itip_invitation(self.cars['mail'], datetime.datetime(2014,7,13, 12,0,0)) | uid = self.send_itip_invitation(self.cars['mail'], datetime.datetime(2014, 7, 13, 12, 0, 0)) | ||||
# one of the collection members accepted the reservation | # one of the collection members accepted the reservation | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }) | accept = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
delegatee = self.find_resource_by_email(accept['from']) | delegatee = self.find_resource_by_email(accept['from']) | ||||
self.assertIn(delegatee['mail'], accept['from']) | self.assertIn(delegatee['mail'], accept['from']) | ||||
# check booking in the delegatee's resource calendar | # check booking in the delegatee's resource calendar | ||||
self.assertIsInstance(self.check_resource_calendar_event(delegatee['kolabtargetfolder'], uid), pykolab.xml.Event) | self.assertIsInstance(self.check_resource_calendar_event(delegatee['kolabtargetfolder'], uid), pykolab.xml.Event) | ||||
# resource collection responds with a DELEGATED message | # resource collection responds with a DELEGATED message | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('DELEGATED') }, self.cars['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('DELEGATED')}, self.cars['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
self.assertIn("ROLE=NON-PARTICIPANT;RSVP=FALSE", str(response)) | self.assertIn("ROLE=NON-PARTICIPANT;RSVP=FALSE", str(response)) | ||||
def test_005_rescheduling_reservation(self): | def test_005_rescheduling_reservation(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
uid = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014,4,1, 10,0,0)) | uid = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014, 4, 1, 10, 0, 0)) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }, self.audi['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}, self.audi['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
self.send_itip_update(self.audi['mail'], uid, datetime.datetime(2014,4,1, 12,0,0)) # conflict with myself | self.send_itip_update(self.audi['mail'], uid, datetime.datetime(2014, 4, 1, 12, 0, 0)) # conflict with myself | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }, self.audi['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}, self.audi['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
event = self.check_resource_calendar_event(self.audi['kolabtargetfolder'], uid) | event = self.check_resource_calendar_event(self.audi['kolabtargetfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(event.get_start().hour, 12) | self.assertEqual(event.get_start().hour, 12) | ||||
self.assertEqual(event.get_sequence(), 2) | self.assertEqual(event.get_sequence(), 2) | ||||
def test_005_rescheduling_collection(self): | def test_005_rescheduling_collection(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
uid = self.send_itip_invitation(self.cars['mail'], datetime.datetime(2014,4,24, 12,0,0)) | uid = self.send_itip_invitation(self.cars['mail'], datetime.datetime(2014, 4, 24, 12, 0, 0)) | ||||
# one of the collection members accepted the reservation | # one of the collection members accepted the reservation | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }) | accept = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
delegatee = self.find_resource_by_email(accept['from']) | delegatee = self.find_resource_by_email(accept['from']) | ||||
# book that resource for the next day | # book that resource for the next day | ||||
self.send_itip_invitation(delegatee['mail'], datetime.datetime(2014,4,25, 14,0,0)) | self.send_itip_invitation(delegatee['mail'], datetime.datetime(2014, 4, 25, 14, 0, 0)) | ||||
accept2 = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }) | accept2 = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}) | ||||
# re-schedule first booking to a conflicting date | # re-schedule first booking to a conflicting date | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
update_template = itip_delegated.replace("resource-car-audia4@example.org", delegatee['mail']) | update_template = itip_delegated.replace("resource-car-audia4@example.org", delegatee['mail']) | ||||
self.send_itip_update(delegatee['mail'], uid, datetime.datetime(2014,4,25, 12,0,0), template=update_template) | self.send_itip_update(delegatee['mail'], uid, datetime.datetime(2014, 4, 25, 12, 0, 0), template=update_template) | ||||
# expect response from another member of the initially delegated collection | # expect response from another member of the initially delegated collection | ||||
new_accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }) | new_accept = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}) | ||||
self.assertIsInstance(new_accept, email.message.Message) | self.assertIsInstance(new_accept, email.message.Message) | ||||
new_delegatee = self.find_resource_by_email(new_accept['from']) | new_delegatee = self.find_resource_by_email(new_accept['from']) | ||||
self.assertNotEqual(delegatee['mail'], new_delegatee['mail']) | self.assertNotEqual(delegatee['mail'], new_delegatee['mail']) | ||||
# event now booked into new delegate's calendar | # event now booked into new delegate's calendar | ||||
event = self.check_resource_calendar_event(new_delegatee['kolabtargetfolder'], uid) | event = self.check_resource_calendar_event(new_delegatee['kolabtargetfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
# old resource responds with a DELEGATED message | # old resource responds with a DELEGATED message | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('DELEGATED') }, delegatee['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('DELEGATED')}, delegatee['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
# old reservation was removed from old delegate's calendar | # old reservation was removed from old delegate's calendar | ||||
self.assertEqual(self.check_resource_calendar_event(delegatee['kolabtargetfolder'], uid), None) | self.assertEqual(self.check_resource_calendar_event(delegatee['kolabtargetfolder'], uid), None) | ||||
def test_006_cancelling_revervation(self): | def test_006_cancelling_revervation(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
uid = self.send_itip_invitation(self.boxter['mail'], datetime.datetime(2014,5,1, 10,0,0)) | uid = self.send_itip_invitation(self.boxter['mail'], datetime.datetime(2014, 5, 1, 10, 0, 0)) | ||||
self.assertIsInstance(self.check_resource_calendar_event(self.boxter['kolabtargetfolder'], uid), pykolab.xml.Event) | self.assertIsInstance(self.check_resource_calendar_event(self.boxter['kolabtargetfolder'], uid), pykolab.xml.Event) | ||||
self.send_itip_cancel(self.boxter['mail'], uid) | self.send_itip_cancel(self.boxter['mail'], uid) | ||||
time.sleep(2) # wait for IMAP to update | time.sleep(2) # wait for IMAP to update | ||||
self.assertEqual(self.check_resource_calendar_event(self.boxter['kolabtargetfolder'], uid), None) | self.assertEqual(self.check_resource_calendar_event(self.boxter['kolabtargetfolder'], uid), None) | ||||
# make new reservation to the now free'd slot | # make new reservation to the now free'd slot | ||||
self.send_itip_invitation(self.boxter['mail'], datetime.datetime(2014,5,1, 9,0,0)) | self.send_itip_invitation(self.boxter['mail'], datetime.datetime(2014, 5, 1, 9, 0, 0)) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }, self.boxter['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}, self.boxter['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
def test_007_update_delegated(self): | def test_007_update_delegated(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
dt = datetime.datetime(2014,8,1, 12,0,0) | dt = datetime.datetime(2014, 8, 1, 12, 0, 0) | ||||
uid = self.send_itip_invitation(self.cars['mail'], dt) | uid = self.send_itip_invitation(self.cars['mail'], dt) | ||||
# wait for accept notification | # wait for accept notification | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }) | accept = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
delegatee = self.find_resource_by_email(accept['from']) | delegatee = self.find_resource_by_email(accept['from']) | ||||
# send update message to all attendees (collection and delegatee) | # send update message to all attendees (collection and delegatee) | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
update_template = itip_delegated.replace("resource-car-audia4@example.org", delegatee['mail']) | update_template = itip_delegated.replace("resource-car-audia4@example.org", delegatee['mail']) | ||||
self.send_itip_update(self.cars['mail'], uid, dt, template=update_template) | self.send_itip_update(self.cars['mail'], uid, dt, template=update_template) | ||||
self.send_itip_update(delegatee['mail'], uid, dt, template=update_template) | self.send_itip_update(delegatee['mail'], uid, dt, template=update_template) | ||||
# get response from delegatee | # get response from delegatee | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }) | accept = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
self.assertIn(delegatee['mail'], accept['from']) | self.assertIn(delegatee['mail'], accept['from']) | ||||
# no delegation response on updates | # no delegation response on updates | ||||
self.assertEqual(self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('DELEGATED') }, self.cars['mail']), None) | self.assertEqual(self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('DELEGATED')}, self.cars['mail']), None) | ||||
def test_008_allday_reservation(self): | def test_008_allday_reservation(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
uid = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014,6,2), True) | uid = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014, 6, 2), True) | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }) | accept = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
event = self.check_resource_calendar_event(self.audi['kolabtargetfolder'], uid) | event = self.check_resource_calendar_event(self.audi['kolabtargetfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertIsInstance(event.get_start(), datetime.date) | self.assertIsInstance(event.get_start(), datetime.date) | ||||
uid2 = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014,6,2, 16,0,0)) | uid2 = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014, 6, 2, 16, 0, 0)) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('DECLINED') }, self.audi['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('DECLINED')}, self.audi['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
def test_009_recurring_events(self): | def test_009_recurring_events(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
# register an infinitely recurring resource invitation | # register an infinitely recurring resource invitation | ||||
uid = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014,2,20, 12,0,0), | uid = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014, 2, 20, 12, 0, 0), | ||||
template=itip_recurring.replace(";COUNT=10", "")) | template=itip_recurring.replace(";COUNT=10", "")) | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }) | accept = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
# check non-recurring against recurring | # check non-recurring against recurring | ||||
uid2 = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014,3,13, 10,0,0)) | uid2 = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014, 3, 13, 10, 0, 0)) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('DECLINED') }, self.audi['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('DECLINED')}, self.audi['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
# check recurring against recurring | # check recurring against recurring | ||||
uid3 = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014,2,22, 8,0,0), template=itip_recurring) | uid3 = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014, 2, 22, 8, 0, 0), template=itip_recurring) | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }) | accept = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
def test_010_invalid_bookings(self): | def test_010_invalid_bookings(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
itip_other = itip_invitation.replace("mailto:%s", "mailto:some-other-resource@example.org\nCOMMENT: Sent to %s") | itip_other = itip_invitation.replace("mailto:%s", "mailto:some-other-resource@example.org\nCOMMENT: Sent to %s") | ||||
self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014,3,22, 8,0,0), template=itip_other) | self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014, 3, 22, 8, 0, 0), template=itip_other) | ||||
time.sleep(1) | time.sleep(1) | ||||
itip_invalid = itip_invitation.replace("DTSTART;", "X-DTSTART;") | itip_invalid = itip_invitation.replace("DTSTART;", "X-DTSTART;") | ||||
self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014,3,24, 19,30,0), template=itip_invalid) | self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014, 3, 24, 19, 30, 0), template=itip_invalid) | ||||
self.assertEqual(self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }, self.audi['mail']), None) | self.assertEqual(self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}, self.audi['mail']), None) | ||||
def test_011_owner_info(self): | def test_011_owner_info(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
self.send_itip_invitation(self.room1['mail'], datetime.datetime(2014,6,19, 16,0,0)) | self.send_itip_invitation(self.room1['mail'], datetime.datetime(2014, 6, 19, 16, 0, 0)) | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }, self.room1['mail']) | accept = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}, self.room1['mail']) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
respose_text = str(accept.get_payload(0)) | respose_text = str(accept.get_payload(0)) | ||||
self.assertIn(self.jane['mail'], respose_text) | self.assertIn(self.jane['mail'], respose_text) | ||||
self.assertIn(self.jane['displayname'], respose_text) | self.assertIn(self.jane['displayname'], respose_text) | ||||
def test_011_owner_info_from_collection(self): | def test_011_owner_info_from_collection(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
self.send_itip_invitation(self.room2['mail'], datetime.datetime(2014,6,19, 16,0,0)) | self.send_itip_invitation(self.room2['mail'], datetime.datetime(2014, 6, 19, 16, 0, 0)) | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }, self.room2['mail']) | accept = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}, self.room2['mail']) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
respose_text = str(accept.get_payload(0)) | respose_text = str(accept.get_payload(0)) | ||||
self.assertIn(self.jane['mail'], respose_text) | self.assertIn(self.jane['mail'], respose_text) | ||||
self.assertIn(self.jane['displayname'], respose_text) | self.assertIn(self.jane['displayname'], respose_text) | ||||
def test_012_owner_notification(self): | def test_012_owner_notification(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
self.purge_mailbox(self.jane['mailbox']) | self.purge_mailbox(self.jane['mailbox']) | ||||
self.send_itip_invitation(self.room1['mail'], datetime.datetime(2014,8,4, 13,0,0)) | self.send_itip_invitation(self.room1['mail'], datetime.datetime(2014, 8, 4, 13, 0, 0)) | ||||
# check notification message sent to resource owner (jane) | # check notification message sent to resource owner (jane) | ||||
notify = self.check_message_received(_('Booking for %s has been %s') % (self.room1['cn'], participant_status_label('ACCEPTED')), self.room1['mail'], self.jane['mailbox']) | notify = self.check_message_received(_('Booking for %s has been %s') % (self.room1['cn'], participant_status_label('ACCEPTED')), self.room1['mail'], self.jane['mailbox']) | ||||
self.assertIsInstance(notify, email.message.Message) | self.assertIsInstance(notify, email.message.Message) | ||||
notification_text = str(notify.get_payload()) | notification_text = str(notify.get_payload()) | ||||
self.assertIn(self.john['mail'], notification_text) | self.assertIn(self.john['mail'], notification_text) | ||||
self.assertIn(participant_status_label('ACCEPTED'), notification_text) | self.assertIn(participant_status_label('ACCEPTED'), notification_text) | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
# check notification sent to collection owner (jane) | # check notification sent to collection owner (jane) | ||||
self.send_itip_invitation(self.rooms['mail'], datetime.datetime(2014,8,4, 12,30,0)) | self.send_itip_invitation(self.rooms['mail'], datetime.datetime(2014, 8, 4, 12, 30, 0)) | ||||
# one of the collection members accepted the reservation | # one of the collection members accepted the reservation | ||||
accepted = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }) | accepted = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}) | ||||
delegatee = self.find_resource_by_email(accepted['from']) | delegatee = self.find_resource_by_email(accepted['from']) | ||||
notify = self.check_message_received(_('Booking for %s has been %s') % (delegatee['cn'], participant_status_label('ACCEPTED')), delegatee['mail'], self.jane['mailbox']) | notify = self.check_message_received(_('Booking for %s has been %s') % (delegatee['cn'], participant_status_label('ACCEPTED')), delegatee['mail'], self.jane['mailbox']) | ||||
self.assertIsInstance(notify, email.message.Message) | self.assertIsInstance(notify, email.message.Message) | ||||
self.assertIn(self.john['mail'], notification_text) | self.assertIn(self.john['mail'], notification_text) | ||||
def test_013_owner_confirmation_accept(self): | def test_013_owner_confirmation_accept(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
self.purge_mailbox(self.jane['mailbox']) | self.purge_mailbox(self.jane['mailbox']) | ||||
uid = self.send_itip_invitation(self.room3['mail'], datetime.datetime(2014,9,12, 14,0,0)) | uid = self.send_itip_invitation(self.room3['mail'], datetime.datetime(2014, 9, 12, 14, 0, 0)) | ||||
# requester (john) gets a TENTATIVE confirmation | # requester (john) gets a TENTATIVE confirmation | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('TENTATIVE') }, self.room3['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('TENTATIVE')}, self.room3['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
event = self.check_resource_calendar_event(self.room3['kolabtargetfolder'], uid) | event = self.check_resource_calendar_event(self.room3['kolabtargetfolder'], 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.assertEqual(event.get_attendee_by_email(self.room3['mail']).get_participant_status(True), 'TENTATIVE') | self.assertEqual(event.get_attendee_by_email(self.room3['mail']).get_participant_status(True), 'TENTATIVE') | ||||
# check confirmation message sent to resource owner (jane) | # check confirmation message sent to resource owner (jane) | ||||
notify = self.check_message_received(_('Booking request for %s requires confirmation') % (self.room3['cn']), mailbox=self.jane['mailbox']) | notify = self.check_message_received(_('Booking request for %s requires confirmation') % (self.room3['cn']), mailbox=self.jane['mailbox']) | ||||
self.assertIsInstance(notify, email.message.Message) | self.assertIsInstance(notify, email.message.Message) | ||||
# resource owner confirms reservation request | # resource owner confirms reservation request | ||||
itip_event = events_from_message(notify)[0] | itip_event = events_from_message(notify)[0] | ||||
self.send_owner_response(itip_event['xml'], 'ACCEPTED', from_addr=self.jane['mail']) | self.send_owner_response(itip_event['xml'], 'ACCEPTED', from_addr=self.jane['mail']) | ||||
# requester (john) now gets the ACCEPTED response | # requester (john) now gets the ACCEPTED response | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }, self.room3['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}, self.room3['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
event = self.check_resource_calendar_event(self.room3['kolabtargetfolder'], uid) | event = self.check_resource_calendar_event(self.room3['kolabtargetfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(event.get_status(True), 'CONFIRMED') | self.assertEqual(event.get_status(True), 'CONFIRMED') | ||||
self.assertEqual(event.get_attendee_by_email(self.room3['mail']).get_participant_status(True), 'ACCEPTED') | self.assertEqual(event.get_attendee_by_email(self.room3['mail']).get_participant_status(True), 'ACCEPTED') | ||||
def test_014_owner_confirmation_decline(self): | def test_014_owner_confirmation_decline(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
self.purge_mailbox(self.jane['mailbox']) | self.purge_mailbox(self.jane['mailbox']) | ||||
uid = self.send_itip_invitation(self.room3['mail'], datetime.datetime(2014,9,14, 9,0,0)) | uid = self.send_itip_invitation(self.room3['mail'], datetime.datetime(2014, 9, 14, 9, 0, 0)) | ||||
# requester (john) gets a TENTATIVE confirmation | # requester (john) gets a TENTATIVE confirmation | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('TENTATIVE') }, self.room3['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('TENTATIVE')}, self.room3['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
# check confirmation message sent to resource owner (jane) | # check confirmation message sent to resource owner (jane) | ||||
notify = self.check_message_received(_('Booking request for %s requires confirmation') % (self.room3['cn']), mailbox=self.jane['mailbox']) | notify = self.check_message_received(_('Booking request for %s requires confirmation') % (self.room3['cn']), mailbox=self.jane['mailbox']) | ||||
self.assertIsInstance(notify, email.message.Message) | self.assertIsInstance(notify, email.message.Message) | ||||
itip_event = events_from_message(notify)[0] | itip_event = events_from_message(notify)[0] | ||||
# resource owner declines reservation request | # resource owner declines reservation request | ||||
itip_reply = itip_event['xml'].to_message_itip(self.jane['mail'], | itip_reply = itip_event['xml'].to_message_itip( | ||||
self.jane['mail'], | |||||
method="REPLY", | method="REPLY", | ||||
participant_status='DECLINED', | participant_status='DECLINED', | ||||
message_text="Request declined", | message_text="Request declined", | ||||
subject=_('Booking for %s has been %s') % (self.room3['cn'], participant_status_label('DECLINED')) | subject=_('Booking for %s has been %s') % (self.room3['cn'], participant_status_label('DECLINED')) | ||||
) | ) | ||||
smtp = smtplib.SMTP('localhost', 10026) | smtp = smtplib.SMTP('localhost', 10026) | ||||
smtp.sendmail(self.jane['mail'], str(itip_event['organizer']), str(itip_reply)) | smtp.sendmail(self.jane['mail'], str(itip_event['organizer']), str(itip_reply)) | ||||
smtp.quit() | smtp.quit() | ||||
# requester (john) now gets the DECLINED response | # requester (john) now gets the DECLINED response | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('DECLINED') }, self.room3['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('DECLINED')}, self.room3['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
# tentative reservation was set to cancelled | # tentative reservation was set to cancelled | ||||
event = self.check_resource_calendar_event(self.room3['kolabtargetfolder'], uid) | event = self.check_resource_calendar_event(self.room3['kolabtargetfolder'], uid) | ||||
self.assertEqual(event, None) | self.assertEqual(event, None) | ||||
#self.assertEqual(event.get_status(True), 'CANCELLED') | # self.assertEqual(event.get_status(True), 'CANCELLED') | ||||
#self.assertEqual(event.get_attendee_by_email(self.room3['mail']).get_participant_status(True), 'DECLINED') | # self.assertEqual(event.get_attendee_by_email(self.room3['mail']).get_participant_status(True), 'DECLINED') | ||||
def test_015_owner_confirmation_update(self): | def test_015_owner_confirmation_update(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
uid = self.send_itip_invitation(self.room3['mail'], datetime.datetime(2014,8,19, 9,0,0), uid="http://a-totally.stupid/?uid") | uid = self.send_itip_invitation(self.room3['mail'], datetime.datetime(2014, 8, 19, 9, 0, 0), uid="http://a-totally.stupid/?uid") | ||||
# requester (john) gets a TENTATIVE confirmation | # requester (john) gets a TENTATIVE confirmation | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('TENTATIVE') }, self.room3['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('TENTATIVE')}, self.room3['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
# check first confirmation message sent to resource owner (jane) | # check first confirmation message sent to resource owner (jane) | ||||
notify1 = self.check_message_received(_('Booking request for %s requires confirmation') % (self.room3['cn']), mailbox=self.jane['mailbox']) | notify1 = self.check_message_received(_('Booking request for %s requires confirmation') % (self.room3['cn']), mailbox=self.jane['mailbox']) | ||||
self.assertIsInstance(notify1, email.message.Message) | self.assertIsInstance(notify1, email.message.Message) | ||||
itip_event1 = events_from_message(notify1)[0] | itip_event1 = events_from_message(notify1)[0] | ||||
self.assertEqual(itip_event1['start'].hour, 9) | self.assertEqual(itip_event1['start'].hour, 9) | ||||
self.purge_mailbox(self.jane['mailbox']) | self.purge_mailbox(self.jane['mailbox']) | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
# send update with new date (and sequence) | # send update with new date (and sequence) | ||||
self.send_itip_update(self.room3['mail'], uid, datetime.datetime(2014,8,19, 16,0,0)) | self.send_itip_update(self.room3['mail'], uid, datetime.datetime(2014, 8, 19, 16, 0, 0)) | ||||
event = self.check_resource_calendar_event(self.room3['kolabtargetfolder'], uid) | event = self.check_resource_calendar_event(self.room3['kolabtargetfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(event.get_attendee_by_email(self.room3['mail']).get_participant_status(True), 'TENTATIVE') | self.assertEqual(event.get_attendee_by_email(self.room3['mail']).get_participant_status(True), 'TENTATIVE') | ||||
# check second confirmation message sent to resource owner (jane) | # check second confirmation message sent to resource owner (jane) | ||||
notify2 = self.check_message_received(_('Booking request for %s requires confirmation') % (self.room3['cn']), mailbox=self.jane['mailbox']) | notify2 = self.check_message_received(_('Booking request for %s requires confirmation') % (self.room3['cn']), mailbox=self.jane['mailbox']) | ||||
self.assertIsInstance(notify2, email.message.Message) | self.assertIsInstance(notify2, email.message.Message) | ||||
itip_event2 = events_from_message(notify2)[0] | itip_event2 = events_from_message(notify2)[0] | ||||
self.assertEqual(itip_event2['start'].hour, 16) | self.assertEqual(itip_event2['start'].hour, 16) | ||||
# resource owner declines the first reservation request | # resource owner declines the first reservation request | ||||
itip_reply = itip_event1['xml'].to_message_itip(self.jane['mail'], | itip_reply = itip_event1['xml'].to_message_itip( | ||||
self.jane['mail'], | |||||
method="REPLY", | method="REPLY", | ||||
participant_status='DECLINED', | participant_status='DECLINED', | ||||
message_text="Request declined", | message_text="Request declined", | ||||
subject=_('Booking for %s has been %s') % (self.room3['cn'], participant_status_label('DECLINED')) | subject=_('Booking for %s has been %s') % (self.room3['cn'], participant_status_label('DECLINED')) | ||||
) | ) | ||||
smtp = smtplib.SMTP('localhost', 10026) | smtp = smtplib.SMTP('localhost', 10026) | ||||
smtp.sendmail(self.jane['mail'], str(itip_event1['organizer']), str(itip_reply)) | smtp.sendmail(self.jane['mail'], str(itip_event1['organizer']), str(itip_reply)) | ||||
smtp.quit() | smtp.quit() | ||||
time.sleep(5) | time.sleep(5) | ||||
# resource owner accpets the second reservation request | # resource owner accpets the second reservation request | ||||
itip_reply = itip_event2['xml'].to_message_itip(self.jane['mail'], | itip_reply = itip_event2['xml'].to_message_itip( | ||||
self.jane['mail'], | |||||
method="REPLY", | method="REPLY", | ||||
participant_status='ACCEPTED', | participant_status='ACCEPTED', | ||||
message_text="Request accepred", | message_text="Request accepred", | ||||
subject=_('Booking for %s has been %s') % (self.room3['cn'], participant_status_label('ACCEPTED')) | subject=_('Booking for %s has been %s') % (self.room3['cn'], participant_status_label('ACCEPTED')) | ||||
) | ) | ||||
smtp = smtplib.SMTP('localhost', 10026) | smtp = smtplib.SMTP('localhost', 10026) | ||||
smtp.sendmail(self.jane['mail'], str(itip_event2['organizer']), str(itip_reply)) | smtp.sendmail(self.jane['mail'], str(itip_event2['organizer']), str(itip_reply)) | ||||
smtp.quit() | smtp.quit() | ||||
# requester (john) now gets the ACCEPTED response | # requester (john) now gets the ACCEPTED response | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }, self.room3['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('ACCEPTED')}, self.room3['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
event = self.check_resource_calendar_event(self.room3['kolabtargetfolder'], uid) | event = self.check_resource_calendar_event(self.room3['kolabtargetfolder'], uid) | ||||
self.assertIsInstance(event, pykolab.xml.Event) | self.assertIsInstance(event, pykolab.xml.Event) | ||||
self.assertEqual(event.get_attendee_by_email(self.room3['mail']).get_participant_status(True), 'ACCEPTED') | self.assertEqual(event.get_attendee_by_email(self.room3['mail']).get_participant_status(True), 'ACCEPTED') | ||||
def test_016_collection_owner_confirmation(self): | def test_016_collection_owner_confirmation(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
uid = self.send_itip_invitation(self.viprooms['mail'], datetime.datetime(2014,8,15, 17,0,0)) | uid = self.send_itip_invitation(self.viprooms['mail'], datetime.datetime(2014, 8, 15, 17, 0, 0)) | ||||
# resource collection responds with a DELEGATED message | # resource collection responds with a DELEGATED message | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('DELEGATED') }, self.viprooms['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('DELEGATED')}, self.viprooms['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
# the collection member tentatively accepted the reservation | # the collection member tentatively accepted the reservation | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('TENTATIVE') }) | accept = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('TENTATIVE')}) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
self.assertIn(self.room3['mail'], accept['from']) | self.assertIn(self.room3['mail'], accept['from']) | ||||
# check confirmation message sent to resource owner (jane) | # check confirmation message sent to resource owner (jane) | ||||
notify = self.check_message_received(_('Booking request for %s requires confirmation') % (self.room3['cn']), mailbox=self.jane['mailbox']) | notify = self.check_message_received(_('Booking request for %s requires confirmation') % (self.room3['cn']), mailbox=self.jane['mailbox']) | ||||
self.assertIsInstance(notify, email.message.Message) | self.assertIsInstance(notify, email.message.Message) | ||||
def test_017_reschedule_single_occurrence(self): | def test_017_reschedule_single_occurrence(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
subject = {'summary': 'test', 'status': participant_status_label('ACCEPTED')} | |||||
subject = self.itip_reply_subject % (subject) | |||||
# register a recurring resource invitation | # register a recurring resource invitation | ||||
start = datetime.datetime(2015,2,10, 12,0,0) | start = datetime.datetime(2015, 2, 10, 12, 0, 0) | ||||
uid = self.send_itip_invitation(self.audi['mail'], start, template=itip_recurring) | uid = self.send_itip_invitation(self.audi['mail'], start, template=itip_recurring) | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }) | accept = self.check_message_received(subject) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
# send rescheduling request to a single instance | # send rescheduling request to a single instance | ||||
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.audi['mail'], uid, exstart, instance=exdate) | self.send_itip_update(self.audi['mail'], uid, exstart, instance=exdate) | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }) | accept = self.check_message_received(subject) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
self.assertIn("RECURRENCE-ID;TZID=Europe/London:" + exdate.strftime('%Y%m%dT%H%M%S'), str(accept)) | self.assertIn("RECURRENCE-ID;TZID=Europe/London:" + exdate.strftime('%Y%m%dT%H%M%S'), str(accept)) | ||||
event = self.check_resource_calendar_event(self.audi['kolabtargetfolder'], uid) | event = self.check_resource_calendar_event(self.audi['kolabtargetfolder'], 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) | ||||
# send new invitation for now free slot | # send new invitation for now free slot | ||||
uid = self.send_itip_invitation(self.audi['mail'], exdate, template=itip_invitation.replace('SUMMARY:test', 'SUMMARY:new')) | uid = self.send_itip_invitation(self.audi['mail'], exdate, template=itip_invitation.replace('SUMMARY:test', 'SUMMARY:new')) | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'new', 'status':participant_status_label('ACCEPTED') }) | accept = self.check_message_received(subject) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
# send rescheduling request to that single instance again: now conflicting | # send rescheduling request to that single instance again: now conflicting | ||||
exdate = start + datetime.timedelta(days=14) | exdate = start + datetime.timedelta(days=14) | ||||
exstart = exdate + datetime.timedelta(hours=2) | exstart = exdate + datetime.timedelta(hours=2) | ||||
self.send_itip_update(self.audi['mail'], uid, exstart, instance=exdate, sequence=3) | self.send_itip_update(self.audi['mail'], uid, exstart, instance=exdate, sequence=3) | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('DECLINED') }) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('DECLINED')}) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
self.assertIn("RECURRENCE-ID;TZID=Europe/London:", str(response)) | self.assertIn("RECURRENCE-ID;TZID=Europe/London:", str(response)) | ||||
def test_018_invite_single_occurrence(self): | def test_018_invite_single_occurrence(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
self.purge_mailbox(self.boxter['kolabtargetfolder']) | self.purge_mailbox(self.boxter['kolabtargetfolder']) | ||||
subject = {'summary': 'test', 'status': participant_status_label('ACCEPTED')} | |||||
subject = self.itip_reply_subject % (subject) | |||||
start = datetime.datetime(2015,3,2, 18,30,0) | start = datetime.datetime(2015, 3, 2, 18, 30, 0) | ||||
uid = self.send_itip_invitation(self.boxter['mail'], start, instance=start) | uid = self.send_itip_invitation(self.boxter['mail'], start, instance=start) | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }) | accept = self.check_message_received(subject) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
self.assertIn("RECURRENCE-ID;TZID=Europe/London:" + start.strftime('%Y%m%dT%H%M%S'), str(accept)) | self.assertIn("RECURRENCE-ID;TZID=Europe/London:" + start.strftime('%Y%m%dT%H%M%S'), str(accept)) | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
# send a second invitation for another instance with the same UID | # send a second invitation for another instance with the same UID | ||||
nextstart = datetime.datetime(2015,3,9, 18,30,0) | nextstart = datetime.datetime(2015, 3, 9, 18, 30, 0) | ||||
self.send_itip_invitation(self.boxter['mail'], nextstart, uid=uid, instance=nextstart) | self.send_itip_invitation(self.boxter['mail'], nextstart, uid=uid, instance=nextstart) | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }) | accept = self.check_message_received(subject) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
self.assertIn("RECURRENCE-ID;TZID=Europe/London:" + nextstart.strftime('%Y%m%dT%H%M%S'), str(accept)) | self.assertIn("RECURRENCE-ID;TZID=Europe/London:" + nextstart.strftime('%Y%m%dT%H%M%S'), str(accept)) | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
# send rescheduling request to the first instance | # send rescheduling request to the first instance | ||||
exstart = start + datetime.timedelta(hours=2) | exstart = start + datetime.timedelta(hours=2) | ||||
self.send_itip_update(self.boxter['mail'], uid, exstart, instance=start) | self.send_itip_update(self.boxter['mail'], uid, exstart, instance=start) | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }) | accept = self.check_message_received(subject) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
self.assertIn("RECURRENCE-ID;TZID=Europe/London:" + start.strftime('%Y%m%dT%H%M%S'), str(accept)) | self.assertIn("RECURRENCE-ID;TZID=Europe/London:" + start.strftime('%Y%m%dT%H%M%S'), str(accept)) | ||||
# the resource calendar now has two reservations stored in one object | # the resource calendar now has two reservations stored in one object | ||||
one = self.check_resource_calendar_event(self.boxter['kolabtargetfolder'], uid) | one = self.check_resource_calendar_event(self.boxter['kolabtargetfolder'], uid) | ||||
self.assertIsInstance(one, pykolab.xml.Event) | self.assertIsInstance(one, pykolab.xml.Event) | ||||
self.assertIsInstance(one.get_recurrence_id(), datetime.datetime) | self.assertIsInstance(one.get_recurrence_id(), datetime.datetime) | ||||
self.assertEqual(one.get_start().hour, exstart.hour) | self.assertEqual(one.get_start().hour, exstart.hour) | ||||
two = one.get_instance(nextstart) | two = one.get_instance(nextstart) | ||||
self.assertIsInstance(two, pykolab.xml.Event) | self.assertIsInstance(two, pykolab.xml.Event) | ||||
self.assertIsInstance(two.get_recurrence_id(), datetime.datetime) | self.assertIsInstance(two.get_recurrence_id(), datetime.datetime) | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
# send rescheduling request to the 2nd instance | # send rescheduling request to the 2nd instance | ||||
self.send_itip_update(self.boxter['mail'], uid, nextstart + datetime.timedelta(hours=2), sequence=2, instance=nextstart) | self.send_itip_update(self.boxter['mail'], uid, nextstart + datetime.timedelta(hours=2), sequence=2, instance=nextstart) | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }) | accept = self.check_message_received(subject) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
self.assertIn("RECURRENCE-ID;TZID=Europe/London:" + nextstart.strftime('%Y%m%dT%H%M%S'), str(accept)) | self.assertIn("RECURRENCE-ID;TZID=Europe/London:" + nextstart.strftime('%Y%m%dT%H%M%S'), str(accept)) | ||||
event = self.check_resource_calendar_event(self.boxter['kolabtargetfolder'], uid) | event = self.check_resource_calendar_event(self.boxter['kolabtargetfolder'], 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) | ||||
two = event.get_instance(nextstart) | two = event.get_instance(nextstart) | ||||
self.assertIsInstance(two, pykolab.xml.Event) | self.assertIsInstance(two, pykolab.xml.Event) | ||||
self.assertEqual(two.get_sequence(), 2) | self.assertEqual(two.get_sequence(), 2) | ||||
self.assertEqual(two.get_start().hour, 20) | self.assertEqual(two.get_start().hour, 20) | ||||
def test_019_cancel_single_occurrence(self): | def test_019_cancel_single_occurrence(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
subject = {'summary': 'test', 'status': participant_status_label('ACCEPTED')} | |||||
subject = self.itip_reply_subject % (subject) | |||||
# register a recurring resource invitation | # register a recurring resource invitation | ||||
start = datetime.datetime(2015,2,12, 14,0,0) | start = datetime.datetime(2015, 2, 12, 14, 0, 0) | ||||
uid = self.send_itip_invitation(self.passat['mail'], start, template=itip_recurring) | uid = self.send_itip_invitation(self.passat['mail'], start, template=itip_recurring) | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }) | accept = self.check_message_received(subject) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
exdate = start + datetime.timedelta(days=7) | exdate = start + datetime.timedelta(days=7) | ||||
self.send_itip_cancel(self.passat['mail'], uid, instance=exdate) | self.send_itip_cancel(self.passat['mail'], uid, instance=exdate) | ||||
time.sleep(5) # wait for IMAP to update | time.sleep(5) # wait for IMAP to update | ||||
event = self.check_resource_calendar_event(self.passat['kolabtargetfolder'], uid) | event = self.check_resource_calendar_event(self.passat['kolabtargetfolder'], 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()) | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
# store a single occurrence with recurrence-id | # store a single occurrence with recurrence-id | ||||
start = datetime.datetime(2015,3,2, 18,30,0) | start = datetime.datetime(2015, 3, 2, 18, 30, 0) | ||||
uid = self.send_itip_invitation(self.passat['mail'], start, instance=start) | uid = self.send_itip_invitation(self.passat['mail'], start, instance=start) | ||||
accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }) | accept = self.check_message_received(subject) | ||||
self.assertIsInstance(accept, email.message.Message) | self.assertIsInstance(accept, email.message.Message) | ||||
self.send_itip_cancel(self.passat['mail'], uid, instance=start) | self.send_itip_cancel(self.passat['mail'], uid, instance=start) | ||||
time.sleep(5) # wait for IMAP to update | time.sleep(5) # wait for IMAP to update | ||||
self.assertEqual(self.check_resource_calendar_event(self.passat['kolabtargetfolder'], uid), None) | self.assertEqual(self.check_resource_calendar_event(self.passat['kolabtargetfolder'], uid), None) | ||||
def test_020_owner_confirmation_single_occurrence(self): | def test_020_owner_confirmation_single_occurrence(self): | ||||
self.purge_mailbox(self.john['mailbox']) | self.purge_mailbox(self.john['mailbox']) | ||||
self.purge_mailbox(self.jane['mailbox']) | self.purge_mailbox(self.jane['mailbox']) | ||||
start = datetime.datetime(2015,4,18, 14,0,0) | start = datetime.datetime(2015, 4, 18, 14, 0, 0) | ||||
uid = self.send_itip_invitation(self.room3['mail'], start, template=itip_recurring) | uid = self.send_itip_invitation(self.room3['mail'], start, template=itip_recurring) | ||||
notify = self.check_message_received(_('Booking request for %s requires confirmation') % (self.room3['cn']), mailbox=self.jane['mailbox']) | notify = self.check_message_received(_('Booking request for %s requires confirmation') % (self.room3['cn']), mailbox=self.jane['mailbox']) | ||||
self.assertIsInstance(notify, email.message.Message) | self.assertIsInstance(notify, email.message.Message) | ||||
# resource owner confirms reservation request (entire series) | # resource owner confirms reservation request (entire series) | ||||
itip_event = events_from_message(notify)[0] | itip_event = events_from_message(notify)[0] | ||||
self.send_owner_response(itip_event['xml'], 'ACCEPTED', from_addr=self.jane['mail']) | self.send_owner_response(itip_event['xml'], 'ACCEPTED', from_addr=self.jane['mail']) | ||||
Show All 13 Lines | def test_020_owner_confirmation_single_occurrence(self): | ||||
itip_event = events_from_message(notify)[0] | itip_event = events_from_message(notify)[0] | ||||
self.assertIsInstance(itip_event['xml'].get_recurrence_id(), datetime.datetime) | self.assertIsInstance(itip_event['xml'].get_recurrence_id(), datetime.datetime) | ||||
# resource owner declines reservation request | # resource owner declines reservation request | ||||
self.send_owner_response(itip_event['xml'], 'DECLINED', from_addr=self.jane['mail']) | self.send_owner_response(itip_event['xml'], 'DECLINED', from_addr=self.jane['mail']) | ||||
# requester (john) now gets the DECLINED response | # requester (john) now gets the DECLINED response | ||||
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('DECLINED') }, self.room3['mail']) | response = self.check_message_received(self.itip_reply_subject % {'summary': 'test', 'status': participant_status_label('DECLINED')}, self.room3['mail']) | ||||
self.assertIsInstance(response, email.message.Message) | self.assertIsInstance(response, email.message.Message) | ||||
self.assertIn("RECURRENCE-ID;TZID=Europe/London:" + exdate.strftime('%Y%m%dT%H%M%S'), str(response)) | self.assertIn("RECURRENCE-ID;TZID=Europe/London:" + exdate.strftime('%Y%m%dT%H%M%S'), str(response)) | ||||
event = self.check_resource_calendar_event(self.room3['kolabtargetfolder'], uid) | event = self.check_resource_calendar_event(self.room3['kolabtargetfolder'], 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_attendee_by_email(self.room3['mail']).get_participant_status(True), 'DECLINED') | self.assertEqual(exception.get_attendee_by_email(self.room3['mail']).get_participant_status(True), 'DECLINED') | ||||