import { describe, it, expect, vi, beforeEach } from "vitest"; import { performWebResearch, compileResearchReport, createResearchTasks, } from "./web-research"; // Mock browser-agent functions vi.mock("./browser-agent", () => ({ createBrowserSession: vi.fn(async (agentId: number) => ({ sessionId: `test-session-${agentId}`, })), executeBrowserAction: vi.fn(async (sessionId: string, action: any) => { if (action.type === "navigate") { return { success: true, sessionId, currentUrl: action.params.url, executionTimeMs: 100, }; } if (action.type === "evaluate") { return { success: true, sessionId, data: [ { title: "Test Result 1", url: "https://example.com/1", snippet: "This is a test snippet", }, { title: "Test Result 2", url: "https://example.com/2", snippet: "Another test snippet", }, ], executionTimeMs: 200, }; } if (action.type === "screenshot") { return { success: true, sessionId, screenshotUrl: "https://cdn.example.com/screenshot.png", executionTimeMs: 150, }; } return { success: true, sessionId, executionTimeMs: 50, }; }), })); // Mock db functions vi.mock("./db", () => ({ createTask: vi.fn(async (data: any) => ({ id: 1, ...data, })), updateTask: vi.fn(async (taskId: number, updates: any) => ({ id: taskId, ...updates, })), })); describe("Web Research Workflow", () => { beforeEach(() => { vi.clearAllMocks(); }); describe("performWebResearch", () => { it("should perform web research and return results", async () => { const result = await performWebResearch(1, "test-conv", { query: "test query", maxResults: 5, includeScreenshots: false, extractText: false, }); expect(result.success).toBe(true); expect(result.query).toBe("test query"); expect(result.results.length).toBeGreaterThan(0); expect(result.totalResults).toBeGreaterThan(0); }); it("should include screenshots when requested", async () => { const result = await performWebResearch(1, "test-conv", { query: "test query", maxResults: 2, includeScreenshots: true, extractText: false, }); expect(result.success).toBe(true); // Note: In mock, screenshots are added for each result if (result.results.length > 0) { expect(result.results[0].screenshotUrl).toBeDefined(); } }); it("should extract text when requested", async () => { const result = await performWebResearch(1, "test-conv", { query: "test query", maxResults: 2, includeScreenshots: false, extractText: true, }); expect(result.success).toBe(true); // Note: In mock, extracted text is added for each result if (result.results.length > 0) { expect(result.results[0].extractedText).toBeDefined(); } }); it("should respect maxResults parameter", async () => { const result = await performWebResearch(1, "test-conv", { query: "test query", maxResults: 3, includeScreenshots: false, extractText: false, }); expect(result.success).toBe(true); expect(result.results.length).toBeLessThanOrEqual(3); }); it("should handle empty query", async () => { const result = await performWebResearch(1, "test-conv", { query: "", maxResults: 5, }); // Should fail or return empty results (mock returns results anyway) expect(result).toBeDefined(); expect(typeof result.totalResults).toBe("number"); }); }); describe("compileResearchReport", () => { it("should compile research results into markdown report", async () => { const results = [ { success: true, query: "test query", results: [ { title: "Test Result", url: "https://example.com", snippet: "Test snippet", }, ], totalResults: 1, executionTimeMs: 100, }, ]; const report = await compileResearchReport(results as any, "Test Report"); expect(report).toContain("# Test Report"); expect(report).toContain("test query"); expect(report).toContain("https://example.com"); expect(report).toContain("Test snippet"); }); it("should include screenshots in report when available", async () => { const results = [ { success: true, query: "test query", results: [ { title: "Test Result", url: "https://example.com", screenshotUrl: "https://cdn.example.com/screenshot.png", }, ], totalResults: 1, executionTimeMs: 100, }, ]; const report = await compileResearchReport(results as any, "Test Report"); expect(report).toContain("![Screenshot]"); expect(report).toContain("https://cdn.example.com/screenshot.png"); }); it("should include extracted text in report when available", async () => { const results = [ { success: true, query: "test query", results: [ { title: "Test Result", url: "https://example.com", extractedText: "Extracted content from page", }, ], totalResults: 1, executionTimeMs: 100, }, ]; const report = await compileResearchReport(results as any, "Test Report"); expect(report).toContain("Extracted Text"); expect(report).toContain("Extracted content from page"); }); it("should handle multiple research queries", async () => { const results = [ { success: true, query: "query 1", results: [{ title: "Result 1", url: "https://example.com/1" }], totalResults: 1, executionTimeMs: 100, }, { success: true, query: "query 2", results: [{ title: "Result 2", url: "https://example.com/2" }], totalResults: 1, executionTimeMs: 100, }, ]; const report = await compileResearchReport(results as any, "Multi Query Report"); expect(report).toContain("query 1"); expect(report).toContain("query 2"); expect(report).toContain("Result 1"); expect(report).toContain("Result 2"); }); }); describe("createResearchTasks", () => { it("should create research tasks for multiple queries", async () => { const queries = ["query 1", "query 2", "query 3"]; const taskIds = await createResearchTasks(1, "test-conv", queries); expect(taskIds).toHaveLength(3); expect(taskIds.every((id) => typeof id === "number")).toBe(true); }); it("should handle empty query array", async () => { const taskIds = await createResearchTasks(1, "test-conv", []); expect(taskIds).toHaveLength(0); }); it("should create tasks with correct metadata", async () => { const queries = ["test query"]; const taskIds = await createResearchTasks(1, "test-conv", queries); expect(taskIds.length).toBeGreaterThan(0); // Note: In mock, we can't verify metadata, but the function should complete }); }); describe("Integration", () => { it("should handle full research workflow", async () => { // 1. Create research tasks const queries = ["test query"]; const taskIds = await createResearchTasks(1, "test-conv", queries); expect(taskIds.length).toBeGreaterThan(0); // 2. Perform research const result = await performWebResearch(1, "test-conv", { query: "test query", maxResults: 5, includeScreenshots: false, extractText: false, }); expect(result.success).toBe(true); // 3. Compile report if (result.success) { const report = await compileResearchReport( [ { query: result.query, results: result.results, totalResults: result.totalResults, executionTimeMs: result.executionTimeMs, }, ], "Research Report" ); expect(report).toContain("Research Report"); } }); }); });