summaryrefslogtreecommitdiffstats
path: root/tests/functional/test_wallace/test_005_resource_invitation.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/functional/test_wallace/test_005_resource_invitation.py')
-rw-r--r--tests/functional/test_wallace/test_005_resource_invitation.py265
1 files changed, 215 insertions, 50 deletions
diff --git a/tests/functional/test_wallace/test_005_resource_invitation.py b/tests/functional/test_wallace/test_005_resource_invitation.py
index 946cb5f..61b9402 100644
--- a/tests/functional/test_wallace/test_005_resource_invitation.py
+++ b/tests/functional/test_wallace/test_005_resource_invitation.py
@@ -8,6 +8,10 @@ import uuid
from pykolab.imap import IMAP
from wallace import module_resources
+from pykolab.translate import _
+from pykolab.xml import event_from_message
+from pykolab.xml import participant_status_label
+from pykolab.itip import events_from_message
from email import message_from_string
from twisted.trial import unittest
@@ -23,13 +27,14 @@ CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
UID:%s
-DTSTAMP:20140213T1254140
+DTSTAMP:20140213T125414Z
DTSTART;TZID=Europe/London:%s
DTEND;TZID=Europe/London:%s
SUMMARY:test
DESCRIPTION:test
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;PARTSTAT=TENTATIVE;CN=Somebody Else:mailto:somebody@else.com
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
@@ -43,7 +48,7 @@ CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
UID:%s
-DTSTAMP:20140215T1254140
+DTSTAMP:20140215T125414Z
DTSTART;TZID=Europe/London:%s
DTEND;TZID=Europe/London:%s
SEQUENCE:2
@@ -90,7 +95,7 @@ CALSCALE:GREGORIAN
METHOD:CANCEL
BEGIN:VEVENT
UID:%s
-DTSTAMP:20140218T1254140
+DTSTAMP:20140218T125414Z
DTSTART;TZID=Europe/London:20120713T100000
DTEND;TZID=Europe/London:20120713T110000
SUMMARY:test
@@ -112,7 +117,7 @@ CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
UID:%s
-DTSTAMP:20140213T1254140
+DTSTAMP:20140213T125414Z
DTSTART;VALUE=DATE:%s
DTEND;VALUE=DATE:%s
SUMMARY:test
@@ -133,7 +138,7 @@ CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
UID:%s
-DTSTAMP:20140213T1254140
+DTSTAMP:20140213T125414Z
DTSTART;TZID=Europe/Zurich:%s
DTEND;TZID=Europe/Zurich:%s
RRULE:FREQ=WEEKLY;INTERVAL=1;COUNT=10
@@ -184,6 +189,8 @@ class TestResourceInvitation(unittest.TestCase):
@classmethod
def setup_class(self, *args, **kw):
+ self.itip_reply_subject = _("Reservation Request for %(summary)s was %(status)s")
+
from tests.functional.purge_users import purge_users
purge_users()
@@ -213,9 +220,12 @@ class TestResourceInvitation(unittest.TestCase):
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.room1 = funcs.resource_add("confroom", "Room 101", owner=self.jane['dn'])
+ 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.rooms = funcs.resource_add("collection", "Rooms", [ self.room1['dn'], self.room2['dn'] ], self.jane['dn'])
+ 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.viprooms = funcs.resource_add("collection", "VIP Rooms", [ self.room3['dn'] ], self.jane['dn'], kolabinvitationpolicy='ACT_MANUAL')
time.sleep(1)
from tests.functional.synchronize import synchronize_once
@@ -227,12 +237,14 @@ class TestResourceInvitation(unittest.TestCase):
smtp = smtplib.SMTP('localhost', 10026)
smtp.sendmail(from_addr, to_addr, mime_message % (to_addr, itip_payload))
+ smtp.quit()
- def send_itip_invitation(self, resource_email, start=None, allday=False, template=None):
+ def send_itip_invitation(self, resource_email, start=None, allday=False, template=None, uid=None):
if start is None:
start = datetime.datetime.now()
- uid = str(uuid.uuid4())
+ if uid is None:
+ uid = str(uuid.uuid4())
if allday:
default_template = itip_allday
@@ -328,17 +340,14 @@ class TestResourceInvitation(unittest.TestCase):
if uid and event_message['subject'] != uid:
continue
- for part in event_message.walk():
- if part.get_content_type() == "application/calendar+xml":
- payload = part.get_payload(decode=True)
- found = pykolab.xml.event_from_string(payload)
- break
-
+ found = event_from_message(event_message)
if found:
break
time.sleep(1)
+ imap.disconnect()
+
return found
def purge_mailbox(self, mailbox):
@@ -357,12 +366,10 @@ class TestResourceInvitation(unittest.TestCase):
def find_resource_by_email(self, email):
resource = None
- if (email.find(self.audi['mail']) >= 0):
- resource = self.audi
- if (email.find(self.passat['mail']) >= 0):
- resource = self.passat
- if (email.find(self.boxter['mail']) >= 0):
- resource = self.boxter
+ for r in [self.audi, self.passat, self.boxter, self.room1, self.room2]:
+ if (email.find(r['mail']) >= 0):
+ resource = r
+ break
return resource
@@ -379,7 +386,7 @@ class TestResourceInvitation(unittest.TestCase):
def test_002_invite_resource(self):
uid = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014,7,13, 10,0,0))
- response = self.check_message_received("Reservation Request for test was 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)
event = self.check_resource_calendar_event(self.audi['kolabtargetfolder'], uid)
@@ -387,10 +394,11 @@ class TestResourceInvitation(unittest.TestCase):
self.assertEqual(event.get_summary(), "test")
+ # @depends test_002_invite_resource
def test_003_invite_resource_conflict(self):
uid = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014,7,13, 12,0,0))
- response = self.check_message_received("Reservation Request for test was 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.assertEqual(self.check_resource_calendar_event(self.audi['kolabtargetfolder'], uid), None)
@@ -402,7 +410,7 @@ class TestResourceInvitation(unittest.TestCase):
uid = self.send_itip_invitation(self.cars['mail'], datetime.datetime(2014,7,13, 12,0,0))
# one of the collection members accepted the reservation
- accept = self.check_message_received("Reservation Request for test was ACCEPTED")
+ accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') })
self.assertIsInstance(accept, email.message.Message)
delegatee = self.find_resource_by_email(accept['from'])
@@ -412,7 +420,7 @@ class TestResourceInvitation(unittest.TestCase):
self.assertIsInstance(self.check_resource_calendar_event(delegatee['kolabtargetfolder'], uid), pykolab.xml.Event)
# resource collection responds with a DELEGATED message
- response = self.check_message_received("Reservation Request for test was 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.assertIn("ROLE=NON-PARTICIPANT;RSVP=FALSE", str(response))
@@ -422,13 +430,13 @@ class TestResourceInvitation(unittest.TestCase):
uid = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014,4,1, 10,0,0))
- response = self.check_message_received("Reservation Request for test was 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.purge_mailbox(self.john['mailbox'])
self.send_itip_update(self.audi['mail'], uid, datetime.datetime(2014,4,1, 12,0,0)) # conflict with myself
- response = self.check_message_received("Reservation Request for test was 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)
event = self.check_resource_calendar_event(self.audi['kolabtargetfolder'], uid)
@@ -443,13 +451,13 @@ class TestResourceInvitation(unittest.TestCase):
uid = self.send_itip_invitation(self.cars['mail'], datetime.datetime(2014,4,24, 12,0,0))
# one of the collection members accepted the reservation
- accept = self.check_message_received("Reservation Request for test was ACCEPTED")
+ accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') })
self.assertIsInstance(accept, email.message.Message)
delegatee = self.find_resource_by_email(accept['from'])
# book that resource for the next day
self.send_itip_invitation(delegatee['mail'], datetime.datetime(2014,4,25, 14,0,0))
- accept2 = self.check_message_received("Reservation Request for test was 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
self.purge_mailbox(self.john['mailbox'])
@@ -457,7 +465,7 @@ class TestResourceInvitation(unittest.TestCase):
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
- new_accept = self.check_message_received("Reservation Request for test was 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)
new_delegatee = self.find_resource_by_email(new_accept['from'])
@@ -468,7 +476,7 @@ class TestResourceInvitation(unittest.TestCase):
self.assertIsInstance(event, pykolab.xml.Event)
# old resource responds with a DELEGATED message
- response = self.check_message_received("Reservation Request for test was 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)
# old reservation was removed from old delegate's calendar
@@ -489,7 +497,7 @@ class TestResourceInvitation(unittest.TestCase):
# make new reservation to the now free'd slot
self.send_itip_invitation(self.boxter['mail'], datetime.datetime(2014,5,1, 9,0,0))
- response = self.check_message_received("Reservation Request for test was 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)
@@ -500,7 +508,7 @@ class TestResourceInvitation(unittest.TestCase):
uid = self.send_itip_invitation(self.cars['mail'], dt)
# wait for accept notification
- accept = self.check_message_received("Reservation Request for test was ACCEPTED")
+ accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') })
self.assertIsInstance(accept, email.message.Message)
delegatee = self.find_resource_by_email(accept['from'])
@@ -511,12 +519,12 @@ class TestResourceInvitation(unittest.TestCase):
self.send_itip_update(delegatee['mail'], uid, dt, template=update_template)
# get response from delegatee
- accept = self.check_message_received("Reservation Request for test was ACCEPTED")
+ accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') })
self.assertIsInstance(accept, email.message.Message)
self.assertIn(delegatee['mail'], accept['from'])
# no delegation response on updates
- self.assertEqual(self.check_message_received("Reservation Request for test was 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):
@@ -524,7 +532,7 @@ class TestResourceInvitation(unittest.TestCase):
uid = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014,6,2), True)
- accept = self.check_message_received("Reservation Request for test was ACCEPTED")
+ accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') })
self.assertIsInstance(accept, email.message.Message)
event = self.check_resource_calendar_event(self.audi['kolabtargetfolder'], uid)
@@ -532,7 +540,7 @@ class TestResourceInvitation(unittest.TestCase):
self.assertIsInstance(event.get_start(), datetime.date)
uid2 = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014,6,2, 16,0,0))
- response = self.check_message_received("Reservation Request for test was 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)
@@ -543,19 +551,19 @@ class TestResourceInvitation(unittest.TestCase):
uid = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014,2,20, 12,0,0),
template=itip_recurring.replace(";COUNT=10", ""))
- accept = self.check_message_received("Reservation Request for test was ACCEPTED")
+ accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') })
self.assertIsInstance(accept, email.message.Message)
# check non-recurring against recurring
uid2 = self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014,3,13, 10,0,0))
- response = self.check_message_received("Reservation Request for test was 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.purge_mailbox(self.john['mailbox'])
# check recurring against 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("Reservation Request for test was ACCEPTED")
+ accept = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') })
self.assertIsInstance(accept, email.message.Message)
@@ -570,7 +578,7 @@ class TestResourceInvitation(unittest.TestCase):
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.assertEqual(self.check_message_received("Reservation Request for test was 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):
@@ -578,7 +586,7 @@ class TestResourceInvitation(unittest.TestCase):
self.send_itip_invitation(self.room1['mail'], datetime.datetime(2014,6,19, 16,0,0))
- accept = self.check_message_received("Reservation Request for test was 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)
respose_text = str(accept.get_payload(0))
self.assertIn(self.jane['mail'], respose_text)
@@ -590,27 +598,184 @@ class TestResourceInvitation(unittest.TestCase):
self.send_itip_invitation(self.room2['mail'], datetime.datetime(2014,6,19, 16,0,0))
- accept = self.check_message_received("Reservation Request for test was 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)
respose_text = str(accept.get_payload(0))
self.assertIn(self.jane['mail'], respose_text)
self.assertIn(self.jane['displayname'], respose_text)
- def TODO_test_012_owner_notification(self):
+ def test_012_owner_notification(self):
self.purge_mailbox(self.john['mailbox'])
self.purge_mailbox(self.jane['mailbox'])
- self.send_itip_invitation(self.room1['mail'], datetime.datetime(2014,5,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)
- notify = self.check_message_received("Reservation Request for test was 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.assertEqual(notify['From'], self.room1['mail'])
- self.assertEqual(notify['Cc'], self.jane['mail'])
+
+ notification_text = str(notify.get_payload())
+ self.assertIn(self.john['mail'], notification_text)
+ self.assertIn(participant_status_label('ACCEPTED'), notification_text)
+
+ self.purge_mailbox(self.john['mailbox'])
# check notification sent to collection owner (jane)
- self.send_itip_invitation(self.rooms['mail'], datetime.datetime(2014,5,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
+ accepted = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') })
+ 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'])
+ self.assertIsInstance(notify, email.message.Message)
+ self.assertIn(self.john['mail'], notification_text)
+
+
+ def test_013_owner_confirmation_accept(self):
+ self.purge_mailbox(self.john['mailbox'])
+ self.purge_mailbox(self.jane['mailbox'])
+
+ uid = self.send_itip_invitation(self.room3['mail'], datetime.datetime(2014,9,12, 14,0,0))
+
+ # 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'])
+ self.assertIsInstance(response, email.message.Message)
+
+ event = self.check_resource_calendar_event(self.room3['kolabtargetfolder'], uid)
+ self.assertIsInstance(event, pykolab.xml.Event)
+ self.assertEqual(event.get_summary(), "test")
+ self.assertEqual(event.get_attendee_by_email(self.room3['mail']).get_participant_status(True), 'TENTATIVE')
+
+ # 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'])
+ self.assertIsInstance(notify, email.message.Message)
+
+ itip_event = events_from_message(notify)[0]
+
+ # resource owner confirms reservation request
+ itip_reply = itip_event['xml'].to_message_itip(self.jane['mail'],
+ method="REPLY",
+ participant_status='ACCEPTED',
+ message_text="Request accepted",
+ subject=_('Booking for %s has been %s') % (self.room3['cn'], participant_status_label('ACCEPTED'))
+ )
+
+ smtp = smtplib.SMTP('localhost', 10026)
+ smtp.sendmail(self.jane['mail'], str(itip_event['organizer']), str(itip_reply))
+ smtp.quit()
+
+ # 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'])
+ self.assertIsInstance(response, email.message.Message)
+
+ event = self.check_resource_calendar_event(self.room3['kolabtargetfolder'], uid)
+ self.assertIsInstance(event, pykolab.xml.Event)
+ self.assertEqual(event.get_status(True), 'CONFIRMED')
+ self.assertEqual(event.get_attendee_by_email(self.room3['mail']).get_participant_status(True), 'ACCEPTED')
+
- notify = self.check_message_received("Reservation Request for test was ACCEPTED", self.room2['mail'], self.jane['mailbox'])
+ def test_014_owner_confirmation_decline(self):
+ self.purge_mailbox(self.john['mailbox'])
+ self.purge_mailbox(self.jane['mailbox'])
+
+ uid = self.send_itip_invitation(self.room3['mail'], datetime.datetime(2014,9,14, 9,0,0))
+
+ # 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'])
+ self.assertIsInstance(response, email.message.Message)
+
+ # 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'])
self.assertIsInstance(notify, email.message.Message)
+
+ itip_event = events_from_message(notify)[0]
+
+ # resource owner declines reservation request
+ itip_reply = itip_event['xml'].to_message_itip(self.jane['mail'],
+ method="REPLY",
+ participant_status='DECLINED',
+ message_text="Request declined",
+ subject=_('Booking for %s has been %s') % (self.room3['cn'], participant_status_label('DECLINED'))
+ )
+
+ smtp = smtplib.SMTP('localhost', 10026)
+ smtp.sendmail(self.jane['mail'], str(itip_event['organizer']), str(itip_reply))
+ smtp.quit()
+
+ # 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'])
+ self.assertIsInstance(response, email.message.Message)
+
+ # tentative reservation was set to cancelled
+ event = self.check_resource_calendar_event(self.room3['kolabtargetfolder'], uid)
+ self.assertEqual(event, None)
+ #self.assertEqual(event.get_status(True), 'CANCELLED')
+ #self.assertEqual(event.get_attendee_by_email(self.room3['mail']).get_participant_status(True), 'DECLINED')
+
+
+ def test_015_owner_confirmation_update(self):
+ 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")
+
+ # 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'])
+ self.assertIsInstance(response, email.message.Message)
+
+ # 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'])
+ self.assertIsInstance(notify1, email.message.Message)
+
+ itip_event1 = events_from_message(notify1)[0]
+ self.assertEqual(itip_event1['start'].hour, 9)
+
+ self.purge_mailbox(self.jane['mailbox'])
+ self.purge_mailbox(self.john['mailbox'])
+
+ # send update with new date (and sequence)
+ 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)
+ self.assertIsInstance(event, pykolab.xml.Event)
+ self.assertEqual(event.get_attendee_by_email(self.room3['mail']).get_participant_status(True), 'TENTATIVE')
+
+ # 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'])
+ self.assertIsInstance(notify2, email.message.Message)
+
+ itip_event2 = events_from_message(notify2)[0]
+ self.assertEqual(itip_event2['start'].hour, 16)
+
+ # resource owner declines the first reservation request
+ itip_reply = itip_event1['xml'].to_message_itip(self.jane['mail'],
+ method="REPLY",
+ participant_status='DECLINED',
+ message_text="Request declined",
+ subject=_('Booking for %s has been %s') % (self.room3['cn'], participant_status_label('DECLINED'))
+ )
+ smtp = smtplib.SMTP('localhost', 10026)
+ smtp.sendmail(self.jane['mail'], str(itip_event1['organizer']), str(itip_reply))
+ smtp.quit()
+
+ time.sleep(5)
+
+ # resource owner accpets the second reservation request
+ itip_reply = itip_event2['xml'].to_message_itip(self.jane['mail'],
+ method="REPLY",
+ participant_status='ACCEPTED',
+ message_text="Request accepred",
+ subject=_('Booking for %s has been %s') % (self.room3['cn'], participant_status_label('ACCEPTED'))
+ )
+ smtp = smtplib.SMTP('localhost', 10026)
+ smtp.sendmail(self.jane['mail'], str(itip_event2['organizer']), str(itip_reply))
+ smtp.quit()
+
+ # 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'])
+ self.assertIsInstance(response, email.message.Message)
+
+ event = self.check_resource_calendar_event(self.room3['kolabtargetfolder'], uid)
+ self.assertIsInstance(event, pykolab.xml.Event)
+ self.assertEqual(event.get_attendee_by_email(self.room3['mail']).get_participant_status(True), 'ACCEPTED')