Files
2026-07-27 08:03:29 +02:00

77 lines
4.2 KiB
Python

#!/usr/bin/env python3
from __future__ import annotations
import json
import re
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
errors: list[str] = []
checks: list[str] = []
def require(condition: bool, message: str) -> None:
(checks if condition else errors).append(message)
app_gradle = (ROOT / "app/build.gradle.kts").read_text()
manifest = (ROOT / "app/src/main/AndroidManifest.xml").read_text()
network = (ROOT / "app/src/main/res/xml/network_security_config.xml").read_text()
source = "\n".join(p.read_text(errors="replace") for p in (ROOT / "app/src/main").rglob("*.*") if p.is_file())
api = (ROOT / "app/src/main/java/de/drazz/boehmitools/training/data/network/Api.kt").read_text()
require('applicationId = "de.drazz.boehmitools.training"' in app_gradle, "Application ID stimmt")
require('minSdk = 26' in app_gradle, "Minimum SDK 26")
require('compileSdk = 35' in app_gradle, "Compile SDK 35")
require('android:usesCleartextTraffic="false"' in manifest, "Release-Manifest verbietet Klartext")
require('cleartextTrafficPermitted="false"' in network, "Release Network Security verbietet Klartext")
require('https://tools.d-razz.de/' in source, "Standardserver ist gesetzt")
require('<string name="app_name">RipMe</string>' in (ROOT / 'app/src/main/res/values/strings.xml').read_text(), "Sichtbarer App-Name RipMe")
require('Planeditor' not in source and 'EditorScreen' not in source, "Planeditor aus App entfernt")
require('WebView' not in source, "Keine WebView")
require('api.openai.com' not in source.lower(), "Keine direkte OpenAI-URL")
require('sk-' not in source, "Kein erkennbarer OpenAI-Key")
require('Credentials.basic' in api, "Basic Auth über OkHttp")
for route in ['tracker/session', '/analysis', '/analysis/status']:
require(route in api, f"API-Route vorhanden: {route}")
require('trainingsplan/api' not in api, "Keine Planeditor-API im Android-Client")
tracker_screen = (ROOT / 'app/src/main/java/de/drazz/boehmitools/training/ui/tracker/TrackerScreen.kt').read_text()
require('ScrollableTabRow' not in tracker_screen, "Hauptnavigation ist nicht horizontal scrollbar")
require(tracker_screen.count('horizontalScroll(') == 2, "Nur Wochen und Tage scrollen horizontal")
require('record.obj("result")' in tracker_screen, "Analyseergebnis liest Serverfeld result")
require('last_seen_version_code' in source, "WhatsNew-Version wird gespeichert")
require('BuildConfig.VERSION_NAME' in source, "Versionsanzeige ist vorhanden")
fixtures = ROOT / "app/src/test/resources/samples"
for name in ["phase-1", "calihoss-newbie-8-wochen"]:
wrapper = json.loads((fixtures / f"plans/{name}.json").read_text())
config = wrapper["config"]
require(config.get("schema_version") == 3, f"{name}: schema_version 3")
require(config.get("contract_version") == 2, f"{name}: contract_version 2")
groups = {"days": [], "rotations": [], "placements": [], "steps": []}
for day in config.get("days", []):
groups["days"].append(day.get("id"))
for rotation in day.get("rotations", []):
groups["rotations"].append(rotation.get("id"))
for exercise in rotation.get("exercises", []):
groups["placements"].append(exercise.get("id"))
require(bool(re.fullmatch(r"d\d+-r\d+-e\d+", exercise.get("legacy_id", ""))), f"{name}: Legacy-ID gültig")
require(bool(exercise.get("result_schema")), f"{name}: Übungsschema vorhanden")
for stage in config.get("stages", {}).values():
for step in stage.get("steps", []):
groups["steps"].append(step.get("id"))
require(bool(step.get("result_schema")), f"{name}: Stufenschema vorhanden")
for label, ids in groups.items():
require(all(ids), f"{name}: {label} vollständig")
require(len(ids) == len(set(ids)), f"{name}: {label} eindeutig")
for name in ["phase-1", "calihoss-newbie-8-wochen"]:
tracker = json.loads((fixtures / f"sessions/{name}.json").read_text())
require(1 <= int(tracker.get("version", 0)) <= 7, f"{name}: Legacy-Tracker unterstützt")
require(bool(tracker.get("sessions")), f"{name}: Sessions vorhanden")
print(f"PASS: {len(checks)} Prüfungen")
if errors:
print(f"FAIL: {len(errors)} Prüfungen")
for error in errors:
print(f"- {error}")
raise SystemExit(1)