164 lines
5.0 KiB
TypeScript
164 lines
5.0 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { fireEvent, render, screen } from '@testing-library/react'
|
|
import type { AudioTrack, VideoQuality } from '../../types'
|
|
import { SettingsMenu } from './SettingsMenu'
|
|
|
|
const { contextState } = vi.hoisted(() => ({
|
|
contextState: {
|
|
value: null as any,
|
|
},
|
|
}))
|
|
|
|
vi.mock('../../contexts/PlayerContext', () => ({
|
|
usePlayerContext: () => contextState.value,
|
|
}))
|
|
|
|
const audioTracks: AudioTrack[] = [
|
|
{
|
|
name: 'English',
|
|
language: 'en',
|
|
url: '',
|
|
groupId: 'audio',
|
|
},
|
|
]
|
|
|
|
const qualities: VideoQuality[] = [
|
|
{ label: '1080p', height: 1080, levelIndex: 0 },
|
|
{ label: '720p', height: 720, levelIndex: 1 },
|
|
]
|
|
|
|
const subtitles = [{ src: '/sub.vtt', lang: 'en', label: 'English' }]
|
|
|
|
describe('SettingsMenu', () => {
|
|
beforeEach(() => {
|
|
contextState.value = {
|
|
uiState: {
|
|
controlsVisible: true,
|
|
settingsOpen: true,
|
|
volumeControlOpen: false,
|
|
qualityMenuOpen: false,
|
|
subtitleMenuOpen: false,
|
|
},
|
|
videoState: {
|
|
playing: false,
|
|
currentTime: 0,
|
|
duration: 0,
|
|
buffered: 0,
|
|
volume: 1,
|
|
muted: false,
|
|
playbackRate: 1,
|
|
fullscreen: false,
|
|
pictureInPicture: false,
|
|
loading: false,
|
|
error: null,
|
|
seeking: false,
|
|
isLiveBroadcast: false,
|
|
},
|
|
settings: {
|
|
quality: null,
|
|
subtitle: null,
|
|
subtitleStyle: {},
|
|
audioTrack: null,
|
|
playbackRate: 1,
|
|
},
|
|
setPlaybackRate: vi.fn(),
|
|
setSubtitle: vi.fn(),
|
|
setSubtitleStyle: vi.fn(),
|
|
saveSubtitleStyle: vi.fn(),
|
|
revertSubtitleStyle: vi.fn(),
|
|
setAudioTrack: vi.fn(),
|
|
setQuality: vi.fn(),
|
|
toggleSettings: vi.fn(),
|
|
subtitleStyleEditorEnabled: true,
|
|
translations: {
|
|
noSubtitlesAvailable: 'No subtitles available',
|
|
subtitles: 'Subtitles',
|
|
subtitleStyle: 'Subtitle Style',
|
|
preview: 'Preview',
|
|
save: 'Save',
|
|
cancel: 'Cancel',
|
|
reset: 'Reset',
|
|
off: 'Off',
|
|
auto: 'Auto',
|
|
quality: 'Quality',
|
|
speed: 'Speed',
|
|
fontSize: 'Font Size',
|
|
fontWeight: 'Font Weight',
|
|
textColor: 'Text Color',
|
|
backgroundColor: 'Background Color',
|
|
backgroundOpacity: 'Background Opacity',
|
|
normal: 'Normal',
|
|
default: 'Default',
|
|
audioTrack: 'Audio Track',
|
|
settings: 'Settings',
|
|
level: 'Level',
|
|
play: 'Play',
|
|
pause: 'Pause',
|
|
mute: 'Mute',
|
|
unmute: 'Unmute',
|
|
enterFullscreen: 'Enter fullscreen',
|
|
exitFullscreen: 'Exit fullscreen',
|
|
enterPictureInPicture: 'Enter picture-in-picture',
|
|
exitPictureInPicture: 'Exit picture-in-picture',
|
|
videoProgress: 'Video progress',
|
|
volume: 'Volume',
|
|
live: 'LIVE',
|
|
},
|
|
}
|
|
})
|
|
|
|
it('does not render when settings are closed', () => {
|
|
contextState.value.uiState.settingsOpen = false
|
|
render(<SettingsMenu subtitles={subtitles} audioTracks={audioTracks} qualities={qualities} />)
|
|
expect(screen.queryByText('Settings')).not.toBeInTheDocument()
|
|
})
|
|
|
|
it('changes playback speed from speed submenu', () => {
|
|
render(<SettingsMenu subtitles={subtitles} audioTracks={audioTracks} qualities={qualities} />)
|
|
|
|
fireEvent.click(screen.getByText('Speed'))
|
|
fireEvent.click(screen.getByText('1.5x'))
|
|
|
|
expect(contextState.value.setPlaybackRate).toHaveBeenCalledWith(1.5)
|
|
})
|
|
|
|
it('selects subtitle from submenu', () => {
|
|
render(<SettingsMenu subtitles={subtitles} audioTracks={audioTracks} qualities={qualities} />)
|
|
|
|
fireEvent.click(screen.getByText('Subtitles'))
|
|
fireEvent.click(screen.getByRole('button', { name: 'English' }))
|
|
expect(contextState.value.setSubtitle).toHaveBeenCalledWith(subtitles[0])
|
|
})
|
|
|
|
it('selects audio track from submenu', () => {
|
|
render(<SettingsMenu subtitles={subtitles} audioTracks={audioTracks} qualities={qualities} />)
|
|
|
|
fireEvent.click(screen.getByText('Audio Track'))
|
|
fireEvent.click(screen.getByRole('button', { name: 'English' }))
|
|
expect(contextState.value.setAudioTrack).toHaveBeenCalledWith(audioTracks[0])
|
|
})
|
|
|
|
it('selects quality from submenu', () => {
|
|
render(<SettingsMenu subtitles={subtitles} audioTracks={audioTracks} qualities={qualities} />)
|
|
|
|
fireEvent.click(screen.getByText('Quality'))
|
|
fireEvent.click(screen.getByText('720p'))
|
|
expect(contextState.value.setQuality).toHaveBeenCalledWith(qualities[1])
|
|
})
|
|
|
|
it('saves subtitle style from subtitle style editor', () => {
|
|
render(<SettingsMenu subtitles={subtitles} audioTracks={audioTracks} qualities={qualities} />)
|
|
|
|
fireEvent.click(screen.getByText('Subtitles'))
|
|
fireEvent.click(screen.getByRole('button', { name: /Subtitle Style/i }))
|
|
fireEvent.change(screen.getByLabelText('Font Size'), { target: { value: '30' } })
|
|
fireEvent.click(screen.getByRole('button', { name: 'Save' }))
|
|
|
|
expect(contextState.value.saveSubtitleStyle).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
fontSize: 30,
|
|
})
|
|
)
|
|
})
|
|
})
|