tests/test_plan_lists_wp15.py hinzugefügt
All checks were successful
Deploy Trainer_LLM to llm-node / deploy (push) Successful in 1s

This commit is contained in:
Lars 2025-08-13 07:07:29 +02:00
parent 7f821b5723
commit 123df8a48a

View File

@ -0,0 +1,73 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Listen-/Filter-Tests für Templates & Pläne (v0.1.0)."""
import os
import requests
from datetime import datetime, timezone, timedelta
BASE = os.getenv("BASE_URL", "http://127.0.0.1:8000").rstrip("/")
def test_list_plan_templates_filters():
# Zwei Templates anlegen (unterschiedliche Sections/Goals)
tpl1 = {
"name": "ListTpl A", "discipline": "Karate", "age_group": "Teenager", "target_group": "Breitensport", "total_minutes": 60,
"sections": [{"name": "Warmup", "target_minutes": 10, "must_keywords": ["Reaktion"], "forbid_keywords": [], "ideal_keywords": ["Koordination"], "supplement_keywords": [], "capability_targets": {}}],
"goals": ["Technik"], "equipment_allowed": [], "created_by": "tester", "version": "1.0"
}
tpl2 = {
"name": "ListTpl B", "discipline": "Karate", "age_group": "Erwachsene", "target_group": "Breitensport", "total_minutes": 60,
"sections": [{"name": "Technikblock", "target_minutes": 30, "must_keywords": ["Mae-Geri"], "forbid_keywords": [], "ideal_keywords": ["Timing"], "supplement_keywords": ["Partnerarbeit"], "capability_targets": {}}],
"goals": ["Kondition"], "equipment_allowed": [], "created_by": "tester", "version": "1.0"
}
r1 = requests.post(f"{BASE}/plan_templates", json=tpl1); assert r1.status_code == 200
r2 = requests.post(f"{BASE}/plan_templates", json=tpl2); assert r2.status_code == 200
# Filter: discipline=Karate & section=Warmup → sollte tpl1 enthalten
r = requests.get(f"{BASE}/plan_templates", params={"discipline": "Karate", "section": "Warmup", "limit": 10, "offset": 0})
assert r.status_code == 200, r.text
js = r.json(); assert js["count"] >= 1
assert any(tpl["name"] == "ListTpl A" for tpl in js["items"])
# Filter: keyword=Timing → sollte tpl2 treffen (ideal_keywords)
r = requests.get(f"{BASE}/plan_templates", params={"keyword": "Timing"})
assert r.status_code == 200
js = r.json(); names = [t["name"] for t in js["items"]]
assert "ListTpl B" in names
def test_list_plans_filters_and_window():
# Plan A (Teenager), Plan B (Erwachsene)
base_tpl = {
"name": "ListTpl PlanBase", "discipline": "Karate", "age_group": "Teenager", "target_group": "Breitensport", "total_minutes": 45,
"sections": [{"name": "Warmup", "target_minutes": 10, "must_keywords": [], "forbid_keywords": [], "capability_targets": {}}],
"goals": ["Technik"], "equipment_allowed": [], "created_by": "tester", "version": "1.0"
}
rt = requests.post(f"{BASE}/plan_templates", json=base_tpl); assert rt.status_code == 200
tpl_id = rt.json()["id"]
now = datetime.now(timezone.utc)
plan_a = {
"template_id": tpl_id, "title": "List Plan A", "discipline": "Karate", "age_group": "Teenager", "target_group": "Breitensport", "total_minutes": 45,
"sections": [{"name": "Warmup", "minutes": 10, "items": []}], "goals": ["Technik"], "capability_summary": {}, "created_by": "tester",
"created_at": now.isoformat(), "source": "test"
}
plan_b = {
"template_id": tpl_id, "title": "List Plan B", "discipline": "Karate", "age_group": "Erwachsene", "target_group": "Breitensport", "total_minutes": 45,
"sections": [{"name": "Technikblock", "minutes": 30, "items": []}], "goals": ["Kondition"], "capability_summary": {}, "created_by": "tester",
"created_at": (now + timedelta(seconds=1)).isoformat(), "source": "test"
}
ra = requests.post(f"{BASE}/plan", json=plan_a); assert ra.status_code == 200
rb = requests.post(f"{BASE}/plan", json=plan_b); assert rb.status_code == 200
# Filter: age_group=Teenager & section=Warmup → sollte Plan A enthalten
r = requests.get(f"{BASE}/plans", params={"age_group": "Teenager", "section": "Warmup"})
assert r.status_code == 200
js = r.json(); assert js["count"] >= 1
assert any(p["title"] == "List Plan A" for p in js["items"])
# Zeitfenster: created_from nach Plan A → sollte Plan B enthalten
r = requests.get(f"{BASE}/plans", params={"created_from": (now + timedelta(milliseconds=500)).isoformat()})
assert r.status_code == 200
js = r.json(); titles = [p["title"] for p in js["items"]]
assert "List Plan B" in titles