slop game oder so

This commit is contained in:
2026-09-24 17:57:54 +02:00
commit 4c997eee21
166 changed files with 14976 additions and 0 deletions
+119
View File
@@ -0,0 +1,119 @@
"""Prüft Assets und Inhalte: Lizenzdokumentation vollständig, Verweise gültig,
SVGs harmlos, keine Namen aus anderen Spielen oder Filmen."""
from __future__ import annotations
import re
import xml.etree.ElementTree as ET
from pathlib import Path
import pytest
from app.config import PROJECT_ROOT
STATIC = PROJECT_ROOT / "app" / "static"
ASSETS = STATIC / "assets"
ASSETS_DOC = PROJECT_ROOT / "docs" / "ASSETS.md"
JS_ROOT = STATIC / "js"
#: Begriffe aus Helldivers bzw. Starship Troopers, die im Spiel nicht vorkommen dürfen
#: (Groß-/Kleinschreibung egal). Der allgemeine Tonfall darf inspiriert sein, Namen nicht.
FORBIDDEN_TERMS = [
"helldiver",
"super earth",
"super-erde",
"supererde",
"stratagem",
"hellpod",
"terminid",
"automaton",
"illuminate",
"managed democracy",
"gelenkte demokratie",
"liber-tea",
"would you like to know more",
"möchten sie mehr erfahren",
"mobile infantry",
"arachnid",
"federation",
"föderation",
"service guarantees citizenship",
"rico",
"klendathu",
]
def _asset_files() -> list[Path]:
return sorted(p for p in ASSETS.rglob("*") if p.is_file())
def test_asset_folder_is_not_empty() -> None:
assert _asset_files(), "Keine Assets gefunden"
@pytest.mark.parametrize("path", _asset_files(), ids=lambda p: p.relative_to(ASSETS).as_posix())
def test_every_asset_is_documented(path: Path) -> None:
documented = ASSETS_DOC.read_text(encoding="utf-8")
relative = path.relative_to(ASSETS).as_posix()
assert relative in documented, f"{relative} fehlt in docs/ASSETS.md"
def test_referenced_asset_files_exist() -> None:
manifest = (JS_ROOT / "systems" / "Assets.js").read_text(encoding="utf-8")
referenced = re.findall(r"file: '([^']+)'", manifest)
assert len(referenced) >= 15
missing = [f for f in referenced if not (ASSETS / f).is_file()]
assert missing == []
@pytest.mark.parametrize("path", sorted(ASSETS.rglob("*.svg")), ids=lambda p: p.name)
def test_svgs_are_well_formed_and_self_contained(path: Path) -> None:
source = path.read_text(encoding="utf-8")
root = ET.fromstring(source) # noqa: S314 – eigene, versionierte Dateien
assert root.tag.endswith("svg")
lowered = source.lower()
# Keine Skripte, keine externen Verweise: SVGs sollen reine Grafik sein.
assert "<script" not in lowered
assert "http://" not in lowered.replace("http://www.w3.org/2000/svg", "")
assert "https://" not in lowered
assert "<image" not in lowered
def test_phaser_is_vendored_locally() -> None:
phaser = JS_ROOT / "lib" / "phaser.min.js"
assert phaser.is_file()
assert phaser.stat().st_size > 500_000
head = phaser.read_text(encoding="utf-8", errors="ignore")[:100_000]
assert '"3.90.0"' in head or "3.90.0" in head
assert (JS_ROOT / "lib" / "PHASER_LICENSE.md").is_file()
def test_no_external_urls_in_page_or_scripts() -> None:
"""Das Spiel lädt nichts von fremden Servern (kein CDN, kein Tracking)."""
offenders = []
for path in [*JS_ROOT.rglob("*.js"), *(PROJECT_ROOT / "app" / "templates").rglob("*.html")]:
if "lib" in path.relative_to(STATIC if path.is_relative_to(STATIC) else PROJECT_ROOT).parts:
continue
text = path.read_text(encoding="utf-8")
for match in re.findall(r"""(?:src|href)=["'](https?://[^"']+)""", text):
offenders.append(f"{path.name}: {match}")
if re.search(r"""\b(?:import|fetch)\s*\(?\s*["']https?://""", text):
offenders.append(f"{path.name}: externer Import/Fetch")
assert offenders == []
def test_no_names_from_other_games_or_films() -> None:
sources = [
*JS_ROOT.rglob("*.js"),
*(PROJECT_ROOT / "app" / "templates").rglob("*.html"),
*ASSETS.rglob("*.svg"),
]
hits = []
for path in sources:
if "lib" in path.parts:
continue
text = path.read_text(encoding="utf-8").lower()
for term in FORBIDDEN_TERMS:
if re.search(rf"\b{re.escape(term)}\b", text):
hits.append(f"{path.relative_to(PROJECT_ROOT).as_posix()}: {term}")
assert hits == []