mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
127 lines
4.1 KiB
TypeScript
127 lines
4.1 KiB
TypeScript
import { afterEach, describe, expect, mock, test } from "bun:test";
|
|
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "fs";
|
|
import { tmpdir } from "os";
|
|
import path from "path";
|
|
|
|
const startAnnotateServerMock = mock(async (_options: any) => ({
|
|
waitForDecision: async () => ({ feedback: "", annotations: [] }),
|
|
stop: () => {},
|
|
}));
|
|
|
|
mock.module("@plannotator/server/annotate", () => ({
|
|
startAnnotateServer: startAnnotateServerMock,
|
|
handleAnnotateServerReady: () => {},
|
|
}));
|
|
|
|
const { handleAnnotateCommand, handleAnnotateLastCommand } = await import("./commands");
|
|
|
|
const tempDirs: string[] = [];
|
|
|
|
function makeTempDir(): string {
|
|
const dir = mkdtempSync(path.join(tmpdir(), "plannotator-opencode-commands-"));
|
|
tempDirs.push(dir);
|
|
return dir;
|
|
}
|
|
|
|
function makeDeps() {
|
|
return {
|
|
client: {
|
|
app: {
|
|
log: mock((_entry: unknown) => {}),
|
|
},
|
|
session: {
|
|
prompt: mock(async (_input: unknown) => {}),
|
|
messages: mock(async (_input: unknown) => ({ data: [] })),
|
|
},
|
|
},
|
|
htmlContent: "<html></html>",
|
|
reviewHtmlContent: "<html></html>",
|
|
getSharingEnabled: async () => true,
|
|
getShareBaseUrl: () => "https://share.example.test",
|
|
getPasteApiUrl: () => "https://paste.example.test",
|
|
directory: undefined as string | undefined,
|
|
};
|
|
}
|
|
|
|
afterEach(() => {
|
|
startAnnotateServerMock.mockClear();
|
|
for (const dir of tempDirs.splice(0)) {
|
|
rmSync(dir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
describe("handleAnnotateCommand", () => {
|
|
test("strips wrapping quotes from HTML paths and forwards pasteApiUrl", async () => {
|
|
const projectRoot = makeTempDir();
|
|
const docsDir = path.join(projectRoot, "docs");
|
|
mkdirSync(docsDir, { recursive: true });
|
|
const htmlPath = path.join(docsDir, "Design Spec.html");
|
|
writeFileSync(htmlPath, "<h1>Design Spec</h1><p>Body</p>");
|
|
|
|
const deps = makeDeps();
|
|
deps.directory = projectRoot;
|
|
|
|
await handleAnnotateCommand(
|
|
{ properties: { arguments: "\"docs/Design Spec.html\"" } },
|
|
deps,
|
|
);
|
|
|
|
expect(startAnnotateServerMock).toHaveBeenCalledTimes(1);
|
|
const options = startAnnotateServerMock.mock.calls[0]?.[0];
|
|
expect(options.filePath).toBe(htmlPath);
|
|
expect(options.mode).toBe("annotate");
|
|
expect(options.pasteApiUrl).toBe("https://paste.example.test");
|
|
expect(options.shareBaseUrl).toBe("https://share.example.test");
|
|
expect(options.markdown).toContain("Design Spec");
|
|
});
|
|
|
|
test("supports quoted folder paths and opens annotate-folder mode", async () => {
|
|
const projectRoot = makeTempDir();
|
|
const folderPath = path.join(projectRoot, "docs", "Specs Folder");
|
|
mkdirSync(folderPath, { recursive: true });
|
|
writeFileSync(path.join(folderPath, "plan.md"), "# Plan\n");
|
|
|
|
const deps = makeDeps();
|
|
deps.directory = projectRoot;
|
|
|
|
await handleAnnotateCommand(
|
|
{ properties: { arguments: "\"docs/Specs Folder\"" } },
|
|
deps,
|
|
);
|
|
|
|
expect(startAnnotateServerMock).toHaveBeenCalledTimes(1);
|
|
const options = startAnnotateServerMock.mock.calls[0]?.[0];
|
|
expect(options.filePath).toBe(folderPath);
|
|
expect(options.folderPath).toBe(folderPath);
|
|
expect(options.mode).toBe("annotate-folder");
|
|
expect(options.pasteApiUrl).toBe("https://paste.example.test");
|
|
expect(options.markdown).toBe("");
|
|
});
|
|
});
|
|
|
|
describe("handleAnnotateLastCommand", () => {
|
|
test("forwards pasteApiUrl for annotate-last sessions", async () => {
|
|
const deps = makeDeps();
|
|
deps.client.session.messages = mock(async (_input: unknown) => ({
|
|
data: [
|
|
{
|
|
info: { role: "assistant" },
|
|
parts: [{ type: "text", text: "Latest assistant message" }],
|
|
},
|
|
],
|
|
}));
|
|
|
|
await handleAnnotateLastCommand(
|
|
{ properties: { sessionID: "session-123" } },
|
|
deps,
|
|
);
|
|
|
|
expect(startAnnotateServerMock).toHaveBeenCalledTimes(1);
|
|
const options = startAnnotateServerMock.mock.calls[0]?.[0];
|
|
expect(options.mode).toBe("annotate-last");
|
|
expect(options.filePath).toBe("last-message");
|
|
expect(options.pasteApiUrl).toBe("https://paste.example.test");
|
|
expect(options.markdown).toBe("Latest assistant message");
|
|
});
|
|
});
|