Files
crucible-agent-build-fastap…/tests/test_api.py

78 lines
3.1 KiB
Python

import asyncio
from collections.abc import Awaitable, Callable
import httpx
async def create(client: httpx.AsyncClient, name: str = "site") -> httpx.Response:
return await client.post(
"/monitors", json={"name": name, "url": "https://example.com/path?secret=value"}
)
async def test_crud_and_error_semantics(client: httpx.AsyncClient) -> None:
response = await create(client)
assert response.status_code == 201
monitor = response.json()
assert monitor["current_status"]["state"] == "never_checked"
response = await client.patch(
f"/monitors/{monitor['id']}", json={"name": "renamed", "expected_status": 204}
)
assert response.status_code == 200
assert response.json()["name"] == "renamed"
assert response.json()["expected_status"] == 204
assert len((await client.get("/monitors")).json()) == 1
assert (await client.delete(f"/monitors/{monitor['id']}")).status_code == 204
response = await client.get(f"/monitors/{monitor['id']}")
assert response.status_code == 404
assert response.json() == {"error": {"code": "not_found", "message": "monitor not found"}}
async def test_typed_validation_is_redacted(client: httpx.AsyncClient) -> None:
response = await client.post(
"/monitors", json={"name": "", "url": "not a URL", "expected_status": 99}
)
assert response.status_code == 422
assert response.json()["error"]["code"] == "invalid_request"
assert "not a URL" not in response.text
async def test_store_survives_concurrent_api_writes(client: httpx.AsyncClient) -> None:
responses = await asyncio.gather(*(create(client, f"site-{n}") for n in range(100)))
ids = {response.json()["id"] for response in responses}
assert len(ids) == 100
listed = (await client.get("/monitors")).json()
assert {item["id"] for item in listed} == ids
async def test_check_updates_current_status(client: httpx.AsyncClient) -> None:
monitor = (await create(client)).json()
checked = await client.post(f"/monitors/{monitor['id']}/check")
assert checked.status_code == 200
assert checked.json()["state"] == "up"
status = await client.get(f"/monitors/{monitor['id']}/status")
assert status.json() == checked.json()
async def test_operational_routes(client: httpx.AsyncClient) -> None:
assert (await client.get("/health/live")).json() == {"status": "ok"}
assert (await client.get("/health/ready")).json()["storage"] == "process-local-memory"
async def test_redirect_is_revalidated(
client_factory: Callable[[httpx.AsyncBaseTransport], Awaitable[httpx.AsyncClient]],
) -> None:
async def handler(request: httpx.Request) -> httpx.Response:
if request.url.host == "example.com":
return httpx.Response(302, headers={"location": "http://127.0.0.1/admin"})
raise AssertionError("blocked redirect must not reach transport")
client = await client_factory(httpx.MockTransport(handler))
async with client:
monitor = (await create(client)).json()
result = await client.post(f"/monitors/{monitor['id']}/check")
assert result.json()["state"] == "blocked"
assert result.json()["observed_status"] == 302