def testRecurrenceEventsWhereExDateIsNotNow(self):
        """
        Recurrence rules that have exceptions.
        """
        # create an event starting 61 minutes ago, lasting 60 minutes, and
        # repeating every hour for five times;
        # but with an exception for the first instances
        now = _now()
        now = now.replace(
            microsecond=0)  # recurring adjustments lose precision
        start = now - timedelta(minutes=61)
        end = now - timedelta(minutes=1)
        exdates = [start]
        rrules = [
            "FREQ=HOURLY;INTERVAL=1;COUNT=5",
        ]

        calendar = Calendar()
        calendar.addEvent(
            Event('uid', start, end, 'foo', rrules=rrules, exdates=exdates))

        eis = calendar.getActiveEventInstances()
        self.failUnless(eis)
        # the first event after the exception happens to start when the
        # exception would have ended
        self.assertEquals(eis[0].start, end)
    def testAddEventsWithDifferentUID(self):
        # test that internally they end up in different event sets
        calendar = Calendar()

        start1 = datetime.now(UTC)
        end1 = start1 + timedelta(hours=1)
        exdates1 = [start1 + timedelta(hours=2)]

        start2 = start1
        end2 = start2 + timedelta(hours=1)
        exdates2 = [start2 + timedelta(hours=2)]

        e1 = Event('uid1', start1, end1, 'content1', exdates=exdates1)
        e2 = Event('uid2', start2, end2, 'content2', exdates=exdates2)
        calendar.addEvent(e1)
        calendar.addEvent(e2)

        event1 = calendar._eventSets['uid1']._events[0]
        event2 = calendar._eventSets['uid2']._events[0]
        self.assertEquals(len(calendar._eventSets['uid1']._events), 1)
        self.assertEquals(len(calendar._eventSets['uid2']._events), 1)
        self.assertEventAttribsEqual(event1, start1, end1, 'content1', None,
                                     exdates1)
        self.assertEventAttribsEqual(event2, start2, end2, 'content2', None,
                                     exdates2)
    def testRecurrenceEventsHourly(self):
        # create an hourly recurring event, starting 1 hour and 58 minutes ago,
        # and lasting an hour
        now = _now()
        now = now.replace(microsecond=0)
        start = now - timedelta(minutes=118)
        end = now - timedelta(minutes=58)
        rrules = [
            "FREQ=HOURLY;WKST=MO",
        ]
        self.debug('now is %s', str(now))
        self.debug('rrule starts at %s', str(start))

        cal = Calendar()
        cal.addEvent(Event('uid', start, end, "event1", rrules=rrules))

        # check active instances now
        eis = cal.getActiveEventInstances()
        self.assertEquals(len(eis), 1)

        self.assertEventAttribsEqual(eis[0].event, start, end, "event1",
                                     rrules, None)
        self.assertEquals(eis[0].start,
                          now - timedelta(hours=1) + timedelta(minutes=2))
        self.assertEquals(eis[0].end, now + timedelta(minutes=2))

        # check active instances 1 hour later
        eis = cal.getActiveEventInstances(now + timedelta(hours=1))
        self.assertEquals(len(eis), 1)

        self.assertEventAttribsEqual(eis[0].event, start, end, "event1",
                                     rrules, None)
        self.assertEquals(eis[0].start, now + timedelta(minutes=2))
        self.assertEquals(eis[0].end,
                          now + timedelta(minutes=2) + timedelta(hours=1))
    def testCurrentEventsDoNotStartLaterThanTomorrow(self):
        now = _now()
        start = now + timedelta(days=2)
        end = now + timedelta(days=3)

        cal = Calendar()
        cal.addEvent(Event('uid', start, end, 'content'))

        self.failIf(cal.getActiveEventInstances())
    def testCurrentEventsDoNotEndBeforeNow(self):
        now = _now()
        start = now - timedelta(hours=2)
        end = now - timedelta(hours=1)

        cal = Calendar()
        cal.addEvent(Event('uid', start, end, 'content'))

        self.failIf(cal.getActiveEventInstances())
    def testGetActiveSimple(self):
        now = _now()
        start = now - timedelta(hours=1)
        end = now + timedelta(minutes=1)

        calendar = Calendar()
        calendar.addEvent(Event('uid', start, end, 'foo'))

        ei = calendar.getActiveEventInstances()[0]
        self.assertEventAttribsEqual(ei.event, start, end, 'foo', None, None)
    def testOverMidnight(self):
        now = _now()
        start = now - timedelta(days=1)
        end = now + timedelta(hours=1)
        cal = Calendar()
        cal.addEvent(Event('uid', start, end, 'content'))

        eis = cal.getActiveEventInstances()
        self.assertEquals(len(eis), 1)
        self.assertEventAttribsEqual(eis[0].event, start, end, 'content', None,
                                     None)
    def testAddEvent(self):
        now = _now()
        start = now
        end = start + timedelta(hours=1)
        exdates = [start + timedelta(hours=2)]

        calendar = Calendar()
        calendar.addEvent(Event('uid', start, end, 'foo', exdates=exdates))

        event = calendar._eventSets['uid']._events[0]
        self.assertEventAttribsEqual(event, start, end, 'foo', None, exdates)
    def testRecurrenceEventsWhereExDateIsNotStartDate(self):
        """
        Recurrence rules that have exceptions.
        """
        now = _now()
        now = now.replace(
            microsecond=0)  # recurring adjustments lose precision
        start = now - timedelta(minutes=61)
        end = now - timedelta(minutes=1)
        exdates = [start + timedelta(hours=1)]
        rrules = [
            "FREQ=HOURLY;INTERVAL=1;COUNT=5",
        ]

        cal = Calendar()
        cal.addEvent(
            Event('uid', start, end, 'content', rrules=rrules,
                  exdates=exdates))

        self.failIf(cal.getActiveEventInstances())
    def testAddEventsWithSameUID(self):
        # test that internally they end up in the same event set
        calendar = Calendar()

        start1 = datetime.now(UTC)
        end1 = start1 + timedelta(hours=1)
        content1 = "content1"
        exdates1 = [start1 + timedelta(hours=2)]

        start2 = start1
        end2 = start2 + timedelta(hours=1)
        content2 = "content2"
        exdates2 = [start2 + timedelta(hours=2)]

        e1 = Event('uid',
                   start1,
                   end1,
                   content1,
                   rrules=None,
                   exdates=exdates1)
        e2 = Event('uid',
                   start2,
                   end2,
                   content2,
                   rrules=None,
                   exdates=exdates2)

        calendar.addEvent(e1)
        calendar.addEvent(e2)

        # verify internals of calendar
        event1 = calendar._eventSets['uid']._events[0]
        event2 = calendar._eventSets['uid']._events[1]
        self.assertEquals(len(calendar._eventSets['uid']._events), 2)
        self.assertEventAttribsEqual(event1, start1, end1, content1, None,
                                     exdates1)
        self.assertEventAttribsEqual(event2, start2, end2, content2, None,
                                     exdates2)
    def testRecurrenceEventsOverMidnight(self):
        """
        Test weekly recurrence rules that starts on one day and spawns to
        the day after, even though they were not planned for the next day.
        """
        def yesterdayDayOfTheWeek(now):
            yesterday = now - timedelta(days=1)
            day = calendar.weekday(yesterday.year, yesterday.month,
                                   yesterday.day)
            return _dayOfTheWeek[day]

        now = _now().replace(microsecond=0)
        start = now - timedelta(days=1) - timedelta(weeks=1)
        end = now + timedelta(hours=1) - timedelta(weeks=1)
        rrules = [
            "FREQ=WEEKLY;BYDAY=" + yesterdayDayOfTheWeek(now) + ";WKST=MO",
        ]
        cal = Calendar()
        cal.addEvent(Event('uid', start, end, 'content', rrules=rrules))

        eis = cal.getActiveEventInstances()
        self.assertEquals(len(eis), 1)
        self.assertEventAttribsEqual(eis[0].event, start, end, 'content',
                                     rrules, None)