From 7e5dc1722e7246a8eb4459d687e79ffa597795b0 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Mon, 6 Jul 2026 15:59:27 +0000 Subject: [PATCH] =?UTF-8?q?A=20rate-limited=20HubSpot=20write=20is=20retri?= =?UTF-8?q?ed=20before=20succeeding=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- .../test_abri_log_job_orchestrator.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/orchestration/test_abri_log_job_orchestrator.py b/tests/orchestration/test_abri_log_job_orchestrator.py index 4673726d9..19c112280 100644 --- a/tests/orchestration/test_abri_log_job_orchestrator.py +++ b/tests/orchestration/test_abri_log_job_orchestrator.py @@ -292,3 +292,26 @@ def test_run_raises_a_write_back_error_scrubbed_of_the_hubspot_response_body( assert "VALIDATION_ERROR" in str(exc_info.value) assert "corr-abc-123" in str(exc_info.value) assert "Invalid value" not in rendered_traceback + + +def test_run_retries_a_rate_limited_hubspot_write_before_succeeding( + orchestrator: AbriLogJobOrchestrator, + mock_session: MagicMock, + sdk_client: MagicMock, + deal_database: FakeDealDatabase, +) -> None: + # Arrange + mock_session.post.return_value.content = _load_fixture( + "abri_relay_logjob_success_response.xml" + ) + rate_limited = DealsApiException(status=429, reason="Too Many Requests") + rate_limited.headers = {"x-hubspot-ratelimit-interval-milliseconds": "0"} + sdk_client.crm.deals.basic_api.update.side_effect = [rate_limited, MagicMock()] + + # Act + result = orchestrator.run(BOOKING) + + # Assert + assert result == LogJobSummary(deal_id=DEAL_ID, job_no="AD0226519") + assert sdk_client.crm.deals.basic_api.update.call_count == 2 + assert deal_database.recorded_job_nos == [(DEAL_ID, "AD0226519")]