diff options
| author | stuppie | 2026-11-04 14:45:25 -0600 |
|---|---|---|
| committer | stuppie | 2026-11-04 14:45:25 -0600 |
| commit | 77f733cbf935e3d442f549b5986f79fd042dede1 (patch) | |
| tree | b34e4f27f6ff153bb9db62ae734a0c953da9e362 /tests/models/thl/test_survey.py | |
| parent | 57fe3c05cb5775bcd4b94917cbc09a9d129a4ed3 (diff) | |
| download | generalresearch-77f733cbf935e3d442f549b5986f79fd042dede1.tar.gz generalresearch-77f733cbf935e3d442f549b5986f79fd042dede1.zip | |
implement active hours on shared Task model
Diffstat (limited to 'tests/models/thl/test_survey.py')
| -rw-r--r-- | tests/models/thl/test_survey.py | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/tests/models/thl/test_survey.py b/tests/models/thl/test_survey.py new file mode 100644 index 0000000..b283e50 --- /dev/null +++ b/tests/models/thl/test_survey.py @@ -0,0 +1,140 @@ +from datetime import UTC, datetime, time +from unittest.mock import patch +from zoneinfo import ZoneInfo + +import pytest + +from generalresearch.models.definitions import Source +from generalresearch.models.thl.survey.model import Survey, TimeInterval + + +@pytest.mark.parametrize( + ("hour", "minute", "expected"), + [ + (6, 59, False), + (7, 0, True), + (12, 0, True), + (22, 0, True), + (22, 1, False), + ], +) +def test_is_currently_active_in_worker_local_time(hour, minute, expected): + interval = TimeInterval(start=time(7), end=time(22), timezone=None) + worker_time = datetime( + 2026, 1, 15, hour, minute, tzinfo=ZoneInfo("America/Chicago") + ) + + assert interval.is_currently_active(worker_time) is expected + + +@pytest.mark.parametrize( + ("hour", "expected"), + [ + (21, False), + (22, True), + (23, True), + (0, True), + (6, True), + (7, False), + ], +) +def test_is_currently_active_for_interval_crossing_midnight(hour, expected): + interval = TimeInterval(start=time(22), end=time(6), timezone=None) + worker_time = datetime(2026, 1, 15, hour, tzinfo=UTC) + + assert interval.is_currently_active(worker_time) is expected + + +def test_is_currently_active_converts_to_interval_timezone(): + interval = TimeInterval( + start=time(7), + end=time(9), + timezone="America/New_York", + ) + # 08:00 in New York on this date. + worker_time = datetime( + 2026, 1, 15, 7, tzinfo=ZoneInfo("America/Chicago") + ) + + assert interval.is_currently_active(worker_time) is True + + +def test_is_currently_active_requires_aware_worker_time(): + interval = TimeInterval(start=time(7), end=time(22), timezone=None) + + with pytest.raises(AssertionError): + interval.is_currently_active(datetime(2026, 1, 15, 12)) + + +def test_is_currently_active_requires_worker_timezone_for_local_interval(): + interval = TimeInterval(start=time(7), end=time(22), timezone=None) + + assert interval.is_currently_active_by_worker_tz(worker_tz=None) is False + + +@pytest.mark.parametrize( + ("interval_timezone", "worker_timezone"), + [ + (None, ZoneInfo("America/Chicago")), + ("America/New_York", None), + ], +) +def test_is_currently_active_supports_interval_crossing_midnight( + interval_timezone, worker_timezone +): + interval = TimeInterval( + start=time(22), + end=time(6), + timezone=interval_timezone, + ) + current_timezone = ( + ZoneInfo(interval_timezone) if interval_timezone else worker_timezone + ) + current_time = datetime(2026, 1, 15, 23, tzinfo=current_timezone) + + with patch("generalresearch.models.thl.survey.model.datetime") as mock_datetime: + mock_datetime.now.return_value = current_time + + assert interval.is_currently_active_by_worker_tz(worker_timezone) is True + mock_datetime.now.assert_called_once_with(tz=current_timezone) + + +@pytest.mark.parametrize( + ("off_start", "off_end", "active_start", "active_end"), + [ + (time(1), time(5), time(5), time(1)), + (time(22), time(6), time(6), time(22)), + ], +) +def test_from_off_hours_returns_complementary_active_hours( + off_start, off_end, active_start, active_end +): + off_hours = TimeInterval( + start=off_start, + end=off_end, + timezone="America/New_York", + ) + + active_hours = Survey.active_hours_from_off_hours(off_hours) + + assert active_hours == [ + TimeInterval( + start=active_start, + end=active_end, + timezone="America/New_York", + ) + ] + + +def test_from_off_hours_result_can_be_assigned_to_survey(): + off_hours = TimeInterval(start=time(1), end=time(5), timezone=None) + + survey = Survey( + source=Source.TESTING, + survey_id="off-hours-test", + active_hours=Survey.active_hours_from_off_hours(off_hours), + ) + + assert survey.active_hours == [ + TimeInterval(start=time(5), end=time(1), timezone=None) + ] |
