tests/test_plan_lists_wp15.py hinzugefügt
All checks were successful
Deploy Trainer_LLM to llm-node / deploy (push) Successful in 1s
All checks were successful
Deploy Trainer_LLM to llm-node / deploy (push) Successful in 1s
This commit is contained in:
parent
7f821b5723
commit
123df8a48a
73
tests/test_plan_lists_wp15.py
Normal file
73
tests/test_plan_lists_wp15.py
Normal 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
|
||||||
Loading…
Reference in New Issue
Block a user