slop game oder so
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
"""Tests für Namensbereinigung und Plausibilitätsprüfung (ohne Flask)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from app.config import GAME_RULE_DEFAULTS
|
||||
from app.validation import (
|
||||
NAME_MAX_LENGTH,
|
||||
PlausibilityRules,
|
||||
ScoreSubmission,
|
||||
SubmissionError,
|
||||
check_plausibility,
|
||||
parse_submission,
|
||||
sanitize_name,
|
||||
)
|
||||
|
||||
RULES = PlausibilityRules.from_config(GAME_RULE_DEFAULTS)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("raw", "expected"),
|
||||
[
|
||||
("Ada", "Ada"),
|
||||
(" Max Muster ", "Max Muster"),
|
||||
("Jürg Größli", "Jürg Größli"),
|
||||
("Fullwidth", "Fullwidth"),
|
||||
("Null\x00Byte", "NullByte"),
|
||||
("Zero\u200bWidth", "ZeroWidth"),
|
||||
("Bidi\u202eTrick", "BidiTrick"),
|
||||
("Tab\tNeu\nZeile", "TabNeuZeile"),
|
||||
("<script>alert(1)</script>", "scriptalert1script"),
|
||||
("O'Neil-Test!?", "O'Neil-Test!?"),
|
||||
("Emoji 🚀 Held", "Emoji Held"),
|
||||
("", ""),
|
||||
],
|
||||
)
|
||||
def test_sanitize_name(raw: str, expected: str) -> None:
|
||||
assert sanitize_name(raw) == expected
|
||||
|
||||
|
||||
def _payload(**overrides: object) -> dict:
|
||||
payload: dict = {"name": "Ada", "score": 100, "wave": 2, "duration_s": 60, "run_token": "t"}
|
||||
payload.update(overrides)
|
||||
return payload
|
||||
|
||||
|
||||
def test_parse_submission_valid() -> None:
|
||||
submission = parse_submission(_payload(name=" Ada "), RULES)
|
||||
assert submission == ScoreSubmission("Ada", 100, 2, 60, "t")
|
||||
|
||||
|
||||
def test_parse_submission_name_exactly_max_length() -> None:
|
||||
name = "N" * NAME_MAX_LENGTH
|
||||
assert parse_submission(_payload(name=name), RULES).name == name
|
||||
|
||||
|
||||
def test_parse_submission_collects_errors() -> None:
|
||||
with pytest.raises(SubmissionError) as info:
|
||||
parse_submission(_payload(name="", score=-1, wave=0), RULES)
|
||||
assert set(info.value.fields) == {"name", "score", "wave"}
|
||||
|
||||
|
||||
def _submission(score: int, wave: int, duration_s: int) -> ScoreSubmission:
|
||||
return ScoreSubmission("Ada", score, wave, duration_s, "t")
|
||||
|
||||
|
||||
def test_plausible_submission() -> None:
|
||||
assert check_plausibility(_submission(2_000, 3, 120), elapsed_s=150, rules=RULES) is None
|
||||
|
||||
|
||||
def test_duration_may_be_shorter_than_elapsed_because_of_pauses() -> None:
|
||||
assert check_plausibility(_submission(500, 2, 60), elapsed_s=3_000, rules=RULES) is None
|
||||
|
||||
|
||||
def test_duration_longer_than_elapsed_is_implausible() -> None:
|
||||
assert check_plausibility(_submission(500, 2, 600), elapsed_s=100, rules=RULES) is not None
|
||||
|
||||
|
||||
def test_duration_within_tolerance_is_accepted() -> None:
|
||||
tolerance = RULES.duration_tolerance_seconds
|
||||
assert check_plausibility(_submission(500, 2, 100 + tolerance), 100, RULES) is None
|
||||
|
||||
|
||||
def test_score_ceiling_depends_on_duration() -> None:
|
||||
ceiling = RULES.score_flat_allowance + 100 * RULES.score_max_points_per_second
|
||||
assert check_plausibility(_submission(ceiling, 5, 100), 200, RULES) is None
|
||||
assert check_plausibility(_submission(ceiling + 1, 5, 100), 200, RULES) is not None
|
||||
|
||||
|
||||
def test_high_wave_needs_minimum_time() -> None:
|
||||
assert check_plausibility(_submission(10, 50, 10), 500, RULES) is not None
|
||||
min_time = 49 * RULES.wave_min_seconds
|
||||
assert check_plausibility(_submission(10, 50, min_time), min_time + 10, RULES) is None
|
||||
Reference in New Issue
Block a user