def setUp(self): synopsis = ''' This programme has complex schedules to test timezone changes. Only active between March and October 2017 ''' programme, created = Programme.objects.get_or_create( name='Timezone', defaults={ 'synopsis': synopsis, 'language': 'en', 'photo': 'defaults/example/radio_1.jpg', 'current_season': 1, 'category': 'News & Politics', '_runtime': 60, 'start_date': datetime.date(2017, 3, 1), 'end_date': datetime.date(2017, 10, 31), } ) self.cest_schedule, created = Schedule.objects.get_or_create( programme=programme, type='L', calendar=self.calendar, recurrences=recurrence.Recurrence( rrules=[recurrence.Rule( recurrence.DAILY, until=SPAIN_TZ.localize(datetime.datetime(2017, 3, 27)))] ), start_dt=SPAIN_TZ.localize(datetime.datetime(2017, 3, 25, 10, 00, 00))) self.cet_schedule, created = Schedule.objects.get_or_create( programme=programme, type='L', calendar=self.calendar, recurrences=recurrence.Recurrence( rrules=[recurrence.Rule(recurrence.DAILY)], ), start_dt=SPAIN_TZ.localize(datetime.datetime(2017, 10, 28, 14, 00, 00)))
def test_CEST_transition(self): after = SPAIN_TZ.localize(datetime.datetime(2017, 2, 1, 0, 0, 00)) before = SPAIN_TZ.localize(datetime.datetime(2017, 11, 30, 0, 0, 00)) dates_between = self.cest_schedule.dates_between(after, before) expected_dates = ( SPAIN_TZ.localize(datetime.datetime(2017, 3, 25, 10, 0, 0)), SPAIN_TZ.localize(datetime.datetime(2017, 3, 26, 10, 0, 0)), SPAIN_TZ.localize(datetime.datetime(2017, 3, 27, 10, 0, 0)), ) self.assertItemsEqual(expected_dates, dates_between)
def test_CET_transition(self): after = SPAIN_TZ.localize(datetime.datetime(2017, 10, 28, 14, 0, 0)) before = SPAIN_TZ.localize(datetime.datetime(2017, 10, 30, 14, 0, 0)) dates_between = self.cet_schedule.dates_between(after, before) expected_dates = ( SPAIN_TZ.localize(datetime.datetime(2017, 10, 28, 14, 0, 0)), SPAIN_TZ.localize(datetime.datetime(2017, 10, 29, 14, 0, 0)), SPAIN_TZ.localize(datetime.datetime(2017, 10, 30, 14, 0, 0)), ) self.assertItemsEqual(expected_dates, dates_between)
def test_CEST_transition(self): after = SPAIN_TZ.localize(datetime.datetime(2017, 2, 1, 0, 0, 00)) before = SPAIN_TZ.localize(datetime.datetime(2017, 11, 30, 0, 0, 00)) dates_between = self.cest_schedule.dates_between(after, before) expected_dates = ( SPAIN_TZ.localize(datetime.datetime(2017, 3, 25, 10, 0, 0)), SPAIN_TZ.localize(datetime.datetime(2017, 3, 26, 10, 0, 0)), SPAIN_TZ.localize(datetime.datetime(2017, 3, 27, 10, 0, 0)), ) self.assertCountEqual(expected_dates, dates_between)
def test_CET_transition(self): after = SPAIN_TZ.localize(datetime.datetime(2017, 10, 28, 14, 0, 0)) before = SPAIN_TZ.localize(datetime.datetime(2017, 10, 30, 14, 0, 0)) dates_between = self.cet_schedule.dates_between(after, before) expected_dates = ( SPAIN_TZ.localize(datetime.datetime(2017, 10, 28, 14, 0, 0)), SPAIN_TZ.localize(datetime.datetime(2017, 10, 29, 14, 0, 0)), SPAIN_TZ.localize(datetime.datetime(2017, 10, 30, 14, 0, 0)), ) self.assertCountEqual(expected_dates, dates_between)
def test_transform_dt_to_default_tz(self): utc_dt = pytz.utc.localize(datetime.datetime(2017, 1, 1, 0, 00, 00)) spain_dt = transform_dt_to_default_tz(utc_dt) self.assertEquals(spain_dt.tzinfo.zone, 'Europe/Madrid') self.assertEquals( spain_dt, SPAIN_TZ.localize(datetime.datetime(2017, 1, 1, 1, 0, 0)))
def test_move_schedule_with_schedules_in_tz(self): schedule = self._create_schedule_with_daily_recurrence() self._login() response = self.client.patch( '/api/2/operations/{id}'.format(id=schedule.id), data={ 'id': schedule.id, 'start': "2015-01-01T18:30:00Z", 'new_start': "2015-01-01T20:30:00" # Dt in naive tz }) self.assertEqual(response.status_code, status.HTTP_200_OK) schedule.refresh_from_db() start_dt = pytz.utc.localize(datetime.datetime(2015, 1, 1, 18, 30, 0)) new_start_dt = SPAIN_TZ.localize( datetime.datetime(2015, 1, 1, 20, 30, 0)) self.assertEqual(schedule.start_dt, start_dt) # Original shouldn't change self.assertEqual(schedule.recurrences.exdates[0], start_dt) # But should be excluded self.assertIsNotNone( ExcludedDates.objects.get(schedule=schedule, datetime=start_dt)) # Exclude that date new_schedule = Schedule.objects.get(programme=schedule.programme, start_dt=new_start_dt) self.assertIsNotNone( new_schedule) # A new schedule should have be created self.assertNotEqual(new_schedule.id, schedule.id) self.assertFalse(new_schedule.has_recurrences()) # Second part of the test # Move schedule to the previous excluded position response = self.client.patch( '/api/2/operations/{id}'.format(id=new_schedule.id), data={ 'id': new_schedule.id, 'start': "2015-01-01T19:30:00Z", # same as 2015-01-01T20:30:00 using this tz 'new_start': "2015-01-01T19:30:00" # same as 2015-01-01T18:30:00Z }) self.assertEqual(response.status_code, status.HTTP_200_OK) schedule.refresh_from_db() # new_schedule has been deleted with self.assertRaises(Schedule.DoesNotExist): Schedule.objects.get(id=new_schedule.id) # the dt is not excluded anymore self.assertTrue(len(schedule.recurrences.exdates) == 0) with self.assertRaises(ExcludedDates.DoesNotExist): ExcludedDates.objects.get(schedule=schedule, datetime=start_dt)
def test_dictionary_key(self): """ Making sure that is safe to use a dt tz aware object in a different timezone to access a dictionary """ utc_dt = pytz.utc.localize(datetime.datetime(2015, 1, 1, 13, 0, 0)) spanish_dt = SPAIN_TZ.localize(datetime.datetime(2015, 1, 1, 13, 0, 0)) utc_dict = {utc_dt: 'Created using utc dt'} spain_dict = {spanish_dt: 'Created using spanish dt'} self.assertEqual(utc_dict.get(utc_dt), utc_dict.get(utc_dt.astimezone(SPAIN_TZ))) self.assertEqual(spain_dict.get(spanish_dt), spain_dict.get(spanish_dt.astimezone(pytz.utc)))
def test_dictionary_key(self): """ Making sure that is safe to use a dt tz aware object in a different timezone to access a dictionary """ utc_dt = pytz.utc.localize(datetime.datetime(2015, 1, 1, 13, 0, 0)) spanish_dt = SPAIN_TZ.localize(datetime.datetime(2015, 1, 1, 13, 0, 0)) utc_dict = {utc_dt: 'Created using utc dt'} spain_dict = {spanish_dt: 'Created using spanish dt'} self.assertEquals(utc_dict.get(utc_dt), utc_dict.get(utc_dt.astimezone(SPAIN_TZ))) self.assertEquals(spain_dict.get(spanish_dt), spain_dict.get(spanish_dt.astimezone(pytz.utc)))
def test_move_schedule_in_tz(self): new_schedule = self._create_schedule() self._login() response = self.client.patch( '/api/2/operations/{id}'.format(id=new_schedule.id), data={ 'id': new_schedule.id, 'start': "2015-01-01T18:30:00Z", 'new_start': "2015-01-01T20:30:00" # Dt in naive tz (should be converting using spanish tz) } ) self.assertEqual(response.status_code, status.HTTP_200_OK) new_schedule.refresh_from_db() self.assertEqual(new_schedule.start_dt, SPAIN_TZ.localize(datetime.datetime(2015, 1, 1, 20, 30, 0)))
def setUp(self): synopsis = ''' This programme has complex schedules to test timezone changes. Only active between March and October 2017 ''' programme, created = Programme.objects.get_or_create( name='Timezone', defaults={ 'synopsis': synopsis, 'language': 'en', 'photo': 'defaults/example/radio_1.jpg', 'current_season': 1, 'category': 'News & Politics', '_runtime': 60, 'start_date': datetime.date(2017, 3, 1), 'end_date': datetime.date(2017, 10, 31), }) self.cest_schedule, created = Schedule.objects.get_or_create( programme=programme, type='L', calendar=self.calendar, recurrences=recurrence.Recurrence(rrules=[ recurrence.Rule(recurrence.DAILY, until=SPAIN_TZ.localize( datetime.datetime(2017, 3, 27))) ]), start_dt=SPAIN_TZ.localize( datetime.datetime(2017, 3, 25, 10, 00, 00))) self.cet_schedule, created = Schedule.objects.get_or_create( programme=programme, type='L', calendar=self.calendar, recurrences=recurrence.Recurrence( rrules=[recurrence.Rule(recurrence.DAILY)], ), start_dt=SPAIN_TZ.localize( datetime.datetime(2017, 10, 28, 14, 00, 00)))
def test_move_schedule_in_tz(self): new_schedule = self._create_schedule() self._login() response = self.client.patch( '/api/2/operations/{id}'.format(id=new_schedule.id), data={ 'id': new_schedule.id, 'start': "2015-01-01T18:30:00Z", 'new_start': "2015-01-01T20:30:00" # Dt in naive tz (should be converting using spanish tz) }) self.assertEqual(response.status_code, status.HTTP_200_OK) new_schedule.refresh_from_db() self.assertEqual( new_schedule.start_dt, SPAIN_TZ.localize(datetime.datetime(2015, 1, 1, 20, 30, 0)))
def test_move_schedule_with_schedules_in_tz(self): schedule = self._create_schedule_with_daily_recurrence() self._login() response = self.client.patch( '/api/2/operations/{id}'.format(id=schedule.id), data={ 'id': schedule.id, 'start': "2015-01-01T18:30:00Z", 'new_start': "2015-01-01T20:30:00" # Dt in naive tz } ) self.assertEqual(response.status_code, status.HTTP_200_OK) schedule.refresh_from_db() start_dt = pytz.utc.localize(datetime.datetime(2015, 1, 1, 18, 30, 0)) new_start_dt = SPAIN_TZ.localize(datetime.datetime(2015, 1, 1, 20, 30, 0)) self.assertEqual(schedule.start_dt, start_dt) # Original shouldn't change self.assertEqual(schedule.recurrences.exdates[0], start_dt) # But should be excluded self.assertIsNotNone(ExcludedDates.objects.get(schedule=schedule, datetime=start_dt)) # Exclude that date new_schedule = Schedule.objects.get(programme=schedule.programme, start_dt=new_start_dt) self.assertIsNotNone(new_schedule) # A new schedule should have be created self.assertNotEqual(new_schedule.id, schedule.id) self.assertFalse(new_schedule.has_recurrences()) # Second part of the test # Move schedule to the previous excluded position response = self.client.patch( '/api/2/operations/{id}'.format(id=new_schedule.id), data={ 'id': new_schedule.id, 'start': "2015-01-01T19:30:00Z", # same as 2015-01-01T20:30:00 using this tz 'new_start': "2015-01-01T19:30:00" # same as 2015-01-01T18:30:00Z } ) self.assertEqual(response.status_code, status.HTTP_200_OK) schedule.refresh_from_db() # new_schedule has been deleted with self.assertRaises(Schedule.DoesNotExist): Schedule.objects.get(id=new_schedule.id) # the dt is not excluded anymore self.assertTrue(len(schedule.recurrences.exdates) == 0) with self.assertRaises(ExcludedDates.DoesNotExist): ExcludedDates.objects.get(schedule=schedule, datetime=start_dt)
import datetime import pytz import recurrence from django.test import TestCase from django.test import override_settings from radioco.apps.programmes.models import Programme from radioco.apps.radioco.test_utils import TestDataMixin, SPAIN_TZ from radioco.apps.radioco.tz_utils import transform_dt_to_default_tz from radioco.apps.schedules.models import Schedule BEFORE_CEST_TRANSITION = SPAIN_TZ.localize( datetime.datetime(2017, 3, 26, 1, 59, 59)) # CET+1:00:00 AFTER_CEST_TRANSITION = SPAIN_TZ.localize( datetime.datetime(2017, 3, 26, 3, 0, 0)) # CEST+2:00:00 BEFORE_CET_TRANSITION = SPAIN_TZ.localize(datetime.datetime( 2017, 10, 29, 2, 59, 59), is_dst=True) # CEST+2:00:00 AFTER_CET_TRANSITION = SPAIN_TZ.localize(datetime.datetime( 2017, 10, 29, 2, 0, 0), is_dst=False) # CET+1:00:00 def test_CET_transitions(self): assert BEFORE_CEST_TRANSITION == pytz.utc.localize( datetime.datetime(2017, 3, 26, 0, 59, 59)) assert AFTER_CEST_TRANSITION == pytz.utc.localize( datetime.datetime(2017, 3, 26, 1, 0, 0))
def test_cleaned_internal_recurrence_dates(self): self.assertEqual( self.cest_schedule.recurrences.rrules[0].until, SPAIN_TZ.localize(datetime.datetime(2017, 3, 27, 23, 59, 59)))
def test_transform_dt_to_default_tz(self): utc_dt = pytz.utc.localize(datetime.datetime(2017, 1, 1, 0, 00, 00)) spain_dt = transform_dt_to_default_tz(utc_dt) self.assertEqual(spain_dt.tzinfo.zone, 'Europe/Madrid') self.assertEqual(spain_dt, SPAIN_TZ.localize(datetime.datetime(2017, 1, 1, 1, 0, 0)))
def test_cleaned_internal_recurrence_dates(self): self.assertEquals( self.cest_schedule.recurrences.rrules[0].until, SPAIN_TZ.localize(datetime.datetime(2017, 3, 27, 23, 59, 59)))
import datetime import pytz import recurrence from django.test import TestCase from django.test import override_settings from radioco.apps.programmes.models import Programme from radioco.apps.radioco.test_utils import TestDataMixin, SPAIN_TZ from radioco.apps.radioco.tz_utils import transform_dt_to_default_tz from radioco.apps.schedules.models import Schedule BEFORE_CEST_TRANSITION = SPAIN_TZ.localize(datetime.datetime(2017, 3, 26, 1, 59, 59)) # CET+1:00:00 AFTER_CEST_TRANSITION = SPAIN_TZ.localize(datetime.datetime(2017, 3, 26, 3, 0, 0)) # CEST+2:00:00 BEFORE_CET_TRANSITION = SPAIN_TZ.localize(datetime.datetime(2017, 10, 29, 2, 59, 59), is_dst=True) # CEST+2:00:00 AFTER_CET_TRANSITION = SPAIN_TZ.localize(datetime.datetime(2017, 10, 29, 2, 0, 0), is_dst=False) # CET+1:00:00 def test_CET_transitions(self): assert BEFORE_CEST_TRANSITION == pytz.utc.localize(datetime.datetime(2017, 3, 26, 0, 59, 59)) assert AFTER_CEST_TRANSITION == pytz.utc.localize(datetime.datetime(2017, 3, 26, 1, 0, 0)) assert BEFORE_CET_TRANSITION == pytz.utc.localize(datetime.datetime(2017, 10, 29, 0, 59, 59)) assert AFTER_CET_TRANSITION == pytz.utc.localize(datetime.datetime(2017, 10, 29, 1, 0, 0)) @override_settings(TIME_ZONE='Europe/Madrid') # @mock.patch('django.utils.timezone.get_default_timezone', spain_tz) # @mock.patch('django.utils.timezone.get_current_timezone', spain_tz)