Skip to main content
Glama

tv-recommender-mcp-server

test.ts12.3 kB
import { discoverShows, findShowsByPersonName, getRecommendationsByActor, findPersonId } from '../tools/discoverShowsTool'; import { tmdbClient } from '../services/tmdbClient'; import { ApiError } from '../utils/errorHandler'; // 模拟 tmdbClient 和其他依赖 jest.mock('../services/tmdbClient', () => { return { tmdbClient: { discoverTvShows: jest.fn(), searchPerson: jest.fn(), searchKeyword: jest.fn(), getPersonTvCredits: jest.fn(), } }; }); // 模拟 console.log 以便测试日志输出 const originalConsoleLog = console.log; beforeAll(() => { console.log = jest.fn(); }); afterAll(() => { console.log = originalConsoleLog; }); jest.mock('../utils/genreMap', () => ({ mapGenreToId: jest.fn(), getGenreNameById: jest.fn() })); jest.mock('../utils/errorHandler', () => { const original = jest.requireActual('../utils/errorHandler'); return { ...original, formatErrorMessage: jest.fn(error => error instanceof Error ? error.message : String(error)), ApiError: original.ApiError }; }); describe('discoverShows Tool', () => { beforeEach(() => { jest.clearAllMocks(); // 设置默认的 mapGenreToId 实现 const { mapGenreToId } = require('../utils/genreMap'); (mapGenreToId as jest.Mock).mockImplementation((genre) => { if (genre === '喜剧') return 35; if (genre === '科幻') return 10765; return null; }); }); it('应该使用默认参数正确调用API', async () => { // 模拟API响应 const mockResponse = { page: 1, results: [ { id: 1, name: '测试剧集1', overview: '测试简介1', poster_path: '/path1.jpg', vote_average: 8.5, first_air_date: '2022-01-01' }, { id: 2, name: '测试剧集2', overview: '测试简介2', poster_path: '/path2.jpg', vote_average: 7.5, first_air_date: '2021-02-01' } ], total_pages: 10, total_results: 200 }; (tmdbClient.discoverTvShows as jest.Mock).mockResolvedValue(mockResponse); // 执行测试 const result = await discoverShows({}); // 验证调用 expect(tmdbClient.discoverTvShows).toHaveBeenCalledWith( expect.objectContaining({ sort_by: 'popularity.desc', page: 1 }) ); // 验证结果格式 expect(result).toEqual({ page: 1, results: [ { id: 1, name: '测试剧集1', overview: '测试简介1', poster_path: '/path1.jpg', vote_average: 8.5, first_air_date: '2022-01-01' }, { id: 2, name: '测试剧集2', overview: '测试简介2', poster_path: '/path2.jpg', vote_average: 7.5, first_air_date: '2021-02-01' } ], total_pages: 10, total_results: 2 }); }); it('应该正确处理类型参数', async () => { // 模拟API响应 const mockResponse = { page: 1, results: [], total_pages: 1, total_results: 0 }; (tmdbClient.discoverTvShows as jest.Mock).mockResolvedValue(mockResponse); // 执行测试 await discoverShows({ with_genres: ['喜剧', '科幻'] }); // 验证调用 expect(tmdbClient.discoverTvShows).toHaveBeenCalledWith( expect.objectContaining({ with_genres: '35,10765' }) ); }); it('应该抛出错误当无法识别所有类型', async () => { const { mapGenreToId } = require('../utils/genreMap'); (mapGenreToId as jest.Mock).mockReturnValue(null); // 执行测试并验证错误 await expect(discoverShows({ with_genres: ['未知类型'] })).rejects.toThrow('无法识别提供的类型'); }); it('应该使用findShowsByPersonName查找演员参与的作品', async () => { // 模拟API响应 const mockPersonResponse = { results: [{ id: 123 }] }; const mockCreditsResponse = { cast: [ { id: 1, name: '测试剧集1', overview: '测试简介1', poster_path: '/path1.jpg', vote_average: 8.5, first_air_date: '2022-01-01' } ] }; (tmdbClient.searchPerson as jest.Mock).mockResolvedValue(mockPersonResponse); (tmdbClient.getPersonTvCredits as jest.Mock).mockResolvedValue(mockCreditsResponse); // 执行测试 const result = await findShowsByPersonName('布莱恩·科兰斯顿'); // 验证调用 expect(tmdbClient.searchPerson).toHaveBeenCalledWith('布莱恩·科兰斯顿'); expect(tmdbClient.getPersonTvCredits).toHaveBeenCalledWith(123); // 验证结果 expect(result.results).toHaveLength(1); expect(result.results[0].name).toBe('测试剧集1'); }); it('应该使用getRecommendationsByActor获取演员推荐', async () => { // 模拟API响应 const mockPersonResponse = { results: [{ id: 123 }] }; const mockCreditsResponse = { cast: [ { id: 1, name: '测试剧集1', overview: '测试简介1', poster_path: '/path1.jpg', vote_average: 8.5, first_air_date: '2022-01-01' }, { id: 2, name: '测试剧集2', overview: '测试简介2', poster_path: '/path2.jpg', vote_average: 7.5, first_air_date: '2021-02-01' } ] }; (tmdbClient.searchPerson as jest.Mock).mockResolvedValue(mockPersonResponse); (tmdbClient.getPersonTvCredits as jest.Mock).mockResolvedValue(mockCreditsResponse); // 执行测试 const result = await getRecommendationsByActor('布莱恩·科兰斯顿', 5); // 验证调用 expect(tmdbClient.searchPerson).toHaveBeenCalledWith('布莱恩·科兰斯顿'); expect(tmdbClient.getPersonTvCredits).toHaveBeenCalledWith(123); // 验证结果 expect(result.results).toHaveLength(2); // 验证按评分排序 expect(result.results[0].vote_average).toBe(8.5); expect(result.results[1].vote_average).toBe(7.5); }); it('findShowsByPersonName应该在找不到人物时抛出错误', async () => { (tmdbClient.searchPerson as jest.Mock).mockResolvedValue({ results: [] }); // 执行测试并验证错误 await expect(findShowsByPersonName('未知演员')).rejects.toThrow('未找到人物'); }); it('getRecommendationsByActor应该在找不到演员时抛出错误', async () => { (tmdbClient.searchPerson as jest.Mock).mockResolvedValue({ results: [] }); // 执行测试并验证错误 await expect(getRecommendationsByActor('未知演员')).rejects.toThrow('未找到演员'); }); it('应该正确处理年份参数并过滤结果', async () => { // 模拟API响应,包含不同年份的剧集 const mockResponse = { page: 1, results: [ { id: 1, name: '2022剧集', overview: '测试简介', poster_path: '/path.jpg', vote_average: 8.5, first_air_date: '2022-05-15' }, { id: 2, name: '2023剧集', overview: '测试简介', poster_path: '/path.jpg', vote_average: 7.5, first_air_date: '2023-01-10' }, { id: 3, name: '无日期剧集', overview: '测试简介', poster_path: '/path.jpg', vote_average: 6.5, first_air_date: null } ], total_pages: 1, total_results: 3 }; (tmdbClient.discoverTvShows as jest.Mock).mockResolvedValue(mockResponse); // 执行测试 const result = await discoverShows({ first_air_date_year: 2022 }); // 验证API调用参数 expect(tmdbClient.discoverTvShows).toHaveBeenCalledWith( expect.objectContaining({ first_air_date_gte: '2022-01-01', first_air_date_lte: '2022-12-31' }) ); // 验证结果过滤 expect(result.results.length).toBe(1); expect(result.results[0].name).toBe('2022剧集'); expect(result.total_results).toBe(1); // 验证日志输出 expect(console.log).toHaveBeenCalledWith('过滤前剧集数量: 3'); expect(console.log).toHaveBeenCalledWith( expect.stringContaining('无日期剧集') && expect.stringContaining('缺少首播日期') ); expect(console.log).toHaveBeenCalledWith( expect.stringContaining('2023剧集') && expect.stringContaining('不匹配') ); expect(console.log).toHaveBeenCalledWith('过滤后剧集数量: 1'); }); it('应该正确处理评分参数', async () => { // 模拟API响应 const mockResponse = { page: 1, results: [], total_pages: 1, total_results: 0 }; (tmdbClient.discoverTvShows as jest.Mock).mockResolvedValue(mockResponse); // 执行测试 await discoverShows({ vote_average_gte: 8.0 }); // 验证调用 expect(tmdbClient.discoverTvShows).toHaveBeenCalledWith( expect.objectContaining({ vote_average_gte: 8.0 }) ); }); it('应该正确处理网络参数', async () => { // 模拟API响应 const mockResponse = { page: 1, results: [], total_pages: 1, total_results: 0 }; (tmdbClient.discoverTvShows as jest.Mock).mockResolvedValue(mockResponse); // 执行测试 await discoverShows({ with_networks: [213, 19] }); // 验证调用 expect(tmdbClient.discoverTvShows).toHaveBeenCalledWith( expect.objectContaining({ with_networks: '213,19' }) ); }); it('应该正确处理关键词参数', async () => { // 模拟API响应 const mockResponse = { page: 1, results: [], total_pages: 1, total_results: 0 }; const mockKeywordResponse = { results: [{ id: 456 }] }; (tmdbClient.discoverTvShows as jest.Mock).mockResolvedValue(mockResponse); (tmdbClient.searchKeyword as jest.Mock).mockResolvedValue(mockKeywordResponse); // 执行测试 await discoverShows({ with_keywords: ['太空'] }); // 验证调用 expect(tmdbClient.searchKeyword).toHaveBeenCalledWith('太空'); expect(tmdbClient.discoverTvShows).toHaveBeenCalledWith( expect.objectContaining({ with_keywords: '456' }) ); }); it('应该抛出错误当找不到任何关键词', async () => { (tmdbClient.searchKeyword as jest.Mock).mockResolvedValue({ results: [] }); // 执行测试并验证错误 await expect(discoverShows({ with_keywords: ['未知关键词'] })).rejects.toThrow('无法找到关键词'); }); it('应该处理 searchKeyword 抛出的错误', async () => { (tmdbClient.searchKeyword as jest.Mock).mockRejectedValue(new Error('API错误')); // 执行测试并验证错误 await expect(discoverShows({ with_keywords: ['太空'] })).rejects.toThrow('无法找到关键词'); }); it('应该正确处理API错误', async () => { (tmdbClient.discoverTvShows as jest.Mock).mockRejectedValue(new Error('API调用失败')); // 执行测试并验证错误 await expect(discoverShows({})).rejects.toThrow(ApiError); await expect(discoverShows({})).rejects.toThrow('高级剧集发现失败'); }); it('应该处理结果中缺少部分字段的情况', async () => { // 模拟API响应中缺少部分字段 const mockResponse = { page: 1, results: [ { id: 1, name: '缺失字段剧集', // 没有overview、poster_path和vote_average first_air_date: '2022-01-01' } ], total_pages: 1, total_results: 1 }; (tmdbClient.discoverTvShows as jest.Mock).mockResolvedValue(mockResponse); // 执行测试 const result = await discoverShows({}); // 验证格式化后的结果包含默认值 expect(result.results[0]).toEqual({ id: 1, name: '缺失字段剧集', overview: '暂无简介', poster_path: null, vote_average: 0, first_air_date: '2022-01-01' }); }); });

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/terryso/tv-recommender-mcp-server'

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