68 lines
2.5 KiB
Python
68 lines
2.5 KiB
Python
import httpx
|
|
import pytest
|
|
from pathlib import Path
|
|
|
|
from app.config import Settings
|
|
from app.api.routes import get_project_repository
|
|
from app.main import app
|
|
from app.repositories.memory import InMemoryProjectRepository
|
|
from app.runtime_settings import EncryptedSettingsStore, get_runtime_store
|
|
|
|
|
|
@pytest.fixture
|
|
def transport(tmp_path: Path) -> httpx.ASGITransport:
|
|
store = EncryptedSettingsStore(
|
|
Settings(
|
|
_env_file=None,
|
|
runtime_settings_dir=str(tmp_path),
|
|
database_url="postgresql://user:secret@postgres:5432/app",
|
|
redis_url="redis://:secret@redis:6379/0",
|
|
)
|
|
)
|
|
repository = InMemoryProjectRepository()
|
|
app.dependency_overrides[get_runtime_store] = lambda: store
|
|
app.dependency_overrides[get_project_repository] = lambda: repository
|
|
return httpx.ASGITransport(app=app)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_health(transport: httpx.ASGITransport) -> None:
|
|
async with httpx.AsyncClient(transport=transport, base_url="http://test") as client:
|
|
response = await client.get("/v1/health")
|
|
assert response.status_code == 200
|
|
assert response.json()["status"] == "ok"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_demo_project_contract(transport: httpx.ASGITransport) -> None:
|
|
async with httpx.AsyncClient(transport=transport, base_url="http://test") as client:
|
|
response = await client.get("/v1/projects/demo-apartment")
|
|
assert response.status_code == 200
|
|
body = response.json()
|
|
assert body["stage"] == "plan_review"
|
|
assert body["plan"]["cad_layer_count"] == 43
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_settings_contract_never_returns_secret_values(transport: httpx.ASGITransport) -> None:
|
|
async with httpx.AsyncClient(transport=transport, base_url="http://test") as client:
|
|
response = await client.get("/v1/settings")
|
|
assert response.status_code == 200
|
|
body = response.json()
|
|
assert len(body["categories"]) == 6
|
|
assert "ai_api_key" not in body["values"]
|
|
assert body["readiness"]["ready"] is False
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_workflow_command_is_blocked_until_required_settings_are_ready(
|
|
transport: httpx.ASGITransport,
|
|
) -> None:
|
|
async with httpx.AsyncClient(transport=transport, base_url="http://test") as client:
|
|
response = await client.post(
|
|
"/v1/projects/demo-apartment/commands",
|
|
json={"command": "confirm_plan", "expected_revision": 3, "payload": {}},
|
|
)
|
|
assert response.status_code == 503
|
|
assert response.json()["detail"]["code"] == "SETTINGS_INCOMPLETE"
|