from contextlib import nullcontext from typing import ContextManager from unittest.mock import MagicMock import pytest from fastapi.testclient import TestClient from httpx import HTTPStatusError, Response from pytest_mock import MockerFixture from starlette.status import ( HTTP_200_OK, HTTP_404_NOT_FOUND, HTTP_500_INTERNAL_SERVER_ERROR, ) from delivery_metadata.clients.ows_track import get_instant_grats from delivery_metadata.clients.ows_track.instant_grats import InstantGrats from tests.unit.conftest import ( get_instant_grats_client_response_mock, ows_track_instant_grats_response_mock, ) @pytest.mark.asyncio @pytest.mark.parametrize( "test_description, mock_response, mock_raises, expected_result", [ ( "success request with response data", Response( status_code=HTTP_200_OK, request=MagicMock(), json=ows_track_instant_grats_response_mock(), ), nullcontext(), get_instant_grats_client_response_mock(), ), ( "success request with empty data", Response( status_code=HTTP_200_OK, request=MagicMock(), json={}, ), nullcontext(), {}, ), ( "404 response", Response( status_code=HTTP_404_NOT_FOUND, request=MagicMock(), ), nullcontext(), {}, ), ( "500 error response", Response( status_code=HTTP_500_INTERNAL_SERVER_ERROR, request=MagicMock(), ), pytest.raises( HTTPStatusError, check=lambda e: ( e.response.status_code == HTTP_500_INTERNAL_SERVER_ERROR ), ), None, ), ], ) async def test_get_instant_grats( test_description: str, mock_response: Response, mock_raises: ContextManager[None], expected_result: dict[int, set[InstantGrats]], mocker: MockerFixture, test_client: TestClient, ) -> None: client_mock = mocker.patch.object( test_client.app.state.ows_connector, # type: ignore[attr-defined] "get", return_value=mock_response, autospec=True, ) release_id = 4953147 with mock_raises: result = await get_instant_grats(release_id) assert result == expected_result client_mock.assert_called_once_with( service_name="ows-track", path=f"/product/{release_id}/tracks/grats", )