from __future__ import annotations import uuid from types import SimpleNamespace from typing import Any import pytest from app.approval.service import ApprovalService from app.domains.data_access import constants as data_access_constants from app.domains.data_access.service import DataAccessService class _ExecuteResult: def __init__(self, approval_request: Any) -> None: self._approval_request = approval_request def scalar_one_or_none(self) -> Any: return self._approval_request class _FakeSession: def __init__( self, approval_request: Any, *, data_access_request_status: str | None = None, ) -> None: self._approval_request = approval_request self._data_access_request_status = data_access_request_status self.added: list[Any] = [] self.flush_count = 0 async def execute(self, _statement: Any) -> _ExecuteResult: return _ExecuteResult(self._approval_request) async def flush(self) -> None: self.flush_count += 1 async def scalar(self, _statement: Any) -> str | None: return self._data_access_request_status def add(self, row: Any) -> None: self.added.append(row) def _approval_request( *, approval_type: str = ( data_access_constants.APPROVAL_FLOW_DATA_ACCESS_SERVICE_ACCOUNT_GRANT ), status: str = "pending", ) -> SimpleNamespace: return SimpleNamespace( id=uuid.uuid4(), external_id="FEISHU-DAX-SA-001", approval_type=approval_type, status=status, source_payload={}, updated_at=None, ) @pytest.mark.asyncio @pytest.mark.parametrize( "approval_type", [ data_access_constants.APPROVAL_FLOW_DATA_ACCESS_GROUP_GRANT, data_access_constants.APPROVAL_FLOW_DATA_ACCESS_SERVICE_ACCOUNT_GRANT, ], ) async def test_data_access_callback_dispatches_to_data_access_domain( monkeypatch: pytest.MonkeyPatch, approval_type: str, ) -> None: approval_request = _approval_request(approval_type=approval_type) session = _FakeSession(approval_request) dispatched: list[dict[str, Any]] = [] async def _capture_callback( self: DataAccessService, db: Any, *, approval_request: Any, instance_detail: dict[str, Any], approval_status: str, trace_id: str, ) -> None: del self dispatched.append({ "db": db, "approval_request": approval_request, "instance_detail": instance_detail, "approval_status": approval_status, "trace_id": trace_id, }) monkeypatch.setattr( DataAccessService, "handle_feishu_callback", _capture_callback, ) instance_detail = { "instance_code": approval_request.external_id, "status": "APPROVED", } await ApprovalService(session).handle_feishu_callback( {"event": {"instance_code": approval_request.external_id}}, prefetched_instance_detail=instance_detail, ) assert dispatched == [{ "db": session, "approval_request": approval_request, "instance_detail": instance_detail, "approval_status": "approved", "trace_id": f"data_access_callback:{approval_request.external_id}", }] @pytest.mark.asyncio async def test_terminal_parent_replays_when_data_access_request_is_still_pending( monkeypatch: pytest.MonkeyPatch, ) -> None: approval_request = _approval_request(status="approved") session = _FakeSession( approval_request, data_access_request_status="pending_feishu", ) dispatched: list[str] = [] async def _capture_callback( self: DataAccessService, db: Any, *, approval_request: Any, instance_detail: dict[str, Any], approval_status: str, trace_id: str, ) -> None: del self, db, approval_request, instance_detail, approval_status dispatched.append(trace_id) monkeypatch.setattr( DataAccessService, "handle_feishu_callback", _capture_callback, ) await ApprovalService(session).handle_feishu_callback( {"event": {"instance_code": approval_request.external_id}}, prefetched_instance_detail={ "instance_code": approval_request.external_id, "status": "APPROVED", }, ) assert dispatched == [ f"data_access_callback:{approval_request.external_id}", ]