From d3c2beabd8bae3b1b55d47b459f949c92597b4d3 Mon Sep 17 00:00:00 2001 From: Xavier Araque Date: Fri, 7 Nov 2025 15:48:08 +0100 Subject: [PATCH] Player.jsx Component - Comprehensive Architecture Improvement, fix vitest --- .../audioplayer/hooks/usePlayerState.test.js | 25 ++++++------- .../audioplayer/hooks/usePreloading.test.js | 19 +++++----- .../audioplayer/hooks/useReplayGain.test.js | 37 +++++++++---------- .../audioplayer/hooks/useScrobbling.test.js | 18 ++++----- 4 files changed, 48 insertions(+), 51 deletions(-) diff --git a/ui/src/audioplayer/hooks/usePlayerState.test.js b/ui/src/audioplayer/hooks/usePlayerState.test.js index 05cd875c3..d8b4f1ad1 100644 --- a/ui/src/audioplayer/hooks/usePlayerState.test.js +++ b/ui/src/audioplayer/hooks/usePlayerState.test.js @@ -1,22 +1,21 @@ -/* eslint-env jest */ - import { renderHook } from '@testing-library/react-hooks' import { usePlayerState } from './usePlayerState' import { useDispatch, useSelector } from 'react-redux' +import { describe, it, beforeEach, vi, expect } from 'vitest' // Mock react-redux -jest.mock('react-redux', () => ({ - useDispatch: jest.fn(), - useSelector: jest.fn(), +vi.mock('react-redux', () => ({ + useDispatch: vi.fn(), + useSelector: vi.fn(), })) // Mock actions -jest.mock('../../actions', () => ({ - clearQueue: jest.fn(() => ({ type: 'CLEAR_QUEUE' })), - currentPlaying: jest.fn(() => ({ type: 'CURRENT_PLAYING' })), - setPlayMode: jest.fn(() => ({ type: 'SET_PLAY_MODE' })), - setVolume: jest.fn(() => ({ type: 'SET_VOLUME' })), - syncQueue: jest.fn(() => ({ type: 'SYNC_QUEUE' })), +vi.mock('../../actions', () => ({ + clearQueue: vi.fn(() => ({ type: 'CLEAR_QUEUE' })), + currentPlaying: vi.fn(() => ({ type: 'CURRENT_PLAYING' })), + setPlayMode: vi.fn(() => ({ type: 'SET_PLAY_MODE' })), + setVolume: vi.fn(() => ({ type: 'SET_VOLUME' })), + syncQueue: vi.fn(() => ({ type: 'SYNC_QUEUE' })), })) // Import the mocked actions @@ -30,10 +29,10 @@ describe('usePlayerState', () => { volume: 0.8, } - const mockDispatch = jest.fn() + const mockDispatch = vi.fn() beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() useDispatch.mockReturnValue(mockDispatch) useSelector.mockReturnValue(mockPlayerState) }) diff --git a/ui/src/audioplayer/hooks/usePreloading.test.js b/ui/src/audioplayer/hooks/usePreloading.test.js index 05c2982c6..e9a46bb3c 100644 --- a/ui/src/audioplayer/hooks/usePreloading.test.js +++ b/ui/src/audioplayer/hooks/usePreloading.test.js @@ -1,7 +1,6 @@ -/* eslint-env jest */ - import { renderHook, act } from '@testing-library/react-hooks' import { usePreloading } from './usePreloading' +import { describe, it, beforeEach, afterEach, vi, expect } from 'vitest' describe('usePreloading', () => { const mockPlayerState = { @@ -13,11 +12,11 @@ describe('usePreloading', () => { } beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() // Mock Audio constructor - global.Audio = jest.fn().mockImplementation(() => ({ + global.Audio = vi.fn().mockImplementation(() => ({ src: '', - addEventListener: jest.fn(), + addEventListener: vi.fn(), })) }) @@ -96,9 +95,9 @@ describe('usePreloading', () => { }) it('should handle Audio constructor errors gracefully', () => { - const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {}) + const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) - global.Audio = jest.fn().mockImplementation(() => { + global.Audio = vi.fn().mockImplementation(() => { throw new Error('Audio creation failed') }) @@ -118,18 +117,18 @@ describe('usePreloading', () => { }) it('should handle audio load errors gracefully', () => { - const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {}) + const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) const mockAudioInstance = { src: '', - addEventListener: jest.fn((event, callback) => { + addEventListener: vi.fn((event, callback) => { if (event === 'error') { callback(new Event('error')) } }), } - global.Audio = jest.fn().mockImplementation(() => mockAudioInstance) + global.Audio = vi.fn().mockImplementation(() => mockAudioInstance) const { result } = renderHook(() => usePreloading(mockPlayerState)) diff --git a/ui/src/audioplayer/hooks/useReplayGain.test.js b/ui/src/audioplayer/hooks/useReplayGain.test.js index d97f5df5f..5edf2a7ca 100644 --- a/ui/src/audioplayer/hooks/useReplayGain.test.js +++ b/ui/src/audioplayer/hooks/useReplayGain.test.js @@ -1,11 +1,10 @@ -/* eslint-env jest */ - import { renderHook, act } from '@testing-library/react-hooks' import { useReplayGain } from './useReplayGain' +import { describe, it, beforeEach, afterEach, vi, expect } from 'vitest' // Mock calculateGain utility -jest.mock('../../utils/calculateReplayGain', () => ({ - calculateGain: jest.fn(), +vi.mock('../../utils/calculateReplayGain', () => ({ + calculateGain: vi.fn(), })) // Import the mocked module @@ -15,17 +14,17 @@ describe('useReplayGain', () => { const mockCalculateGain = calculateReplayGain.calculateGain beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() // Mock Web Audio API - global.AudioContext = jest.fn().mockImplementation(() => ({ - createMediaElementSource: jest.fn(() => ({ - connect: jest.fn(), + global.AudioContext = vi.fn().mockImplementation(() => ({ + createMediaElementSource: vi.fn(() => ({ + connect: vi.fn(), })), - createGain: jest.fn(() => ({ + createGain: vi.fn(() => ({ gain: { - setValueAtTime: jest.fn(), + setValueAtTime: vi.fn(), }, - connect: jest.fn(), + connect: vi.fn(), })), currentTime: 0, })) @@ -83,10 +82,10 @@ describe('useReplayGain', () => { }) it('should handle Web Audio API errors gracefully', () => { - const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {}) + const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) // Mock AudioContext to throw error - global.AudioContext = jest.fn().mockImplementation(() => { + global.AudioContext = vi.fn().mockImplementation(() => { throw new Error('Web Audio API not supported') }) @@ -108,7 +107,7 @@ describe('useReplayGain', () => { }) it('should handle gain application errors gracefully', () => { - const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {}) + const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) const mockAudioInstance = { crossOrigin: '' } const mockPlayerState = { @@ -119,17 +118,17 @@ describe('useReplayGain', () => { // Mock gain.setValueAtTime to throw error const mockGainNode = { gain: { - setValueAtTime: jest.fn(() => { + setValueAtTime: vi.fn(() => { throw new Error('Gain application failed') }), }, } - global.AudioContext = jest.fn().mockImplementation(() => ({ - createMediaElementSource: jest.fn(() => ({ - connect: jest.fn(), + global.AudioContext = vi.fn().mockImplementation(() => ({ + createMediaElementSource: vi.fn(() => ({ + connect: vi.fn(), })), - createGain: jest.fn(() => mockGainNode), + createGain: vi.fn(() => mockGainNode), currentTime: 0, })) diff --git a/ui/src/audioplayer/hooks/useScrobbling.test.js b/ui/src/audioplayer/hooks/useScrobbling.test.js index 65ef6a022..028ce71e5 100644 --- a/ui/src/audioplayer/hooks/useScrobbling.test.js +++ b/ui/src/audioplayer/hooks/useScrobbling.test.js @@ -1,12 +1,12 @@ -/* eslint-env jest */ - import { renderHook, act } from '@testing-library/react-hooks' import { useScrobbling } from './useScrobbling' +import { describe, it, beforeEach, vi, expect } from 'vitest' // Mock subsonic module -jest.mock('../../subsonic', () => ({ - scrobble: jest.fn(), - nowPlaying: jest.fn(), +vi.mock('../../subsonic', () => ({ + default: {}, + scrobble: vi.fn(), + nowPlaying: vi.fn(), })) // Import the mocked module @@ -14,7 +14,7 @@ import * as subsonic from '../../subsonic' // Mock dataProvider const mockDataProvider = { - getOne: jest.fn(), + getOne: vi.fn(), } describe('useScrobbling', () => { @@ -26,10 +26,10 @@ describe('useScrobbling', () => { current: { uuid: '1', trackId: 'track1' }, } - const mockDispatch = jest.fn() + const mockDispatch = vi.fn() beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() mockDataProvider.getOne.mockResolvedValue({ data: {} }) }) @@ -131,7 +131,7 @@ describe('useScrobbling', () => { }) it('should handle scrobbling errors gracefully', () => { - const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {}) + const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) // const mockSubsonic = subsonic subsonic.scrobble.mockImplementation(() => { throw new Error('Scrobbling failed')