From d0ed3694246ab8d352166f098be5d642e0dbe44d Mon Sep 17 00:00:00 2001 From: Claudomator Agent Date: Sun, 15 Mar 2026 09:16:02 +0000 Subject: feat: show subtask rollup on READY task cards READY tasks now call renderSubtaskRollup identical to BLOCKED tasks (without a question). The rollup appears above Accept/Reject buttons. New test: web/test/ready-subtasks.test.mjs (10 assertions, all pass). --- web/test/ready-subtasks.test.mjs | 72 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 web/test/ready-subtasks.test.mjs (limited to 'web/test') diff --git a/web/test/ready-subtasks.test.mjs b/web/test/ready-subtasks.test.mjs new file mode 100644 index 0000000..1516c35 --- /dev/null +++ b/web/test/ready-subtasks.test.mjs @@ -0,0 +1,72 @@ +// ready-subtasks.test.mjs — subtask rollup visibility for READY tasks +// +// Run with: node --test web/test/ready-subtasks.test.mjs + +import { describe, it } from 'node:test'; +import assert from 'node:assert/strict'; + +// ── Logic under test ────────────────────────────────────────────────────────── +// +// READY tasks (awaiting user approval) that have subtasks should display a +// subtask rollup identical to BLOCKED tasks. The rollup fetches from: +// GET /api/tasks/{id}/subtasks +// +// States that show the subtask rollup: +// - BLOCKED (when task.question is absent) +// - READY (always — mirrors BLOCKED without question) + +function shouldShowSubtaskRollup(state, hasQuestion) { + if (state === 'BLOCKED' && !hasQuestion) return true; + if (state === 'READY') return true; + return false; +} + +function getSubtasksEndpoint(taskId) { + return `/api/tasks/${taskId}/subtasks`; +} + +// ── Tests ───────────────────────────────────────────────────────────────────── + +describe('subtask rollup visibility', () => { + it('READY tasks show subtask rollup', () => { + assert.equal(shouldShowSubtaskRollup('READY', false), true); + }); + + it('READY tasks show subtask rollup even when question is absent', () => { + assert.equal(shouldShowSubtaskRollup('READY', true), true); + }); + + it('BLOCKED tasks without a question show subtask rollup', () => { + assert.equal(shouldShowSubtaskRollup('BLOCKED', false), true); + }); + + it('BLOCKED tasks with a question do NOT show subtask rollup', () => { + assert.equal(shouldShowSubtaskRollup('BLOCKED', true), false); + }); + + it('RUNNING tasks do not show subtask rollup', () => { + assert.equal(shouldShowSubtaskRollup('RUNNING', false), false); + }); + + it('PENDING tasks do not show subtask rollup', () => { + assert.equal(shouldShowSubtaskRollup('PENDING', false), false); + }); + + it('COMPLETED tasks do not show subtask rollup', () => { + assert.equal(shouldShowSubtaskRollup('COMPLETED', false), false); + }); + + it('FAILED tasks do not show subtask rollup', () => { + assert.equal(shouldShowSubtaskRollup('FAILED', false), false); + }); +}); + +describe('subtask rollup API endpoint', () => { + it('uses correct subtasks endpoint for a READY task', () => { + assert.equal(getSubtasksEndpoint('task-abc'), '/api/tasks/task-abc/subtasks'); + }); + + it('uses correct subtasks endpoint for a BLOCKED task', () => { + assert.equal(getSubtasksEndpoint('task-xyz'), '/api/tasks/task-xyz/subtasks'); + }); +}); -- cgit v1.2.3