test(FN-4316): complete Step 4 — add todo aging column coverage
Fusion-Task-Id: FN-4316 Fusion-Task-Lineage: 6b2b78b4-effa-479c-9a22-5a53d0f74894
This commit is contained in:
@@ -438,7 +438,7 @@ describe("Column same-column drop", () => {
|
||||
|
||||
render(<Column {...defaultProps} column="todo" tasks={tasks} onMoveTask={onMoveTask} addToast={addToast} />);
|
||||
|
||||
const columnEl = screen.getByText("1").closest(".column") as HTMLElement;
|
||||
const columnEl = screen.getByRole("heading", { name: "Todo" }).closest(".column") as HTMLElement;
|
||||
const dataTransfer = {
|
||||
getData: vi.fn().mockReturnValue("FN-001"),
|
||||
dropEffect: "move",
|
||||
@@ -456,7 +456,7 @@ describe("Column same-column drop", () => {
|
||||
|
||||
render(<Column {...defaultProps} column="todo" tasks={tasks} onMoveTask={onMoveTask} />);
|
||||
|
||||
const columnEl = screen.getByText("1").closest(".column") as HTMLElement;
|
||||
const columnEl = screen.getByRole("heading", { name: "Todo" }).closest(".column") as HTMLElement;
|
||||
const dataTransfer = {
|
||||
getData: vi.fn().mockReturnValue("FN-001"),
|
||||
dropEffect: "move",
|
||||
@@ -536,6 +536,90 @@ describe("Column same-column drop", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("Column todo aging summary", () => {
|
||||
const now = new Date("2026-04-04T12:00:00Z").getTime();
|
||||
|
||||
const makeTodoTask = (id: string, ageDays: number): Task => ({
|
||||
...makeTask(id),
|
||||
column: "todo",
|
||||
columnMovedAt: new Date(now - ageDays * 24 * 60 * 60 * 1000).toISOString(),
|
||||
createdAt: new Date(now - ageDays * 24 * 60 * 60 * 1000).toISOString(),
|
||||
updatedAt: new Date(now - ageDays * 24 * 60 * 60 * 1000).toISOString(),
|
||||
});
|
||||
|
||||
it.each(["triage", "in-progress", "in-review", "done", "archived"] as const)(
|
||||
"renders aging summary only on todo column (not %s)",
|
||||
(column) => {
|
||||
render(<Column {...defaultProps} column={column} tasks={[{ ...makeTask("FN-001"), column }]} lastFetchTimeMs={now} />);
|
||||
expect(screen.queryByTestId("todo-aging-summary")).toBeNull();
|
||||
},
|
||||
);
|
||||
|
||||
it("renders aging summary counts for todo bucket totals", () => {
|
||||
render(
|
||||
<Column
|
||||
{...defaultProps}
|
||||
column="todo"
|
||||
tasks={[makeTodoTask("FN-001", 2), makeTodoTask("FN-002", 10), makeTodoTask("FN-003", 45)]}
|
||||
lastFetchTimeMs={now}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByTestId("todo-aging-chip-fresh")).toHaveTextContent("0–7d1");
|
||||
expect(screen.getByTestId("todo-aging-chip-aging")).toHaveTextContent("8–30d1");
|
||||
expect(screen.getByTestId("todo-aging-chip-stale")).toHaveTextContent("31+d1");
|
||||
});
|
||||
|
||||
it("filters todo tasks by selected bucket and toggles off on second click", async () => {
|
||||
const user = userEvent.setup();
|
||||
render(
|
||||
<Column
|
||||
{...defaultProps}
|
||||
column="todo"
|
||||
tasks={[makeTodoTask("FN-001", 2), makeTodoTask("FN-002", 10), makeTodoTask("FN-003", 45)]}
|
||||
lastFetchTimeMs={now}
|
||||
/>,
|
||||
);
|
||||
|
||||
await user.click(screen.getByTestId("todo-aging-chip-stale"));
|
||||
expect(screen.queryByTestId("task-FN-001")).toBeNull();
|
||||
expect(screen.queryByTestId("task-FN-002")).toBeNull();
|
||||
expect(screen.getByTestId("task-FN-003")).toBeTruthy();
|
||||
const columnCount = screen.getByText((_content, node) => {
|
||||
if (!node || !node.classList.contains("column-count")) {
|
||||
return false;
|
||||
}
|
||||
return node.textContent?.includes("1 / 3") ?? false;
|
||||
});
|
||||
expect(columnCount).toBeTruthy();
|
||||
|
||||
await user.click(screen.getByTestId("todo-aging-chip-stale"));
|
||||
expect(screen.getByTestId("task-FN-001")).toBeTruthy();
|
||||
expect(screen.getByTestId("task-FN-002")).toBeTruthy();
|
||||
expect(screen.getByTestId("task-FN-003")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("renders empty bucket hint and clear filter action when selected bucket has no tasks", async () => {
|
||||
const user = userEvent.setup();
|
||||
render(
|
||||
<Column
|
||||
{...defaultProps}
|
||||
column="todo"
|
||||
tasks={[makeTodoTask("FN-001", 2), makeTodoTask("FN-002", 8)]}
|
||||
lastFetchTimeMs={now}
|
||||
/>,
|
||||
);
|
||||
|
||||
await user.click(screen.getByTestId("todo-aging-chip-stale"));
|
||||
expect(screen.getByText("No tasks in this bucket")).toBeTruthy();
|
||||
|
||||
await user.click(screen.getByRole("button", { name: "Clear filter" }));
|
||||
expect(screen.queryByText("No tasks in this bucket")).toBeNull();
|
||||
expect(screen.getByTestId("task-FN-001")).toBeTruthy();
|
||||
expect(screen.getByTestId("task-FN-002")).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Column PluginSlot integration", () => {
|
||||
it("renders PluginSlot for board-column-footer", () => {
|
||||
mockUsePluginUiSlots.mockReturnValue({
|
||||
|
||||
Reference in New Issue
Block a user