feat(agent): add test frontend and Docker stack

This commit is contained in:
2026-09-16 21:42:05 +02:00
parent c8b55fbd38
commit 4f5107a46a
16 changed files with 1065 additions and 71 deletions
+26
View File
@@ -69,6 +69,32 @@ def configure_state(*, api_key: str = "", admin_key: str = "") -> None:
app.state.rag.retriever = FakeRetriever()
def test_frontend_is_served_with_security_headers():
with TestClient(app) as client:
configure_state(api_key="service-secret")
response = client.get("/")
assert response.status_code == 200
assert "PV Wissen" in response.text
assert "service-secret" not in response.text
assert response.headers["cache-control"] == "no-store"
assert response.headers["x-frame-options"] == "DENY"
assert response.headers["x-content-type-options"] == "nosniff"
assert "script-src 'self'" in response.headers["content-security-policy"]
def test_frontend_assets_use_v1_api_and_unknown_assets_are_hidden():
with TestClient(app) as client:
configure_state()
script = client.get("/assets/app.js")
styles = client.get("/assets/styles.css")
missing = client.get("/assets/index.html")
assert script.status_code == 200
assert styles.status_code == 200
assert 'fetch("/v1/ask"' in script.text
assert "innerHTML" not in script.text
assert missing.status_code == 404
def test_nonlocal_bind_without_api_key_is_rejected(capsys):
class Args:
host = "0.0.0.0"
+47
View File
@@ -0,0 +1,47 @@
"""Statische Schutztests für den Docker-Compose-Deploymentvertrag."""
from pathlib import Path
import yaml
ROOT = Path(__file__).resolve().parents[1]
def load_compose() -> dict:
return yaml.safe_load((ROOT / "compose.yaml").read_text(encoding="utf-8"))
def test_compose_uses_external_ollama_network_and_tailscale_bind():
compose = load_compose()
service = compose["services"]["pv-agent"]
assert service["networks"] == ["ollama-default"]
assert compose["networks"]["ollama-default"] == {
"external": True,
"name": "ollama-default",
}
assert "100.103.83.12:${PV_PORT:-8080}:8080" in service["ports"]
assert service["environment"]["OLLAMA_URL"] == (
"${OLLAMA_URL:-http://ollama:11434}"
)
def test_compose_requires_auth_and_limits_container_privileges():
service = load_compose()["services"]["pv-agent"]
assert ":?" in service["environment"]["PV_API_KEY"]
assert "env_file" not in service
assert service["read_only"] is True
assert service["security_opt"] == ["no-new-privileges:true"]
assert service["cap_drop"] == ["ALL"]
assert "./data:/app/data" in service["volumes"]
assert "./wissensbasis:/app/wissensbasis:ro" in service["volumes"]
def test_docker_context_excludes_secrets_and_runtime_data():
ignored = set(
(ROOT / ".dockerignore").read_text(encoding="utf-8").splitlines()
)
assert {".env", "data", ".lexis360", ".rechtsprechung", "wissensbasis"} <= ignored
dockerfile = (ROOT / "Dockerfile").read_text(encoding="utf-8")
assert "requirements-runtime.txt" in dockerfile
assert "COPY agent/" in dockerfile
assert "COPY web/" in dockerfile
assert "COPY ." not in dockerfile