def testFromPage(self): page = RecurringEventPage( owner=self.user, slug="code-for-boston", title="Code for Boston", repeat=Recurrence(dtstart=dt.date(2017, 1, 1), freq=WEEKLY, byweekday=[TU], until=dt.date(2017, 12, 26)), time_from=dt.time(19), time_to=dt.time(21, 30), tz=pytz.timezone("US/Eastern"), location="4th Floor, 1 Broadway, Cambridge, MA") self.calendar.add_child(instance=page) page.save_revision().publish() vev = VEventFactory().makeFromPage(page) self.assertIs(type(vev), RecurringVEvent) vev.set('UID', "this-is-not-a-unique-identifier") codeForBoston = b"\r\n".join([ b"BEGIN:VEVENT", b"SUMMARY:Code for Boston", b"DTSTART;TZID=US/Eastern:20170103T190000", b"DTEND;TZID=US/Eastern:20170103T213000", b"DTSTAMP:20170815T000000Z", b"UID:this-is-not-a-unique-identifier", b"SEQUENCE:1", b"RRULE:FREQ=WEEKLY;UNTIL=20171227T045959Z;BYDAY=TU;WKST=SU", b"CREATED:20170815T000000Z", b"DESCRIPTION:", b"LAST-MODIFIED:20170815T000000Z", b"LOCATION:4th Floor\\, 1 Broadway\\, Cambridge\\, MA", b"URL:http://joy.test/events/code-for-boston/", b"END:VEVENT", b"" ]) self.assertEqual(vev.to_ical(), codeForBoston)
def testExtraInfo(self): page = RecurringEventPage( owner=self.user, slug="code-for-boston", title="Code for Boston", repeat=Recurrence(dtstart=dt.date(2017, 1, 1), freq=WEEKLY, byweekday=[TU], until=dt.date(2017, 12, 26)), time_from=dt.time(19), time_to=dt.time(21, 30), tz=pytz.timezone("US/Eastern"), location="4th Floor, 1 Broadway, Cambridge, MA") self.calendar.add_child(instance=page) page.save_revision().publish() info = ExtraInfoPage(owner=self.user, slug="2017-06-06-extra-info", title="Extra Information for Tuesday 6th of June", overrides=page, except_date=dt.date(2017, 6, 6), extra_title="Handling Time Zones with Python") page.add_child(instance=info) info.save_revision().publish() vev = VEventFactory().makeFromPage(page) self.assertIs(type(vev), RecurringVEvent) vev.set('UID', "this-is-not-a-unique-identifier") codeForBoston = b"\r\n".join([ b"BEGIN:VEVENT", b"SUMMARY:Code for Boston", b"DTSTART;TZID=US/Eastern:20170103T190000", b"DTEND;TZID=US/Eastern:20170103T213000", b"DTSTAMP:20170515T000000Z", b"UID:this-is-not-a-unique-identifier", b"SEQUENCE:1", b"RRULE:FREQ=WEEKLY;UNTIL=20171227T045959Z;BYDAY=TU;WKST=SU", b"CREATED:20170515T000000Z", b"DESCRIPTION:", b"LAST-MODIFIED:20170515T000000Z", b"LOCATION:4th Floor\\, 1 Broadway\\, Cambridge\\, MA", b"URL:http://joy.test/events/code-for-boston/", b"END:VEVENT", b"" ]) self.assertEqual(vev.to_ical(), codeForBoston) self.assertEqual(len(vev.vchildren), 1) vchild = vev.vchildren[0] vchild.set('UID', "this-is-not-a-unique-identifier") self.assertIs(type(vchild), ExtraInfoVEvent) talk = b"\r\n".join([ b"BEGIN:VEVENT", b"SUMMARY:Handling Time Zones with Python", b"DTSTART;TZID=US/Eastern:20170606T190000", b"DTEND;TZID=US/Eastern:20170606T213000", b"DTSTAMP:20170515T000000Z", b"UID:this-is-not-a-unique-identifier", b"RECURRENCE-ID;TZID=US/Eastern:20170606T190000", b"SEQUENCE:1", b"CREATED:20170515T000000Z", b"DESCRIPTION:", b"LAST-MODIFIED:20170515T000000Z", b"LOCATION:4th Floor\\, 1 Broadway\\, Cambridge\\, MA", b"URL:http://joy.test/events/code-for-boston/2017-06-06-extra-info/", b"END:VEVENT", b"" ]) self.assertEqual(vchild.to_ical(), talk)
def testExdate(self): page = RecurringEventPage(owner=self.user, slug="sleep", title="Sleep In", repeat=Recurrence(dtstart=dt.date( 2018, 5, 1), freq=MONTHLY, byweekday=[SA(+2)]), time_from=dt.time(7), time_to=dt.time(10, 30), tz=pytz.timezone("Pacific/Auckland"), details="<p>zzzZZZZZZZZZ</p>", location="Bed") self.calendar.add_child(instance=page) page.save_revision().publish() except1 = CancellationPage( owner=self.user, slug="2018-06-09-cancellation", title="Cancellation for Saturday 9th of June", overrides=page, except_date=dt.date(2018, 6, 9)) page.add_child(instance=except1) except1.save_revision().publish() except2 = CancellationPage( owner=self.user, slug="2018-07-14-cancellation", title="Cancellation for Saturday 14th of July", overrides=page, except_date=dt.date(2018, 7, 14)) page.add_child(instance=except2) except2.save_revision().publish() vev = VEventFactory().makeFromPage(except1) self.assertIs(type(vev), RecurringVEvent) vev.set('UID', "this-is-not-a-unique-identifier") tz = pytz.timezone("Pacific/Auckland") exDates = [exDate.dt for exDate in vev['EXDATE'].dts] self.assertEqual(exDates, [ tz.localize(dt.datetime(2018, 6, 9, 7)), tz.localize(dt.datetime(2018, 7, 14, 7)) ]) sleepIn = b"\r\n".join([ b"BEGIN:VEVENT", b"SUMMARY:Sleep In", b"DTSTART;TZID=Pacific/Auckland:20180512T070000", b"DTEND;TZID=Pacific/Auckland:20180512T103000", b"DTSTAMP:20180510T000000Z", b"UID:this-is-not-a-unique-identifier", b"SEQUENCE:1", b"RRULE:FREQ=MONTHLY;BYDAY=+2SA;WKST=SU", b"EXDATE;TZID=Pacific/Auckland:20180609T070000,20180714T070000", b"CREATED:20180510T000000Z", b"DESCRIPTION:zzzZZZZZZZZZ", b"LAST-MODIFIED:20180510T000000Z", b"LOCATION:Bed", b"URL:http://joy.test/events/sleep/", b"X-ALT-DESC;FMTTYPE=text/html:<p>zzzZZZZZZZZZ</p>", b"END:VEVENT", b"" ]) self.assertEqual(vev.to_ical(), sleepIn)
def testFromPage(self): page = SimpleEventPage(owner=self.user, slug="pet-show", title="Pet Show", date=dt.date(1987, 6, 5), time_from=dt.time(11), time_to=dt.time(17, 30), tz=pytz.timezone("Australia/Sydney")) self.calendar.add_child(instance=page) page.save_revision().publish() vev = VEventFactory().makeFromPage(page) self.assertIs(type(vev), SimpleVEvent) tz = pytz.timezone("Australia/Sydney") self.assertEqual(vev['DTSTART'].dt, tz.localize(dt.datetime(1987, 6, 5, 11, 0)))
def testFromPage(self): page = MultidayEventPage(owner=self.user, slug="niuekulele2018", title="Niuekulele Ukulele Music Festival", date_from=dt.date(2018, 3, 16), date_to=dt.date(2018, 3, 20), tz=pytz.timezone("Pacific/Niue")) self.calendar.add_child(instance=page) page.save_revision().publish() vev = VEventFactory().makeFromPage(page) self.assertIs(type(vev), MultidayVEvent) tz = pytz.timezone("Pacific/Niue") self.assertEqual(vev['DTSTART'].dt, tz.localize(dt.datetime(2018, 3, 16, 0, 0))) self.assertEqual( vev['DTEND'].dt, tz.localize(dt.datetime(2018, 3, 20, 23, 59, 59, 999999)))
def testPostponement(self): page = RecurringEventPage( owner=self.user, slug="code-for-boston", title="Code for Boston", repeat=Recurrence(dtstart=dt.date(2017, 1, 1), freq=WEEKLY, byweekday=[TU], until=dt.date(2017, 12, 26)), time_from=dt.time(19), time_to=dt.time(21, 30), tz=pytz.timezone("US/Eastern"), location="4th Floor, 1 Broadway, Cambridge, MA") self.calendar.add_child(instance=page) page.save_revision().publish() post = PostponementPage(owner=self.user, slug="2017-06-13-postponement", title="Postponement for Tuesday 13th of June", postponement_title="Code for Boston (on Weds)", overrides=page, except_date=dt.date(2017, 6, 13), date=dt.date(2017, 6, 14)) page.add_child(instance=post) post.save_revision().publish() vev = VEventFactory().makeFromPage(page) self.assertIs(type(vev), RecurringVEvent) self.assertEqual(len(vev.vchildren), 1) vchild = vev.vchildren[0] vchild.set('UID', "this-is-not-a-unique-identifier") self.assertIs(type(vchild), PostponementVEvent) talk = b"\r\n".join([ b"BEGIN:VEVENT", b"SUMMARY:Code for Boston (on Weds)", b"DTSTART;TZID=US/Eastern:20170614T000000", b"DTEND;TZID=US/Eastern:20170614T235959", b"DTSTAMP:20170515T000000Z", b"UID:this-is-not-a-unique-identifier", b"RECURRENCE-ID;TZID=US/Eastern:20170613T190000", b"SEQUENCE:1", b"CREATED:20170515T000000Z", b"DESCRIPTION:", b"LAST-MODIFIED:20170515T000000Z", b"LOCATION:", b"URL:http://joy.test/events/code-for-boston/2017-06-13-postponement/", b"END:VEVENT", b"" ]) self.assertEqual(vchild.to_ical(), talk)
def testFromPage(self): page = MultidayRecurringEventPage(owner=self.user, slug="bought-from-rubber-man", title="Bought from a Rubber Man", repeat=Recurrence(dtstart=dt.date( 2019, 4, 2), freq=WEEKLY, byweekday=[TU]), num_days=3, time_from=dt.time(16), time_to=dt.time(18), tz=pytz.timezone("Pacific/Auckland")) self.calendar.add_child(instance=page) page.save_revision().publish() vev = VEventFactory().makeFromPage(page) self.assertIs(type(vev), MultidayRecurringVEvent) tz = pytz.timezone("Pacific/Auckland") self.assertEqual(vev['DTSTART'].dt, tz.localize(dt.datetime(2019, 4, 2, 16, 0))) self.assertEqual(vev['DTEND'].dt, tz.localize(dt.datetime(2019, 4, 4, 18, 0))) self.assertEqual(vev['RRULE']['FREQ'], ["WEEKLY"]) self.assertEqual(vev['RRULE']['BYDAY'], ["TU"])
def setUp(self): self.factory = VEventFactory()
class TestVEventFactory(TestCase): def setUp(self): self.factory = VEventFactory() def testMissingUid(self): props = Event() addProps(props, summary="Event", dtstart=dt.datetime(2016, 4, 5, 9), dtend=dt.datetime(2016, 4, 5, 13)) with self.assertRaises(CalendarTypeError) as expected: self.factory.makeFromProps(props, None) self.assertEqual(str(expected.exception), "Missing UID") def testMissingDtstamp(self): props = Event() addProps(props, summary="Event", uid="1234", dtstart=dt.datetime(2016, 4, 5, 9), dtend=dt.datetime(2016, 4, 5, 13)) with self.assertRaises(CalendarTypeError) as expected: self.factory.makeFromProps(props, None) self.assertEqual(str(expected.exception), "Missing DTSTAMP") def testMissingDtstart(self): props = Event() addProps(props, summary="Event", uid="1234", dtend=dt.datetime(2016, 4, 5, 13), dtstamp=dt.datetime(2016, 4, 5, 13)) with self.assertRaises(CalendarTypeError) as expected: self.factory.makeFromProps(props, None) self.assertEqual(str(expected.exception), "Missing DTSTART") def testDtendAndDuration(self): props = Event() addProps(props, summary="Event", uid="1234", dtstart=dt.datetime(2016, 4, 5, 9), dtend=dt.datetime(2016, 4, 5, 13), dtstamp=dt.datetime(2016, 4, 5, 13), duration=dt.timedelta(2)) with self.assertRaises(CalendarTypeError) as expected: self.factory.makeFromProps(props, None) self.assertEqual(str(expected.exception), "Both DURATION and DTEND set") def testDtstartDtendTypes(self): props = Event() addProps(props, summary="Event", uid="1234", dtstart=dt.datetime(2016, 4, 5, 9), dtend=dt.date(2016, 4, 5), dtstamp=dt.datetime(2016, 4, 5, 13)) with self.assertRaises(CalendarTypeError) as expected: self.factory.makeFromProps(props, None) self.assertEqual(str(expected.exception), "DTSTART and DTEND types do not match") def testDiffTZsDtstartDtEnd(self): tz1 = pytz.timezone("Pacific/Auckland") tz2 = pytz.timezone("Australia/Sydney") props = Event() addProps(props, summary="Event", uid="1234", dtstart=timezone.make_aware(dt.datetime(2016, 6, 1, 7), tz1), dtend=timezone.make_aware(dt.datetime(2016, 6, 1, 8), tz2), dtstamp=timezone.make_aware(dt.datetime(2016, 6, 1, 8), tz2)) with self.assertRaises(CalendarTypeError) as expected: self.factory.makeFromProps(props, None) self.assertEqual(str(expected.exception), "DTSTART.timezone != DTEND.timezone") def testMultipleRRules(self): props = Event() addProps( props, summary="Event", uid="1234", dtstart=dt.datetime(2016, 4, 5, 9), dtend=dt.datetime(2016, 4, 5, 13), dtstamp=dt.datetime(2016, 4, 5, 13), rrule=vRecur.from_ical("FREQ=WEEKLY;WKST=SU;BYDAY=MO,TU,WE,TH,FR")) props.add('rrule', vRecur.from_ical("FREQ=MONTHLY;WKST=SU;BYDAY=-1SA,-1SU")) with self.assertRaises(CalendarTypeError) as expected: self.factory.makeFromProps(props, None) self.assertEqual(str(expected.exception), "Multiple RRULEs") def testDiffTZsDtstartRecurrenceId(self): tz1 = pytz.timezone("Pacific/Auckland") tz2 = pytz.timezone("Australia/Sydney") props = Event() addProps(props, summary="Event", uid="1234", dtstart=timezone.make_aware(dt.datetime(2016, 6, 1, 7), tz1), dtend=timezone.make_aware(dt.datetime(2016, 6, 1, 10), tz1), dtstamp=timezone.make_aware(dt.datetime(2016, 6, 1, 8), tz2)) props.add('RECURRENCE-ID', timezone.make_aware(dt.datetime(2016, 6, 1, 8), tz2)) with self.assertRaises(CalendarTypeError) as expected: self.factory.makeFromProps(props, None) self.assertEqual(str(expected.exception), "DTSTART.timezone != RECURRENCE-ID.timezone") def testWholeDayEvent(self): props = Event(summary="Event", uid="1234") props.add('dtstart', dt.date(2017, 6, 5)) props.add('dtend', dt.date(2017, 6, 6)) props.add('dtstamp', vDt(timezone.make_aware(dt.datetime(2016, 6, 7, 8)))) vev = self.factory.makeFromProps(props, None) self.assertIs(type(vev), SimpleVEvent) def test1hrDuration(self): props = Event() addProps(props, summary="Event", uid="1234", dtstart=timezone.make_aware(dt.datetime(2016, 6, 1, 7)), duration=dt.timedelta(hours=1), dtstamp=timezone.make_aware(dt.datetime(2016, 6, 1, 8))) vev = self.factory.makeFromProps(props, None) self.assertIs(type(vev), SimpleVEvent) self.assertEqual(vev['DTSTART'], timezone.make_aware(dt.datetime(2016, 6, 1, 7))) self.assertEqual(vev['DTEND'], timezone.make_aware(dt.datetime(2016, 6, 1, 8))) def testNoDuration(self): props = Event() addProps(props, summary="Event", uid="1234", dtstart=dt.date(2016, 6, 1), dtstamp=timezone.make_aware(dt.datetime(2016, 6, 1, 8))) vev = self.factory.makeFromProps(props, None) self.assertIs(type(vev), SimpleVEvent) self.assertEqual(vev['DTSTART'], dt.date(2016, 6, 1)) self.assertEqual(vev['DTEND'], dt.date(2016, 6, 2)) def testUnsupportedPageType(self): page = Page(title="Event", slug="event") with self.assertRaises(CalendarTypeError) as expected: vev = self.factory.makeFromPage(page, None) self.assertEqual(str(expected.exception), "Unsupported page type")