All checks were successful
Deploy Development / deploy (push) Successful in 46s
Test Suite / pytest-backend (push) Successful in 5m3s
Test Suite / lint-backend (push) Successful in 3s
Test Suite / compose-smoke (push) Has been skipped
Test Suite / k6 /api/health Baseline (push) Successful in 19s
Test Suite / playwright-smoke (push) Successful in 13s
Gate- und Kit-Übungen legen ein Arbeitspaket plus Schedule an; Today zeigt nur fällige Wochentage, nicht die ganze Gate-Liste. Co-authored-by: Cursor <cursoragent@cursor.com>
192 lines
6.4 KiB
Python
192 lines
6.4 KiB
Python
"""AP2.2c — A1 maturity journey End-to-End (Spagat Happy Path)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from tests.factories import provision_user_in_tenant
|
|
from tests.test_initiatives_actions import _auth, _create_initiative, _login
|
|
|
|
_STAGE1 = "Stufe 1 — Basis"
|
|
_STAGE1_EXERCISES = ("Vorbeuge-Dehnung", "Hüftöffner (Schmetterling)")
|
|
|
|
|
|
def _create_spagat(client, token):
|
|
created = _create_initiative(
|
|
client,
|
|
token,
|
|
title="Spagat können",
|
|
archetype_key="initiative.maturity_journey",
|
|
)
|
|
assert created.status_code == 201
|
|
body = created.json()
|
|
assert body["starter_kit"]["applied"] is True
|
|
return body["id"]
|
|
|
|
|
|
def test_a1_starter_kit_spagat_structure(client):
|
|
"""Starter-Kit: Stufen, Training-Project, Wochentags-Übung, Operating Context."""
|
|
user = provision_user_in_tenant(tenant_role="admin")
|
|
token = _login(client, user)
|
|
initiative_id = _create_spagat(client, token)
|
|
|
|
ctx = client.get(
|
|
f"/api/initiatives/{initiative_id}/operating-context",
|
|
headers=_auth(token),
|
|
)
|
|
assert ctx.status_code == 200
|
|
body = ctx.json()
|
|
assert body["method_key"] == "maturity_progression"
|
|
assert "maturity_stage" in body["steering_elements"]
|
|
assert "recurring_rhythm" in body["steering_elements"]
|
|
assert body["ui_profile"]["controlDefaultRoute"] == "/control/status"
|
|
|
|
roadmap = client.get(
|
|
f"/api/initiatives/{initiative_id}/roadmap/items",
|
|
headers=_auth(token),
|
|
)
|
|
assert roadmap.status_code == 200
|
|
stages = [i for i in roadmap.json() if i.get("item_type") == "maturity_stage"]
|
|
assert len(stages) == 3
|
|
assert sum(1 for s in stages if s["status"] == "active") == 1
|
|
assert any(s["title"] == _STAGE1 and s["status"] == "active" for s in stages)
|
|
|
|
recurring = client.get(
|
|
f"/api/initiatives/{initiative_id}/recurring",
|
|
headers=_auth(token),
|
|
)
|
|
assert recurring.status_code == 200
|
|
assert any(r["title"] == _STAGE1_EXERCISES[0] and r["status"] == "active" for r in recurring.json())
|
|
assert any(r["title"] == _STAGE1_EXERCISES[1] and r["status"] == "active" for r in recurring.json())
|
|
|
|
projects = client.get(
|
|
f"/api/initiatives/{initiative_id}/projects",
|
|
headers=_auth(token),
|
|
)
|
|
assert projects.status_code == 200
|
|
assert any(p["title"] == "Training" for p in projects.json())
|
|
|
|
snap = client.get(
|
|
f"/api/initiatives/{initiative_id}/steering-snapshot",
|
|
headers=_auth(token),
|
|
)
|
|
assert snap.status_code == 200
|
|
snap_body = snap.json()
|
|
assert snap_body["steering_kernel"]["primary_method_key"] == "maturity_progression"
|
|
assert snap_body.get("steering_guidance")
|
|
next_actions = snap_body.get("next_actions") or []
|
|
assert next_actions
|
|
top = next_actions[0]
|
|
assert top.get("kind") in ("recurring_due", "action", "review_milestone")
|
|
if top.get("kind") == "recurring_due":
|
|
assert top.get("reason_code") == "recurring_due"
|
|
|
|
|
|
def test_a1_stage_verify_rotates_recurring_and_next_action(client):
|
|
"""AP2.0e: Stufe 1 reached → alte Übung pausiert, Stufe 2 aktiv, neue Routine."""
|
|
user = provision_user_in_tenant(tenant_role="admin")
|
|
token = _login(client, user)
|
|
initiative_id = _create_spagat(client, token)
|
|
|
|
items = client.get(
|
|
f"/api/initiatives/{initiative_id}/roadmap/items",
|
|
headers=_auth(token),
|
|
).json()
|
|
stage1 = next(i for i in items if i["title"] == _STAGE1)
|
|
|
|
snap_before = client.get(
|
|
f"/api/initiatives/{initiative_id}/steering-snapshot",
|
|
headers=_auth(token),
|
|
)
|
|
assert snap_before.status_code == 200
|
|
|
|
client.post(
|
|
f"/api/initiatives/{initiative_id}/evidence",
|
|
json={
|
|
"title": "Stufe 1 geschafft",
|
|
"roadmap_item_id": stage1["id"],
|
|
"status": "accepted",
|
|
},
|
|
headers=_auth(token),
|
|
)
|
|
|
|
verify = client.post(
|
|
f"/api/roadmap-items/{stage1['id']}/verify-reached",
|
|
headers=_auth(token),
|
|
)
|
|
assert verify.status_code == 200
|
|
body = verify.json()
|
|
assert body["status"] == "reached"
|
|
transition = body.get("maturity_transition") or {}
|
|
legacy = transition.get("legacy_linear") or {}
|
|
practice_ids = (legacy.get("practice_transition") or {}).get("practice_ids") or []
|
|
assert (
|
|
practice_ids
|
|
or transition.get("successors_activated")
|
|
or transition.get("joins_switched")
|
|
)
|
|
|
|
recurring = client.get(
|
|
f"/api/initiatives/{initiative_id}/recurring",
|
|
headers=_auth(token),
|
|
).json()
|
|
titles = {r["title"]: r["status"] for r in recurring}
|
|
for title in _STAGE1_EXERCISES:
|
|
assert titles.get(title) == "paused"
|
|
assert any(
|
|
t.startswith("Seitlicher Spagat") and titles[t] == "active" for t in titles
|
|
)
|
|
|
|
items_after = client.get(
|
|
f"/api/initiatives/{initiative_id}/roadmap/items",
|
|
headers=_auth(token),
|
|
).json()
|
|
stage2 = next(i for i in items_after if i["title"] == "Stufe 2 — Aufbau")
|
|
assert stage2["status"] == "active"
|
|
|
|
snap_after = client.get(
|
|
f"/api/initiatives/{initiative_id}/steering-snapshot",
|
|
headers=_auth(token),
|
|
)
|
|
assert snap_after.status_code == 200
|
|
next_after = snap_after.json().get("next_actions") or []
|
|
assert next_after
|
|
assert next_after[0].get("kind") == "recurring_due" or next_after[0].get("title") in (
|
|
"Seitlicher Spagat — links",
|
|
"Seitlicher Spagat — rechts",
|
|
"Aktive Vorbeuge",
|
|
)
|
|
|
|
|
|
def test_a1_journey_lists_stage_reached_event(client):
|
|
"""Journey enthält nach Verify mindestens ein Ereignis."""
|
|
user = provision_user_in_tenant(tenant_role="admin")
|
|
token = _login(client, user)
|
|
initiative_id = _create_spagat(client, token)
|
|
|
|
items = client.get(
|
|
f"/api/initiatives/{initiative_id}/roadmap/items",
|
|
headers=_auth(token),
|
|
).json()
|
|
stage1 = next(i for i in items if i["title"] == _STAGE1)
|
|
|
|
client.post(
|
|
f"/api/initiatives/{initiative_id}/evidence",
|
|
json={
|
|
"title": "Nachweis Stufe 1",
|
|
"roadmap_item_id": stage1["id"],
|
|
"status": "accepted",
|
|
},
|
|
headers=_auth(token),
|
|
)
|
|
client.post(
|
|
f"/api/roadmap-items/{stage1['id']}/verify-reached",
|
|
headers=_auth(token),
|
|
)
|
|
|
|
journey = client.get(
|
|
f"/api/initiatives/{initiative_id}/journey",
|
|
headers=_auth(token),
|
|
)
|
|
assert journey.status_code == 200
|
|
events = journey.json().get("events") or []
|
|
assert len(events) >= 1
|