Kairo-Jinkendo/backend/tests/test_epic_rollup_unit.py

126 lines
3.7 KiB
Python
Raw Permalink Normal View History

"""Unit tests — Epic roll-up read model (P4)."""
from __future__ import annotations
from steering.read_models.epic_rollup import (
compute_epic_rollup,
epic_rollup_attention_items,
)
def _item(
*,
id: str,
title: str,
item_kind: str = "story",
status: str = "accepted",
parent_backlog_id: str | None = None,
converted_action_id: str | None = None,
) -> dict:
return {
"id": id,
"title": title,
"item_kind": item_kind,
"status": status,
"parent_backlog_id": parent_backlog_id,
"converted_action_id": converted_action_id,
}
def test_epic_rollup_empty_epic():
rollups = compute_epic_rollup(
backlog_items=[_item(id="e1", title="Epic", item_kind="epic")],
actions=[],
)
assert len(rollups) == 1
assert rollups[0]["status"] == "empty"
assert rollups[0]["child_total"] == 0
def test_epic_rollup_intake_only():
rollups = compute_epic_rollup(
backlog_items=[
_item(id="e1", title="Checkout", item_kind="epic"),
_item(id="s1", title="Login", parent_backlog_id="e1"),
_item(id="s2", title="Pay", parent_backlog_id="e1"),
],
actions=[],
)
assert rollups[0]["status"] == "intake_only"
assert rollups[0]["child_total"] == 2
assert rollups[0]["child_uncommitted"] == 2
assert rollups[0]["completion_ratio"] == 0.0
def test_epic_rollup_partial_and_done():
rollups = compute_epic_rollup(
backlog_items=[
_item(id="e1", title="Epic", item_kind="epic"),
_item(
id="s1",
title="Done story",
parent_backlog_id="e1",
status="converted",
converted_action_id="a1",
),
_item(id="s2", title="Open story", parent_backlog_id="e1"),
],
actions=[
{"id": "a1", "status": "done"},
{"id": "a2", "status": "in_progress"},
],
)
assert rollups[0]["status"] == "in_progress"
assert rollups[0]["actions_done"] == 1
assert rollups[0]["child_uncommitted"] == 1
assert rollups[0]["completion_ratio"] == 0.5
def test_epic_rollup_all_done():
rollups = compute_epic_rollup(
backlog_items=[
_item(id="e1", title="Epic", item_kind="epic"),
_item(
id="s1",
title="A",
parent_backlog_id="e1",
status="converted",
converted_action_id="a1",
),
],
actions=[{"id": "a1", "status": "done"}],
)
assert rollups[0]["status"] == "done"
assert rollups[0]["completion_ratio"] == 1.0
def test_epic_rollup_attention_awaiting_commit():
rollups = compute_epic_rollup(
backlog_items=[
_item(id="e1", title="Epic", item_kind="epic"),
_item(id="s1", title="Story", parent_backlog_id="e1"),
],
actions=[],
)
items = epic_rollup_attention_items(initiative_id="init-1", rollups=rollups)
assert any(i["reason_code"] == "epic_awaiting_commit" for i in items)
def test_epic_rollup_attention_split_focus():
rollups = compute_epic_rollup(
backlog_items=[
_item(id="e1", title="Epic", item_kind="epic"),
_item(
id="s1",
title="Running",
parent_backlog_id="e1",
status="converted",
converted_action_id="a1",
),
_item(id="s2", title="Waiting", parent_backlog_id="e1"),
],
actions=[{"id": "a1", "status": "in_progress"}],
)
items = epic_rollup_attention_items(initiative_id="init-1", rollups=rollups)
assert any(i["reason_code"] == "epic_uncommitted_during_execution" for i in items)