Model/etl/hubspot/tests/test_hubspot_deal_differ.py
Daniel Roth a3985389ab The deal row names the job number client_booking_reference, matching HubSpot and the schema 🟪
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 12:43:40 +00:00

1313 lines
29 KiB
Python

from datetime import datetime, timezone
from typing import Any, Dict
import uuid
import pytest
from backend.app.db.models.hubspot_deal_data import HubspotDealData
from etl.hubspot.hubspot_deal_differ import HubspotDealDiffer
from etl.hubspot.project_data import ProjectData
BASE_TIME = datetime(2025, 12, 1, 12, 0, 0)
ABRI_PROJECT_CODE = (
"[Abri Stock Condition - Privately Funded - 062026 - 1247536318670]"
)
def make_old_deal(**overrides: Any) -> HubspotDealData:
return HubspotDealData(
id=overrides.get("id", uuid.uuid4()),
deal_id="1",
created_at=BASE_TIME,
updated_at=BASE_TIME,
**{k: v for k, v in overrides.items() if k != "id"},
)
def make_new_deal(deal_id: uuid.UUID, **overrides: Any) -> Dict[str, str]:
return {
"id": str(deal_id),
"deal_id": "1",
"created_at": BASE_TIME.isoformat(),
"updated_at": datetime(2025, 12, 1, 12, 30, 0).isoformat(),
**overrides,
}
# ====================
# PASHUB TRIGGER TESTS
# ====================
@pytest.mark.parametrize(
"new_overrides,expected",
[
({"outcome_notes": "test note"}, False),
],
)
def test_pashub_trigger__outcome_note_added__returns_false(
new_overrides: Dict[str, str],
expected: bool,
) -> None:
deal_id = uuid.uuid4()
old_deal = make_old_deal(id=deal_id)
new_deal = make_new_deal(deal_id, **new_overrides)
assert (
HubspotDealDiffer.check_for_pashub_trigger(
new_deal=new_deal,
old_deal=old_deal,
)
== expected
)
@pytest.mark.parametrize(
"old_overrides,new_overrides,expected",
[
(
{"pashub_link": "www.google.co.uk"},
{"pashub_link": "www.bbc.co.uk"},
True,
),
],
)
def test_pashub_trigger__pashub_link_changed__returns_true(
old_overrides: Dict[str, str],
new_overrides: Dict[str, str],
expected: bool,
) -> None:
deal_id = uuid.uuid4()
old_deal = make_old_deal(id=deal_id, **old_overrides)
new_deal = make_new_deal(deal_id, **new_overrides)
assert (
HubspotDealDiffer.check_for_pashub_trigger(
new_deal=new_deal,
old_deal=old_deal,
)
== expected
)
@pytest.mark.parametrize(
"coordination_status,expected",
[
("(v1) ioe/mtp complete", True),
("(v2) ioe/mtp complete", True),
],
)
def test_pashub_trigger__coordination_completed_and_pashub_link_set__returns_true(
coordination_status: str,
expected: bool,
) -> None:
deal_id = uuid.uuid4()
old_deal = make_old_deal(
id=deal_id,
pashub_link="www.google.co.uk",
coordination_status="random",
)
new_deal = make_new_deal(
deal_id,
pashub_link="www.google.co.uk",
**{"coordination_status__stage_1_": coordination_status},
)
assert (
HubspotDealDiffer.check_for_pashub_trigger(
new_deal=new_deal,
old_deal=old_deal,
)
== expected
)
def test_pashub_trigger__coordination_completed_and_pashub_link_not_set__returns_false() -> (
None
):
deal_id = uuid.uuid4()
old_deal = make_old_deal(
id=deal_id,
coordination_status="random",
)
new_deal = make_new_deal(
deal_id,
coordination_status="v2 ioe/mtp complete",
)
assert (
HubspotDealDiffer.check_for_pashub_trigger(
new_deal=new_deal,
old_deal=old_deal,
)
is False
)
def test_pashub_trigger__design_completed_and_pashub_link_set__returns_true() -> None:
deal_id = uuid.uuid4()
old_deal = make_old_deal(
id=deal_id,
pashub_link="www.google.co.uk",
)
new_deal = make_new_deal(
deal_id,
pashub_link="www.google.co.uk",
retrofit_design_status="uploaded",
)
assert (
HubspotDealDiffer.check_for_pashub_trigger(
new_deal=new_deal,
old_deal=old_deal,
)
is True
)
def test_pashub_trigger__design_completed_and_pashub_link_not_set__returns_false() -> (
None
):
deal_id = uuid.uuid4()
old_deal = make_old_deal(id=deal_id)
new_deal = make_new_deal(
deal_id,
retrofit_design_status="uploaded",
)
assert (
HubspotDealDiffer.check_for_pashub_trigger(
new_deal=new_deal,
old_deal=old_deal,
)
is False
)
@pytest.mark.parametrize(
"lodgement_status,expected",
[
("lodgement complete", True),
("measures lodged", True),
],
)
def test_pashub_trigger__lodgement_completed_and_pashub_link_set__returns_true(
lodgement_status: str,
expected: bool,
) -> None:
deal_id = uuid.uuid4()
old_deal = make_old_deal(
id=deal_id,
pashub_link="www.google.co.uk",
)
new_deal = make_new_deal(
deal_id,
pashub_link="www.google.co.uk",
lodgement_status=lodgement_status,
)
assert (
HubspotDealDiffer.check_for_pashub_trigger(
new_deal=new_deal,
old_deal=old_deal,
)
== expected
)
def test_pashub_trigger__lodgement_completed_and_pashub_link_not_set__returns_false() -> (
None
):
deal_id = uuid.uuid4()
old_deal = make_old_deal(id=deal_id)
new_deal = make_new_deal(
deal_id,
design_status="lodgement complete",
)
assert (
HubspotDealDiffer.check_for_pashub_trigger(
new_deal=new_deal,
old_deal=old_deal,
)
is False
)
def test_pashub_trigger__coordination_design_lodgement_not_completed_and_pashub_link_set__returns_false() -> (
None
):
deal_id = uuid.uuid4()
old_deal = make_old_deal(
id=deal_id,
pashub_link="www.google.co.uk",
)
new_deal = make_new_deal(
deal_id,
pashub_link="www.google.co.uk",
coordination_status="not uploaded",
design_status="not uploaded",
lodgement_status="not uploaded",
)
assert (
HubspotDealDiffer.check_for_pashub_trigger(
new_deal=new_deal,
old_deal=old_deal,
)
is False
)
# ==========================
# MAGICPLAN TRIGGER TESTS
# ==========================
def test_magicplan_trigger__outcome_transitions_to_surveyed__returns_true() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(id=deal_id, outcome="assessed")
new_deal = make_new_deal(deal_id, outcome="surveyed")
# Act
result = HubspotDealDiffer.check_for_magicplan_trigger(
new_deal=new_deal,
old_deal=old_deal,
)
# Assert
assert result is True
def test_magicplan_trigger__outcome_already_surveyed__returns_false() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(id=deal_id, outcome="surveyed")
new_deal = make_new_deal(deal_id, outcome="surveyed")
# Act
result = HubspotDealDiffer.check_for_magicplan_trigger(
new_deal=new_deal,
old_deal=old_deal,
)
# Assert
assert result is False
def test_magicplan_trigger__outcome_transitions_to_non_surveyed__returns_false() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(id=deal_id, outcome="assessed")
new_deal = make_new_deal(deal_id, outcome="assessed")
# Act
result = HubspotDealDiffer.check_for_magicplan_trigger(
new_deal=new_deal,
old_deal=old_deal,
)
# Assert
assert result is False
def test_magicplan_trigger__outcome_surveyed_uppercase__returns_true() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(id=deal_id, outcome="assessed")
new_deal = make_new_deal(deal_id, outcome="SURVEYED")
# Act
result = HubspotDealDiffer.check_for_magicplan_trigger(
new_deal=new_deal,
old_deal=old_deal,
)
# Assert
assert result is True
# ==============================
# ABRI JOB LOGGING TRIGGER TESTS
# ==============================
def test_abri_job_logging__date_first_set_on_abri_deal__returns_true() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code=ABRI_PROJECT_CODE,
confirmed_survey_date=None,
)
new_deal = make_new_deal(
deal_id,
project_code=ABRI_PROJECT_CODE,
confirmed_survey_date="2026-07-15",
)
# Act
result = HubspotDealDiffer.check_for_abri_job_logging(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is True
def test_abri_job_logging__date_already_set__returns_false() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code=ABRI_PROJECT_CODE,
confirmed_survey_date=datetime(2026, 7, 1, tzinfo=timezone.utc),
)
new_deal = make_new_deal(
deal_id,
project_code=ABRI_PROJECT_CODE,
confirmed_survey_date="2026-07-15",
)
# Act
result = HubspotDealDiffer.check_for_abri_job_logging(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is False
def test_abri_job_logging__non_abri_project_code__returns_false() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code="Southern Retrofit",
confirmed_survey_date=None,
)
new_deal = make_new_deal(
deal_id,
project_code="Southern Retrofit",
confirmed_survey_date="2026-07-15",
)
# Act
result = HubspotDealDiffer.check_for_abri_job_logging(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is False
def test_abri_job_logging__project_code_cased_differently__returns_true() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code=ABRI_PROJECT_CODE.upper(),
confirmed_survey_date=None,
)
new_deal = make_new_deal(
deal_id,
project_code=ABRI_PROJECT_CODE.upper(),
confirmed_survey_date="2026-07-15",
)
# Act
result = HubspotDealDiffer.check_for_abri_job_logging(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is True
def test_abri_job_logging__real_portal_project_code__returns_true() -> None:
# The code carried by every Abri stock-condition deal in the portal
# (verified 2026-07-07); these deals have no project association, so the
# project_code fallback is the branch that must fire in production.
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code="[Abri Stock Condition - Privately Funded - 062026 - 1247536318670]",
confirmed_survey_date=None,
)
new_deal = make_new_deal(
deal_id,
project_code="[Abri Stock Condition - Privately Funded - 062026 - 1247536318670]",
confirmed_survey_date="2026-07-15",
)
# Act
result = HubspotDealDiffer.check_for_abri_job_logging(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is True
@pytest.mark.parametrize(
"new_overrides",
[
{},
{"confirmed_survey_date": ""},
{"confirmed_survey_date": "not-a-date"},
],
)
def test_abri_job_logging__no_parseable_new_date__returns_false(
new_overrides: Dict[str, str],
) -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code=ABRI_PROJECT_CODE,
confirmed_survey_date=None,
)
new_deal = make_new_deal(
deal_id,
project_code=ABRI_PROJECT_CODE,
**new_overrides,
)
# Act
result = HubspotDealDiffer.check_for_abri_job_logging(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is False
def test_abri_job_logging__associated_abri_project_id__returns_true() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code="Southern Retrofit",
confirmed_survey_date=None,
)
new_deal = make_new_deal(
deal_id,
project_code="Southern Retrofit",
confirmed_survey_date="2026-07-15",
)
new_project = ProjectData(
project_id=HubspotDealDiffer.ABRI_CONDITION_ASSOCIATED_PROJECT_ID,
name="Abri Condition",
)
# Act
result = HubspotDealDiffer.check_for_abri_job_logging(
new_deal=new_deal,
new_project=new_project,
old_deal=old_deal,
)
# Assert
assert result is True
def test_abri_job_logging__non_abri_project_id_with_abri_code__returns_false() -> (
None
):
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code=ABRI_PROJECT_CODE,
confirmed_survey_date=None,
)
new_deal = make_new_deal(
deal_id,
project_code=ABRI_PROJECT_CODE,
confirmed_survey_date="2026-07-15",
)
new_project = ProjectData(project_id="999999", name="Southern Retrofit")
# Act
result = HubspotDealDiffer.check_for_abri_job_logging(
new_deal=new_deal,
new_project=new_project,
old_deal=old_deal,
)
# Assert
assert result is False
# ================================
# ABRI JOB AMENDMENT TRIGGER TESTS
# ================================
def test_abri_job_amendment__date_changed_on_abri_deal__returns_true() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code=ABRI_PROJECT_CODE,
confirmed_survey_date=datetime(2026, 7, 1, tzinfo=timezone.utc),
)
new_deal = make_new_deal(
deal_id,
project_code=ABRI_PROJECT_CODE,
confirmed_survey_date="2026-07-15",
)
# Act
result = HubspotDealDiffer.check_for_abri_job_amendment(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is True
def test_abri_job_amendment__non_abri_deal__returns_false() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code="Southern Retrofit",
confirmed_survey_date=datetime(2026, 7, 1, tzinfo=timezone.utc),
)
new_deal = make_new_deal(
deal_id,
project_code="Southern Retrofit",
confirmed_survey_date="2026-07-15",
)
# Act
result = HubspotDealDiffer.check_for_abri_job_amendment(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is False
def test_abri_job_amendment__date_and_time_unchanged__returns_false() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code=ABRI_PROJECT_CODE,
confirmed_survey_date=datetime(2026, 7, 15, tzinfo=timezone.utc),
confirmed_survey_time="09:30",
)
new_deal = make_new_deal(
deal_id,
project_code=ABRI_PROJECT_CODE,
confirmed_survey_date="2026-07-15",
confirmed_survey_time="09:30",
)
# Act
result = HubspotDealDiffer.check_for_abri_job_amendment(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is False
def test_abri_job_amendment__time_changed_on_abri_deal__returns_true() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code=ABRI_PROJECT_CODE,
confirmed_survey_date=datetime(2026, 7, 15, tzinfo=timezone.utc),
confirmed_survey_time="09:30",
)
new_deal = make_new_deal(
deal_id,
project_code=ABRI_PROJECT_CODE,
confirmed_survey_date="2026-07-15",
confirmed_survey_time="14:00",
)
# Act
result = HubspotDealDiffer.check_for_abri_job_amendment(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is True
def test_abri_job_amendment__date_first_set_on_abri_deal__returns_false() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code=ABRI_PROJECT_CODE,
confirmed_survey_date=None,
)
new_deal = make_new_deal(
deal_id,
project_code=ABRI_PROJECT_CODE,
confirmed_survey_date="2026-07-15",
)
# Act
result = HubspotDealDiffer.check_for_abri_job_amendment(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is False
# ====================================
# ABRI TENANT DATA FETCH TRIGGER TESTS
# ====================================
def test_abri_tenant_data_fetch__commencement_date_first_set_on_abri_deal__returns_true() -> (
None
):
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code=ABRI_PROJECT_CODE,
expected_commencement_date=None,
)
new_deal = make_new_deal(
deal_id,
project_code=ABRI_PROJECT_CODE,
expected_commencement_date="2026-08-01",
)
# Act
result = HubspotDealDiffer.check_for_abri_tenant_data_fetch(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is True
def test_abri_tenant_data_fetch__non_abri_deal__returns_false() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code="Southern Retrofit",
expected_commencement_date=None,
)
new_deal = make_new_deal(
deal_id,
project_code="Southern Retrofit",
expected_commencement_date="2026-08-01",
)
# Act
result = HubspotDealDiffer.check_for_abri_tenant_data_fetch(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is False
def test_abri_tenant_data_fetch__commencement_date_already_set__returns_false() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code=ABRI_PROJECT_CODE,
expected_commencement_date=datetime(2026, 7, 1, tzinfo=timezone.utc),
)
new_deal = make_new_deal(
deal_id,
project_code=ABRI_PROJECT_CODE,
expected_commencement_date="2026-08-01",
)
# Act
result = HubspotDealDiffer.check_for_abri_tenant_data_fetch(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is False
@pytest.mark.parametrize(
"new_overrides",
[
{},
{"expected_commencement_date": ""},
{"expected_commencement_date": "not-a-date"},
],
)
def test_abri_tenant_data_fetch__no_parseable_new_commencement_date__returns_false(
new_overrides: Dict[str, str],
) -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code=ABRI_PROJECT_CODE,
expected_commencement_date=None,
)
new_deal = make_new_deal(
deal_id,
project_code=ABRI_PROJECT_CODE,
**new_overrides,
)
# Act
result = HubspotDealDiffer.check_for_abri_tenant_data_fetch(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is False
def test_abri_tenant_data_fetch__associated_abri_project_id__returns_true() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code="Southern Retrofit",
expected_commencement_date=None,
)
new_deal = make_new_deal(
deal_id,
project_code="Southern Retrofit",
expected_commencement_date="2026-08-01",
)
new_project = ProjectData(
project_id=HubspotDealDiffer.ABRI_CONDITION_ASSOCIATED_PROJECT_ID,
name="Abri Condition",
)
# Act
result = HubspotDealDiffer.check_for_abri_tenant_data_fetch(
new_deal=new_deal,
new_project=new_project,
old_deal=old_deal,
)
# Assert
assert result is True
def test_abri_tenant_data_fetch__non_abri_project_id_with_abri_code__returns_false() -> (
None
):
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code=ABRI_PROJECT_CODE,
expected_commencement_date=None,
)
new_deal = make_new_deal(
deal_id,
project_code=ABRI_PROJECT_CODE,
expected_commencement_date="2026-08-01",
)
new_project = ProjectData(project_id="999999", name="Southern Retrofit")
# Act
result = HubspotDealDiffer.check_for_abri_tenant_data_fetch(
new_deal=new_deal,
new_project=new_project,
old_deal=old_deal,
)
# Assert
assert result is False
# ====================================
# ABRI DEAL ABANDONMENT TRIGGER TESTS
# ====================================
def test_abri_deal_abandonment__third_attempt_with_negative_outcome__returns_true() -> (
None
):
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code=ABRI_PROJECT_CODE,
outcome=None,
)
new_deal = make_new_deal(
deal_id,
project_code=ABRI_PROJECT_CODE,
number_of_attempts="3",
outcome="No Answer",
)
# Act
result = HubspotDealDiffer.check_for_abri_deal_abandonment(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is True
def test_abri_deal_abandonment__non_abri_deal__returns_false() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code="Southern Retrofit",
outcome=None,
)
new_deal = make_new_deal(
deal_id,
project_code="Southern Retrofit",
number_of_attempts="3",
outcome="No Answer",
)
# Act
result = HubspotDealDiffer.check_for_abri_deal_abandonment(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is False
@pytest.mark.parametrize(
"new_overrides",
[
{"number_of_attempts": "2"},
{"number_of_attempts": ""},
{"number_of_attempts": "not-a-number"},
{},
],
)
def test_abri_deal_abandonment__fewer_than_three_parseable_attempts__returns_false(
new_overrides: Dict[str, str],
) -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code=ABRI_PROJECT_CODE,
outcome=None,
)
new_deal = make_new_deal(
deal_id,
project_code=ABRI_PROJECT_CODE,
outcome="No Answer",
**new_overrides,
)
# Act
result = HubspotDealDiffer.check_for_abri_deal_abandonment(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is False
@pytest.mark.parametrize(
"new_overrides",
[
{"outcome": "Surveyed"},
{"outcome": ""},
{},
],
)
def test_abri_deal_abandonment__outcome_not_negative__returns_false(
new_overrides: Dict[str, str],
) -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code=ABRI_PROJECT_CODE,
outcome=None,
)
new_deal = make_new_deal(
deal_id,
project_code=ABRI_PROJECT_CODE,
number_of_attempts="3",
**new_overrides,
)
# Act
result = HubspotDealDiffer.check_for_abri_deal_abandonment(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is False
@pytest.mark.parametrize(
"outcome",
[
"No Answer",
"Cancelled",
"No Show",
"Tenant Refusal",
"Not Viable",
"NO ANSWER",
],
)
def test_abri_deal_abandonment__each_negative_outcome__returns_true(
outcome: str,
) -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code=ABRI_PROJECT_CODE,
outcome=None,
)
new_deal = make_new_deal(
deal_id,
project_code=ABRI_PROJECT_CODE,
number_of_attempts="3",
outcome=outcome,
)
# Act
result = HubspotDealDiffer.check_for_abri_deal_abandonment(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is True
def test_abri_deal_abandonment__deal_already_abandoned__returns_false() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
project_code=ABRI_PROJECT_CODE,
number_of_attempts="3",
outcome="No Answer",
)
new_deal = make_new_deal(
deal_id,
project_code=ABRI_PROJECT_CODE,
number_of_attempts="4",
outcome="No Answer",
)
# Act
result = HubspotDealDiffer.check_for_abri_deal_abandonment(
new_deal=new_deal,
new_project=None,
old_deal=old_deal,
)
# Assert
assert result is False
# =======================
# DB UPDATE TRIGGER TESTS
# =======================
def test_db_update_trigger__no_changes__returns_false() -> None:
deal_id = uuid.uuid4()
old_deal = make_old_deal(
id=deal_id,
dealname="Test Deal",
dealstage="stage_1",
outcome="won",
)
new_deal = make_new_deal(
deal_id,
hs_object_id="1",
dealname="Test Deal",
dealstage="stage_1",
outcome="won",
)
result = HubspotDealDiffer.check_for_db_update_trigger(
new_deal=new_deal,
new_company=None,
new_listing=None,
old_deal=old_deal,
)
assert result is False
def test_db_update_trigger__dealname_changed__returns_true() -> None:
deal_id = uuid.uuid4()
old_deal = make_old_deal(
id=deal_id,
dealname="Old Name",
)
new_deal = make_new_deal(
deal_id,
hs_object_id="1",
dealname="New Name",
)
result = HubspotDealDiffer.check_for_db_update_trigger(
new_deal=new_deal,
new_company=None,
new_listing=None,
old_deal=old_deal,
)
assert result is True
def test_db_update_trigger__number_of_attempts_changed__returns_true() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
number_of_attempts="2",
)
new_deal = make_new_deal(
deal_id,
hs_object_id="1",
number_of_attempts="3",
)
# Act
result = HubspotDealDiffer.check_for_db_update_trigger(
new_deal=new_deal,
new_company=None,
new_listing=None,
old_deal=old_deal,
)
# Assert
assert result is True
def test_db_update_trigger__company_changed__returns_true() -> None:
deal_id = uuid.uuid4()
old_deal = make_old_deal(
id=deal_id,
company_id="old_company",
)
new_deal = make_new_deal(
deal_id,
hs_object_id="1",
)
new_company = "new_company"
result = HubspotDealDiffer.check_for_db_update_trigger(
new_deal=new_deal,
new_company=new_company,
new_listing=None,
old_deal=old_deal,
)
assert result is True
def test_db_update_trigger__missing_hubspot_timezone__returns_false() -> None:
deal_id = uuid.uuid4()
old_deal = make_old_deal(
id=deal_id,
design_completion_date=datetime(2025, 11, 3, 0, 0, tzinfo=timezone.utc),
)
new_deal = make_new_deal(
deal_id,
hs_object_id="1",
design_completion_date=datetime(2025, 11, 3, 0, 0).isoformat(),
)
result = HubspotDealDiffer.check_for_db_update_trigger(
new_deal=new_deal,
new_company=None,
new_listing=None,
old_deal=old_deal,
)
assert result is False
def test_db_update_trigger__listing_changed__returns_true() -> None:
deal_id = uuid.uuid4()
old_deal = make_old_deal(
id=deal_id,
listing_id="abc",
)
new_deal = make_new_deal(
deal_id,
hs_object_id="1",
)
new_listing = {"listing_id": "xyz"}
result = HubspotDealDiffer.check_for_db_update_trigger(
new_deal=new_deal,
new_company=None,
new_listing=new_listing,
old_deal=old_deal,
)
assert result is True
def test_db_update_trigger__client_booking_reference_changed__returns_true() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
client_booking_reference=None,
)
new_deal = make_new_deal(
deal_id,
hs_object_id="1",
client_booking_reference="AD0226519",
)
# Act
result = HubspotDealDiffer.check_for_db_update_trigger(
new_deal=new_deal,
new_company=None,
new_listing=None,
old_deal=old_deal,
)
# Assert
assert result is True
def test_db_update_trigger__client_booking_reference_unchanged__returns_false() -> None:
deal_id = uuid.uuid4()
# Arrange
old_deal = make_old_deal(
id=deal_id,
client_booking_reference="AD0226519",
)
new_deal = make_new_deal(
deal_id,
hs_object_id="1",
client_booking_reference="AD0226519",
)
# Act
result = HubspotDealDiffer.check_for_db_update_trigger(
new_deal=new_deal,
new_company=None,
new_listing=None,
old_deal=old_deal,
)
# Assert
assert result is False