diff --git a/tests/infrastructure/abri/test_abri_client.py b/tests/infrastructure/abri/test_abri_client.py index 7c1d6ff99..fff0a3865 100644 --- a/tests/infrastructure/abri/test_abri_client.py +++ b/tests/infrastructure/abri/test_abri_client.py @@ -172,6 +172,76 @@ def test_abandon_job_returns_rejection_from_the_shared_failure_envelope( ) +# --- abandon_job: ambiguous responses are retriable, never success or rejection --- + + +def test_abandon_job_raises_retriable_parse_error_on_a_malformed_response_body( + client: AbriClient, mock_session: MagicMock +) -> None: + # Arrange + mock_session.post.return_value.content = b"not xml at all <<<" + + # Act / Assert + with pytest.raises(AbriResponseParseError): + client.abandon_job(_spec_example_abandon_request()) + + +@pytest.mark.parametrize( + "body", + [ + # A cancellation collection with no JobCancelled and no ErrorDetails: + # genuinely ambiguous, so a dead job never churns as success/rejection. + b"", + b"", + # JobCancelled present but missing its job_no. + b"", + # ErrorDetails present but missing code or message. + b'', + b'', + # The shared envelope, but not a failure document. + b"true", + b"", + ], +) +def test_abandon_job_raises_retriable_parse_error_on_an_unexpectedly_shaped_response( + client: AbriClient, mock_session: MagicMock, body: bytes +) -> None: + # Arrange + mock_session.post.return_value.content = body + + # Act / Assert + with pytest.raises(AbriResponseParseError): + client.abandon_job(_spec_example_abandon_request()) + + +# --- abandon_job: transport failures --- + + +def test_abandon_job_raises_transport_error_on_http_error_status( + client: AbriClient, mock_session: MagicMock +) -> None: + # Arrange + mock_session.post.return_value.content = b"Server Error" + mock_session.post.return_value.raise_for_status.side_effect = requests.HTTPError( + "500 Server Error" + ) + + # Act / Assert + with pytest.raises(AbriTransportError): + client.abandon_job(_spec_example_abandon_request()) + + +def test_abandon_job_raises_transport_error_when_the_relay_is_unreachable( + client: AbriClient, mock_session: MagicMock +) -> None: + # Arrange + mock_session.post.side_effect = requests.ConnectionError("connection refused") + + # Act / Assert + with pytest.raises(AbriTransportError): + client.abandon_job(_spec_example_abandon_request()) + + # --- log_job: rejection ---