Skip to main content
Glama

mcp-youtube

by kirbah
batchFetchChannelStatistics.test.ts6.35 kB
import { YoutubeService } from "../../youtube.service"; // Adjusted path import { CacheService } from "../../cache.service"; // Adjusted path // Mock googleapis jest.mock("googleapis", () => { const mockChannelsListFn = jest.fn(); const mockYoutubeInstance = { videos: { list: jest.fn() }, channels: { list: mockChannelsListFn }, search: { list: jest.fn() }, }; return { google: { youtube: jest.fn(() => mockYoutubeInstance), }, __mockVideosList: jest.fn(), __mockChannelsList: mockChannelsListFn, __mockSearchList: jest.fn(), }; }); // Mock CacheService jest.mock("../../cache.service", () => { // Adjusted path const mockCacheInstanceInternal = { getOrSet: jest.fn(), createOperationKey: jest.fn( (operationName, params) => `${operationName}-${JSON.stringify(params)}` ), }; return { CacheService: jest.fn(() => mockCacheInstanceInternal), }; }); // Import the specific mocks for googleapis const { __mockChannelsList: mockChannelsList } = jest.requireMock("googleapis"); // Import the CacheService factory const { CacheService: MockedCacheService } = jest.requireMock( "../../cache.service" ); // Adjusted path describe("YoutubeService - batchFetchChannelStatistics", () => { let youtubeService: YoutubeService; let mockCacheServiceInstance: jest.Mocked<CacheService>; beforeEach(() => { process.env.YOUTUBE_API_KEY = "test_api_key"; mockChannelsList.mockReset(); mockCacheServiceInstance = new MockedCacheService() as jest.Mocked<CacheService>; mockCacheServiceInstance.getOrSet.mockImplementation( (cacheKey, operation) => operation() ); youtubeService = new YoutubeService(mockCacheServiceInstance); youtubeService.resetApiCreditsUsed(); }); afterEach(() => { delete process.env.YOUTUBE_API_KEY; }); // Copied from the original youtube.service.test.ts it("should return an empty map if no channel IDs are provided", async () => { const result = await youtubeService.batchFetchChannelStatistics([]); expect(result).toEqual(new Map()); expect(mockChannelsList).not.toHaveBeenCalled(); expect(youtubeService.getApiCreditsUsed()).toBe(0); }); it("should fetch statistics for a single channel ID", async () => { const mockChannelData = { id: "channel1", snippet: { title: "Channel 1" }, statistics: { viewCount: "100" }, }; mockChannelsList.mockResolvedValueOnce({ data: { items: [mockChannelData] }, }); const result = await youtubeService.batchFetchChannelStatistics([ "channel1", ]); expect(mockChannelsList).toHaveBeenCalledWith({ part: ["snippet", "statistics"], id: ["channel1"], }); expect(result.size).toBe(1); expect(result.get("channel1")).toEqual(mockChannelData); expect(youtubeService.getApiCreditsUsed()).toBe(1); }); it("should fetch statistics for multiple channel IDs in a single batch", async () => { const mockChannelData1 = { id: "channel1", snippet: { title: "Channel 1" }, statistics: { viewCount: "100" }, }; const mockChannelData2 = { id: "channel2", snippet: { title: "Channel 2" }, statistics: { viewCount: "200" }, }; mockChannelsList.mockResolvedValueOnce({ data: { items: [mockChannelData1, mockChannelData2] }, }); const result = await youtubeService.batchFetchChannelStatistics([ "channel1", "channel2", ]); expect(mockChannelsList).toHaveBeenCalledWith({ part: ["snippet", "statistics"], id: ["channel1", "channel2"], }); expect(result.size).toBe(2); expect(result.get("channel1")).toEqual(mockChannelData1); expect(result.get("channel2")).toEqual(mockChannelData2); expect(youtubeService.getApiCreditsUsed()).toBe(1); }); it("should fetch statistics for multiple channel IDs in multiple batches", async () => { const manyChannelIds = Array.from({ length: 51 }, (_, i) => `channel${i}`); const firstBatchIds = manyChannelIds.slice(0, 50); const secondBatchIds = manyChannelIds.slice(50); const mockResponseItems1 = firstBatchIds.map((id) => ({ id, snippet: { title: id }, statistics: {}, })); const mockResponseItems2 = secondBatchIds.map((id) => ({ id, snippet: { title: id }, statistics: {}, })); mockChannelsList .mockResolvedValueOnce({ data: { items: mockResponseItems1 } }) .mockResolvedValueOnce({ data: { items: mockResponseItems2 } }); const result = await youtubeService.batchFetchChannelStatistics(manyChannelIds); expect(mockChannelsList).toHaveBeenCalledTimes(2); expect(mockChannelsList).toHaveBeenNthCalledWith(1, { part: ["snippet", "statistics"], id: firstBatchIds, }); expect(mockChannelsList).toHaveBeenNthCalledWith(2, { part: ["snippet", "statistics"], id: secondBatchIds, }); expect(result.size).toBe(51); expect(result.get("channel0")).toEqual(mockResponseItems1[0]); expect(result.get("channel50")).toEqual(mockResponseItems2[0]); expect(youtubeService.getApiCreditsUsed()).toBe(2); }); it("should handle cases where some channels are not found or API returns partial data", async () => { const mockChannelData1 = { id: "channel1", snippet: { title: "Channel 1" }, statistics: { viewCount: "100" }, }; mockChannelsList.mockResolvedValueOnce({ data: { items: [mockChannelData1] }, }); const result = await youtubeService.batchFetchChannelStatistics([ "channel1", "channel2", ]); expect(mockChannelsList).toHaveBeenCalledWith({ part: ["snippet", "statistics"], id: ["channel1", "channel2"], }); expect(result.size).toBe(1); expect(result.get("channel1")).toEqual(mockChannelData1); expect(result.has("channel2")).toBe(false); expect(youtubeService.getApiCreditsUsed()).toBe(1); }); it("should throw an error if the API call fails", async () => { mockChannelsList.mockRejectedValueOnce(new Error("API Error")); await expect( youtubeService.batchFetchChannelStatistics(["channel1"]) ).rejects.toThrow("API call for batchFetchChannelStatistics failed"); expect(youtubeService.getApiCreditsUsed()).toBe(1); }); });

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