{"version":3,"file":"websearch-entrypoint.test.d.ts","sourceRoot":"","sources":["../../src/modes/websearch-entrypoint.test.ts"],"names":[],"mappings":"","sourcesContent":["import { beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { BUILTIN_SLASH_COMMANDS } from \"../core/slash-commands.js\";\nimport type { UltraplanArtifact, UltraplanRunResult } from \"../core/ultraplan.js\";\nimport { getPrintModeLocalCommandOutput } from \"./print-mode.js\";\n\nvi.mock(\"../core/tools/web-search.js\", () => ({\n\tsearchDuckDuckGoLite: vi.fn(),\n}));\n\nconst { searchDuckDuckGoLite } = await import(\"../core/tools/web-search.js\");\n\nfunction createPrintModeSessionStub() {\n\tconst artifact: UltraplanArtifact = {\n\t\tversion: 1,\n\t\tplannerMode: \"local_subagent\",\n\t\tplannerAgent: \"planner\",\n\t\texecutionState: \"plan_only\",\n\t\tobjective: \"unused\",\n\t\tassumptions: [],\n\t\tconstraints: [],\n\t\tphases: [],\n\t\trisks: [],\n\t\trecommendedExecutionOrder: [],\n\t\tactionableNextSteps: [],\n\t\tcreatedAt: \"2026-04-03T00:00:00.000Z\",\n\t};\n\n\tconst makeRunResult = (): UltraplanRunResult => ({\n\t\tartifact,\n\t\tdisplayText: \"\",\n\t\trawPlannerOutput: \"\",\n\t});\n\n\treturn {\n\t\tbriefOnly: false,\n\t\tsetBriefOnly: () => {},\n\t\tqueueByTheWay: () => {},\n\t\tgetPendingByTheWayNotes: () => [],\n\t\tgetMemoryHistory: () => [],\n\t\tresolveMemorySnapshotSelector: () => ({\n\t\t\tsnapshot: undefined,\n\t\t\tmatchedInput: \"\",\n\t\t\tresolvedId: undefined,\n\t\t\terror: \"empty\" as const,\n\t\t\tcandidates: [],\n\t\t}),\n\t\tgetLatestUltraplanPlan: () => undefined,\n\t\trunUltraplan: async () => makeRunResult(),\n\t\trunUltraplanRevise: async () => makeRunResult(),\n\t\tapplyUltraplan: () => ({ applied: [], displayText: \"\" }),\n\t\tresourceLoader: {\n\t\t\tgetAgentsFiles: () => ({ agentsFiles: [] }),\n\t\t},\n\t};\n}\n\ndescribe(\"/websearch command entrypoint\", () => {\n\tbeforeEach(() => {\n\t\tvi.clearAllMocks();\n\t});\n\n\tit(\"registers a built-in /websearch slash command\", () => {\n\t\tconst command = BUILTIN_SLASH_COMMANDS.find((entry) => entry.name === \"websearch\");\n\t\texpect(command).toBeDefined();\n\t\texpect(command?.description).toContain(\"DuckDuckGo\");\n\t});\n\n\tit(\"routes interactive mode submissions through the explicit websearch handler\", async () => {\n\t\tconst { readFileSync } = await import(\"node:fs\");\n\t\tconst { fileURLToPath } = await import(\"node:url\");\n\t\tconst { dirname, join } = await import(\"node:path\");\n\n\t\tconst __dirname = dirname(fileURLToPath(import.meta.url));\n\t\tconst source = readFileSync(join(__dirname, \"interactive/interactive-mode.ts\"), \"utf8\");\n\n\t\texpect(source).toContain('if (text === \"/websearch\" || text.startsWith(\"/websearch \")');\n\t\texpect(source).toContain(\"this.handleWebsearchCommand(text);\");\n\t});\n\n\tit(\"reports web search results through print mode\", async () => {\n\t\tconst mockResults = [\n\t\t\t{ title: \"Test Result 1\", url: \"https://example.com/1\", snippet: \"First result snippet\" },\n\t\t\t{ title: \"Test Result 2\", url: \"https://example.com/2\", snippet: \"Second result snippet\" },\n\t\t];\n\t\tvi.mocked(searchDuckDuckGoLite).mockResolvedValue(mockResults);\n\n\t\tconst output = await getPrintModeLocalCommandOutput(createPrintModeSessionStub(), \"/websearch test query\");\n\n\t\texpect(searchDuckDuckGoLite).toHaveBeenCalledWith(\"test query\");\n\t\texpect(output).toContain(\"Web Search: test query\");\n\t\texpect(output).toContain(\"1. Test Result 1\");\n\t\texpect(output).toContain(\"https://example.com/1\");\n\t\texpect(output).toContain(\"First result snippet\");\n\t\texpect(output).toContain(\"2. Test Result 2\");\n\t\texpect(output).toContain(\"https://example.com/2\");\n\t});\n\n\tit(\"handles empty search results through print mode\", async () => {\n\t\tvi.mocked(searchDuckDuckGoLite).mockResolvedValue([]);\n\n\t\tconst output = await getPrintModeLocalCommandOutput(createPrintModeSessionStub(), \"/websearch empty query\");\n\n\t\texpect(output).toContain(\"No web results found for\");\n\t\texpect(output).toContain(\"empty query\");\n\t});\n\n\tit(\"handles missing query through print mode\", async () => {\n\t\tconst output = await getPrintModeLocalCommandOutput(createPrintModeSessionStub(), \"/websearch\");\n\n\t\texpect(output).toBe(\"Usage: /websearch <query>\");\n\t\texpect(searchDuckDuckGoLite).not.toHaveBeenCalled();\n\t});\n\n\tit(\"handles search errors through print mode\", async () => {\n\t\tvi.mocked(searchDuckDuckGoLite).mockRejectedValue(new Error(\"Network error\"));\n\n\t\tconst output = await getPrintModeLocalCommandOutput(createPrintModeSessionStub(), \"/websearch failing query\");\n\n\t\texpect(output).toContain(\"Search failed:\");\n\t\texpect(output).toContain(\"Network error\");\n\t});\n\n\tit(\"reports web search results with results that have no snippet\", async () => {\n\t\tconst mockResults = [{ title: \"No Snippet Result\", url: \"https://example.com/no-snippet\", snippet: \"\" }];\n\t\tvi.mocked(searchDuckDuckGoLite).mockResolvedValue(mockResults);\n\n\t\tconst output = await getPrintModeLocalCommandOutput(createPrintModeSessionStub(), \"/websearch no snippet\");\n\n\t\texpect(output).toContain(\"Web Search: no snippet\");\n\t\texpect(output).toContain(\"1. No Snippet Result\");\n\t\texpect(output).toContain(\"https://example.com/no-snippet\");\n\t});\n});\n"]}