import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { TmdbClient } from '../../../../src/app/clients/tmdb/TmdbClient'; describe('TmdbClient', () => { const fetchMock = vi.fn(); beforeEach(() => { vi.stubGlobal('fetch', fetchMock); fetchMock.mockReset(); }); afterEach(() => { vi.unstubAllGlobals(); }); it('searchMovie returns the first result mapped to a TMDbMovie', async () => { fetchMock.mockResolvedValue({ ok: true, status: 200, text: async () => JSON.stringify({ results: [{ id: 438631, title: 'Dune', release_date: '2021-09-15' }] }), }); const client = new TmdbClient('tmdb-key', 'https://api.themoviedb.org'); const result = await client.searchMovie('Dune', 2021); expect(result).toEqual({ id: 438631, title: 'Dune', year: 2021 }); const [url] = fetchMock.mock.calls[0]; expect(url).toContain('/3/search/movie'); expect(url).toContain('query=Dune'); expect(url).toContain('year=2021'); }); it('searchMovie returns undefined when there are no results', async () => { fetchMock.mockResolvedValue({ ok: true, status: 200, text: async () => JSON.stringify({ results: [] }) }); const client = new TmdbClient('tmdb-key', 'https://api.themoviedb.org'); const result = await client.searchMovie('Nonexistent'); expect(result).toBeUndefined(); }); it('getSimilar and getRecommendations hit the right paths', async () => { fetchMock.mockResolvedValue({ ok: true, status: 200, text: async () => JSON.stringify({ results: [] }) }); const client = new TmdbClient('tmdb-key', 'https://api.themoviedb.org'); await client.getSimilar(438631); await client.getRecommendations(438631); expect(fetchMock.mock.calls[0][0]).toContain('/3/movie/438631/similar'); expect(fetchMock.mock.calls[1][0]).toContain('/3/movie/438631/recommendations'); }); });