Startpunkt 02.10.2026: aktueller Stand des Trainingsplans
Historie bewusst neu aufgesetzt, ein einziger Commit als neuer Ausgangspunkt.
This commit is contained in:
commit
8fc77212cb
18 files changed
+10863
No files matched your search
@@ -0,0 +1,193 @@
|
||||
#!/usr/bin/env python3
|
||||
"""API-Test fuer Einstellungen + Auto-Reset (offener Modus).
|
||||
|
||||
Lauf: python3 tests/test_api_settings.py
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
|
||||
BASE = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
STATE = "/tmp/tp_state2"
|
||||
PORT = 8255
|
||||
BASE_URL = f"http://127.0.0.1:{PORT}"
|
||||
|
||||
PASS = 0
|
||||
FAIL = 0
|
||||
|
||||
|
||||
def check(name, cond, detail=""):
|
||||
global PASS, FAIL
|
||||
if cond:
|
||||
PASS += 1
|
||||
print(f" ok {name}")
|
||||
else:
|
||||
FAIL += 1
|
||||
print(f"FAIL {name} {detail}")
|
||||
|
||||
|
||||
def req(method, path, body=None):
|
||||
url = BASE_URL + path
|
||||
data = None
|
||||
headers = {}
|
||||
if body is not None:
|
||||
data = json.dumps(body).encode("utf-8")
|
||||
headers["Content-Type"] = "application/json"
|
||||
r = urllib.request.Request(url, data=data, headers=headers, method=method)
|
||||
try:
|
||||
with urllib.request.urlopen(r, timeout=5) as resp:
|
||||
return resp.status, json.loads(resp.read().decode("utf-8"))
|
||||
except urllib.error.HTTPError as e:
|
||||
try:
|
||||
return e.code, json.loads(e.read().decode("utf-8"))
|
||||
except Exception:
|
||||
return e.code, {}
|
||||
|
||||
|
||||
def main():
|
||||
if os.path.exists(STATE):
|
||||
shutil.rmtree(STATE)
|
||||
os.makedirs(STATE, exist_ok=True)
|
||||
env = dict(os.environ, TRAINING_STATE_DIR=STATE, PORT=str(PORT))
|
||||
proc = subprocess.Popen(
|
||||
[sys.executable, os.path.join(BASE, "server.py")],
|
||||
env=env, cwd=BASE,
|
||||
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
try:
|
||||
for _ in range(40):
|
||||
time.sleep(0.25)
|
||||
try:
|
||||
urllib.request.urlopen(BASE_URL + "/api/meta", timeout=1)
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
print("Server nicht erreichbar")
|
||||
sys.exit(1)
|
||||
|
||||
st, s = req("GET", "/api/settings")
|
||||
check("Settings Defaults", st == 200
|
||||
and s["theme"] == "dark" and s["accent"] == "white"
|
||||
and s["autoReset"] is False and s["showTips"] is True, s)
|
||||
|
||||
st, s = req("PUT", "/api/settings",
|
||||
{"theme": "light", "accent": "green",
|
||||
"autoReset": True, "showTips": False})
|
||||
check("Settings speichern", st == 200 and s["theme"] == "light"
|
||||
and s["accent"] == "green" and s["autoReset"] is True
|
||||
and s["showTips"] is False, s)
|
||||
st, s = req("GET", "/api/settings")
|
||||
check("Settings persistiert", s["theme"] == "light"
|
||||
and s["autoReset"] is True and s["showTips"] is False, s)
|
||||
|
||||
st, s = req("PUT", "/api/settings", {"autoReset": False})
|
||||
check("Teil-Update", s["autoReset"] is False
|
||||
and s["theme"] == "light", s)
|
||||
req("PUT", "/api/settings", {"autoReset": True, "showTips": True})
|
||||
|
||||
ex = "Push/Bankdrücken KH (je Hand)"
|
||||
st, done = req("POST", "/api/sessions",
|
||||
{"activity": "gym", "day": "Push"})
|
||||
did = done["id"]
|
||||
sets = []
|
||||
for i, w in enumerate(["18", "18,5", "20", ""]):
|
||||
sets.append({"exercise": ex, "sort": i, "weight": w,
|
||||
"reps": "10", "done": 1 if i < 3 else 0})
|
||||
req("PATCH", f"/api/sessions/{did}", {"sets": sets})
|
||||
req("PATCH", f"/api/sessions/{did}", {"meta": {"status": "done"}})
|
||||
|
||||
req("PUT", "/api/settings", {"autoReset": False})
|
||||
st, s1 = req("POST", "/api/sessions", {"activity": "gym", "day": "Push"})
|
||||
check("AutoReset OFF: keine vorbefuellten Sets",
|
||||
len(s1["entries"]) == 0, s1["entries"])
|
||||
req("DELETE", f"/api/sessions/{s1['id']}")
|
||||
|
||||
req("PUT", "/api/settings", {"autoReset": True})
|
||||
st, s2 = req("POST", "/api/sessions", {"activity": "gym", "day": "Push"})
|
||||
entries = s2["entries"]
|
||||
check("AutoReset ON: nur 3 gefuellte Sets geladen",
|
||||
len(entries) == 3, entries)
|
||||
check("AutoReset ON: Gewichte uebernommen",
|
||||
[e["weight"] for e in entries] == ["18", "18,5", "20"],
|
||||
[e["weight"] for e in entries])
|
||||
check("AutoReset ON: Abhak-Status zurueckgesetzt",
|
||||
all(e["done"] == 0 for e in entries), entries)
|
||||
check("AutoReset ON: Reps uebernommen",
|
||||
all(e["reps"] == "10" for e in entries), entries)
|
||||
|
||||
new_sets = [{"exercise": ex, "sort": 0, "weight": "999", "reps": "1",
|
||||
"done": 0}]
|
||||
req("PATCH", f"/api/sessions/{s2['id']}", {"sets": new_sets})
|
||||
st, filled = req("POST", f"/api/sessions/{s2['id']}/autofill")
|
||||
check("Autofill: Saetze ersetzt", st == 200
|
||||
and len(filled["entries"]) == 3
|
||||
and filled["entries"][0]["weight"] == "18", filled["entries"])
|
||||
|
||||
exB = "Push/Schrägbank KH (je Hand)"
|
||||
req("PATCH", f"/api/sessions/{s2['id']}",
|
||||
{"sets": [{"exercise": exB, "sort": 0, "weight": "14", "reps": "12",
|
||||
"done": 0}]})
|
||||
st, filled = req("POST", f"/api/sessions/{s2['id']}/autofill")
|
||||
b = [e for e in filled["entries"] if e["exercise"] == exB]
|
||||
check("Autofill: Uebung ohne Verlauf unberuehrt",
|
||||
b and b[0]["weight"] == "14", filled["entries"])
|
||||
|
||||
req("PUT", "/api/settings",
|
||||
{"autoReset": "ja", "showTips": 1, "bogus": 42, "theme": "oled"})
|
||||
st, s = req("GET", "/api/settings")
|
||||
check("Typen + unbekannte Keys", s["autoReset"] is True
|
||||
and s["showTips"] is True and "bogus" not in s
|
||||
and s["theme"] == "oled", s)
|
||||
|
||||
# --- Plan-Gewichte vorbefuellen ------------------------------------
|
||||
req("PUT", "/api/settings", {"autoReset": False, "planPrefill": True})
|
||||
st, s3 = req("POST", "/api/sessions", {"activity": "gym", "day": "Push"})
|
||||
bd = [e for e in s3["entries"] if e["exercise"] == "Push/Bankdrücken KH (je Hand)"]
|
||||
check("PlanPrefill: alle Plan-Saetze mit startKg",
|
||||
len(bd) == 4 and all(e["weight"] == "18" for e in bd), bd)
|
||||
check("PlanPrefill: alle Uebungen des Tags befuellt",
|
||||
len({e["exercise"] for e in s3["entries"]}) == 8,
|
||||
len(s3["entries"]))
|
||||
check("PlanPrefill: Reps leer, done=0",
|
||||
all(e["reps"] == "" and e["done"] == 0 for e in s3["entries"]),
|
||||
s3["entries"])
|
||||
req("DELETE", f"/api/sessions/{s3['id']}")
|
||||
# Auto-Reset hat Vorrang vor Plan-Gewichten (je Uebung)
|
||||
req("PUT", "/api/settings", {"autoReset": True, "planPrefill": True})
|
||||
st, s4 = req("POST", "/api/sessions", {"activity": "gym", "day": "Push"})
|
||||
bd4 = [e for e in s4["entries"] if e["exercise"] == "Push/Bankdrücken KH (je Hand)"]
|
||||
sb4 = [e for e in s4["entries"] if e["exercise"] == "Push/Schrägbank KH (je Hand)"]
|
||||
check("PlanPrefill+AutoReset: letztes Workout gewinnt",
|
||||
len(bd4) == 3
|
||||
and [e["weight"] for e in bd4] == ["18", "18,5", "20"], bd4)
|
||||
check("PlanPrefill+AutoReset: ohne Verlauf Plan-Gewicht",
|
||||
len(sb4) == 3 and all(e["weight"] == "14" for e in sb4), sb4)
|
||||
req("DELETE", f"/api/sessions/{s4['id']}")
|
||||
|
||||
req("PUT", "/api/settings",
|
||||
{"theme": "dark", "oled": False, "accent": "white",
|
||||
"autoReset": False, "planPrefill": False, "showTips": True,
|
||||
"language": "de", "setupDone": False, "onboarded": False,
|
||||
"weightUnit": "kg", "startTab": "today"})
|
||||
st, s = req("GET", "/api/settings")
|
||||
check("Zurueck auf Standard", s == {
|
||||
"theme": "dark", "oled": False, "accent": "white",
|
||||
"autoReset": False, "planPrefill": False, "showTips": True,
|
||||
"language": "de", "setupDone": False, "onboarded": False,
|
||||
"weightUnit": "kg", "startTab": "today"}, s)
|
||||
|
||||
finally:
|
||||
proc.terminate()
|
||||
proc.wait(timeout=5)
|
||||
|
||||
print(f"\n{PASS} ok, {FAIL} fail")
|
||||
sys.exit(1 if FAIL else 0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user