from typing import Any from unittest.mock import MagicMock, patch import pytest from pydantic import ValidationError from backend.magic_plan.handler import handler ADDRESS = "2 Laburnum Way Bromley BR2 8BZ" PLAN_UID = "a7285ed1-878d-47eb-8aa6-85ef9e187516" def _make_settings(**overrides: str) -> MagicMock: settings = MagicMock() settings.MAGICPLAN_CUSTOMER_ID = overrides.get("customer_id", "cust-123") settings.MAGICPLAN_API_KEY = overrides.get("api_key", "key-abc") return settings def _call_handler(body: dict[str, Any]) -> Any: return handler.__wrapped__(body, None) # type: ignore[attr-defined] @pytest.fixture() def mock_plan() -> MagicMock: plan = MagicMock() plan.uid = PLAN_UID return plan @pytest.fixture() def mock_service(mock_plan: MagicMock) -> MagicMock: service = MagicMock() service.run.return_value = mock_plan return service # --- request validation --- def test_handler_raises_on_missing_address(mock_plan: MagicMock) -> None: # Arrange body: dict[str, Any] = {} with patch("backend.magic_plan.handler.get_settings", return_value=_make_settings()), \ patch("backend.magic_plan.handler.MagicPlanClient"), \ patch("backend.magic_plan.handler.MagicPlanService"): # Act / Assert with pytest.raises(ValidationError): _call_handler(body) # --- client construction --- def test_handler_constructs_client_from_settings(mock_service: MagicMock) -> None: # Arrange body = {"address": ADDRESS, "hubspot_deal_id": "deal-123"} with patch("backend.magic_plan.handler.get_settings", return_value=_make_settings(customer_id="cust-xyz", api_key="key-xyz")), \ patch("backend.magic_plan.handler.MagicPlanClient") as MockClient, \ patch("backend.magic_plan.handler.MagicPlanService", return_value=mock_service): # Act _call_handler(body) # Assert MockClient.assert_called_once_with(customer_id="cust-xyz", api_key="key-xyz") # --- service orchestration --- def test_handler_calls_service_run_with_address(mock_service: MagicMock) -> None: # Arrange body = {"address": ADDRESS, "hubspot_deal_id": "deal-123"} with patch("backend.magic_plan.handler.get_settings", return_value=_make_settings()), \ patch("backend.magic_plan.handler.MagicPlanClient"), \ patch("backend.magic_plan.handler.MagicPlanService", return_value=mock_service): # Act _call_handler(body) # Assert mock_service.run.assert_called_once() request = mock_service.run.call_args.args[0] assert request.address == ADDRESS assert request.uprn is None def test_handler_passes_uprn_to_service(mock_service: MagicMock) -> None: # Arrange body = {"address": ADDRESS, "uprn": "100023336956", "hubspot_deal_id": "deal-123"} with patch("backend.magic_plan.handler.get_settings", return_value=_make_settings()), \ patch("backend.magic_plan.handler.MagicPlanClient"), \ patch("backend.magic_plan.handler.MagicPlanService", return_value=mock_service): # Act _call_handler(body) # Assert mock_service.run.assert_called_once() request = mock_service.run.call_args.args[0] assert request.address == ADDRESS assert request.uprn == "100023336956" def test_handler_returns_plan_uid(mock_service: MagicMock) -> None: # Arrange body = {"address": ADDRESS, "hubspot_deal_id": "deal-123"} with patch("backend.magic_plan.handler.get_settings", return_value=_make_settings()), \ patch("backend.magic_plan.handler.MagicPlanClient"), \ patch("backend.magic_plan.handler.MagicPlanService", return_value=mock_service): # Act result = _call_handler(body) # Assert assert result == PLAN_UID