test(KB-601): add test for pause/unpause with missing directory

This commit is contained in:
gsxdsm
2026-03-31 14:43:55 -07:00
parent fdc70cbd5c
commit b36c164261
21 changed files with 1090 additions and 24 deletions

View File

@@ -52,7 +52,7 @@ vi.mock("@fusion/core/gh-cli", () => ({
import { createInterface } from "node:readline/promises";
import { TaskStore } from "@fusion/core";
import { watchFile, unwatchFile, statSync, existsSync, readFileSync } from "node:fs";
import { runTaskShow, runTaskCreate, runTaskDuplicate, runTaskRefine, runTaskDelete, runTaskRetry, runTaskLogs, runTaskPrCreate, type LogsOptions } from "./task.js";
import { runTaskShow, runTaskCreate, runTaskDuplicate, runTaskRefine, runTaskDelete, runTaskRetry, runTaskLogs, runTaskComment, runTaskComments, runTaskPrCreate, type LogsOptions } from "./task.js";
import { isGhAvailable, isGhAuthenticated, getCurrentRepo } from "@fusion/core/gh-cli";
import { GitHubClient } from "@fusion/dashboard";
@@ -1204,6 +1204,44 @@ describe("runTaskDelete", () => {
// --- Retry Tests ---
describe("runTaskComment", () => {
let logSpy: ReturnType<typeof vi.spyOn>;
let errorSpy: ReturnType<typeof vi.spyOn>;
beforeEach(() => {
logSpy = vi.spyOn(console, "log").mockImplementation(() => {});
errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
});
afterEach(() => {
vi.restoreAllMocks();
});
it("adds a task comment with explicit author", async () => {
(TaskStore as unknown as ReturnType<typeof vi.fn>).mockImplementation(() => ({
init: vi.fn(),
addTaskComment: vi.fn().mockResolvedValue(makeTask({ comments: [{ id: "c1", text: "Hello", author: "alice", createdAt: new Date().toISOString() }] })),
}));
await runTaskComment("KB-001", "Hello", "alice");
const store = (TaskStore as unknown as ReturnType<typeof vi.fn>).mock.results.at(-1)?.value;
expect(store.addTaskComment).toHaveBeenCalledWith("KB-001", "Hello", "alice");
expect(logSpy).toHaveBeenCalledWith(" ✓ Comment added to KB-001");
});
it("lists task comments", async () => {
(TaskStore as unknown as ReturnType<typeof vi.fn>).mockImplementation(() => ({
init: vi.fn(),
getTask: vi.fn().mockResolvedValue(makeTask({ comments: [{ id: "c1", text: "Hello", author: "alice", createdAt: "2026-01-01T00:00:00.000Z" }] })),
}));
await runTaskComments("KB-001");
expect(logSpy).toHaveBeenCalledWith(" Comments for KB-001:");
});
});
describe("runTaskRetry", () => {
let logSpy: ReturnType<typeof vi.spyOn>;
let mockGetTask: ReturnType<typeof vi.fn>;

View File

@@ -895,6 +895,58 @@ export async function runTaskImportFromGitHub(
console.log();
}
export async function runTaskComment(id: string, message?: string, author = "user") {
const store = await getStore();
let text = message;
if (text === undefined) {
const rl = createInterface({ input: process.stdin, output: process.stdout });
text = await rl.question("Comment: ");
rl.close();
}
if (!text || text.trim().length === 0) {
console.error("Error: Comment is required");
process.exit(1);
}
const trimmed = text.trim();
if (trimmed.length > 2000) {
console.error("Error: Comment must be between 1 and 2000 characters");
process.exit(1);
}
const task = await store.addTaskComment(id, trimmed, author || "user");
const latestComment = task.comments?.[task.comments.length - 1];
console.log();
console.log(` ✓ Comment added to ${task.id}`);
if (latestComment) {
console.log(` ID: ${latestComment.id}`);
}
console.log();
}
export async function runTaskComments(id: string) {
const store = await getStore();
const task = await store.getTask(id);
const comments = task.comments || [];
console.log();
if (comments.length === 0) {
console.log(` No comments on ${id}`);
console.log();
return;
}
console.log(` Comments for ${id}:`);
for (const comment of comments) {
console.log(` ${comment.id} · ${comment.author} · ${new Date(comment.updatedAt || comment.createdAt).toLocaleString()}`);
console.log(` ${comment.text}`);
}
console.log();
}
export async function runTaskSteer(id: string, message?: string) {
const store = await getStore();