118 lines
3.8 KiB
Python
118 lines
3.8 KiB
Python
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()
|