from __future__ import annotations import shutil import tempfile import unittest from pathlib import Path from fastapi import FastAPI from fastapi.testclient import TestClient from govoplan_access.backend.db.models import Account, User from govoplan_core.auth import ApiPrincipal, get_api_principal from govoplan_core.core.access import PrincipalRef from govoplan_core.db.base import Base from govoplan_identity.backend.api.v1.routes import router as identity_router from govoplan_identity.backend.db.models import Identity, IdentityAccountLink from tests.db_isolation import temporary_database class IdentityApiTests(unittest.TestCase): def _principal(self, scopes: set[str]) -> ApiPrincipal: account = Account( id="account-identity-api", email="identity-admin@example.test", normalized_email="identity-admin@example.test", display_name="Identity Admin", ) user = User( id="user-identity-api", tenant_id="tenant-identity-api", account_id=account.id, email=account.email, display_name=account.display_name, settings={}, mail_profile_policy={}, ) return ApiPrincipal( principal=PrincipalRef( account_id=account.id, membership_id=user.id, tenant_id=user.tenant_id, scopes=frozenset(scopes), ), account=account, user=user, ) def _app(self, scopes: set[str]) -> FastAPI: app = FastAPI() app.include_router(identity_router, prefix="/api/v1") app.dependency_overrides[get_api_principal] = lambda: self._principal(scopes) return app def test_identity_search_returns_account_links(self) -> None: root = Path(tempfile.mkdtemp(prefix="govoplan-identity-api-")) try: with temporary_database(f"sqlite:///{root / 'identity.db'}") as database: Base.metadata.create_all(bind=database.engine) with database.session() as session: identity = Identity( id="identity-alice", display_name="Alice Registry", external_subject="alice@example.test", source="local", ) session.add(identity) session.add( IdentityAccountLink( identity_id=identity.id, account_id="account-alice-primary", is_primary=True, source="local", ) ) session.add( IdentityAccountLink( identity_id=identity.id, account_id="account-alice-secondary", is_primary=False, source="local", ) ) session.commit() app = self._app({"identity:identity:read"}) with TestClient(app) as client: response = client.get("/api/v1/identity/identities", params={"query": "registry"}) self.assertEqual(200, response.status_code, response.text) payload = response.json() self.assertEqual(1, len(payload["identities"])) item = payload["identities"][0] self.assertEqual("identity-alice", item["id"]) self.assertEqual("Alice Registry", item["display_name"]) self.assertEqual("account-alice-primary", item["primary_account_id"]) self.assertEqual(["account-alice-primary", "account-alice-secondary"], item["account_ids"]) finally: shutil.rmtree(root, ignore_errors=True) if __name__ == "__main__": unittest.main()