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});