"""Tests for T01 — REST service foundation (FR-900 core).""" from __future__ import annotations import pytest from fastapi.testclient import TestClient from markidocx import __version__ from markidocx.manifest import SUPPORTED_FAMILIES, FeatureLevel from markidocx.rest import create_app @pytest.fixture() def client() -> TestClient: return TestClient(create_app()) # --------------------------------------------------------------------------- # GET /health (FR-910) # --------------------------------------------------------------------------- def test_health_returns_200(client: TestClient) -> None: resp = client.get("/health") assert resp.status_code == 200 def test_health_body(client: TestClient) -> None: body = client.get("/health").json() assert body["status"] == "ok" assert body["version"] == __version__ # --------------------------------------------------------------------------- # GET /version (FR-911) # --------------------------------------------------------------------------- def test_version_returns_200(client: TestClient) -> None: assert client.get("/version").status_code == 200 def test_version_envelope(client: TestClient) -> None: body = client.get("/version").json() assert body["status"] == "ok" assert body["outputs"]["version"] == __version__ assert "warnings" in body assert "errors" in body assert "context" in body # --------------------------------------------------------------------------- # GET /capabilities (FR-909) # --------------------------------------------------------------------------- def test_capabilities_returns_200(client: TestClient) -> None: assert client.get("/capabilities").status_code == 200 def test_capabilities_feature_levels(client: TestClient) -> None: body = client.get("/capabilities").json() assert body["status"] == "ok" levels = body["outputs"]["feature_levels"] for level in FeatureLevel: assert level.value in levels def test_capabilities_families(client: TestClient) -> None: body = client.get("/capabilities").json() families = body["outputs"]["families"] for family in SUPPORTED_FAMILIES: assert family in families def test_capabilities_has_context(client: TestClient) -> None: body = client.get("/capabilities").json() assert "version" in body["context"] # --------------------------------------------------------------------------- # GET /templates (FR-906) # --------------------------------------------------------------------------- def test_templates_returns_200(client: TestClient) -> None: assert client.get("/templates").status_code == 200 def test_templates_lists_built_ins(client: TestClient) -> None: body = client.get("/templates").json() assert body["status"] == "ok" names = {f["name"] for f in body["outputs"]} assert "article" in names assert "book" in names assert "website" in names def test_templates_envelope_shape(client: TestClient) -> None: body = client.get("/templates").json() assert "warnings" in body assert "errors" in body assert "context" in body # --------------------------------------------------------------------------- # GET /styles (FR-907) # --------------------------------------------------------------------------- def test_styles_returns_200(client: TestClient) -> None: assert client.get("/styles").status_code == 200 def test_styles_is_list(client: TestClient) -> None: body = client.get("/styles").json() assert body["status"] == "ok" assert isinstance(body["outputs"], list) # --------------------------------------------------------------------------- # Response envelope shape (FR-912) # --------------------------------------------------------------------------- @pytest.mark.parametrize("endpoint", ["/version", "/capabilities", "/templates", "/styles"]) def test_envelope_fields_present(client: TestClient, endpoint: str) -> None: body = client.get(endpoint).json() assert "status" in body assert "outputs" in body assert "warnings" in body assert "errors" in body assert "context" in body