mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
273 lines
9 KiB
Python
273 lines
9 KiB
Python
import json
|
|
from pathlib import Path
|
|
from unittest.mock import ANY, MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from datatypes.magicplan.api.response import MagicPlanPlan, PlanSummary
|
|
from datatypes.magicplan.domain.mapper import map_plan
|
|
from datatypes.magicplan.domain.models import Plan
|
|
|
|
from backend.app.db.models.uploaded_file import (
|
|
FileSourceEnum,
|
|
FileTypeEnum,
|
|
UploadedFile,
|
|
)
|
|
from backend.magic_plan.magic_plan_client import MagicPlanClient
|
|
from backend.magic_plan.magic_plan_service import MagicPlanService
|
|
from backend.magic_plan.magic_plan_trigger_request import MagicPlanTriggerRequest
|
|
|
|
FIXTURE_DIR = Path(__file__).parents[2] / "magic_plan"
|
|
PLAN_ID = "a7285ed1-878d-47eb-8aa6-85ef9e187516"
|
|
S3_BUCKET = "test-bucket"
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def domain_plan() -> Plan:
|
|
data = json.loads(
|
|
(FIXTURE_DIR / "magicplan_api_plan_response_example.json").read_text()
|
|
)
|
|
return map_plan(MagicPlanPlan.model_validate(data["data"]))
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def api_magic_plan() -> MagicPlanPlan:
|
|
data = json.loads(
|
|
(FIXTURE_DIR / "magicplan_api_plan_response_example.json").read_text()
|
|
)
|
|
return MagicPlanPlan.model_validate(data["data"])
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def plan_summary() -> PlanSummary:
|
|
data = json.loads(
|
|
(FIXTURE_DIR / "magicplan_api_plan_response_example.json").read_text()
|
|
)
|
|
return MagicPlanPlan.model_validate(data["data"]).plan
|
|
|
|
|
|
@pytest.fixture()
|
|
def mock_client() -> MagicMock:
|
|
client = MagicMock(spec=MagicPlanClient)
|
|
client.get_plan_raw.return_value = (
|
|
FIXTURE_DIR / "magicplan_api_plan_response_example.json"
|
|
).read_bytes()
|
|
return client
|
|
|
|
|
|
def _make_service(mock_client: MagicMock) -> MagicPlanService:
|
|
return MagicPlanService(client=mock_client, s3_bucket=S3_BUCKET)
|
|
|
|
|
|
def _make_request(
|
|
address: str = "2 Laburnum Way Bromley BR2 8BZ",
|
|
hubspot_deal_id: str = "deal-123",
|
|
uprn: str | None = None,
|
|
) -> MagicPlanTriggerRequest:
|
|
return MagicPlanTriggerRequest(
|
|
address=address, hubspot_deal_id=hubspot_deal_id, uprn=uprn
|
|
)
|
|
|
|
|
|
# --- no match ---
|
|
|
|
|
|
def test_run_raises_when_no_plan_found(mock_client: MagicMock) -> None:
|
|
# Arrange
|
|
mock_client.get_plans.return_value.plans = []
|
|
service = _make_service(mock_client)
|
|
# Act / Assert
|
|
with pytest.raises(ValueError, match="No MagicPlan found"):
|
|
service.run(_make_request(address="99 Nowhere Road London SW1A 1AA"))
|
|
|
|
|
|
# --- match found ---
|
|
|
|
|
|
def test_run_fetches_plan_with_matched_id(
|
|
mock_client: MagicMock,
|
|
api_magic_plan: MagicPlanPlan,
|
|
plan_summary: PlanSummary,
|
|
domain_plan: Plan,
|
|
) -> None:
|
|
# Arrange
|
|
mock_client.get_plans.return_value = [plan_summary]
|
|
mock_client.get_plan.return_value = api_magic_plan
|
|
service = _make_service(mock_client)
|
|
with patch(
|
|
"backend.magic_plan.magic_plan_service.find_matching_plan",
|
|
return_value=plan_summary,
|
|
), patch("backend.magic_plan.magic_plan_service.save_plan"), patch(
|
|
"backend.magic_plan.magic_plan_service.db_session"
|
|
), patch(
|
|
"backend.magic_plan.magic_plan_service.save_data_to_s3"
|
|
):
|
|
service.run(_make_request())
|
|
# Assert
|
|
mock_client.get_plan_raw.assert_called_once_with(plan_summary.id)
|
|
|
|
|
|
def test_run_returns_mapped_plan(
|
|
mock_client: MagicMock,
|
|
api_magic_plan: MagicPlanPlan,
|
|
plan_summary: PlanSummary,
|
|
domain_plan: Plan,
|
|
) -> None:
|
|
# Arrange
|
|
mock_client.get_plans.return_value = [plan_summary]
|
|
mock_client.get_plan.return_value = api_magic_plan
|
|
service = _make_service(mock_client)
|
|
with patch(
|
|
"backend.magic_plan.magic_plan_service.find_matching_plan",
|
|
return_value=plan_summary,
|
|
), patch("backend.magic_plan.magic_plan_service.save_plan"), patch(
|
|
"backend.magic_plan.magic_plan_service.db_session"
|
|
), patch(
|
|
"backend.magic_plan.magic_plan_service.save_data_to_s3"
|
|
):
|
|
result = service.run(_make_request())
|
|
# Assert
|
|
assert isinstance(result, Plan)
|
|
assert result.uid == PLAN_ID
|
|
|
|
|
|
def test_run_calls_save_plan_with_mapped_plan(
|
|
mock_client: MagicMock,
|
|
api_magic_plan: MagicPlanPlan,
|
|
plan_summary: PlanSummary,
|
|
) -> None:
|
|
# Arrange
|
|
mock_client.get_plans.return_value = [plan_summary]
|
|
mock_client.get_plan.return_value = api_magic_plan
|
|
service = _make_service(mock_client)
|
|
with patch(
|
|
"backend.magic_plan.magic_plan_service.find_matching_plan",
|
|
return_value=plan_summary,
|
|
), patch("backend.magic_plan.magic_plan_service.save_plan") as mock_save, patch(
|
|
"backend.magic_plan.magic_plan_service.db_session"
|
|
), patch(
|
|
"backend.magic_plan.magic_plan_service.save_data_to_s3"
|
|
):
|
|
service.run(_make_request())
|
|
# Assert — save_plan called with a Plan whose uid matches
|
|
call_args = mock_save.call_args
|
|
saved_plan: Plan = call_args[0][1]
|
|
assert saved_plan.uid == PLAN_ID
|
|
|
|
|
|
def test_run_accepts_uprn_without_error(
|
|
mock_client: MagicMock,
|
|
api_magic_plan: MagicPlanPlan,
|
|
plan_summary: PlanSummary,
|
|
) -> None:
|
|
# Arrange
|
|
mock_client.get_plans.return_value = [plan_summary]
|
|
mock_client.get_plan.return_value = api_magic_plan
|
|
service = _make_service(mock_client)
|
|
with patch(
|
|
"backend.magic_plan.magic_plan_service.find_matching_plan",
|
|
return_value=plan_summary,
|
|
), patch("backend.magic_plan.magic_plan_service.save_plan"), patch(
|
|
"backend.magic_plan.magic_plan_service.db_session"
|
|
), patch(
|
|
"backend.magic_plan.magic_plan_service.save_data_to_s3"
|
|
):
|
|
service.run(_make_request(uprn="100023336956"))
|
|
|
|
|
|
# --- S3 upload ---
|
|
|
|
|
|
def test_run_uploads_to_s3_with_uprn_key(
|
|
mock_client: MagicMock,
|
|
api_magic_plan: MagicPlanPlan,
|
|
plan_summary: PlanSummary,
|
|
) -> None:
|
|
# Arrange
|
|
mock_client.get_plans.return_value = [plan_summary]
|
|
request = _make_request(uprn="100023336956")
|
|
service = MagicPlanService(client=mock_client, s3_bucket=S3_BUCKET)
|
|
with patch(
|
|
"backend.magic_plan.magic_plan_service.find_matching_plan",
|
|
return_value=plan_summary,
|
|
), patch("backend.magic_plan.magic_plan_service.save_plan"), patch(
|
|
"backend.magic_plan.magic_plan_service.db_session"
|
|
), patch(
|
|
"backend.magic_plan.magic_plan_service.save_data_to_s3"
|
|
) as mock_s3:
|
|
# Act
|
|
service.run(request)
|
|
# Assert
|
|
mock_s3.assert_called_once_with(
|
|
ANY,
|
|
S3_BUCKET,
|
|
f"documents/uprn/100023336956/magic_plan_{plan_summary.id}.json.gz",
|
|
)
|
|
|
|
|
|
def test_run_uploads_to_s3_with_deal_id_key_when_uprn_absent(
|
|
mock_client: MagicMock,
|
|
api_magic_plan: MagicPlanPlan,
|
|
plan_summary: PlanSummary,
|
|
) -> None:
|
|
# Arrange
|
|
mock_client.get_plans.return_value = [plan_summary]
|
|
mock_client.get_plan.return_value = api_magic_plan
|
|
request = _make_request(hubspot_deal_id="deal-456", uprn=None)
|
|
service = MagicPlanService(client=mock_client, s3_bucket=S3_BUCKET)
|
|
with patch(
|
|
"backend.magic_plan.magic_plan_service.find_matching_plan",
|
|
return_value=plan_summary,
|
|
), patch("backend.magic_plan.magic_plan_service.save_plan"), patch(
|
|
"backend.magic_plan.magic_plan_service.db_session"
|
|
), patch(
|
|
"backend.magic_plan.magic_plan_service.save_data_to_s3"
|
|
) as mock_s3:
|
|
# Act
|
|
service.run(request)
|
|
# Assert
|
|
mock_s3.assert_called_once_with(
|
|
ANY,
|
|
S3_BUCKET,
|
|
f"documents/hubspot_deal_id/deal-456/magic_plan_{plan_summary.id}.json.gz",
|
|
)
|
|
|
|
|
|
# --- UploadedFile record ---
|
|
|
|
|
|
def test_run_creates_uploaded_file_record(
|
|
mock_client: MagicMock,
|
|
api_magic_plan: MagicPlanPlan,
|
|
plan_summary: PlanSummary,
|
|
) -> None:
|
|
# Arrange
|
|
mock_client.get_plans.return_value = [plan_summary]
|
|
mock_client.get_plan.return_value = api_magic_plan
|
|
request = _make_request(hubspot_deal_id="deal-789", uprn="100023336956")
|
|
service = MagicPlanService(client=mock_client, s3_bucket=S3_BUCKET)
|
|
mock_session = MagicMock()
|
|
with patch(
|
|
"backend.magic_plan.magic_plan_service.find_matching_plan",
|
|
return_value=plan_summary,
|
|
), patch("backend.magic_plan.magic_plan_service.save_plan"), patch(
|
|
"backend.magic_plan.magic_plan_service.db_session"
|
|
) as mock_db, patch(
|
|
"backend.magic_plan.magic_plan_service.save_data_to_s3"
|
|
):
|
|
mock_db.return_value.__enter__.return_value = mock_session
|
|
# Act
|
|
service.run(request)
|
|
# Assert
|
|
added_objects = [call.args[0] for call in mock_session.add.call_args_list]
|
|
uploaded_file = next(
|
|
(obj for obj in added_objects if isinstance(obj, UploadedFile)), None
|
|
)
|
|
assert uploaded_file is not None
|
|
assert uploaded_file.file_source == FileSourceEnum.MAGIC_PLAN.value
|
|
assert uploaded_file.file_type == FileTypeEnum.MAGIC_PLAN_JSON.value
|
|
assert uploaded_file.s3_file_bucket == S3_BUCKET
|
|
assert uploaded_file.s3_file_key == f"documents/uprn/100023336956/magic_plan_{plan_summary.id}.json.gz"
|
|
assert uploaded_file.s3_upload_timestamp is not None
|
|
assert uploaded_file.uprn == 100023336956
|
|
assert uploaded_file.hubspot_deal_id == "deal-789"
|