PAS falls back to coordination client when UPRN lookup returns 401 🟥

This commit is contained in:
Daniel Roth 2026-05-18 09:05:54 +00:00
parent 0573db1151
commit a999724578
2 changed files with 39 additions and 4 deletions

View file

@ -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

View file

@ -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