slop game oder so
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
"""Tests für Datenbank-Initialisierung und die SQLite-Hilfsfunktionen."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sqlite3
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from flask import Flask
|
||||
|
||||
from app import create_app
|
||||
from app.models import (
|
||||
SCHEMA_VERSION,
|
||||
connect,
|
||||
consume_run_token,
|
||||
init_db,
|
||||
insert_score,
|
||||
rank_of,
|
||||
register_submission_attempt,
|
||||
top_scores,
|
||||
)
|
||||
|
||||
|
||||
def _tables(path: Path) -> set[str]:
|
||||
with sqlite3.connect(path) as conn:
|
||||
rows = conn.execute("SELECT name FROM sqlite_master WHERE type = 'table'").fetchall()
|
||||
return {row[0] for row in rows}
|
||||
|
||||
|
||||
def test_create_app_initializes_database(app: Flask, db_path: Path) -> None:
|
||||
assert db_path.exists()
|
||||
assert {"highscores", "submission_log", "used_run_tokens"} <= _tables(db_path)
|
||||
|
||||
|
||||
def test_init_db_creates_missing_parent_directories(tmp_path: Path) -> None:
|
||||
target = tmp_path / "tief" / "verschachtelt" / "scores.sqlite3"
|
||||
init_db(target)
|
||||
assert target.exists()
|
||||
with sqlite3.connect(target) as conn:
|
||||
assert conn.execute("PRAGMA user_version").fetchone()[0] == SCHEMA_VERSION
|
||||
|
||||
|
||||
def test_init_db_is_idempotent_and_keeps_data(tmp_path: Path) -> None:
|
||||
target = tmp_path / "scores.sqlite3"
|
||||
init_db(target)
|
||||
conn = connect(target)
|
||||
insert_score(conn, "Bleibt", 42, wave=1, duration_s=10)
|
||||
conn.close()
|
||||
|
||||
init_db(target)
|
||||
init_db(target)
|
||||
conn = connect(target)
|
||||
assert [row["name"] for row in top_scores(conn, 10)] == ["Bleibt"]
|
||||
conn.close()
|
||||
|
||||
|
||||
def test_db_path_from_environment(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
target = tmp_path / "env" / "glory.sqlite3"
|
||||
monkeypatch.setenv("GLORY_DB_PATH", str(target))
|
||||
monkeypatch.setenv("SECRET_KEY", "env-secret")
|
||||
app = create_app()
|
||||
assert Path(app.config["DATABASE_PATH"]) == target
|
||||
assert target.exists()
|
||||
|
||||
|
||||
def test_init_db_cli_command(app: Flask, db_path: Path) -> None:
|
||||
db_path.unlink()
|
||||
result = app.test_cli_runner().invoke(args=["init-db"])
|
||||
assert result.exit_code == 0
|
||||
assert "Datenbank bereit" in result.output
|
||||
assert db_path.exists()
|
||||
|
||||
|
||||
def test_rank_of_matches_top_scores_order(tmp_path: Path) -> None:
|
||||
target = tmp_path / "rank.sqlite3"
|
||||
init_db(target)
|
||||
conn = connect(target)
|
||||
ids = [
|
||||
insert_score(conn, name, score, 1, 1)
|
||||
for name, score in [("A", 300), ("B", 500), ("C", 300), ("D", 100)]
|
||||
]
|
||||
ranks = [rank_of(conn, score_id) for score_id in ids]
|
||||
assert ranks == [2, 1, 3, 4]
|
||||
conn.close()
|
||||
|
||||
|
||||
def test_register_submission_attempt_limits_and_recovers(tmp_path: Path) -> None:
|
||||
target = tmp_path / "limit.sqlite3"
|
||||
init_db(target)
|
||||
conn = connect(target)
|
||||
now = 5_000.0
|
||||
results = [register_submission_attempt(conn, "client", now + i, 60, 3) for i in range(4)]
|
||||
assert [allowed for allowed, _ in results] == [True, True, True, False]
|
||||
# Ältester Versuch bei t=5000 fällt bei t=5060 aus dem Fenster; Anfrage kam bei t=5003.
|
||||
assert results[3][1] == 57
|
||||
assert register_submission_attempt(conn, "client", now + 61, 60, 3)[0] is True
|
||||
conn.close()
|
||||
|
||||
|
||||
def test_consume_run_token_only_once(tmp_path: Path) -> None:
|
||||
target = tmp_path / "tokens.sqlite3"
|
||||
init_db(target)
|
||||
conn = connect(target)
|
||||
assert consume_run_token(conn, "run-1", 100.0, 3600) is True
|
||||
assert consume_run_token(conn, "run-1", 101.0, 3600) is False
|
||||
assert consume_run_token(conn, "run-2", 101.0, 3600) is True
|
||||
conn.close()
|
||||
Reference in New Issue
Block a user