from datetime import date, datetime, time, timedelta import pytest from model_bakery import baker import calendar from dateutil.relativedelta import relativedelta from aircox import utils from aircox.models import Diffusion, Schedule class TestSchedule: @pytest.mark.django_db def test_save_rerun(self, sched_reruns): for schedule in sched_reruns: schedule.duration = None schedule.frequency = None schedule.save_rerun() assert schedule.program == schedule.initial.program assert schedule.duration == schedule.initial.duration assert schedule.frequency == schedule.initial.frequency @pytest.mark.django_db def test_tz(self, schedules): for schedule in schedules: assert schedule.timezone == schedule.tz.key @pytest.mark.django_db def test_start(self, schedules): for schedule in schedules: assert schedule.start.date() == schedule.date assert schedule.start.time() == schedule.time @pytest.mark.django_db def test_end(self, schedules): for schedule in schedules: delta = utils.to_timedelta(schedule.duration) assert schedule.end - schedule.start == delta # def test_get_frequency_display(self): # pass @pytest.mark.django_db def test_normalize(self, schedules): for schedule in schedules: dt = datetime.combine(schedule.date, schedule.time) assert schedule.normalize(dt).tzinfo.key == schedule.timezone @pytest.mark.django_db def test_dates_of_month_ponctual(self): schedule = baker.prepare(Schedule, frequency=Schedule.Frequency.ponctual) at = schedule.date + relativedelta(months=4) assert schedule.dates_of_month(at) == [] @pytest.mark.django_db @pytest.mark.parametrize("months", range(0, 25, 4)) @pytest.mark.parametrize("hour", range(0, 24, 4)) def test_dates_of_month_last(self, months, hour): schedule = baker.prepare(Schedule, time=time(hour, 00), frequency=Schedule.Frequency.last) at = schedule.date + relativedelta(months=months) datetimes = schedule.dates_of_month(at) assert len(datetimes) == 1 dt = datetimes[0] self._assert_date(schedule, at, dt) month_info = calendar.monthrange(at.year, at.month) at = date(at.year, at.month, month_info[1]) if at.weekday() < schedule.date.weekday(): at -= timedelta(days=7) at += timedelta(days=schedule.date.weekday()) - timedelta(days=at.weekday()) assert dt.date() == at # since the same method is used for first, second, etc. frequencies # we assume testing every is sufficient @pytest.mark.django_db @pytest.mark.parametrize("months", range(0, 25, 4)) @pytest.mark.parametrize("hour", range(0, 24, 4)) def test_dates_of_month_every(self, months, hour): schedule = baker.prepare(Schedule, time=time(hour, 00), frequency=Schedule.Frequency.every) at = schedule.date + relativedelta(months=months) datetimes = schedule.dates_of_month(at) last = None for dt in datetimes: self._assert_date(schedule, at, dt) if last: assert (dt - last).days == 7 last = dt @pytest.mark.django_db @pytest.mark.parametrize("months", range(0, 25, 4)) @pytest.mark.parametrize("hour", range(0, 24, 4)) def test_dates_of_month_one_on_two(self, months, hour): schedule = baker.prepare( Schedule, time=time(hour, 00), frequency=Schedule.Frequency.one_on_two, ) at = schedule.date + relativedelta(months=months) datetimes = schedule.dates_of_month(at) for dt in datetimes: self._assert_date(schedule, at, dt) delta = dt.date() - schedule.date assert delta.days % 14 == 0 def _assert_date(self, schedule, at, dt): assert dt.year == at.year assert dt.month == at.month assert dt.weekday() == schedule.date.weekday() assert dt.time() == schedule.time assert dt.tzinfo.key == schedule.timezone @pytest.mark.django_db def test_diffusions_of_month(self, sched_initials): # TODO: test values of initial, rerun for schedule in sched_initials: at = schedule.date + timedelta(days=30) dates = set(schedule.dates_of_month(at)) episodes, diffusions = schedule.diffusions_of_month(at) assert all(r.date in dates for r in episodes) assert all((not r.initial or r.date in dates) and r.type == Diffusion.TYPE_ON_AIR for r in diffusions)