def test_001_itip_events_from_message(self): itips1 = itip.events_from_message(message_from_string(itip_multipart)) self.assertEqual(len(itips1), 1, "Multipart iTip message with text/calendar") self.assertEqual(itips1[0]['method'], "REQUEST", "iTip request method property") itips2 = itip.events_from_message(message_from_string(itip_non_multipart)) self.assertEqual(len(itips2), 1, "Detect non-multipart iTip messages") itips3 = itip.events_from_message(message_from_string(itip_application_ics)) self.assertEqual(len(itips3), 1, "Multipart iTip message with application/ics attachment") itips4 = itip.events_from_message(message_from_string(itip_google_multipart)) self.assertEqual(len(itips4), 1, "Multipart iTip message from Google") itips5 = itip.events_from_message(message_from_string(itip_empty)) self.assertEqual(len(itips5), 0, "Simple plain text message") # invalid itip blocks self.assertRaises(Exception, itip.events_from_message, message_from_string(itip_multipart.replace("BEGIN:VEVENT", ""))) itips6 = itip.events_from_message(message_from_string(itip_multipart.replace("DTSTART;", "X-DTSTART;"))) self.assertEqual(len(itips6), 0, "Event with not DTSTART") itips7 = itip.events_from_message(message_from_string(itip_non_multipart.replace("METHOD:REQUEST", "METHOD:PUBLISH").replace("method=REQUEST", "method=PUBLISH"))) self.assertEqual(len(itips7), 0, "Invalid METHOD") # iTips with unicode data itips8 = itip.events_from_message(message_from_string(itip_unicode)) self.assertEqual(len(itips8), 1) xml = itips8[0]['xml'] self.assertEqual(xml.get_summary(), "Testing Ümlauts") self.assertEqual(xml.get_location(), "Rue the Genève")
def test_001_itip_events_from_message(self): itips1 = itip.events_from_message(message_from_string(itip_multipart)) self.assertEqual(len(itips1), 1, "Multipart iTip message with text/calendar") self.assertEqual(itips1[0]['method'], "REQUEST", "iTip request method property") itips2 = itip.events_from_message( message_from_string(itip_non_multipart)) self.assertEqual(len(itips2), 1, "Detect non-multipart iTip messages") itips3 = itip.events_from_message( message_from_string(itip_application_ics)) self.assertEqual( len(itips3), 1, "Multipart iTip message with application/ics attachment") itips4 = itip.events_from_message( message_from_string(itip_google_multipart)) self.assertEqual(len(itips4), 1, "Multipart iTip message from Google") itips5 = itip.events_from_message(message_from_string(itip_empty)) self.assertEqual(len(itips5), 0, "Simple plain text message") # invalid itip blocks self.assertRaises( Exception, itip.events_from_message, message_from_string(itip_multipart.replace("BEGIN:VEVENT", ""))) itips6 = itip.events_from_message( message_from_string( itip_multipart.replace("DTSTART;", "X-DTSTART;"))) self.assertEqual(len(itips6), 0, "Event with not DTSTART") itips7 = itip.events_from_message( message_from_string( itip_non_multipart.replace("METHOD:REQUEST", "METHOD:PUBLISH").replace( "method=REQUEST", "method=PUBLISH"))) self.assertEqual(len(itips7), 0, "Invalid METHOD") # iTips with unicode data itips8 = itip.events_from_message(message_from_string(itip_unicode)) self.assertEqual(len(itips8), 1) xml = itips8[0]['xml'] self.assertEqual(xml.get_summary(), "Testing Ümlauts") self.assertEqual(xml.get_location(), "Rue the Genève") # Timezone conversion itips = itip.events_from_message(message_from_string(itip_unicode)) xml = itips[0]['xml'] self.assertEqual(xml.get_start().tzinfo.__str__(), "Europe/Berlin")
def test_004_send_reply_unicode(self): itip_events = itip.events_from_message(message_from_string(itip_non_multipart.replace('SUMMARY:test', "SUMMARY:With äöü"))) itip.send_reply("*****@*****.**", itip_events, "SUMMARY=%(summary)s; STATUS=%(status)s; NAME=%(name)s;") self.assertEqual(len(self.smtplog), 1) self.assertIn("Subject: =?utf-8?q?Invitation_for_With_=C3=A4=C3=B6=C3=BC_was_Accepted?=", self.smtplog[0][2]) self.assertIn('SUMMARY=3DWith =C3=A4=C3=B6=C3=BC', self.smtplog[0][2])
def test_003_send_reply(self): itip_events = itip.events_from_message( message_from_string(itip_non_multipart)) itip.send_reply( "*****@*****.**", itip_events, "SUMMARY=%(summary)s; STATUS=%(status)s; NAME=%(name)s;") self.assertEqual(len(self.smtplog), 1) self.assertEqual(self.smtplog[0][0], '*****@*****.**', "From attendee") self.assertEqual(self.smtplog[0][1], '*****@*****.**', "To organizer") _accepted = participant_status_label('ACCEPTED') message = message_from_string(self.smtplog[0][2]) self.assertEqual( message.get('Subject'), _("Invitation for %(summary)s was %(status)s") % { 'summary': 'test', 'status': _accepted }) text = str(message.get_payload(0)) self.assertIn('SUMMARY=3Dtest', text) self.assertIn('STATUS=3D' + _accepted, text)
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)
def test_002_check_event_conflict(self): itip_event = itip.events_from_message(message_from_string(itip_non_multipart))[0] event = Event() event.set_start(datetime.datetime(2012,7,13, 9,30,0, tzinfo=itip_event['start'].tzinfo)) event.set_end(datetime.datetime(2012,7,13, 10,30,0, tzinfo=itip_event['start'].tzinfo)) self.assertTrue(itip.check_event_conflict(event, itip_event), "Conflicting dates") event.set_uid(itip_event['uid']) self.assertFalse(itip.check_event_conflict(event, itip_event), "No conflict for same UID") allday = Event() allday.set_start(datetime.date(2012,7,13)) allday.set_end(datetime.date(2012,7,13)) self.assertTrue(itip.check_event_conflict(allday, itip_event), "Conflicting allday event") allday.set_transparency(True) self.assertFalse(itip.check_event_conflict(allday, itip_event), "No conflict if event is set to transparent") event2 = Event() event2.set_start(datetime.datetime(2012,7,13, 10,0,0, tzinfo=pytz.timezone("US/Central"))) event2.set_end(datetime.datetime(2012,7,13, 11,0,0, tzinfo=pytz.timezone("US/Central"))) self.assertFalse(itip.check_event_conflict(event, itip_event), "No conflict with timezone shift") rrule = kolabformat.RecurrenceRule() rrule.setFrequency(kolabformat.RecurrenceRule.Weekly) rrule.setCount(10) event3 = Event() event3.set_recurrence(rrule); event3.set_start(datetime.datetime(2012,6,29, 9,30,0, tzinfo=pytz.utc)) event3.set_end(datetime.datetime(2012,6,29, 10,30,0, tzinfo=pytz.utc)) self.assertTrue(itip.check_event_conflict(event3, itip_event), "Conflict in (3rd) recurring event instance") itip_event = itip.events_from_message(message_from_string(itip_recurring))[0] self.assertTrue(itip.check_event_conflict(event3, itip_event), "Conflict in two recurring events") event4 = Event() event4.set_recurrence(rrule); event4.set_start(datetime.datetime(2012,7,1, 9,30,0, tzinfo=pytz.utc)) event4.set_end(datetime.datetime(2012,7,1, 10,30,0, tzinfo=pytz.utc)) self.assertFalse(itip.check_event_conflict(event4, itip_event), "No conflict in two recurring events")
def test_003_resource_records_from_itip_events(self): message = message_from_string(itip_multipart) itips = itip.events_from_message(message) res = module_resources.resource_records_from_itip_events(itips) self.assertEqual(len(res), 2, "Return all attendee resources"); res = module_resources.resource_records_from_itip_events(itips, message['To']) self.assertEqual(len(res), 1, "Return only recipient resource"); self.assertEqual("uid=resource-collection-car,dc=example,dc=org", res[0]);
def test_003_resource_records_from_itip_events(self): message = message_from_string(itip_multipart) itips = itip.events_from_message(message) res = module_resources.resource_records_from_itip_events(itips) self.assertEqual(len(res), 2, "Return resources: %r" % (res)) res = module_resources.resource_records_from_itip_events( itips, message['To']) self.assertEqual(len(res), 1, "Return target resource: %r" % (res)) self.assertEqual( "cn=resource-collection-car,ou=Resources,dc=example,dc=org", res[0])
def test_004_send_reply_unicode(self): itip_events = itip.events_from_message( message_from_string( itip_non_multipart.replace('SUMMARY:test', "SUMMARY:With äöü"))) itip.send_reply( "*****@*****.**", itip_events, "SUMMARY=%(summary)s; STATUS=%(status)s; NAME=%(name)s;") self.assertEqual(len(self.smtplog), 1) self.assertIn( "Subject: =?utf-8?q?Invitation_for_With_=C3=A4=C3=B6=C3=BC_was_Accepted?=", self.smtplog[0][2]) self.assertIn('SUMMARY=3DWith =C3=A4=C3=B6=C3=BC', self.smtplog[0][2])
def test_003_send_reply(self): itip_events = itip.events_from_message(message_from_string(itip_non_multipart)) itip.send_reply("*****@*****.**", itip_events, "SUMMARY=%(summary)s; STATUS=%(status)s; NAME=%(name)s;") self.assertEqual(len(self.smtplog), 1) self.assertEqual(self.smtplog[0][0], '*****@*****.**', "From attendee") self.assertEqual(self.smtplog[0][1], '*****@*****.**', "To organizer") _accepted = participant_status_label('ACCEPTED') message = message_from_string(self.smtplog[0][2]) self.assertEqual(message.get('Subject'), _("Invitation for %(summary)s was %(status)s") % { 'summary':'test', 'status':_accepted }) text = str(message.get_payload(0)); self.assertIn('SUMMARY=3Dtest', text) self.assertIn('STATUS=3D' + _accepted, text)
def test_005_send_response_accept(self): itip_event = itip.events_from_message(message_from_string(itip_non_multipart)) module_resources.send_response("*****@*****.**", itip_event) self.assertEqual(len(self.smtplog), 1); self.assertEqual("*****@*****.**", self.smtplog[0][0]) self.assertEqual("*****@*****.**", self.smtplog[0][1]) response = message_from_string(self.smtplog[0][2]) self.assertIn("ACCEPTED", response['subject'], "Participant status in message subject") self.assertTrue(response.is_multipart()) # find ics part of the response ics_part = self._get_ics_part(response) self.assertIsInstance(ics_part, message.Message) self.assertEqual(ics_part.get_param('method'), "REPLY")
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')
def test_006_send_response_delegate(self): # delegate [email protected] => [email protected] itip_event = itip.events_from_message( message_from_string(itip_non_multipart))[0] itip_event['xml'].delegate('*****@*****.**', '*****@*****.**') itip_event['xml'].set_attendee_participant_status( itip_event['xml'].get_attendee('*****@*****.**'), "ACCEPTED") module_resources.send_response("*****@*****.**", itip_event) self.assertEqual(len(self.smtplog), 2) self.assertEqual("*****@*****.**", self.smtplog[0][0]) self.assertEqual("*****@*****.**", self.smtplog[1][0]) # delegated resource responds ACCEPTED response1 = message_from_string(self.smtplog[0][2]) ical1 = self._get_ical( self._get_ics_part(response1).get_payload(decode=True)) self.assertIn( "DELEGATED".lower(), response1['subject'].lower(), "Participant status in message subject: %r" % (response1['subject'])) self.assertEqual(ical1['attendee'][1].__str__(), "MAILTO:[email protected]") # resource collection responds DELEGATED response2 = message_from_string(self.smtplog[1][2]) ical2 = self._get_ical( self._get_ics_part(response2).get_payload(decode=True)) self.assertIn( "ACCEPTED".lower(), response2['subject'].lower(), "Delegation message subject: %r" % (response2['subject'])) self.assertEqual(ical2['attendee'].__str__(), "MAILTO:[email protected]") self.assertEqual(ical2['attendee'].params['PARTSTAT'], u"ACCEPTED")
def test_005_send_response_accept(self): itip_event = itip.events_from_message( message_from_string(itip_non_multipart)) module_resources.send_response("*****@*****.**", itip_event) self.assertEqual(len(self.smtplog), 1) self.assertEqual("*****@*****.**", self.smtplog[0][0]) self.assertEqual("*****@*****.**", self.smtplog[0][1]) response = message_from_string(self.smtplog[0][2]) self.assertIn( "ACCEPTED".lower(), response['subject'].lower(), "Participant status in message subject: %r" % (response['subject'])) self.assertTrue(response.is_multipart()) # find ics part of the response ics_part = self._get_ics_part(response) self.assertIsInstance(ics_part, message.Message) self.assertEqual(ics_part.get_param('method'), "REPLY")
def test_006_send_response_delegate(self): # delegate [email protected] => [email protected] itip_event = itip.events_from_message(message_from_string(itip_non_multipart))[0] itip_event['xml'].delegate('*****@*****.**', '*****@*****.**') itip_event['xml'].set_attendee_participant_status(itip_event['xml'].get_attendee('*****@*****.**'), "ACCEPTED") module_resources.send_response("*****@*****.**", itip_event) self.assertEqual(len(self.smtplog), 2); self.assertEqual("*****@*****.**", self.smtplog[0][0]) self.assertEqual("*****@*****.**", self.smtplog[1][0]) # delegated resource responds ACCEPTED response1 = message_from_string(self.smtplog[0][2]) ical1 = self._get_ical(self._get_ics_part(response1).get_payload(decode=True)) self.assertIn("ACCEPTED", response1['subject'], "Participant status in message subject") self.assertEqual(ical1['attendee'], "MAILTO:[email protected]") # resource collection responds DELEGATED response2 = message_from_string(self.smtplog[1][2]) ical2 = self._get_ical(self._get_ics_part(response2).get_payload(decode=True)) self.assertIn("DELEGATED", response2['subject'], "Delegation message subject") self.assertEqual(ical2['attendee'], "MAILTO:[email protected]") self.assertEqual(ical2['attendee'].params['PARTSTAT'], "DELEGATED")
def execute(*args, **kw): global auth, imap # (re)set language to default pykolab.translate.setUserLanguage(conf.get('kolab','default_locale')) if not os.path.isdir(mybasepath): os.makedirs(mybasepath) for stage in ['incoming', 'ACCEPT', 'REJECT', 'HOLD', 'DEFER' ]: if not os.path.isdir(os.path.join(mybasepath, stage)): os.makedirs(os.path.join(mybasepath, stage)) log.debug(_("Resource Management called for %r, %r") % (args, kw), level=8) auth = Auth() imap = IMAP() # TODO: Test for correct call. filepath = args[0] if kw.has_key('stage'): log.debug( _("Issuing callback after processing to stage %s") % ( kw['stage'] ), level=8 ) log.debug(_("Testing cb_action_%s()") % (kw['stage']), level=8) if hasattr(modules, 'cb_action_%s' % (kw['stage'])): log.debug( _("Attempting to execute cb_action_%s()") % (kw['stage']), level=8 ) exec( 'modules.cb_action_%s(%r, %r)' % ( kw['stage'], 'resources', filepath ) ) return filepath else: # Move to incoming new_filepath = os.path.join( mybasepath, 'incoming', os.path.basename(filepath) ) if not filepath == new_filepath: log.debug("Renaming %r to %r" % (filepath, new_filepath)) os.rename(filepath, new_filepath) filepath = new_filepath # parse full message message = Parser().parse(open(filepath, 'r')) # invalid message, skip if not message.get('X-Kolab-To'): return filepath recipients = [address for displayname,address in getaddresses(message.get_all('X-Kolab-To'))] sender_email = [address for displayname,address in getaddresses(message.get_all('X-Kolab-From'))][0] any_itips = False any_resources = False possibly_any_resources = False reference_uid = None # An iTip message may contain multiple events. Later on, test if the message # is an iTip message by checking the length of this list. try: itip_events = events_from_message(message, ['REQUEST', 'REPLY', 'CANCEL']) except Exception, e: log.error(_("Failed to parse iTip events from message: %r" % (e))) itip_events = []
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')
def test_002_check_event_conflict_single(self): itip_event = itip.events_from_message( message_from_string(itip_non_multipart))[0] event = Event() event.set_start( datetime.datetime(2012, 7, 10, 9, 30, 0, tzinfo=itip_event['start'].tzinfo)) event.set_end( datetime.datetime(2012, 7, 10, 10, 30, 0, tzinfo=itip_event['start'].tzinfo)) event.set_recurrence_id(event.get_start()) dtstart = datetime.datetime(2012, 7, 13, 9, 30, 0, tzinfo=itip_event['start'].tzinfo) second = Event(from_string=str(event)) second.set_start(dtstart) second.set_end(dtstart + datetime.timedelta(hours=1)) second.set_recurrence_id(dtstart) event.add_exception(second) self.assertTrue(itip.check_event_conflict(event, itip_event), "Conflicting dates (exception)") itip_event = itip.events_from_message( message_from_string(itip_non_multipart))[0] dtstart = datetime.datetime(2012, 7, 15, 10, 0, 0, tzinfo=itip_event['start'].tzinfo) second = Event(from_string=str(itip_event['xml'])) second.set_start(dtstart + datetime.timedelta(hours=1)) second.set_end(dtstart + datetime.timedelta(hours=2)) second.set_recurrence_id(dtstart) second.set_transparency(True) itip_event['xml'].add_exception(second) self.assertEqual(len(itip_event['xml'].get_exceptions()), 1) event = Event() event.set_start( datetime.datetime(2012, 7, 11, 9, 30, 0, tzinfo=itip_event['start'].tzinfo)) event.set_end( datetime.datetime(2012, 7, 11, 10, 30, 0, tzinfo=itip_event['start'].tzinfo)) self.assertFalse(itip.check_event_conflict(event, itip_event), "Conflicting dates (no)") event = Event() event.set_start( datetime.datetime(2012, 7, 15, 11, 0, 0, tzinfo=itip_event['start'].tzinfo)) event.set_end( datetime.datetime(2012, 7, 15, 11, 30, 0, tzinfo=itip_event['start'].tzinfo)) self.assertFalse(itip.check_event_conflict(event, itip_event), "Conflicting dates (exception)")
def test_002_check_event_conflict(self): itip_event = itip.events_from_message( message_from_string(itip_non_multipart))[0] event = Event() event.set_start( datetime.datetime(2012, 7, 13, 9, 30, 0, tzinfo=itip_event['start'].tzinfo)) event.set_end( datetime.datetime(2012, 7, 13, 10, 30, 0, tzinfo=itip_event['start'].tzinfo)) self.assertTrue(itip.check_event_conflict(event, itip_event), "Conflicting dates") event.set_uid(itip_event['uid']) self.assertFalse(itip.check_event_conflict(event, itip_event), "No conflict for same UID") allday = Event() allday.set_start(datetime.date(2012, 7, 13)) allday.set_end(datetime.date(2012, 7, 13)) self.assertTrue(itip.check_event_conflict(allday, itip_event), "Conflicting allday event") allday.set_transparency(True) self.assertFalse(itip.check_event_conflict(allday, itip_event), "No conflict if event is set to transparent") event2 = Event() event2.set_start( datetime.datetime(2012, 7, 13, 10, 0, 0, tzinfo=pytz.timezone("US/Central"))) event2.set_end( datetime.datetime(2012, 7, 13, 11, 0, 0, tzinfo=pytz.timezone("US/Central"))) self.assertFalse(itip.check_event_conflict(event, itip_event), "No conflict with timezone shift") rrule = kolabformat.RecurrenceRule() rrule.setFrequency(kolabformat.RecurrenceRule.Weekly) rrule.setCount(10) event3 = Event() event3.set_recurrence(rrule) event3.set_start( datetime.datetime(2012, 6, 29, 9, 30, 0, tzinfo=pytz.utc)) event3.set_end( datetime.datetime(2012, 6, 29, 10, 30, 0, tzinfo=pytz.utc)) self.assertTrue(itip.check_event_conflict(event3, itip_event), "Conflict in (3rd) recurring event instance") itip_event = itip.events_from_message( message_from_string(itip_recurring))[0] self.assertTrue(itip.check_event_conflict(event3, itip_event), "Conflict in two recurring events") event4 = Event() event4.set_recurrence(rrule) event4.set_start( datetime.datetime(2012, 7, 1, 9, 30, 0, tzinfo=pytz.utc)) event4.set_end( datetime.datetime(2012, 7, 1, 10, 30, 0, tzinfo=pytz.utc)) self.assertFalse(itip.check_event_conflict(event4, itip_event), "No conflict in two recurring events") itip_event = itip.events_from_message( message_from_string(itip_non_multipart))[0] rrule.setFrequency(kolabformat.RecurrenceRule.Daily) rrule.setCount(10) event5 = Event() event5.set_recurrence(rrule) event5.set_start( datetime.datetime(2012, 7, 9, 10, 0, 0, tzinfo=pytz.timezone("Europe/London"))) event5.set_end( datetime.datetime(2012, 7, 9, 11, 0, 0, tzinfo=pytz.timezone("Europe/London"))) event_xml = str(event5) exception = Event(from_string=event_xml) exception.set_start( datetime.datetime(2012, 7, 13, 14, 0, 0, tzinfo=pytz.timezone("Europe/London"))) exception.set_end( datetime.datetime(2012, 7, 13, 16, 0, 0, tzinfo=pytz.timezone("Europe/London"))) exception.set_recurrence_id( datetime.datetime(2012, 7, 13, 10, 0, 0, tzinfo=pytz.timezone("Europe/London")), False) event5.add_exception(exception) self.assertFalse(itip.check_event_conflict(event5, itip_event), "No conflict with exception date") exception = Event(from_string=event_xml) exception.set_start( datetime.datetime(2012, 7, 13, 10, 0, 0, tzinfo=pytz.timezone("Europe/London"))) exception.set_end( datetime.datetime(2012, 7, 13, 11, 0, 0, tzinfo=pytz.timezone("Europe/London"))) exception.set_status('CANCELLED') exception.set_recurrence_id( datetime.datetime(2012, 7, 13, 10, 0, 0, tzinfo=pytz.timezone("Europe/London")), False) event5.add_exception(exception) self.assertFalse(itip.check_event_conflict(event5, itip_event), "No conflict with cancelled exception")