/xivo_agid/tests/test_schedule.py
Python | 335 lines | 228 code | 91 blank | 16 comment | 1 complexity | bef28726e609d198f22ffb491efbcc55 MD5 | raw file
- # -*- coding: utf-8 -*-
- # Copyright (C) 2013-2014 Avencall
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <http://www.gnu.org/licenses/>
- import datetime
- import unittest
- from mock import Mock, call
- from xivo_agid.schedule import ScheduleBuilder, SchedulePeriodBuilder, \
- HoursChecker, WeekdaysChecker, DaysChecker, MonthsChecker, SchedulePeriod, \
- ScheduleAction
- class TestHoursChecker(unittest.TestCase):
- def test_range_is_in(self):
- value = '08:05-08:10'
- current_time = _a_time().hour('08:07').build()
- self._assert_time_is_in(current_time, value)
- def _assert_time_is_in(self, current_time, value):
- hours_checker = HoursChecker.new_from_value(value)
- self.assertTrue(hours_checker.is_in(current_time))
- def _assert_time_is_not_in(self, current_time, value):
- hours_checker = HoursChecker.new_from_value(value)
- self.assertFalse(hours_checker.is_in(current_time))
- def test_upper_limit_is_not_in(self):
- value = '08:05-08:10'
- current_time = _a_time().hour('08:10').build()
- self._assert_time_is_not_in(current_time, value)
- def test_lower_limit_is_in(self):
- value = '08:05-08:10'
- current_time = _a_time().hour('08:05').build()
- self._assert_time_is_in(current_time, value)
- def test_upper_limit_plus_one_is_not_in(self):
- value = '08:05-08:10'
- current_time = _a_time().hour('08:11').build()
- self._assert_time_is_not_in(current_time, value)
- def test_upper_limit_less_one_is_not_in(self):
- value = '08:05-08:10'
- current_time = _a_time().hour('08:04').build()
- self._assert_time_is_not_in(current_time, value)
- def test_minute_is_in_but_hour_is_more(self):
- value = '08:05-08:10'
- current_time = _a_time().hour('09:07').build()
- self._assert_time_is_not_in(current_time, value)
- def test_minute_is_in_but_hour_is_less(self):
- value = '08:05-08:10'
- current_time = _a_time().hour('07:07').build()
- self._assert_time_is_not_in(current_time, value)
- class TestWeekdaysChecker(unittest.TestCase):
- def test_single_weekday_is_in(self):
- value = '3'
- current_time = _a_time().weekday('3').build()
- self._assert_time_is_in(current_time, value)
- def _assert_time_is_in(self, current_time, value):
- weekdays_checker = WeekdaysChecker.new_from_value(value)
- self.assertTrue(weekdays_checker.is_in(current_time))
- def _assert_time_is_not_in(self, current_time, value):
- weekdays_checker = WeekdaysChecker.new_from_value(value)
- self.assertFalse(weekdays_checker.is_in(current_time))
- def test_single_weekday_range_is_in(self):
- value = '1-5'
- current_time = _a_time().weekday('3').build()
- self._assert_time_is_in(current_time, value)
- def test_upper_limit_single_weekday_range(self):
- value = '1-5'
- current_time = _a_time().weekday('5').build()
- self._assert_time_is_in(current_time, value)
- def test_lower_limit_single_weekday_range(self):
- value = '1-5'
- current_time = _a_time().weekday('1').build()
- self._assert_time_is_in(current_time, value)
- def test_upper_limit_plus_one_is_not_in(self):
- value = '1-5'
- current_time = _a_time().weekday('6').build()
- self._assert_time_is_not_in(current_time, value)
- def test_lower_limit_less_one_is_not_in(self):
- value = '2-5'
- current_time = _a_time().weekday('1').build()
- self._assert_time_is_not_in(current_time, value)
- def test_mixed_weekday_range_is_in(self):
- value = '1,3-4,7'
- weekdays_checker = WeekdaysChecker.new_from_value(value)
- self.assertTrue(weekdays_checker.is_in(_a_time().weekday('1').build()))
- self.assertFalse(weekdays_checker.is_in(_a_time().weekday('2').build()))
- self.assertTrue(weekdays_checker.is_in(_a_time().weekday('3').build()))
- self.assertTrue(weekdays_checker.is_in(_a_time().weekday('4').build()))
- self.assertFalse(weekdays_checker.is_in(_a_time().weekday('5').build()))
- self.assertFalse(weekdays_checker.is_in(_a_time().weekday('6').build()))
- self.assertTrue(weekdays_checker.is_in(_a_time().weekday('7').build()))
- class TestDaysChecker(unittest.TestCase):
- def test_simple_day(self):
- value = '5'
- days_checker = DaysChecker.new_from_value(value)
- self.assertTrue(days_checker.is_in(_a_time().day('5').build()))
- self.assertFalse(days_checker.is_in(_a_time().day('6').build()))
- class TestMonthsChecker(unittest.TestCase):
- def test_simple_month(self):
- value = '5'
- months_checker = MonthsChecker.new_from_value(value)
- self.assertTrue(months_checker.is_in(_a_time().month('5').build()))
- self.assertFalse(months_checker.is_in(_a_time().month('6').build()))
- class TestSchedulePeriod(unittest.TestCase):
- def test_is_in_with_true_checker(self):
- checker = self._new_true_checker()
- schedule_period = SchedulePeriod([checker], None)
- self.assertTrue(schedule_period.is_in(None))
- def _new_true_checker(self):
- mock = Mock()
- mock.is_in.return_value = True
- return mock
- def test_is_in_with_false_checker(self):
- checker = self._new_false_checker()
- schedule_period = SchedulePeriod([checker], None)
- self.assertFalse(schedule_period.is_in(None))
- def _new_false_checker(self):
- mock = Mock()
- mock.is_in.return_value = False
- return mock
- def test_is_in_with_true_and_false_checker(self):
- checker1 = self._new_true_checker()
- checker2 = self._new_false_checker()
- schedule_period = SchedulePeriod([checker1, checker2], None)
- self.assertFalse(schedule_period.is_in(None))
- class TestSchedule(unittest.TestCase):
- def test_schedule_is_opened_when_hours_is_in_open_period(self):
- schedule = (_a_schedule()
- .opened(_a_period()
- .hours('18:00-18:10').build())
- .build())
- current_time = (_a_time()
- .hour('18:05')
- .build())
- self._assert_schedule_is_in_state(schedule, current_time, 'opened')
- def _assert_schedule_is_in_state(self, schedule, current_time, state, action=None):
- schedule_state = schedule.compute_state(current_time)
- self.assertEqual(state, schedule_state.state)
- if action is not None:
- self.assertEqual(action, schedule_state.action)
- def test_simple_schedule_is_closed_when_hours_not_in_open_period(self):
- schedule = (_a_schedule()
- .opened(_a_period()
- .hours('18:00-18:10').build())
- .build())
- current_time = (_a_time()
- .hour('18:15')
- .build())
- self._assert_schedule_is_in_state(schedule, current_time, 'closed')
- def test_schedule_is_closed_when_day_doesnt_match(self):
- schedule = (_a_schedule()
- .opened(_a_period()
- .days('22').build())
- .build())
- current_time = (_a_time()
- .day('23')
- .build())
- self._assert_schedule_is_in_state(schedule, current_time, 'closed')
- def test_schedule_is_closed_when_weekday_doesnt_match(self):
- schedule = (_a_schedule()
- .opened(_a_period()
- .weekdays('6').build())
- .build())
- current_time = (_a_time()
- .weekday('7')
- .build())
- self._assert_schedule_is_in_state(schedule, current_time, 'closed')
- def test_schedule_is_closed_when_month_doesnt_match(self):
- schedule = (_a_schedule()
- .opened(_a_period()
- .months('3').build())
- .build())
- current_time = (_a_time()
- .month('4')
- .build())
- self._assert_schedule_is_in_state(schedule, current_time, 'closed')
- def test_complex_schedule(self):
- schedule = (_a_schedule()
- .opened(_a_period()
- .hours('16:00-17:00').build())
- .closed(_a_period()
- .hours('16:05-16:07')
- .days('5')
- .action(1).build())
- .closed(_a_period()
- .hours('16:05-16:07')
- .days('6')
- .action(2).build())
- .build())
- current_time_builder = (_a_time()
- .hour('16:06'))
- current_time = current_time_builder.day('5').build()
- self._assert_schedule_is_in_state(schedule, current_time, 'closed', action=1)
- current_time = current_time_builder.day('6').build()
- self._assert_schedule_is_in_state(schedule, current_time, 'closed', action=2)
- current_time = current_time_builder.day('7').build()
- self._assert_schedule_is_in_state(schedule, current_time, 'opened')
- def _a_schedule():
- return ScheduleBuilder()
- def _a_period():
- return SchedulePeriodBuilder()
- def _a_time():
- return _DatetimeBuilder()
- class _DatetimeBuilder(object):
- def __init__(self):
- self._year = 1970
- self._month = 1
- self._day = 1
- self._hour = 0
- self._minute = 0
- def hour(self, hour):
- hour, minute = hour.split(':', 1)
- self._hour = int(hour)
- self._minute = int(minute)
- return self
- def month(self, month):
- self._month = int(month)
- return self
- def day(self, day):
- self._day = int(day)
- return self
- def weekday(self, weekday):
- # monday = 1, sunday = 7
- weekday = int(weekday)
- self._year = 1970
- self._month = 1
- self._day = 4 + weekday
- return self
- def build(self):
- return datetime.datetime(self._year, self._month, self._day, self._hour, self._minute)
- class TestScheduleAction(unittest.TestCase):
- def test_action_arg2_is_not_set_if_none(self):
- action = ScheduleAction('foo', 'bar', None)
- agi = Mock()
- action.set_variables_in_agi(agi)
- expected_call_args = [call('XIVO_FWD_SCHEDULE_OUT_ACTION', 'foo'),
- call('XIVO_FWD_SCHEDULE_OUT_ACTIONARG1', 'bar')]
- self.assertEqual(expected_call_args, agi.set_variable.call_args_list)