Replace new-deal MagicPlan trigger to use outcome=="surveyed" 🟥

This commit is contained in:
Daniel Roth 2026-05-12 08:57:24 +00:00
parent 5ed120b83b
commit f0300eb8ff
3 changed files with 39 additions and 44 deletions

View file

@ -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

View file

@ -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)

View file

@ -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