Skip to main content
Glama
findConsistentOutlierChannels.test.ts4.97 kB
import { FindConsistentOutlierChannelsTool } from "../findConsistentOutlierChannels"; import { NicheAnalyzerService } from "../../../services/nicheAnalyzer.service"; import { NicheRepository } from "../../../services/analysis/niche.repository"; import { YoutubeService } from "../../../services/youtube.service"; import { IServiceContainer } from "../../../container"; // Mock the dependencies that are instantiated inside the Tool jest.mock("../../../services/nicheAnalyzer.service"); jest.mock("../../../services/analysis/niche.repository"); // Mock the dependency passed via container jest.mock("../../../services/youtube.service"); describe("FindConsistentOutlierChannelsTool", () => { let mockYoutubeService: jest.Mocked<YoutubeService>; let mockNicheAnalyzerInstance: { findConsistentOutlierChannels: jest.Mock; }; let tool: FindConsistentOutlierChannelsTool; beforeEach(() => { // 1. Setup Container Mock mockYoutubeService = {} as unknown as jest.Mocked<YoutubeService>; const container = { youtubeService: mockYoutubeService, } as unknown as IServiceContainer; // 2. Setup NicheAnalyzerService Mock (Constructor & Instance) mockNicheAnalyzerInstance = { findConsistentOutlierChannels: jest.fn(), }; (NicheAnalyzerService as jest.Mock).mockImplementation( () => mockNicheAnalyzerInstance ); // 3. Setup NicheRepository Mock (Constructor) (NicheRepository as jest.Mock).mockImplementation(() => ({})); // 4. Initialize Tool tool = new FindConsistentOutlierChannelsTool(container); jest.clearAllMocks(); }); it("should be defined", () => { expect(tool).toBeDefined(); expect(tool.name).toBe("findConsistentOutlierChannels"); }); it("should validate inputs, instantiate services, and return results", async () => { // Arrange const mockOutlierChannels = [ { channelId: "UC-test", title: "Test Channel" }, ]; mockNicheAnalyzerInstance.findConsistentOutlierChannels.mockResolvedValue( mockOutlierChannels ); const params = { query: "test niche", maxResults: 5, }; // Act const result = await tool.execute(params); // Assert: Check Service Instantiation expect(NicheRepository).toHaveBeenCalledTimes(1); expect(NicheAnalyzerService).toHaveBeenCalledTimes(1); expect(NicheAnalyzerService).toHaveBeenCalledWith( mockYoutubeService, expect.any(Object) // The mock repository instance ); // Assert: Check Method Call with Defaults + Explicit Params expect( mockNicheAnalyzerInstance.findConsistentOutlierChannels ).toHaveBeenCalledWith({ query: "test niche", maxResults: 5, channelAge: "NEW", // Default from Zod consistencyLevel: "MODERATE", // Default from Zod outlierMagnitude: "STANDARD", // Default from Zod }); // Assert: Check Result expect(result.success).toBe(true); expect(JSON.parse(result.content[0].text as string)).toEqual( mockOutlierChannels ); }); it("should correctly pass all optional parameters", async () => { mockNicheAnalyzerInstance.findConsistentOutlierChannels.mockResolvedValue( [] ); const params = { query: "advanced niche", channelAge: "ESTABLISHED" as const, consistencyLevel: "HIGH" as const, outlierMagnitude: "STRONG" as const, regionCode: "DE", videoCategoryId: "27", maxResults: 20, }; await tool.execute(params); expect( mockNicheAnalyzerInstance.findConsistentOutlierChannels ).toHaveBeenCalledWith(params); }); it("should return a validation error if query is missing", async () => { // @ts-ignore - deliberately passing empty object to test required field const result = await tool.execute({}); expect( mockNicheAnalyzerInstance.findConsistentOutlierChannels ).not.toHaveBeenCalled(); expect(result.isError).toBe(true); // Zod error for required field expect(result.content[0].text).toContain( "Invalid input: expected string, received undefined" ); }); it("should return a validation error if regionCode is invalid", async () => { const params = { query: "test", regionCode: "INVALID_CODE", // Too long }; const result = await tool.execute(params); expect( mockNicheAnalyzerInstance.findConsistentOutlierChannels ).not.toHaveBeenCalled(); expect(result.isError).toBe(true); expect(result.content[0].text).toMatch(/regionCode/); }); it("should handle service errors gracefully", async () => { const errorMessage = "Analyzer failed"; mockNicheAnalyzerInstance.findConsistentOutlierChannels.mockRejectedValue( new Error(errorMessage) ); const params = { query: "test" }; const result = await tool.execute(params); expect(result.isError).toBe(true); expect(result.content[0].text).toContain(errorMessage); }); });

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