def assertEqualCalendarData(self, cal1, cal2): if isinstance(cal1, str): cal1 = Component.fromString(cal1) if isinstance(cal2, str): cal2 = Component.fromString(cal2) ncal1 = normalize_iCalStr(cal1) ncal2 = normalize_iCalStr(cal2) self.assertEqual(ncal1, ncal2, msg=diff_iCalStrs(ncal1, ncal2))
def test_needsActionOrganizerChange(self): """ Test that if the organizer makes an inconsequential change and also changes the attendee partstat, then the new partstat is sent to the attendee. """ organizer1 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080601T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION:urn:x-uid:user02 END:VEVENT END:VCALENDAR """) organizer2 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080601T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:urn:x-uid:user02 END:VEVENT END:VCALENDAR """) organizer3 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080601T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION:urn:x-uid:user02 SUMMARY:Test END:VEVENT END:VCALENDAR """) attendee1 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080601T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION;RSVP=TRUE:urn:x-uid:user02 TRANSP:TRANSPARENT END:VEVENT END:VCALENDAR """) attendee2 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080601T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user02 END:VEVENT END:VCALENDAR """) attendee3 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080601T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected];SCHEDULE-STATUS=1.2:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION;RSVP=TRUE:urn:x-uid:user02 SEQUENCE:1 SUMMARY:Test TRANSP:TRANSPARENT END:VEVENT END:VCALENDAR """) yield self.createOrganizerEvent("user01", organizer1) attendee = yield self.getAttendeeEvent("user02") self.assertEqual(attendee, attendee1, msg=diff_iCalStrs(attendee, attendee1)) yield self.setAttendeeEvent("user02", attendee2) organizer = yield self.getOrganizerEvent("user01") self.assertEqual(normalize_iCalStr(organizer), normalize_iCalStr(organizer2), msg=diff_iCalStrs(organizer2, organizer)) yield self.setOrganizerEvent("user01", organizer3) attendee = yield self.getAttendeeEvent("user02") self.assertEqual(normalize_iCalStr(attendee), normalize_iCalStr(attendee3), msg=diff_iCalStrs(attendee3, attendee))
def test_replyBeforeOrganizerConsequentialChange(self): """ Test that the organizer and attendee see the attendee's partstat change when the organizer makes a consequential change whilst the attendee reply is in progress. """ organizer1 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080601T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION:urn:x-uid:user02 END:VEVENT END:VCALENDAR """) organizer2 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080602T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION:urn:x-uid:user02 SUMMARY:Test END:VEVENT END:VCALENDAR """) organizer3 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080602T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION;RSVP=TRUE;SCHEDULE-STATUS=1.2;X-CALENDARSERVER-RESET-PARTSTAT=1:urn:x-uid:user02 SEQUENCE:1 SUMMARY:Test END:VEVENT END:VCALENDAR """) attendee1 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080601T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION;RSVP=TRUE:urn:x-uid:user02 TRANSP:TRANSPARENT END:VEVENT END:VCALENDAR """) attendee2 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080601T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user02 END:VEVENT END:VCALENDAR """) attendee3 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080602T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected];SCHEDULE-STATUS=1.2:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION;RSVP=TRUE:urn:x-uid:user02 SEQUENCE:1 SUMMARY:Test TRANSP:TRANSPARENT END:VEVENT END:VCALENDAR """) yield self.createOrganizerEvent("user01", organizer1) attendee = yield self.getAttendeeEvent("user02") self.assertEqual(attendee, attendee1, msg=diff_iCalStrs(attendee, attendee1)) yield self.setOrganizerEvent("user01", organizer2, run_jobs=False) yield self._runOneJob() yield self.setAttendeeEvent("user02", attendee2, run_jobs=False) yield self._runAllJobs() jobs = yield JobItem.all(self.transactionUnderTest()) self.assertEqual(len(jobs), 0) yield self.commit() organizer = yield self.getOrganizerEvent("user01") self.assertEqual(normalize_iCalStr(organizer), normalize_iCalStr(organizer3), msg=diff_iCalStrs(organizer3, organizer)) attendee = yield self.getAttendeeEvent("user02") self.assertEqual(normalize_iCalStr(attendee), normalize_iCalStr(attendee3), msg=diff_iCalStrs(attendee3, attendee))
def test_replyBeforeOrganizerEXDATE(self): """ Test that a reply is sent if an attendee changes an event, but the organizer exdate's the instance before the reply work is processed. """ organizer1 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080601T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION:urn:x-uid:user02 RRULE:FREQ=DAILY END:VEVENT END:VCALENDAR """) attendee1 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080601T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION;RSVP=TRUE:urn:x-uid:user02 RRULE:FREQ=DAILY TRANSP:TRANSPARENT END:VEVENT END:VCALENDAR """) organizer2 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080601T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION:urn:x-uid:user02 EXDATE:20080602T130000Z RRULE:FREQ=DAILY SUMMARY:Test END:VEVENT END:VCALENDAR """) attendee2 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080601T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION;RSVP=TRUE:urn:x-uid:user02 RRULE:FREQ=DAILY TRANSP:TRANSPARENT END:VEVENT BEGIN:VEVENT UID:12345-67890 RECURRENCE-ID:20080602T130000Z DTSTAMP:20080601T130000Z DTSTART:20080602T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=DECLINED:urn:x-uid:user02 TRANSP:TRANSPARENT END:VEVENT END:VCALENDAR """) attendee3 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080601T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION;RSVP=TRUE:urn:x-uid:user02 EXDATE:20080602T130000Z RRULE:FREQ=DAILY TRANSP:TRANSPARENT END:VEVENT END:VCALENDAR """) yield self.createOrganizerEvent("user01", organizer1) attendee = yield self.getAttendeeEvent("user02") self.assertEqual(attendee, attendee1, msg=diff_iCalStrs(attendee, attendee1)) yield self.setOrganizerEvent("user01", organizer2, run_jobs=False) yield self._runOneJob() yield self.setAttendeeEvent("user02", attendee2, run_jobs=False) yield self.setAttendeeEvent("user02", attendee3, run_jobs=False) yield self._runAllJobs() jobs = yield JobItem.all(self.transactionUnderTest()) self.assertEqual(len(jobs), 0) yield self.commit()
def test_replyBeforeResourceDelete(self): """ Test that a reply is sent if an attendee changes an event, then immediately deletes it. """ organizer1 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080601T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION:urn:x-uid:user02 END:VEVENT END:VCALENDAR """) attendee1 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080601T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION;RSVP=TRUE:urn:x-uid:user02 TRANSP:TRANSPARENT END:VEVENT END:VCALENDAR """) organizer2 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080601T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=DECLINED;SCHEDULE-STATUS=2.0:urn:x-uid:user02 END:VEVENT END:VCALENDAR """) attendee2 = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T130000Z DTSTART:20080601T130000Z DURATION:PT1H ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01 ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01 ATTENDEE;CN=User 02;[email protected];PARTSTAT=DECLINED:urn:x-uid:user02 TRANSP:TRANSPARENT END:VEVENT END:VCALENDAR """) yield self.createOrganizerEvent("user01", organizer1) attendee = yield self.getAttendeeEvent("user02") self.assertEqual(attendee, attendee1, msg=diff_iCalStrs(attendee, attendee1)) yield self.setAttendeeEvent("user02", attendee2, run_jobs=False) calobj = yield self.getAttendeeResource("user02") yield calobj.remove() yield self.commit() yield self._runAllJobs() jobs = yield JobItem.all(self.transactionUnderTest()) self.assertEqual(len(jobs), 0) yield self.commit() organizer = yield self.getOrganizerEvent("user01") self.assertEqual(organizer, organizer2, msg=diff_iCalStrs(organizer, organizer2))