Skip to main content
Glama
getTrendingVideos.test.ts2.96 kB
import { GetTrendingVideosTool } from "../getTrendingVideos"; import type { YoutubeService } from "../../../services/youtube.service"; import { IServiceContainer } from "../../../container"; // Only mock the heavy service, not the utils jest.mock("../../../services/youtube.service"); describe("GetTrendingVideosTool", () => { let mockYoutubeService: jest.Mocked<YoutubeService>; let tool: GetTrendingVideosTool; beforeEach(() => { // Create a type-safe mock mockYoutubeService = { getTrendingVideos: jest.fn(), } as unknown as jest.Mocked<YoutubeService>; // Ideally use jest-mock-extended here const container = { youtubeService: mockYoutubeService, } as unknown as IServiceContainer; tool = new GetTrendingVideosTool(container); jest.clearAllMocks(); }); it("should be defined", () => { expect(tool).toBeDefined(); expect(tool.name).toBe("getTrendingVideos"); }); it("should validate defaults and call service", async () => { const mockTrendingVideos = [{ id: "1", title: "Video 1" }]; // Simplified mock mockYoutubeService.getTrendingVideos.mockResolvedValue( mockTrendingVideos as any ); // Act: Call with empty object const result = await tool.execute({}); // Assert: Zod default applied (US, 10) expect(mockYoutubeService.getTrendingVideos).toHaveBeenCalledWith({ regionCode: "US", maxResults: 10, }); // Assert: Real formatter output structure expect(result).toEqual({ success: true, content: [ { type: "text", text: JSON.stringify(mockTrendingVideos, null, 2) }, ], }); }); it("should pass provided parameters correctly", async () => { const mockTrendingVideos = [{ id: "2", title: "Video 2" }]; mockYoutubeService.getTrendingVideos.mockResolvedValue( mockTrendingVideos as any ); const params = { regionCode: "GB", categoryId: "10", maxResults: 5 }; // We explicitly cast params to satisfy TS if needed, or rely on internal Zod inference await tool.execute(params); expect(mockYoutubeService.getTrendingVideos).toHaveBeenCalledWith(params); }); it("should return a formatted error if schema validation fails", async () => { const invalidParams = { regionCode: "INVALID_COUNTRY", // Too long maxResults: 1000, // Too high }; const result = await tool.execute(invalidParams); expect(result.isError).toBe(true); // Verify BaseTool captured the Zod error message specifically expect(result.content[0].text).toContain("regionCode"); }); it("should handle service errors gracefully", async () => { const mockError = new Error("YouTube API Quota Exceeded"); mockYoutubeService.getTrendingVideos.mockRejectedValue(mockError); const result = await tool.execute({}); expect(result.isError).toBe(true); expect(result.content[0].text).toContain("YouTube API Quota Exceeded"); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kirbah/mcp-youtube'

If you have feedback or need assistance with the MCP directory API, please join our Discord server