import pytest from pytest_mock import MockerFixture from src.errors import PermanentError, TransientError from src.ows_response import parse_json_response def _mock_resp(mocker: MockerFixture, status_code: int, json_body: object = None, text: str = "") -> object: resp = mocker.MagicMock() resp.status_code = status_code resp.text = text if json_body is not None: resp.json.return_value = json_body else: resp.json.side_effect = ValueError("no JSON") return resp def test_2xx_returns_parsed_json(mocker: MockerFixture) -> None: resp = _mock_resp(mocker, 200, {"key": "value"}) assert parse_json_response("ows-royalties", resp) == {"key": "value"} def test_4xx_raises_permanent_error(mocker: MockerFixture) -> None: resp = _mock_resp(mocker, 404, text="not found") with pytest.raises(PermanentError, match="ows-royalties.*404"): parse_json_response("ows-royalties", resp) def test_5xx_raises_transient_error(mocker: MockerFixture) -> None: resp = _mock_resp(mocker, 503, text="unavailable") with pytest.raises(TransientError, match="ows-royalties.*503"): parse_json_response("ows-royalties", resp) def test_non_json_raises_transient_error(mocker: MockerFixture) -> None: resp = _mock_resp(mocker, 200, text="not json") with pytest.raises(TransientError, match="non-JSON"): parse_json_response("ows-royalties", resp) def test_service_name_in_error_message(mocker: MockerFixture) -> None: resp = _mock_resp(mocker, 400, text="bad request") with pytest.raises(PermanentError, match="ows-project-manager"): parse_json_response("ows-project-manager", resp)