Some checks failed
Test Suite / lint-backend (push) Waiting to run
Test Suite / compose-smoke (push) Waiting to run
Test Suite / k6 /api/health Baseline (push) Blocked by required conditions
Test Suite / playwright-smoke (push) Blocked by required conditions
Deploy Development / deploy (push) Successful in 46s
Test Suite / pytest-backend (push) Has been cancelled
Initiative-API fuer Roadmap-Dependencies, SVG-Layout mit Liste/Graph-Umschalter auf der Zielzustaende-Seite. Co-authored-by: Cursor <cursoragent@cursor.com>
149 lines
4.7 KiB
Python
149 lines
4.7 KiB
Python
"""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"] in ("criteria_ready", "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
|
|
|
|
|
|
def test_initiative_roadmap_dependencies_list(client):
|
|
user = provision_user_in_tenant(tenant_role="member")
|
|
token = _login(client, user)
|
|
initiative_id = _create_initiative(client, token).json()["id"]
|
|
gate_a = _create_roadmap_item(client, token, initiative_id, title="Gate A").json()
|
|
gate_b = _create_roadmap_item(client, token, initiative_id, title="Gate B").json()
|
|
|
|
created = client.post(
|
|
f"/api/roadmap-items/{gate_a['id']}/dependencies",
|
|
json={"to_item_id": gate_b["id"], "dependency_type": "requires"},
|
|
headers=_auth(token),
|
|
)
|
|
assert created.status_code == 201
|
|
|
|
listed = client.get(
|
|
f"/api/initiatives/{initiative_id}/roadmap/dependencies",
|
|
headers=_auth(token),
|
|
)
|
|
assert listed.status_code == 200
|
|
deps = listed.json()
|
|
assert len(deps) == 1
|
|
assert deps[0]["from_item_id"] == gate_a["id"]
|
|
assert deps[0]["to_item_id"] == gate_b["id"]
|
|
assert deps[0]["dependency_type"] == "requires"
|