import json from datetime import datetime from zoneinfo import ZoneInfo import requests as req from app.api import fetch_scores, refresh_scores EASTERN = ZoneInfo("America/New_York") class TestFetchScores: def test_uses_now_url_during_evening(self, mocker): """7:30 PM ET → /score/now""" mock_dt = mocker.patch("app.api.datetime") mock_dt.now.return_value = datetime(2024, 4, 10, 19, 30, tzinfo=EASTERN) mock_get = mocker.patch("app.api.requests.get") mock_get.return_value.json.return_value = {"games": []} fetch_scores() url = mock_get.call_args[0][0] assert url == "https://api-web.nhle.com/v1/score/now" def test_uses_now_url_after_midnight(self, mocker): """1:00 AM ET → /score/now (still considered game hours)""" mock_dt = mocker.patch("app.api.datetime") mock_dt.now.return_value = datetime(2024, 4, 11, 1, 0, tzinfo=EASTERN) mock_get = mocker.patch("app.api.requests.get") mock_get.return_value.json.return_value = {"games": []} fetch_scores() url = mock_get.call_args[0][0] assert url == "https://api-web.nhle.com/v1/score/now" def test_uses_date_url_during_afternoon(self, mocker): """2:00 PM ET → date-based endpoint""" mock_dt = mocker.patch("app.api.datetime") mock_dt.now.return_value = datetime(2024, 4, 10, 14, 0, tzinfo=EASTERN) mock_get = mocker.patch("app.api.requests.get") mock_get.return_value.json.return_value = {"games": []} fetch_scores() url = mock_get.call_args[0][0] assert "2024-04-10" in url assert "now" not in url def test_returns_json_on_success(self, mocker): mock_dt = mocker.patch("app.api.datetime") mock_dt.now.return_value = datetime(2024, 4, 10, 14, 0, tzinfo=EASTERN) expected = {"games": [{"id": 1}]} mock_get = mocker.patch("app.api.requests.get") mock_get.return_value.json.return_value = expected result = fetch_scores() assert result == expected def test_returns_none_on_request_exception(self, mocker): mock_dt = mocker.patch("app.api.datetime") mock_dt.now.return_value = datetime(2024, 4, 10, 14, 0, tzinfo=EASTERN) mocker.patch( "app.api.requests.get", side_effect=req.RequestException("timeout") ) result = fetch_scores() assert result is None def test_returns_none_on_bad_status(self, mocker): mock_dt = mocker.patch("app.api.datetime") mock_dt.now.return_value = datetime(2024, 4, 10, 14, 0, tzinfo=EASTERN) mock_get = mocker.patch("app.api.requests.get") mock_get.return_value.raise_for_status.side_effect = req.HTTPError("404") result = fetch_scores() assert result is None class TestRefreshScores: def test_writes_data_to_file(self, mocker, tmp_path): data = {"games": [{"id": 1}]} mocker.patch("app.api.fetch_scores", return_value=data) score_file = tmp_path / "scoreboard_data.json" mocker.patch("app.api.SCOREBOARD_DATA_FILE", str(score_file)) result = refresh_scores() assert result == data assert score_file.exists() assert json.loads(score_file.read_text()) == data def test_returns_none_when_fetch_fails(self, mocker): mocker.patch("app.api.fetch_scores", return_value=None) result = refresh_scores() assert result is None def test_does_not_write_file_when_fetch_fails(self, mocker, tmp_path): mocker.patch("app.api.fetch_scores", return_value=None) score_file = tmp_path / "scoreboard_data.json" mocker.patch("app.api.SCOREBOARD_DATA_FILE", str(score_file)) refresh_scores() assert not score_file.exists()