import YoutubeMediaTrackerAdapter from '../client/trackingAdapter' interface MockYouTubePlayer { getDuration: jest.Mock getCurrentTime: jest.Mock getVideoData: jest.Mock getVideoUrl: jest.Mock getIframe: jest.Mock } describe('YoutubeMediaTrackerAdapter', () => { let playerElement: HTMLMediaElement let youtubePlayer: MockYouTubePlayer let adapter: YoutubeMediaTrackerAdapter beforeEach(() => { playerElement = document.createElement('video') youtubePlayer = { getDuration: jest.fn().mockReturnValue(120), getCurrentTime: jest.fn().mockReturnValue(30), getVideoData: jest.fn().mockReturnValue({ video_id: 'video-123', title: 'Test YouTube Video', }), getVideoUrl: jest.fn().mockReturnValue('https://youtu.be/video-123'), getIframe: jest.fn().mockReturnValue(document.createElement('iframe')), } adapter = new YoutubeMediaTrackerAdapter( playerElement, youtubePlayer as unknown as YT.Player, () => 2 ) }) it('should expose playback timing from the YouTube player', () => { expect(adapter.getCurrentTime()).toBe(30) expect(adapter.getDuration()).toBe(120) }) it('should return 0 duration when the YouTube duration is NaN', () => { youtubePlayer.getDuration.mockReturnValue(Number.NaN) expect(adapter.getDuration()).toBe(0) }) it('should return 0 timing values when YouTube timing calls fail', () => { youtubePlayer.getCurrentTime.mockImplementation(() => { throw new Error('current time unavailable') }) youtubePlayer.getDuration.mockImplementation(() => { throw new Error('duration unavailable') }) expect(adapter.getCurrentTime()).toBe(0) expect(adapter.getDuration()).toBe(0) }) it('should expose video metadata for SDK-built tracking events', () => { expect(adapter.getMediaId()).toBe('video-123') expect(adapter.getMediaName()).toBe('Test YouTube Video') expect(adapter.getVideoType()).toBe('youtube-clip') expect(adapter.getSourceUrl()).toBe('https://youtu.be/video-123') expect(adapter.getVideoLayout()).toBe('in-line') expect(adapter.getLoopCount()).toBe(2) }) it('should gracefully handle unavailable YouTube metadata', () => { youtubePlayer.getVideoData.mockImplementation(() => { throw new Error('metadata unavailable') }) youtubePlayer.getVideoUrl.mockImplementation(() => { throw new Error('url unavailable') }) expect(adapter.getMediaId()).toBeUndefined() expect(adapter.getMediaName()).toBeUndefined() expect(adapter.getSourceUrl()).toBe('') }) it('should detect autoplay from the YouTube iframe', () => { const iframe = document.createElement('iframe') iframe.setAttribute('autoplay', '1') youtubePlayer.getIframe.mockReturnValue(iframe) expect(adapter.isAutoplay()).toBe(true) }) it('should report non-autoplay when the iframe does not contain autoplay', () => { expect(adapter.isAutoplay()).toBe(false) }) it('should report non-autoplay when the YouTube iframe is unavailable', () => { youtubePlayer.getIframe.mockImplementation(() => { throw new Error('iframe unavailable') }) expect(adapter.isAutoplay()).toBe(false) }) it('should add and remove event listeners on the placeholder player element', () => { const callback = jest.fn() adapter.on('playing', callback) playerElement.dispatchEvent(new Event('playing')) adapter.off('playing', callback) playerElement.dispatchEvent(new Event('playing')) expect(callback).toHaveBeenCalledTimes(1) }) })