test: refactor suite to use AsyncClient, in-memory DBs, and parallel coverage

This commit is contained in:
2026-04-09 16:43:49 -04:00
parent de84cc664f
commit 6fc1a2a3ea
11 changed files with 230 additions and 215 deletions

View File

@@ -1,58 +1,48 @@
from typing import Any
from fastapi.testclient import TestClient
from decnet.web.api import app
from hypothesis import given, strategies as st, settings
import pytest
import httpx
from typing import Any
from decnet.env import DECNET_ADMIN_USER, DECNET_ADMIN_PASSWORD
from ..conftest import _FUZZ_SETTINGS
from hypothesis import given, strategies as st, settings
def test_get_stats_unauthorized() -> None:
with TestClient(app) as client:
response = client.get("/api/v1/stats")
assert response.status_code == 401
@pytest.mark.anyio
async def test_get_stats_unauthorized(client: httpx.AsyncClient) -> None:
response = await client.get("/api/v1/stats")
assert response.status_code == 401
def test_get_stats_success() -> None:
with TestClient(app) as client:
login_response = client.post(
"/api/v1/auth/login",
json={"username": DECNET_ADMIN_USER, "password": DECNET_ADMIN_PASSWORD}
)
token = login_response.json()["access_token"]
response = client.get(
"/api/v1/stats",
headers={"Authorization": f"Bearer {token}"}
)
assert response.status_code == 200
data = response.json()
assert "total_logs" in data
assert "unique_attackers" in data
assert "active_deckies" in data
@pytest.mark.anyio
async def test_get_stats_success(client: httpx.AsyncClient, auth_token: str) -> None:
response = await client.get(
"/api/v1/stats",
headers={"Authorization": f"Bearer {auth_token}"}
)
assert response.status_code == 200
data = response.json()
assert "total_logs" in data
assert "unique_attackers" in data
assert "active_deckies" in data
def test_stats_includes_deployed_count(mock_state_file):
with TestClient(app) as _client:
_login_resp = _client.post("/api/v1/auth/login", json={"username": DECNET_ADMIN_USER, "password": DECNET_ADMIN_PASSWORD})
_token = _login_resp.json()["access_token"]
_response = _client.get("/api/v1/stats", headers={"Authorization": f"Bearer {_token}"})
assert _response.status_code == 200
_data = _response.json()
assert "deployed_deckies" in _data
assert _data["deployed_deckies"] == 2
@pytest.mark.anyio
async def test_stats_includes_deployed_count(mock_state_file, client: httpx.AsyncClient, auth_token: str):
_response = await client.get("/api/v1/stats", headers={"Authorization": f"Bearer {auth_token}"})
assert _response.status_code == 200
_data = _response.json()
assert "deployed_deckies" in _data
assert _data["deployed_deckies"] == 2
@pytest.mark.anyio
@settings(**_FUZZ_SETTINGS)
@given(
token=st.text(min_size=0, max_size=4096)
)
def test_fuzz_auth_header(token: str) -> None:
async def test_fuzz_auth_header(client: httpx.AsyncClient, token: str) -> None:
"""Fuzz the Authorization header with full unicode noise."""
with TestClient(app) as _client:
try:
_response: httpx.Response = _client.get(
"/api/v1/stats",
headers={"Authorization": f"Bearer {token}"}
)
assert _response.status_code in (401, 422)
except (UnicodeEncodeError, httpx.InvalidURL, httpx.CookieConflict):
# Expected client-side rejection of invalid header characters
pass
try:
_response: httpx.Response = await client.get(
"/api/v1/stats",
headers={"Authorization": f"Bearer {token}"}
)
assert _response.status_code in (401, 422)
except (UnicodeEncodeError, httpx.InvalidURL, httpx.CookieConflict):
# Expected client-side rejection of invalid header characters
pass