def get_random_datetime(start_date=EWSDate(1996, 1, 1), end_date=EWSDate(2030, 1, 1), tz=UTC): # Create a random datetime with minute precision. Both dates are inclusive. # Keep with a reasonable date range. A wider date range than the default values is unstable WRT timezones. random_date = get_random_date(start_date=start_date, end_date=end_date) random_datetime = datetime.datetime.combine(random_date, datetime.time.min) \ + datetime.timedelta(minutes=random.randint(0, 60 * 24)) return EWSDateTime.from_datetime(random_datetime).replace(tzinfo=tz)
def test_task_validation(self): tz = self.account.default_timezone task = Task(due_date=EWSDate(2017, 1, 1), start_date=EWSDate(2017, 2, 1)) task.clean() # We reset due date if it's before start date self.assertEqual(task.due_date, EWSDate(2017, 2, 1)) self.assertEqual(task.due_date, task.start_date) task = Task(complete_date=EWSDateTime(2099, 1, 1, tzinfo=tz), status=Task.NOT_STARTED) task.clean() # We reset status if complete_date is set self.assertEqual(task.status, Task.COMPLETED) # We also reset complete date to now() if it's in the future self.assertEqual(task.complete_date.date(), UTC_NOW().date()) task = Task(complete_date=EWSDateTime(2017, 1, 1, tzinfo=tz), start_date=EWSDate(2017, 2, 1)) task.clean() # We also reset complete date to start_date if it's before start_date self.assertEqual(task.complete_date.date(), task.start_date) task = Task(percent_complete=Decimal('50.0'), status=Task.COMPLETED) task.clean() # We reset percent_complete to 100.0 if state is completed self.assertEqual(task.percent_complete, Decimal(100)) task = Task(percent_complete=Decimal('50.0'), status=Task.NOT_STARTED) task.clean() # We reset percent_complete to 0.0 if state is not_started self.assertEqual(task.percent_complete, Decimal(0))
def get_random_datetime_range(start_date=EWSDate(1996, 1, 1), end_date=EWSDate(2030, 1, 1), tz=UTC): # Create two random datetimes. Both dates are inclusive. # Keep with a reasonable date range. A wider date range than the default values is unstable WRT timezones. # Calendar items raise ErrorCalendarDurationIsTooLong if duration is > 5 years. return sorted([ get_random_datetime(start_date=start_date, end_date=end_date, tz=tz), get_random_datetime(start_date=start_date, end_date=end_date, tz=tz), ])
def test_no_account(self): # Test corner cases with bulk operations on items with no self.account item = self.get_test_item() item.recurrence = None item.is_all_day = True item.start, item.end = EWSDate(2020, 1, 1), EWSDate(2020, 1, 2) item.account = None res = self.test_folder.bulk_create(items=[item])[0] item.id, item.changekey = res.id, res.changekey item.account = None self.account.bulk_update(items=[(item, ('start', ))])
def get_random_datetime(start_date=EWSDate(1996, 1, 1), end_date=EWSDate(2030, 1, 1), tz=UTC): # Create a random datetime with minute precision. Both dates are inclusive. # Keep with a reasonable date range. A wider date range than the default values is unstable WRT timezones. while True: try: random_date = get_random_date(start_date=start_date, end_date=end_date) random_datetime = datetime.datetime.combine(random_date, datetime.time.min) \ + datetime.timedelta(minutes=random.randint(0, 60 * 24)) return tz.localize(EWSDateTime.from_datetime(random_datetime), is_dst=None) except (AmbiguousTimeError, NonExistentTimeError): pass
def get_random_date(start_date=EWSDate(1996, 1, 1), end_date=EWSDate(2030, 1, 1)): # Keep with a reasonable date range. A wider date range is unstable WRT timezones return EWSDate.fromordinal( random.randint(start_date.toordinal(), end_date.toordinal()))
def test_ewsdate(self): self.assertEqual(EWSDate(2000, 1, 1).ewsformat(), '2000-01-01') self.assertEqual(EWSDate.from_string('2000-01-01'), EWSDate(2000, 1, 1)) self.assertEqual(EWSDate.from_string('2000-01-01Z'), EWSDate(2000, 1, 1)) self.assertEqual(EWSDate.from_string('2000-01-01+01:00'), EWSDate(2000, 1, 1)) self.assertEqual(EWSDate.from_string('2000-01-01-01:00'), EWSDate(2000, 1, 1)) self.assertIsInstance( EWSDate(2000, 1, 2) - EWSDate(2000, 1, 1), datetime.timedelta) self.assertIsInstance( EWSDate(2000, 1, 2) + datetime.timedelta(days=1), EWSDate) self.assertIsInstance( EWSDate(2000, 1, 2) - datetime.timedelta(days=1), EWSDate) # Test in-place add and subtract dt = EWSDate(2000, 1, 2) dt += datetime.timedelta(days=1) self.assertIsInstance(dt, EWSDate) self.assertEqual(dt, EWSDate(2000, 1, 3)) dt = EWSDate(2000, 1, 2) dt -= datetime.timedelta(days=1) self.assertIsInstance(dt, EWSDate) self.assertEqual(dt, EWSDate(2000, 1, 1)) with self.assertRaises(ValueError): EWSDate.from_date(EWSDate(2000, 1, 2))
def get_random_date(start_date=date(1900, 1, 1), end_date=date(2100, 1, 1)): return EWSDate.fromordinal(random.randint(start_date.toordinal(), end_date.toordinal()))
def test_recurring_item(self): """Changes to an occurrence of a recurring task cause one-off tasks to be generated when the following updates are made: * The status property of a regenerating or nonregenerating recurrent task is set to Completed. * The start date or end date of a nonregenerating recurrent task is changed. """ # Create a master non-regenerating item with 4 daily occurrences start = EWSDate(2016, 1, 1) recurrence = TaskRecurrence(pattern=DailyPattern(interval=1), start=start, number=4) nonregenerating_item = self.ITEM_CLASS( folder=self.test_folder, categories=self.categories, recurrence=recurrence, ).save() nonregenerating_item.refresh() master_item_id = nonregenerating_item.id self.assertEqual(nonregenerating_item.is_recurring, True) self.assertEqual(nonregenerating_item.change_count, 1) self.assertEqual(self.test_folder.filter(categories__contains=self.categories).count(), 1) # Change the start date. We should see a new task appear. master_item = self.get_item_by_id((master_item_id, None)) master_item.recurrence.boundary.start = EWSDate(2016, 2, 1) occurrence_item = master_item.save() occurrence_item.refresh() self.assertEqual(occurrence_item.is_recurring, False) # This is now the occurrence self.assertEqual(self.test_folder.filter(categories__contains=self.categories).count(), 2) # Check fields on the recurring item master_item = self.get_item_by_id((master_item_id, None)) self.assertEqual(master_item.change_count, 2) self.assertEqual(master_item.due_date, EWSDate(2016, 1, 2)) # This is the next occurrence self.assertEqual(master_item.recurrence.boundary.number, 3) # One less # Change the status to 'Completed'. We should see a new task appear. master_item.status = Task.COMPLETED occurrence_item = master_item.save() occurrence_item.refresh() self.assertEqual(occurrence_item.is_recurring, False) # This is now the occurrence self.assertEqual(self.test_folder.filter(categories__contains=self.categories).count(), 3) # Check fields on the recurring item master_item = self.get_item_by_id((master_item_id, None)) self.assertEqual(master_item.change_count, 3) self.assertEqual(master_item.due_date, EWSDate(2016, 2, 1)) # This is the next occurrence self.assertEqual(master_item.recurrence.boundary.number, 2) # One less self.test_folder.filter(categories__contains=self.categories).delete() # Create a master regenerating item with 4 daily occurrences recurrence = TaskRecurrence(pattern=DailyRegeneration(interval=1), start=start, number=4) regenerating_item = self.ITEM_CLASS( folder=self.test_folder, categories=self.categories, recurrence=recurrence, ).save() regenerating_item.refresh() master_item_id = regenerating_item.id self.assertEqual(regenerating_item.is_recurring, True) self.assertEqual(regenerating_item.change_count, 1) self.assertEqual(self.test_folder.filter(categories__contains=self.categories).count(), 1) # Change the start date. We should *not* see a new task appear. master_item = self.get_item_by_id((master_item_id, None)) master_item.recurrence.boundary.start = EWSDate(2016, 1, 2) occurrence_item = master_item.save() occurrence_item.refresh() self.assertEqual(occurrence_item.id, master_item.id) # This is not an occurrence. No new task was created self.assertEqual(self.test_folder.filter(categories__contains=self.categories).count(), 1) # Change the status to 'Completed'. We should see a new task appear. master_item.status = Task.COMPLETED occurrence_item = master_item.save() occurrence_item.refresh() self.assertEqual(occurrence_item.is_recurring, False) # This is now the occurrence self.assertEqual(self.test_folder.filter(categories__contains=self.categories).count(), 2) # Check fields on the recurring item master_item = self.get_item_by_id((master_item_id, None)) self.assertEqual(master_item.change_count, 2) # The due date is the next occurrence after today tz = self.account.default_timezone self.assertEqual(master_item.due_date, EWSDateTime.now(tz).date() + datetime.timedelta(days=1)) self.assertEqual(master_item.recurrence.boundary.number, 3) # One less