Artur Mukhamadiev e65fbf4b67 backend: FastAPI backend track handoff (contract revision 1)
FastAPI app, upstream Confluence/model adapters, authoritative history,
rootless container lifecycle, artifact storage and downloads, fake peers
under backend/dev, tests under tests/backend. Root pytest.ini deselects
the live marker by default; requirements gain the backend dependencies.
2026-09-14 21:57:54 +03:00

83 lines
2.9 KiB
Python

"""Shared test fixtures and mock factories for backend tests."""
from __future__ import annotations
from pathlib import Path
from typing import Callable, Optional
import httpx
import pytest
from backend.confluence import ConfluenceClient
@pytest.fixture
def make_confluence_client_factory():
"""Fixture and direct helper share the same controlled upstream implementation."""
return make_test_confluence_client_factory
def make_test_confluence_client_factory():
"""Helper function for backwards-compatibility in existing test files."""
def factory(
base_url: str,
pat: str,
approved_origins: list[str],
corporate_ca_path: Optional[Path] = None,
timeout: float = 30.0,
transport: Optional[httpx.BaseTransport] = None,
) -> ConfluenceClient:
async def handler(request: httpx.Request) -> httpx.Response:
if request.url.path == "/rest/api/space":
if request.headers.get("Authorization") == "Bearer valid-pat":
return httpx.Response(
200,
json={"results": [{"key": "OPS"}]},
headers={"content-type": "application/json"},
)
return httpx.Response(
401,
json={"message": "Unauthorized"},
headers={"content-type": "application/json"},
)
elif request.url.path == "/rest/api/content/search":
return httpx.Response(
200,
json={
"results": [
{
"id": "847291",
"title": "Deployment Guide",
"space": {"key": "OPS"},
"excerpt": "Deployment steps",
}
],
"totalSize": 1,
},
headers={"content-type": "application/json"},
)
elif request.url.path == "/rest/api/content/847291":
return httpx.Response(
200,
json={
"id": "847291",
"title": "Deployment Guide",
"space": {"key": "OPS"},
"body": {"storage": {"value": "<p>Deploy service X using the release checklist.</p>"}},
},
headers={"content-type": "application/json"},
)
return httpx.Response(404)
mock_transport = transport or httpx.MockTransport(handler)
return ConfluenceClient(
base_url=base_url,
pat=pat,
approved_origins=approved_origins,
corporate_ca_path=corporate_ca_path,
timeout=timeout,
transport=mock_transport,
)
return factory