"""Test for ows-track.""" import time from contextlib import nullcontext from typing import Any, ContextManager from unittest.mock import MagicMock, call import pytest from flask.ctx import AppContext from owsrequest.utils import mock_request from owsrequest.utils.fixture_plugin import RequestEngine from requests import HTTPError from assets.constants import error, service from assets.exceptions import TrackNotFound from assets.models import ows_track @pytest.fixture def fixture_track() -> dict[str, int]: """Fixture for track data.""" return {"tuid": 105, "product_id": 111} def test_clean_cached_tracks(fixture_track: dict[str, int]) -> None: """Test cleaning cached tracks.""" # ensure we start with an empty cache ows_track._cached_tracks = [] old_track = { "track_id": 0, "track": {}, "created": time.time() - ows_track.CACHE_TTL - 1, } ows_track._cached_tracks.append(old_track) ows_track._add_track_to_cache(fixture_track) ows_track._cached_tracks.append(old_track) ows_track._clean_cached_tracks() assert len(ows_track._cached_tracks) == 1 assert ows_track._cached_tracks[0]["track"] == fixture_track @pytest.mark.parametrize( "track_id, raised_exception, expected_raises, expected_message", [ (1, None, nullcontext(), {"tuid": 123}), ( 1, HTTPError(response=MagicMock(status_code=404)), pytest.raises(TrackNotFound), None, ), ( 1, HTTPError(response=MagicMock(status_code=400)), pytest.raises(HTTPError, check=lambda e: e.response.status_code == 400), None, ), ], ) def test_get_track_by_id( track_id: int, raised_exception: Exception | None, expected_raises: ContextManager[None], expected_message: Any, fixture_app: AppContext, mock_raise_for_status: MagicMock, ) -> None: """Test getting track by track id.""" path = service.OWS_TRACK_BY_TRACK_ID.format(track_id=track_id) mock_raise_for_status.side_effect = raised_exception mock_request.get(service.OWS_TRACK, path, expected_message) with expected_raises: response = ows_track.get_track_by_id(track_id) assert response == expected_message assert ows_track._cached_tracks[-1]["track"] == expected_message def test_get_track_by_id_from_cache( monkeypatch: pytest.MonkeyPatch, fixture_track: dict[str, int] ) -> None: """Test getting track by track id from cache.""" ows_track._add_track_to_cache(fixture_track) assert ows_track.get_track_by_id(fixture_track["tuid"]) == fixture_track @pytest.mark.parametrize( "raised_exception, expected_raises, expected_message", [ (None, nullcontext(), error.SUCCESS_CODE), ( HTTPError(response=MagicMock(status_code=404)), pytest.raises(HTTPError), None, ), ( HTTPError(response=MagicMock(status_code=500)), pytest.raises(HTTPError), None, ), ], ) def test_get_product_tracks( raised_exception: Exception | None, expected_raises: ContextManager[None], expected_message: Any, fixture_app: AppContext, mock_raise_for_status: MagicMock, ) -> None: """Test getting product tracks.""" product_id = 12321 path = "/product/12321/tracks/light" mock_raise_for_status.side_effect = raised_exception mock_request.get(service.OWS_TRACK, path, expected_message) with expected_raises: response = ows_track.get_tracks_by_product_id(product_id) assert response == expected_message assert mock_raise_for_status.mock_calls == [call()] def test_check_profile_track_access( fixture_app: AppContext, request_engine: RequestEngine, mock_raise_for_status: MagicMock, ) -> None: """Test check_profile_track_access.""" request_engine["ows-track"].add_spec( "HEAD", "/profile/uuid/abc/resource/track/id/10" ) ows_track.check_profile_track_access("abc", 10)