"""Shared test helpers: a mock ESI client backed by httpx.MockTransport.""" from __future__ import annotations import base64 import json from collections.abc import Callable import httpx import pytest from familiar import esi def make_jwt(claims: dict) -> str: """Build a fake JWT (header.payload.signature) whose payload is `claims`. Only the payload segment is ever decoded by familiar, so the header and signature can be arbitrary. """ payload = base64.urlsafe_b64encode(json.dumps(claims).encode()).rstrip(b"=").decode() return f"header.{payload}.signature" Handler = Callable[[httpx.Request], httpx.Response] @pytest.fixture def mock_esi(): """Install a mock ESI client driven by a request handler. Usage:: def test_x(mock_esi): def handler(request): return httpx.Response(200, json={...}) mock_esi(handler) ... The shared client is reset after the test. """ def _make(handler: Handler) -> esi.EsiClient: client = esi.EsiClient(transport=httpx.MockTransport(handler)) esi.set_client(client) return client yield _make esi.set_client(None) def route(request: httpx.Request, fixtures: dict[str, object]) -> httpx.Response: """Match a request against ``{substring_in_path: json_body}`` and respond. The special key ``"/universe/ids/"`` is matched for the name-resolution POST. A missing match returns 404 so tests fail loudly. """ path = request.url.path for needle, body in fixtures.items(): if needle in path: return httpx.Response(200, json=body) return httpx.Response(404, json={"error": f"no fixture for {path}"})