"""AP1.4 — RoadmapItem & Quality Gate tests.""" from __future__ import annotations from tests.factories import provision_user_in_tenant from tests.test_initiatives_actions import ( _auth, _create_initiative, _login, ) def _create_roadmap_item(client, token, initiative_id, **kwargs): body = {"title": "Gate A", "item_type": "milestone", **kwargs} return client.post( f"/api/initiatives/{initiative_id}/roadmap/items", json=body, headers=_auth(token), ) def test_roadmap_item_crud(client): user = provision_user_in_tenant(tenant_role="member") token = _login(client, user) initiative_id = _create_initiative(client, token).json()["id"] created = _create_roadmap_item( client, token, initiative_id, sequencing_mode="parallel", item_type="maturity_stage", ) assert created.status_code == 201 item = created.json() assert item["item_type"] == "maturity_stage" assert item["sequencing_mode"] == "parallel" listed = client.get( f"/api/initiatives/{initiative_id}/roadmap/items", headers=_auth(token), ) assert listed.status_code == 200 assert len(listed.json()) >= 1 patched = client.patch( f"/api/roadmap-items/{item['id']}", json={"status": "at_risk"}, headers=_auth(token), ) assert patched.status_code == 200 assert patched.json()["status"] == "at_risk" deleted = client.delete(f"/api/roadmap-items/{item['id']}", headers=_auth(token)) assert deleted.status_code == 204 def test_verify_reached_requires_evidence(client): user = provision_user_in_tenant(tenant_role="member") token = _login(client, user) initiative_id = _create_initiative(client, token).json()["id"] item = _create_roadmap_item(client, token, initiative_id, status="active").json() fail = client.post( f"/api/roadmap-items/{item['id']}/verify-reached", headers=_auth(token), ) assert fail.status_code == 400 evidence = client.post( f"/api/initiatives/{initiative_id}/evidence", json={ "title": "Nachweis", "roadmap_item_id": item["id"], "status": "accepted", }, headers=_auth(token), ) assert evidence.status_code == 201 ok = client.post( f"/api/roadmap-items/{item['id']}/verify-reached", headers=_auth(token), ) assert ok.status_code == 200 assert ok.json()["status"] == "reached" assert ok.json()["verify_reason"] == "evidence_accepted" def test_milestone_compat_api_uses_roadmap(client): user = provision_user_in_tenant(tenant_role="member") token = _login(client, user) initiative_id = _create_initiative(client, token).json()["id"] created = client.post( f"/api/initiatives/{initiative_id}/milestones", json={"title": "Legacy MS", "status": "planned"}, headers=_auth(token), ) assert created.status_code == 201 ms_id = created.json()["id"] roadmap = client.get( f"/api/initiatives/{initiative_id}/roadmap/items", headers=_auth(token), ).json() assert any(i["id"] == ms_id and i["item_type"] == "milestone" for i in roadmap) def test_steering_snapshot_reads_roadmap_items(client): user = provision_user_in_tenant(tenant_role="member") token = _login(client, user) initiative_id = _create_initiative(client, token).json()["id"] _create_roadmap_item(client, token, initiative_id, status="active", target_date="2026-12-31") snap = client.get( f"/api/initiatives/{initiative_id}/steering-snapshot", headers=_auth(token), ).json() assert snap.get("roadmap_items") assert snap.get("upcoming_milestones") assert len(snap["upcoming_roadmap_items"]) >= 1