mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
MagicPlanService orchestrating fetch, match, map, persist 🟥
This commit is contained in:
parent
2f8e08a676
commit
1a8b27453e
1 changed files with 128 additions and 0 deletions
128
backend/magic_plan/tests/test_magic_plan_service.py
Normal file
128
backend/magic_plan/tests/test_magic_plan_service.py
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
import json
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from datatypes.magicplan.api.response import MagicPlan, PlanSummary
|
||||
from datatypes.magicplan.domain.mapper import map_plan
|
||||
from datatypes.magicplan.domain.models import Plan
|
||||
|
||||
from backend.magic_plan.magic_plan_client import MagicPlanClient
|
||||
from backend.magic_plan.magic_plan_service import MagicPlanService
|
||||
|
||||
FIXTURE_DIR = Path(__file__).parents[2] / "magic_plan"
|
||||
PLAN_ID = "a7285ed1-878d-47eb-8aa6-85ef9e187516"
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def domain_plan() -> Plan:
|
||||
data = json.loads((FIXTURE_DIR / "magicplan_api_plan_response_example.json").read_text())
|
||||
return map_plan(MagicPlan.model_validate(data["data"]))
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def api_magic_plan() -> MagicPlan:
|
||||
data = json.loads((FIXTURE_DIR / "magicplan_api_plan_response_example.json").read_text())
|
||||
return MagicPlan.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 MagicPlan.model_validate(data["data"]).plan
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def mock_client() -> MagicMock:
|
||||
return MagicMock(spec=MagicPlanClient)
|
||||
|
||||
|
||||
def _make_service(mock_client: MagicMock) -> MagicPlanService:
|
||||
return MagicPlanService(client=mock_client)
|
||||
|
||||
|
||||
# --- 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("99 Nowhere Road London SW1A 1AA")
|
||||
|
||||
|
||||
# --- match found ---
|
||||
|
||||
|
||||
def test_run_fetches_plan_with_matched_id(
|
||||
mock_client: MagicMock,
|
||||
api_magic_plan: MagicPlan,
|
||||
plan_summary: PlanSummary,
|
||||
domain_plan: Plan,
|
||||
) -> None:
|
||||
# Arrange
|
||||
mock_client.get_plans.return_value.plans = [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"):
|
||||
service.run("2 Laburnum Way Bromley BR2 8BZ")
|
||||
# Assert
|
||||
mock_client.get_plan.assert_called_once_with(plan_summary.id)
|
||||
|
||||
|
||||
def test_run_returns_mapped_plan(
|
||||
mock_client: MagicMock,
|
||||
api_magic_plan: MagicPlan,
|
||||
plan_summary: PlanSummary,
|
||||
domain_plan: Plan,
|
||||
) -> None:
|
||||
# Arrange
|
||||
mock_client.get_plans.return_value.plans = [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"):
|
||||
result = service.run("2 Laburnum Way Bromley BR2 8BZ")
|
||||
# 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: MagicPlan,
|
||||
plan_summary: PlanSummary,
|
||||
) -> None:
|
||||
# Arrange
|
||||
mock_client.get_plans.return_value.plans = [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"):
|
||||
service.run("2 Laburnum Way Bromley BR2 8BZ")
|
||||
# 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: MagicPlan,
|
||||
plan_summary: PlanSummary,
|
||||
) -> None:
|
||||
# Arrange
|
||||
mock_client.get_plans.return_value.plans = [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"):
|
||||
service.run("2 Laburnum Way Bromley BR2 8BZ", uprn="100023336956")
|
||||
Loading…
Add table
Reference in a new issue