Files
2026-09-24 17:57:54 +02:00

80 lines
2.2 KiB
Python

"""Gemeinsame pytest-Fixtures: App mit temporärer Datenbank, Test-Client, Run-Tokens."""
from __future__ import annotations
import time
from collections.abc import Callable, Iterator
from pathlib import Path
import pytest
from flask import Flask
from flask.testing import FlaskClient
from itsdangerous.timed import TimestampSigner
from app import create_app
@pytest.fixture()
def db_path(tmp_path: Path) -> Path:
return tmp_path / "data" / "test.sqlite3"
@pytest.fixture()
def app(db_path: Path) -> Iterator[Flask]:
app = create_app(
{
"TESTING": True,
"SECRET_KEY": "test-secret-key",
"DATABASE_PATH": str(db_path),
"RATE_LIMIT_MAX_SUBMISSIONS": 5,
"RATE_LIMIT_WINDOW_SECONDS": 600,
}
)
yield app
@pytest.fixture()
def client(app: Flask) -> FlaskClient:
return app.test_client()
@pytest.fixture()
def issue_token(client: FlaskClient, monkeypatch: pytest.MonkeyPatch) -> Callable[..., str]:
"""Holt ein Run-Token über die API; ``started_ago`` simuliert eine bereits laufende Runde.
Die Signatur enthält den Ausgabezeitpunkt. Um eine lange Runde zu simulieren, ohne
wirklich zu warten, wird der Zeitstempel beim Signieren zurückdatiert.
"""
def _issue(started_ago: int = 0) -> str:
original = TimestampSigner.get_timestamp
monkeypatch.setattr(
TimestampSigner, "get_timestamp", lambda _self: int(time.time()) - started_ago
)
try:
response = client.post("/api/runs")
finally:
monkeypatch.setattr(TimestampSigner, "get_timestamp", original)
assert response.status_code == 201
return response.get_json()["run_token"]
return _issue
@pytest.fixture()
def valid_payload(issue_token: Callable[..., str]) -> Callable[..., dict]:
"""Erzeugt eine gültige Einreichung; einzelne Felder lassen sich überschreiben."""
def _payload(**overrides: object) -> dict:
payload: dict = {
"name": "Kadettin Ada",
"score": 1234,
"wave": 3,
"duration_s": 95,
"run_token": issue_token(started_ago=120),
}
payload.update(overrides)
return payload
return _payload