import pytest from pytest_mock import MockerFixture from src import config from src.errors import PermanentError, TransientError from src.transfer_job import get_transfer_job _SUCCESS_BODY = {"originating_vendor_id": 10, "destination_vendor_id": 20, "status": "pending"} 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_happy_path_returns_vendor_ids(mocker: MockerFixture) -> None: mock_get = mocker.patch.object(config.ows_client, "get") mock_get.return_value = _mock_resp(mocker, 200, _SUCCESS_BODY) result = get_transfer_job(job_id=42) assert result == {"originating_vendor_id": 10, "destination_vendor_id": 20} mock_get.assert_called_once_with("ows-project-manager", path="/transfer/job/42") def test_4xx_raises_permanent_error(mocker: MockerFixture) -> None: mock_get = mocker.patch.object(config.ows_client, "get") mock_get.return_value = _mock_resp(mocker, 404, text="not found") with pytest.raises(PermanentError, match="404"): get_transfer_job(job_id=42) def test_5xx_raises_transient_error(mocker: MockerFixture) -> None: mock_get = mocker.patch.object(config.ows_client, "get") mock_get.return_value = _mock_resp(mocker, 500, text="server error") with pytest.raises(TransientError, match="500"): get_transfer_job(job_id=42) def test_missing_originating_vendor_id_raises_permanent_error(mocker: MockerFixture) -> None: mock_get = mocker.patch.object(config.ows_client, "get") mock_get.return_value = _mock_resp(mocker, 200, {"destination_vendor_id": 20}) with pytest.raises(PermanentError, match="originating_vendor_id"): get_transfer_job(job_id=42) def test_missing_destination_vendor_id_raises_permanent_error(mocker: MockerFixture) -> None: mock_get = mocker.patch.object(config.ows_client, "get") mock_get.return_value = _mock_resp(mocker, 200, {"originating_vendor_id": 10}) with pytest.raises(PermanentError, match="destination_vendor_id"): get_transfer_job(job_id=42) def test_non_int_vendor_id_raises_permanent_error(mocker: MockerFixture) -> None: mock_get = mocker.patch.object(config.ows_client, "get") mock_get.return_value = _mock_resp(mocker, 200, {"originating_vendor_id": "abc", "destination_vendor_id": 20}) with pytest.raises(PermanentError, match="originating_vendor_id"): get_transfer_job(job_id=42)