From f0300eb8ff4749da93a49a259c88f448ab7dee08 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Tue, 12 May 2026 08:57:24 +0000 Subject: [PATCH] =?UTF-8?q?Replace=20new-deal=20MagicPlan=20trigger=20to?= =?UTF-8?q?=20use=20outcome=3D=3D"surveyed"=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- etl/hubspot/hubspot_deal_differ.py | 16 ++--- .../hubspot/tests/test_scraper_handler.py | 65 +++++++++---------- pytest.ini | 2 +- 3 files changed, 39 insertions(+), 44 deletions(-) rename backend/hubspot_trigger_orchestrator/tests/test_orchestrator.py => etl/hubspot/tests/test_scraper_handler.py (61%) diff --git a/etl/hubspot/hubspot_deal_differ.py b/etl/hubspot/hubspot_deal_differ.py index 724a3e68..da0072c1 100644 --- a/etl/hubspot/hubspot_deal_differ.py +++ b/etl/hubspot/hubspot_deal_differ.py @@ -162,6 +162,14 @@ class HubspotDealDiffer: return False + @staticmethod + def check_for_magicplan_trigger( + new_deal: Dict[str, str], old_deal: HubspotDealData + ) -> bool: + new_outcome = (new_deal.get("outcome") or "").lower() + old_outcome = (old_deal.outcome or "").lower() + return new_outcome == "surveyed" and old_outcome != "surveyed" + @staticmethod def _has_valid_pashub_link(new_pashub_link: str) -> bool: return bool(new_pashub_link) @@ -194,14 +202,6 @@ class HubspotDealDiffer: and new_status != old_deal.design_status ) - @staticmethod - def check_for_magicplan_trigger( - new_deal: Dict[str, str], old_deal: HubspotDealData - ) -> bool: - new_outcome = (new_deal.get("outcome") or "").lower() - old_outcome = (old_deal.outcome or "").lower() - return new_outcome == "surveyed" and old_outcome != "surveyed" - @staticmethod def _lodgement_completed( new_deal: Dict[str, str], old_deal: HubspotDealData diff --git a/backend/hubspot_trigger_orchestrator/tests/test_orchestrator.py b/etl/hubspot/tests/test_scraper_handler.py similarity index 61% rename from backend/hubspot_trigger_orchestrator/tests/test_orchestrator.py rename to etl/hubspot/tests/test_scraper_handler.py index 6d18c4b4..e2f80d07 100644 --- a/backend/hubspot_trigger_orchestrator/tests/test_orchestrator.py +++ b/etl/hubspot/tests/test_scraper_handler.py @@ -3,37 +3,28 @@ import uuid from typing import Any, Dict, Optional from unittest.mock import MagicMock, patch -import pytest - from backend.app.db.models.hubspot_deal_data import HubspotDealData from etl.hubspot.scripts.scraper.main import handler -COORDINATION_COMPLETE = "(v1) ioe/mtp complete" DEAL_NAME = "123 Main Street" UPRN = "12345678" DEAL_ID = "999" MAGICPLAN_QUEUE_URL = "https://sqs.eu-west-2.amazonaws.com/123/magic-plan-dev" -def make_hubspot_deal( - coordination_status: Optional[str] = None, **kwargs: Any -) -> Dict[str, Any]: - deal: Dict[str, Any] = { +def make_hubspot_deal(**kwargs: Any) -> Dict[str, Any]: + return { "hs_object_id": DEAL_ID, "dealname": DEAL_NAME, "pashub_link": None, **kwargs, } - if coordination_status is not None: - deal["coordination_status__stage_1_"] = coordination_status - return deal -def make_db_deal(coordination_status: Optional[str] = None, **kwargs: Any) -> HubspotDealData: +def make_db_deal(**kwargs: Any) -> HubspotDealData: return HubspotDealData( id=uuid.uuid4(), deal_id=DEAL_ID, - coordination_status=coordination_status, **kwargs, ) @@ -68,14 +59,14 @@ def run_handler( return mock_sqs -# ======================= -# NEW DEAL PATH -# ======================= +# ==================================== +# NEW DEAL PATH - MagicPlan trigger +# ==================================== -def test_new_deal_in_coordination_complete__sends_sqs_message() -> None: +def test_new_deal__outcome_is_surveyed__triggers_magicplan() -> None: # Arrange - hubspot_deal = make_hubspot_deal(coordination_status=COORDINATION_COMPLETE) + hubspot_deal = make_hubspot_deal(outcome="surveyed") listing = {"national_uprn": UPRN} # Act @@ -84,13 +75,15 @@ def test_new_deal_in_coordination_complete__sends_sqs_message() -> None: # Assert mock_sqs.send_message.assert_called_once_with( QueueUrl=MAGICPLAN_QUEUE_URL, - MessageBody=json.dumps({"address": DEAL_NAME, "uprn": UPRN}), + MessageBody=json.dumps( + {"address": DEAL_NAME, "hubspot_deal_id": DEAL_ID, "uprn": UPRN} + ), ) -def test_new_deal_not_in_coordination_complete__no_sqs_message() -> None: +def test_new_deal__outcome_is_not_surveyed__does_not_trigger_magicplan() -> None: # Arrange - hubspot_deal = make_hubspot_deal(coordination_status="in progress") + hubspot_deal = make_hubspot_deal(outcome="assessed") # Act mock_sqs = run_handler(hubspot_deal=hubspot_deal, db_deal=None, listing=None) @@ -99,9 +92,9 @@ def test_new_deal_not_in_coordination_complete__no_sqs_message() -> None: mock_sqs.send_message.assert_not_called() -def test_new_deal_with_no_listing__uprn_is_none_in_message() -> None: +def test_new_deal__outcome_is_surveyed__no_listing__magicplan_message_uprn_is_null() -> None: # Arrange - hubspot_deal = make_hubspot_deal(coordination_status=COORDINATION_COMPLETE) + hubspot_deal = make_hubspot_deal(outcome="surveyed") # Act mock_sqs = run_handler(hubspot_deal=hubspot_deal, db_deal=None, listing=None) @@ -109,19 +102,21 @@ def test_new_deal_with_no_listing__uprn_is_none_in_message() -> None: # Assert mock_sqs.send_message.assert_called_once_with( QueueUrl=MAGICPLAN_QUEUE_URL, - MessageBody=json.dumps({"address": DEAL_NAME, "uprn": None}), + MessageBody=json.dumps( + {"address": DEAL_NAME, "hubspot_deal_id": DEAL_ID, "uprn": None} + ), ) -# ======================= -# EXISTING DEAL PATH -# ======================= +# ========================================== +# EXISTING DEAL PATH - MagicPlan trigger +# ========================================== -def test_existing_deal_transitions_to_coordination_complete__sends_sqs_message() -> None: +def test_existing_deal__outcome_transitions_to_surveyed__triggers_magicplan() -> None: # Arrange - db_deal = make_db_deal(coordination_status="in progress") - hubspot_deal = make_hubspot_deal(coordination_status=COORDINATION_COMPLETE) + db_deal = make_db_deal(outcome="assessed") + hubspot_deal = make_hubspot_deal(outcome="surveyed") listing = {"national_uprn": UPRN} # Act @@ -130,16 +125,16 @@ def test_existing_deal_transitions_to_coordination_complete__sends_sqs_message() # Assert mock_sqs.send_message.assert_called_once_with( QueueUrl=MAGICPLAN_QUEUE_URL, - MessageBody=json.dumps({"address": DEAL_NAME, "uprn": UPRN}), + MessageBody=json.dumps( + {"address": DEAL_NAME, "hubspot_deal_id": DEAL_ID, "uprn": UPRN} + ), ) -def test_existing_deal_already_in_coordination_complete_unrelated_change__no_sqs_message() -> None: +def test_existing_deal__outcome_already_surveyed__unrelated_change__does_not_trigger_magicplan() -> None: # Arrange - db_deal = make_db_deal(coordination_status=COORDINATION_COMPLETE, dealname="Old Name") - hubspot_deal = make_hubspot_deal( - coordination_status=COORDINATION_COMPLETE, dealname="New Name" - ) + db_deal = make_db_deal(outcome="surveyed", dealname="Old Name") + hubspot_deal = make_hubspot_deal(outcome="surveyed", dealname="New Name") # Act mock_sqs = run_handler(hubspot_deal=hubspot_deal, db_deal=db_deal, listing=None) diff --git a/pytest.ini b/pytest.ini index 398c5b71..e2a4a25d 100644 --- a/pytest.ini +++ b/pytest.ini @@ -3,6 +3,6 @@ pythonpath = . log_cli = true log_cli_level = INFO addopts = --cov-report term-missing --cov=etl/epc --cov=recommendations --cov=backend --cov=etl/epc_clean --cov=etl/spatial -testpaths = recommendations/tests backend/tests etl/epc/tests etl/epc_clean/tests etl/spatial/tests backend/condition/tests backend/address2UPRN/tests backend/onboarders/tests backend/categorisation/tests backend/export/tests etl/hubspot/tests backend/hubspot_trigger_orchestrator/tests datatypes/epc/schema/tests datatypes/epc/surveys/tests datatypes/epc/domain/tests backend/ecmk_fetcher/tests/ backend/pashub_fetcher/tests backend/documents_parser/tests backend/magic_plan/tests datatypes/magicplan/api/tests datatypes/magicplan/domain/tests backend/app/db/functions/tests +testpaths = recommendations/tests backend/tests etl/epc/tests etl/epc_clean/tests etl/spatial/tests backend/condition/tests backend/address2UPRN/tests backend/onboarders/tests backend/categorisation/tests backend/export/tests etl/hubspot/tests datatypes/epc/schema/tests datatypes/epc/surveys/tests datatypes/epc/domain/tests backend/ecmk_fetcher/tests/ backend/pashub_fetcher/tests backend/documents_parser/tests backend/magic_plan/tests datatypes/magicplan/api/tests datatypes/magicplan/domain/tests backend/app/db/functions/tests markers = integration: mark a test as an integration test