Add kanban dependency view summaries

This commit is contained in:
HumbleTurtle
2026-05-10 03:35:57 -03:00
parent dfead93d15
commit ecb549d159
2 changed files with 242 additions and 6 deletions
+54 -2
View File
@@ -19,7 +19,7 @@ def load_module():
return module
def node(path, status="planned", metadata=None, tags=None, content="body text", archived_at=None, node_type="plan"):
def node(path, status="planned", metadata=None, tags=None, content="body text", archived_at=None, node_type="plan", links=None):
folder, name = path.rsplit("/", 1)
merged_metadata = {"status": status}
if metadata:
@@ -32,7 +32,7 @@ def node(path, status="planned", metadata=None, tags=None, content="body text",
"name": name,
"type": node_type,
"tags": tags or [],
"links": [],
"links": links or [],
"metadata": merged_metadata,
"content_text": content,
"updated_at": "2026-05-06T12:00:00Z",
@@ -140,6 +140,56 @@ def test_kanban_list_grouping_and_filters(mod):
assert list(result["groups"]) == ["doing"]
def test_kanban_dependency_summary_filters_ready_and_blocking(mod):
plan = node(
"/kanban/backlog/plan",
"backlog",
metadata={"column": "backlog", "priority": "urgent", "blocked": False},
tags=["kanban"],
node_type="kanban_card",
links=[{"path": "/kanban/backlog/implementation", "relation": "blocks"}],
)
implementation = node(
"/kanban/todo/implementation",
"todo",
metadata={
"column": "todo",
"priority": "high",
"blocked_by": "/kanban/backlog/plan",
"external_blockers": [{"id": "deploy", "state": "open", "strength": "hard"}],
},
tags=["kanban"],
node_type="kanban_card",
links=[
{"path": "/kanban/backlog/plan", "relation": "blocked-by"},
{"path": "/kanban/backlog/context", "relation": "relates-to"},
{"path": "/kanban/backlog/child", "relation": "parent_of"},
{"path": "/kanban/backlog/canonical", "relation": "duplicate-of"},
],
)
def fake_request(method, path, payload=None, **kwargs):
assert method == "GET"
return {"items": [plan, implementation], "next_cursor": None}
mod.request_json = fake_request
blocked = mod.list_kanban_cards({"dependency_view": "blocked", "limit": 10})
assert [item["full_path"] for item in blocked["items"]] == ["/kanban/todo/implementation"]
assert blocked["items"][0]["dependency_summary"]["hard_blockers"] == 1
assert blocked["items"][0]["dependency_summary"]["external_blockers"] == 1
assert blocked["items"][0]["hard_blockers"] == ["/kanban/backlog/plan"]
assert blocked["items"][0]["related"] == ["/kanban/backlog/context"]
assert blocked["items"][0]["children"] == ["/kanban/backlog/child"]
assert blocked["items"][0]["duplicates"] == ["/kanban/backlog/canonical"]
ready = mod.list_kanban_cards({"dependency_view": "ready", "limit": 10})
assert [item["full_path"] for item in ready["items"]] == ["/kanban/backlog/plan"]
blocking = mod.list_kanban_cards({"dependency_view": "blocking", "limit": 10})
assert blocking["items"][0]["blocking"] == ["/kanban/backlog/implementation"]
def test_kanban_list_reads_beyond_first_source_page(mod):
first_page = [
node(
@@ -367,6 +417,8 @@ def run():
mod = load_module()
test_kanban_list_grouping_and_filters(mod)
mod = load_module()
test_kanban_dependency_summary_filters_ready_and_blocking(mod)
mod = load_module()
test_kanban_list_reads_beyond_first_source_page(mod)
mod = load_module()
test_kanban_workflow_reads_pending_and_pick_next(mod)