/** * YouTubeClient.getVideoStatistics Unit Tests * * Tests the batch video statistics retrieval method that fetches * view counts, like counts, and comment counts for multiple videos. */ import { describe, it, expect, vi, beforeEach } from 'vitest' const mockVideosList = vi.fn() vi.mock('googleapis', () => { class MockOAuth2 { setCredentials(): void { // no-op } } return { google: { auth: { OAuth2: MockOAuth2, }, youtube: () => ({ videos: { list: mockVideosList, }, commentThreads: { list: vi.fn() }, comments: { insert: vi.fn(), setModerationStatus: vi.fn(), delete: vi.fn(), }, channels: { list: vi.fn() }, }), }, } }) const mockPayload = {} as import('payload').Payload describe('YouTubeClient.getVideoStatistics', () => { beforeEach(() => { vi.clearAllMocks() }) it('should return parsed statistics for multiple videos', async () => { mockVideosList.mockResolvedValueOnce({ data: { items: [ { id: 'vid1', statistics: { viewCount: '1500', likeCount: '120', commentCount: '45', }, }, { id: 'vid2', statistics: { viewCount: '3200', likeCount: '250', commentCount: '80', }, }, ], }, }) const { YouTubeClient } = await import( '@/lib/integrations/youtube/YouTubeClient' ) const client = new YouTubeClient( { clientId: 'test-id', clientSecret: 'test-secret', accessToken: 'test-token', refreshToken: 'test-refresh', }, mockPayload, ) const result = await client.getVideoStatistics(['vid1', 'vid2']) expect(result).toEqual([ { id: 'vid1', views: 1500, likes: 120, comments: 45 }, { id: 'vid2', views: 3200, likes: 250, comments: 80 }, ]) expect(mockVideosList).toHaveBeenCalledWith({ part: ['statistics'], id: ['vid1', 'vid2'], maxResults: 50, }) }) it('should return empty array for empty input without calling API', async () => { const { YouTubeClient } = await import( '@/lib/integrations/youtube/YouTubeClient' ) const client = new YouTubeClient( { clientId: 'test-id', clientSecret: 'test-secret', accessToken: 'test-token', refreshToken: 'test-refresh', }, mockPayload, ) const result = await client.getVideoStatistics([]) expect(result).toEqual([]) expect(mockVideosList).not.toHaveBeenCalled() }) it('should default missing statistics to zero', async () => { mockVideosList.mockResolvedValueOnce({ data: { items: [ { id: 'vid3', statistics: {}, }, ], }, }) const { YouTubeClient } = await import( '@/lib/integrations/youtube/YouTubeClient' ) const client = new YouTubeClient( { clientId: 'test-id', clientSecret: 'test-secret', accessToken: 'test-token', refreshToken: 'test-refresh', }, mockPayload, ) const result = await client.getVideoStatistics(['vid3']) expect(result).toEqual([ { id: 'vid3', views: 0, likes: 0, comments: 0 }, ]) }) it('should handle null items in API response', async () => { mockVideosList.mockResolvedValueOnce({ data: { items: null, }, }) const { YouTubeClient } = await import( '@/lib/integrations/youtube/YouTubeClient' ) const client = new YouTubeClient( { clientId: 'test-id', clientSecret: 'test-secret', accessToken: 'test-token', refreshToken: 'test-refresh', }, mockPayload, ) const result = await client.getVideoStatistics(['vid-missing']) expect(result).toEqual([]) }) it('should propagate API errors', async () => { mockVideosList.mockRejectedValueOnce(new Error('API quota exceeded')) const { YouTubeClient } = await import( '@/lib/integrations/youtube/YouTubeClient' ) const client = new YouTubeClient( { clientId: 'test-id', clientSecret: 'test-secret', accessToken: 'test-token', refreshToken: 'test-refresh', }, mockPayload, ) await expect( client.getVideoStatistics(['vid1']), ).rejects.toThrow('API quota exceeded') }) })