diff --git a/orchestration/abri_orchestrator.py b/orchestration/abri_orchestrator.py index 9441fdd66..bf833ac42 100644 --- a/orchestration/abri_orchestrator.py +++ b/orchestration/abri_orchestrator.py @@ -65,7 +65,20 @@ class TenantDataSyncSummary: vulnerable_contact_count: int -TenantDataSyncResult = Union[TenantDataSyncSummary, AbriRequestRejected] +@dataclass(frozen=True) +class PropertyReportedVoid: + """Abri reported no live tenancy: no contacts to create for the deal. + + A normal outcome, not a failure — an empty property has no signatories to + sync, so the flow completes rather than failing the task. + """ + + place_ref: PlaceRef + + +TenantDataSyncResult = Union[ + TenantDataSyncSummary, PropertyReportedVoid, AbriRequestRejected +] class TenantDataSyncError(Exception): diff --git a/tests/orchestration/test_abri_orchestrator_tenant_data_sync.py b/tests/orchestration/test_abri_orchestrator_tenant_data_sync.py index b5bd17728..a7368ecb2 100644 --- a/tests/orchestration/test_abri_orchestrator_tenant_data_sync.py +++ b/tests/orchestration/test_abri_orchestrator_tenant_data_sync.py @@ -20,6 +20,7 @@ from infrastructure.abri.errors import AbriResponseParseError, AbriTransportErro from orchestration.abri_orchestrator import ( TenantDataSyncError, AbriOrchestrator, + PropertyReportedVoid, TenantDataSyncSummary, ) @@ -539,3 +540,24 @@ def test_sync_tenant_data_retries_a_rate_limited_hubspot_call_before_succeeding( vulnerable_contact_count=0, ) assert sdk_client.crm.contacts.basic_api.create.call_count == 2 + + +# --- void property: no tenancy to sync, and not a failure --- + + +def test_sync_tenant_data_reports_the_property_void_and_creates_no_contacts( + orchestrator: AbriOrchestrator, + mock_session: MagicMock, + sdk_client: MagicMock, +) -> None: + # Arrange: Abri's agreed signal that the place is known to be empty. + mock_session.post.return_value.content = _load_fixture( + "abri_relay_getscstenantdata_notenancyfound_response.xml" + ) + + # Act + result = orchestrator.sync_tenant_data(PLACE_REF, deal_id=DEAL_ID) + + # Assert + assert result == PropertyReportedVoid(place_ref=PLACE_REF) + assert sdk_client.crm.contacts.mock_calls == []