"""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