feature/pi-refactor
 1/**
 2 * Tests for Research Tool
 3 * 
 4 * RED phase: Write these tests first, verify they fail
 5 * GREEN phase: Implement research functionality
 6 * REFACTOR phase: Improve structure
 7 */
 8
 9import { describe, it, expect } from "vitest";
10import { researchTool } from "./research.js";
11
12describe("Research Tool", () => {
13  it("should have correct tool metadata", () => {
14    expect(researchTool.name).toBe("research");
15    expect(researchTool.label).toBeDefined();
16    expect(researchTool.description).toBeDefined();
17    expect(researchTool.description.toLowerCase()).toContain("research");
18  });
19
20  it("should require a topic parameter", () => {
21    expect(researchTool.parameters).toBeDefined();
22    
23    const schema = researchTool.parameters as any;
24    expect(schema.properties).toBeDefined();
25    expect(schema.properties.topic).toBeDefined();
26  });
27
28  it("should execute research and return synthesized results", async () => {
29    const result = await researchTool.execute(
30      "test-call-id",
31      { topic: "TypeScript benefits" },
32      new AbortController().signal,
33      () => {}
34    );
35
36    expect(result).toBeDefined();
37    expect(result.content).toBeDefined();
38    expect(Array.isArray(result.content)).toBe(true);
39    expect(result.content.length).toBeGreaterThan(0);
40  }, 60000); // Very long timeout for search + LLM
41
42  it("should return text content with research summary", async () => {
43    const result = await researchTool.execute(
44      "test-call-id",
45      { topic: "Rust vs Go" },
46      new AbortController().signal,
47      () => {}
48    );
49
50    const textContent = result.content.find((c: any) => c.type === "text");
51    expect(textContent).toBeDefined();
52    
53    const text = (textContent as any).text;
54    expect(text).toBeDefined();
55    expect(text.length).toBeGreaterThan(50);
56  }, 60000);
57
58  it("should provide research content", async () => {
59    const result = await researchTool.execute(
60      "test-call-id",
61      { topic: "TypeScript features" },
62      new AbortController().signal,
63      () => {}
64    );
65
66    const textContent = result.content.find((c: any) => c.type === "text");
67    const text = (textContent as any).text;
68    
69    // Should return content
70    expect(text).toBeDefined();
71    expect(text.length).toBeGreaterThan(0);
72  }, 60000);
73
74  it("should handle empty topic gracefully", async () => {
75    const result = await researchTool.execute(
76      "test-call-id",
77      { topic: "" },
78      new AbortController().signal,
79      () => {}
80    );
81
82    expect(result).toBeDefined();
83    expect(result.content).toBeDefined();
84    
85    const textContent = result.content.find((c: any) => c.type === "text");
86    const text = (textContent as any).text;
87    expect(text).toContain("Error");
88  });
89});