diff --git a/backend/pashub_fetcher/pashub_service.py b/backend/pashub_fetcher/pashub_service.py index b3302fd9..2b8f0926 100644 --- a/backend/pashub_fetcher/pashub_service.py +++ b/backend/pashub_fetcher/pashub_service.py @@ -1,6 +1,6 @@ import os from datetime import datetime, timezone -from typing import List, NamedTuple, Optional, cast +from typing import Callable, List, NamedTuple, Optional, cast from backend.app.db.connection import db_session from backend.app.db.models.uploaded_file import ( @@ -11,7 +11,7 @@ from backend.app.db.models.uploaded_file import ( from backend.documents_parser.db_writer import save_epc_property_data from backend.documents_parser.parser import parse_site_notes_pdf from backend.pashub_fetcher.core_files import get_file_type_string -from backend.pashub_fetcher.pashub_client import PashubClient +from backend.pashub_fetcher.pashub_client import PashubClient, UnauthorizedError from backend.pashub_fetcher.pashub_to_ara_trigger_request import ( PashubToAraTriggerRequest, ) @@ -36,10 +36,13 @@ class PashubService: pashub_client: PashubClient, sharepoint_client: DomnaSharepointClient, s3_bucket: str, + coordination_client_factory: Optional[Callable[[], PashubClient]] = None, ) -> None: self._pashub_client = pashub_client self._sharepoint_client = sharepoint_client self._s3_bucket = s3_bucket + self._coordination_client_factory = coordination_client_factory + self._coordination_client: Optional[PashubClient] = None def run(self, request: PashubToAraTriggerRequest) -> List[str]: job_id = request.pashub_job_id diff --git a/backend/pashub_fetcher/tests/test_pashub_service.py b/backend/pashub_fetcher/tests/test_pashub_service.py index 2aff416b..44c6af1a 100644 --- a/backend/pashub_fetcher/tests/test_pashub_service.py +++ b/backend/pashub_fetcher/tests/test_pashub_service.py @@ -1,8 +1,8 @@ -from typing import Optional +from typing import Callable, Optional from unittest.mock import MagicMock, call, patch -from backend.pashub_fetcher.pashub_client import PashubClient +from backend.pashub_fetcher.pashub_client import PashubClient, UnauthorizedError from backend.pashub_fetcher.pashub_service import PashubService from backend.pashub_fetcher.pashub_to_ara_trigger_request import ( PashubToAraTriggerRequest, @@ -31,11 +31,13 @@ def make_service( pashub_client: Optional[PashubClient] = None, sharepoint_client: Optional[DomnaSharepointClient] = None, s3_bucket: str = "test-bucket", + coordination_client_factory: Optional[Callable[[], PashubClient]] = None, ) -> PashubService: return PashubService( pashub_client=pashub_client or MagicMock(spec=PashubClient), sharepoint_client=sharepoint_client or MagicMock(spec=DomnaSharepointClient), s3_bucket=s3_bucket, + coordination_client_factory=coordination_client_factory, ) @@ -225,6 +227,36 @@ def test_run_parses_and_saves_site_notes_for_rd_sap_site_note_file() -> None: # --------------------------------------------------------------------------- +# --------------------------------------------------------------------------- +# run(): coordination fallback +# --------------------------------------------------------------------------- + + +def test_run_uses_coordination_client_when_pas_401_on_uprn_lookup() -> None: + pas_client = MagicMock(spec=PashubClient) + pas_client.get_uprn_by_job_id.side_effect = UnauthorizedError() + + coord_client = MagicMock(spec=PashubClient) + coord_client.get_uprn_by_job_id.return_value = "99999" + coord_client.get_core_evidence_files_by_job_id.return_value = ["/tmp/a.pdf"] + + factory = MagicMock(return_value=coord_client) + + service = make_service(pashub_client=pas_client, coordination_client_factory=factory) + + with ( + patch("backend.pashub_fetcher.pashub_service.upload_file_to_s3"), + patch("backend.pashub_fetcher.pashub_service.db_session"), + patch("backend.pashub_fetcher.pashub_service.os.remove"), + ): + result = service.run(make_request()) + + assert result == ["/tmp/a.pdf"] + coord_client.get_uprn_by_job_id.assert_called_once() + coord_client.get_core_evidence_files_by_job_id.assert_called_once() + assert factory.call_count == 1 + + def test_run_warns_and_continues_when_site_notes_parsing_fails() -> None: mock_client = MagicMock(spec=PashubClient) mock_client.get_uprn_by_job_id.return_value = None