b8e0dd7dc5
Co-authored-by: Kandev Agent <agent@kandev.dev> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
90 lines
3.1 KiB
TypeScript
90 lines
3.1 KiB
TypeScript
import { renderHook, waitFor } from "@testing-library/react";
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
|
|
const listTasksByWorkspace = vi.fn();
|
|
vi.mock("@/lib/api", () => ({
|
|
listTasksByWorkspace: (...args: unknown[]) => listTasksByWorkspace(...args),
|
|
}));
|
|
|
|
import { useInlineTaskSearchEffect } from "./use-command-panel-task-results";
|
|
import type { Task } from "@/lib/types/http";
|
|
import { taskId, workflowId, workspaceId } from "@/lib/types/ids";
|
|
|
|
function task(id: string, title: string): Task {
|
|
return {
|
|
id: taskId(id),
|
|
workspace_id: workspaceId("workspace-1"),
|
|
workflow_id: workflowId("workflow-1"),
|
|
workflow_step_id: "step-1",
|
|
position: 0,
|
|
title,
|
|
description: "",
|
|
state: "IN_PROGRESS",
|
|
priority: "medium",
|
|
created_at: "2026-08-24T09:00:00Z",
|
|
updated_at: "2026-08-24T09:00:00Z",
|
|
};
|
|
}
|
|
|
|
const STEPS = [{ id: "step-1", position: 0, show_in_command_panel: true }];
|
|
|
|
function harness(setTaskResults: (t: Task[]) => void, setIsSearching: (s: boolean) => void) {
|
|
return renderHook(
|
|
({ mode }: { mode: "commands" | "search-tasks" }) =>
|
|
useInlineTaskSearchEffect({
|
|
mode,
|
|
search: "",
|
|
open: true,
|
|
workspaceId: "workspace-1",
|
|
steps: STEPS,
|
|
setTaskResults,
|
|
setIsSearching,
|
|
}),
|
|
{ initialProps: { mode: "commands" } as { mode: "commands" | "search-tasks" } },
|
|
);
|
|
}
|
|
|
|
afterEach(() => {
|
|
listTasksByWorkspace.mockReset();
|
|
});
|
|
|
|
describe("useInlineTaskSearchEffect", () => {
|
|
it("caps the commands scope at a five-row preview and the tasks scope at twenty", async () => {
|
|
const many = Array.from({ length: 20 }, (_, i) => task(`task-${i}`, `Task ${i}`));
|
|
listTasksByWorkspace.mockResolvedValue({ tasks: many });
|
|
const setTaskResults = vi.fn();
|
|
const { rerender } = harness(setTaskResults, vi.fn());
|
|
|
|
await waitFor(() => expect(setTaskResults).toHaveBeenCalledWith(many.slice(0, 5)));
|
|
|
|
setTaskResults.mockClear();
|
|
rerender({ mode: "search-tasks" });
|
|
await waitFor(() => expect(setTaskResults).toHaveBeenCalledWith(many));
|
|
});
|
|
|
|
it("drops the previous scope's results when the scope changes", async () => {
|
|
listTasksByWorkspace.mockResolvedValue({ tasks: [task("task-1", "Only task")] });
|
|
const setTaskResults = vi.fn();
|
|
const { rerender } = harness(setTaskResults, vi.fn());
|
|
await waitFor(() => expect(setTaskResults).toHaveBeenCalled());
|
|
|
|
setTaskResults.mockClear();
|
|
rerender({ mode: "search-tasks" });
|
|
|
|
// The five-row preview must not stand in as the tasks scope's full result
|
|
// set (nor suppress its loading state) while the wider request is in flight.
|
|
expect(setTaskResults).toHaveBeenNthCalledWith(1, []);
|
|
});
|
|
|
|
it("keeps results when the scope is unchanged", async () => {
|
|
listTasksByWorkspace.mockResolvedValue({ tasks: [task("task-1", "Only task")] });
|
|
const setTaskResults = vi.fn();
|
|
const { rerender } = harness(setTaskResults, vi.fn());
|
|
await waitFor(() => expect(setTaskResults).toHaveBeenCalled());
|
|
|
|
setTaskResults.mockClear();
|
|
rerender({ mode: "commands" });
|
|
expect(setTaskResults).not.toHaveBeenCalledWith([]);
|
|
});
|
|
});
|