176 lines
6.6 KiB
Python
176 lines
6.6 KiB
Python
from __future__ import annotations
|
|
|
|
import importlib.util
|
|
import json
|
|
import os
|
|
import uuid
|
|
from pathlib import Path
|
|
|
|
|
|
def load_module(module_path: Path, data_dir: Path, plans_dir: Path):
|
|
try:
|
|
import flask # noqa: F401
|
|
except ModuleNotFoundError:
|
|
import pytest
|
|
pytest.skip("Flask ist in dieser isolierten Testumgebung nicht installiert")
|
|
os.environ["TRAININGSTRACKER_DATA_DIR"] = str(data_dir)
|
|
os.environ["TRAININGSTRACKER_PLANS_DIR"] = str(plans_dir)
|
|
name = f"tracker_test_app_{uuid.uuid4().hex}"
|
|
spec = importlib.util.spec_from_file_location(name, module_path)
|
|
module = importlib.util.module_from_spec(spec)
|
|
assert spec.loader
|
|
spec.loader.exec_module(module)
|
|
return module
|
|
|
|
|
|
def sample_plan() -> dict:
|
|
return {
|
|
"name": "Testplan",
|
|
"revision": 4,
|
|
"published_revision": 4,
|
|
"config": {
|
|
"schema_version": 5,
|
|
"contract_version": 4,
|
|
"plan_id": "testplan",
|
|
"meta": {"title": "Testplan"},
|
|
"exercises": [
|
|
{
|
|
"id": "exercise-push",
|
|
"name": "Push-up-Progression",
|
|
"progressions": [
|
|
{"id": "progression-high-plank", "name": "High Plank"},
|
|
{"id": "progression-negative", "name": "Negative"},
|
|
],
|
|
"current_progression_id": "progression-high-plank",
|
|
}
|
|
],
|
|
"days": [
|
|
{
|
|
"id": "day-1",
|
|
"num": 1,
|
|
"name": "Tag 1",
|
|
"warmup": {"items": ["Mobilisieren"]},
|
|
"cooldown": {"items": ["Atmen"]},
|
|
"exercises": [{"id": "item-1", "exercise_id": "exercise-push"}],
|
|
},
|
|
{
|
|
"id": "day-2",
|
|
"num": 2,
|
|
"name": "Tag 2",
|
|
"warmup": {"items": []},
|
|
"cooldown": {"items": []},
|
|
"exercises": [{"id": "item-2", "exercise_id": "exercise-push"}],
|
|
}
|
|
],
|
|
},
|
|
"draft": {
|
|
"schema_version": 5,
|
|
"contract_version": 4,
|
|
"plan_id": "testplan",
|
|
"meta": {"title": "Testplan"},
|
|
"exercises": [
|
|
{
|
|
"id": "exercise-push",
|
|
"name": "Push-up-Progression",
|
|
"progressions": [
|
|
{"id": "progression-high-plank", "name": "High Plank"},
|
|
{"id": "progression-negative", "name": "Negative"},
|
|
],
|
|
"current_progression_id": "progression-high-plank",
|
|
}
|
|
],
|
|
"days": [
|
|
{
|
|
"id": "day-1",
|
|
"num": 1,
|
|
"name": "Tag 1",
|
|
"warmup": {"items": ["Mobilisieren"]},
|
|
"cooldown": {"items": ["Atmen"]},
|
|
"exercises": [{"id": "item-1", "exercise_id": "exercise-push"}],
|
|
},
|
|
{
|
|
"id": "day-2",
|
|
"num": 2,
|
|
"name": "Tag 2",
|
|
"warmup": {"items": []},
|
|
"cooldown": {"items": []},
|
|
"exercises": [{"id": "item-2", "exercise_id": "exercise-push"}],
|
|
}
|
|
],
|
|
},
|
|
}
|
|
|
|
|
|
def test_lists_only_training_plans_and_returns_slim_detail(tmp_path: Path):
|
|
plans = tmp_path / "data" / "trainingsplan" / "plans"
|
|
data_dir = tmp_path / "data" / "trainingstracker"
|
|
plans.mkdir(parents=True)
|
|
(plans / "training.json").write_text(json.dumps(sample_plan()), encoding="utf-8")
|
|
(plans / "food.json").write_text(json.dumps({"name": "Essen", "config": {"type": "recipe", "days": []}}), encoding="utf-8")
|
|
|
|
module = load_module(Path(__file__).parents[1] / "app.py", data_dir, plans)
|
|
client = module.app.test_client()
|
|
|
|
listed = client.get("/api/plans").get_json()
|
|
assert [item["id"] for item in listed["plans"]] == ["training.json"]
|
|
|
|
detail = client.get("/api/plans/training.json").get_json()
|
|
cfg = detail["plan"]["config"]
|
|
assert cfg["schema_version"] == 5
|
|
assert cfg["contract_version"] == 4
|
|
assert cfg["days"][0]["exercises"][0]["exercise"]["current_progression"]["name"] == "High Plank"
|
|
|
|
|
|
def test_current_progression_update_writes_config_and_draft(tmp_path: Path):
|
|
plans = tmp_path / "data" / "trainingsplan" / "plans"
|
|
data_dir = tmp_path / "data" / "trainingstracker"
|
|
plans.mkdir(parents=True)
|
|
plan_file = plans / "training.json"
|
|
plan_file.write_text(json.dumps(sample_plan()), encoding="utf-8")
|
|
|
|
module = load_module(Path(__file__).parents[1] / "app.py", data_dir, plans)
|
|
client = module.app.test_client()
|
|
|
|
response = client.patch(
|
|
"/api/plans/training.json/exercises/exercise-push/current",
|
|
json={"current_progression_id": "progression-negative"},
|
|
)
|
|
|
|
assert response.status_code == 200
|
|
payload = response.get_json()
|
|
exercise = payload["plan"]["config"]["exercises"][0]
|
|
assert exercise["current_progression_id"] == "progression-negative"
|
|
day_progressions = [
|
|
item["exercise"]["current_progression"]["id"]
|
|
for day in payload["plan"]["config"]["days"]
|
|
for item in day["exercises"]
|
|
]
|
|
assert day_progressions == ["progression-negative", "progression-negative"]
|
|
|
|
saved = json.loads(plan_file.read_text(encoding="utf-8"))
|
|
assert saved["config"]["exercises"][0]["current_progression_id"] == "progression-negative"
|
|
assert saved["draft"]["exercises"][0]["current_progression_id"] == "progression-negative"
|
|
assert saved["revision"] == 5
|
|
assert saved["published_revision"] == 5
|
|
|
|
|
|
def test_frontend_no_longer_contains_session_or_analysis_surfaces():
|
|
source = (Path(__file__).parents[1] / "static" / "index.html").read_text(encoding="utf-8")
|
|
assert "data-current-progression" in source
|
|
assert "analysis/status" not in source
|
|
assert "sessionView" not in source
|
|
assert "week" not in source.lower()
|
|
|
|
|
|
def test_frontend_embeds_plugin_mount_path(tmp_path: Path):
|
|
plans = tmp_path / "data" / "trainingsplan" / "plans"
|
|
data_dir = tmp_path / "data" / "trainingstracker"
|
|
plans.mkdir(parents=True)
|
|
(plans / "training.json").write_text(json.dumps(sample_plan()), encoding="utf-8")
|
|
|
|
module = load_module(Path(__file__).parents[1] / "app.py", data_dir, plans)
|
|
client = module.app.test_client()
|
|
|
|
html = client.get("/", environ_overrides={"SCRIPT_NAME": "/plugins/trainingstracker"}).get_data(as_text=True)
|
|
assert 'data-base="/plugins/trainingstracker"' in html
|