diff --git a/data/schedule.py b/data/schedule.py index 68f6fca..f286b60 100644 --- a/data/schedule.py +++ b/data/schedule.py @@ -145,14 +145,13 @@ class Schedule: self.end_date = fromArray(self.schedule_dict["semester_end"]) # Semester is over - if self.end_date <= self.day: + if self.end_date < self.day: self.semester_over = True return self.check_holidays() self.week = self.get_week() - # TODO show a custom embed when no class instead of fast-forwarding # # Store the target weekday (in case it exists) so we can ask for the next # # friday after the holiday, for example # target_weekday = -1 if not self.targeted_weekday else self.day.weekday() @@ -181,7 +180,8 @@ class Schedule: # In the past: add the offset if holiday.has_passed(self.day): - self.holiday_offset += (self.day - holiday.end_date_parsed).days // 7 + # Add 1 because Monday-Sunday is only 6 days, but should be counted as a week + self.holiday_offset += (holiday.duration.days + 1) // 7 elif holiday.start_date_parsed <= self.day <= holiday.end_date_parsed: self.current_holiday = holiday @@ -203,7 +203,9 @@ class Schedule: return 1 # Add +1 at the end because week 1 would be 0 as it's not over yet - return (diff.days // 7) + self.holiday_offset + 1 + # Every week would be one behind + # Also subtract all passed holidays + return (diff.days // 7) - self.holiday_offset + 1 def find_slots_for_course(self, course_dict: Dict) -> List[Timeslot]: """ diff --git a/tests/data/test_schedule.py b/tests/data/test_schedule.py index 34fbb3e..5c9da8c 100644 --- a/tests/data/test_schedule.py +++ b/tests/data/test_schedule.py @@ -1,10 +1,12 @@ from data import schedule from datetime import datetime +from enums.platform import Platform import pytz -import unittest +from unittest import TestCase +from unittest.mock import patch -class TestSchedule(unittest.TestCase): +class TestSchedule(TestCase): def test_holiday_has_passed(self): tz = pytz.timezone("Europe/Brussels") before = datetime(2020, 8, 8, tzinfo=tz) @@ -16,3 +18,76 @@ class TestSchedule(unittest.TestCase): self.assertFalse(holiday.has_passed(before)) self.assertFalse(holiday.has_passed(during)) self.assertTrue(holiday.has_passed(after)) + + def test_timeslot_link(self): + slot = schedule.Timeslot(schedule.Course("a"), 1234, 5678) + self.assertEqual(None, slot.get_link_str()) + + slot = schedule.Timeslot(schedule.Course("a"), 1234, 5678, online_link="link", online_platform=Platform.Zoom) + self.assertEqual("[Zoom](link)", slot.get_link_str()) + + @patch("data.schedule.Schedule.check_holidays") + @patch("data.schedule.Schedule.load_schedule_file") + def test_schedule_semester_over(self, mock_load, mock_check_holidays): + mock_load.return_value = {"semester_start": [1, 2, 2020], "semester_end": [4, 5, 2021]} + dt = datetime(2021, 8, 8, tzinfo=pytz.timezone("Europe/Brussels")) + + s = schedule.Schedule(dt, 3, 1) + self.assertTrue(s.semester_over) + + # Check that the code stopped running in case the semester is over + mock_check_holidays.assert_not_called() + + @patch("data.schedule.Schedule.load_schedule_file") + def test_schedule_holidays(self, mock_load): + mock_load.return_value = { + "semester_start": [6, 7, 2021], "semester_end": [20, 8, 2021], + "holidays": [ + {"start_date": [1, 8, 2021], "end_date": [10, 8, 2021]} + ] + } + + # During holiday + dt = datetime(2021, 8, 8, tzinfo=pytz.timezone("Europe/Brussels")) + s = schedule.Schedule(dt, 3, 1) + self.assertNotEqual(None, s.current_holiday) + + # Not during holiday + dt = datetime(2021, 8, 15, tzinfo=pytz.timezone("Europe/Brussels")) + s = schedule.Schedule(dt, 3, 1) + self.assertEqual(None, s.current_holiday) + + @patch("data.schedule.Schedule.load_schedule_file") + def test_schedule_holiday_offset(self, mock_load): + # Week 1, no holidays + mock_load.return_value = { + "semester_start": [2, 8, 2021], "semester_end": [20, 8, 2021] + } + + dt = datetime(2021, 8, 6, tzinfo=pytz.timezone("Europe/Brussels")) + s = schedule.Schedule(dt, 3, 1) + self.assertEqual(1, s.get_week()) + + # Week 1, one off-day doesn't change the week + mock_load.return_value = { + "semester_start": [2, 8, 2021], "semester_end": [20, 8, 2021], + "holidays": [ + {"start_date": [5, 8, 2021], "end_date": [5, 8, 2021]} + ] + } + + s = schedule.Schedule(dt, 3, 1) + self.assertEqual(1, s.get_week()) + + # Week 3, with a one-week holiday in between + mock_load.return_value = { + "semester_start": [2, 8, 2021], "semester_end": [20, 8, 2021], + "holidays": [ + {"start_date": [5, 8, 2021], "end_date": [5, 8, 2021]}, + {"start_date": [9, 8, 2021], "end_date": [15, 8, 2021]} + ] + } + + dt = datetime(2021, 8, 19, tzinfo=pytz.timezone("Europe/Brussels")) + s = schedule.Schedule(dt, 3, 1) + self.assertEqual(2, s.get_week()) diff --git a/tests/functions/__init__.py b/tests/functions/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/functions/test_timeFormatters.py b/tests/functions/test_timeFormatters.py new file mode 100644 index 0000000..8b9f5fb --- /dev/null +++ b/tests/functions/test_timeFormatters.py @@ -0,0 +1,64 @@ +from datetime import datetime +from functions import timeFormatters +import unittest + + +class TestTimeFormatters(unittest.TestCase): + def test_leadingZero(self): + self.assertEqual("0123", timeFormatters.leadingZero("123")) + self.assertEqual("0123", timeFormatters.leadingZero("0123")) + + def test_delimiter(self): + self.assertEqual("0123", timeFormatters.delimiter("0123")) + self.assertEqual("01.23", timeFormatters.delimiter("0123", delim=".")) + + def test_timeFromInt(self): + self.assertEqual("01:23", timeFormatters.timeFromInt(123)) + self.assertEqual("12:34", timeFormatters.timeFromInt(1234)) + + def test_fromArray(self): + # Only day/month/year + d, m, y = 1, 2, 2021 + inp = [d, m, y] + + dt = timeFormatters.fromArray(inp) + self.assertEqual(d, dt.day) + self.assertEqual(m, dt.month) + self.assertEqual(y, dt.year) + + # Also hours/minutes/seconds + d, m, y, hh, mm, ss = 1, 2, 2021, 1, 2, 3 + inp = [d, m, y, hh, mm, ss] + + dt = timeFormatters.fromArray(inp) + self.assertEqual(d, dt.day) + self.assertEqual(m, dt.month) + self.assertEqual(y, dt.year) + self.assertEqual(hh, dt.hour) + self.assertEqual(mm, dt.minute) + self.assertEqual(ss, dt.second) + + def test_skipWeekends(self): + # Already a weekday + weekday = datetime(2021, 8, 11) + skipped = timeFormatters.skip_weekends(weekday) + self.assertEqual(weekday, skipped) + + # Weekend + weekend = datetime(2021, 8, 7) + skipped = timeFormatters.skip_weekends(weekend) + self.assertEqual(0, skipped.weekday()) + + def test_forwardToWeekday(self): + mo = datetime(2021, 8, 10) + # Before + forwarded = timeFormatters.forward_to_weekday(mo, 2) + self.assertEqual(1, (forwarded - mo).days) + + # Same day + forwarded = timeFormatters.forward_to_weekday(mo, 1) + self.assertEqual(7, (forwarded - mo).days) + + # After + forwarded = timeFormatters.forward_to_weekday(mo, 0) + self.assertEqual(6, (forwarded - mo).days)