import { afterEach, describe, expect, test, vi } from 'vitest'; import { render, screen, fireEvent, waitFor } from '@testing-library/svelte'; vi.mock('$lib/api/normalization', async (importOriginal) => ({ ...(await importOriginal()), getNormalization: vi.fn(), putNormalization: vi.fn() })); vi.mock('$lib/stores/toast.svelte', () => ({ pushToast: vi.fn() })); import NormalizationSetting from './NormalizationSetting.svelte'; import { getNormalization, putNormalization } from '$lib/api/normalization'; import { normalization } from '$lib/stores/normalization.svelte'; import { pushToast } from '$lib/stores/toast.svelte'; afterEach(() => { vi.clearAllMocks(); localStorage.clear(); }); describe('NormalizationSetting', () => { test('shows the server value and saves the whole preference on a change', async () => { vi.mocked(getNormalization).mockResolvedValue({ mode: 'track', target_lufs: -16, boost: 'headroom' }); vi.mocked(putNormalization).mockImplementation(async (p) => p); render(NormalizationSetting); await waitFor(() => expect(screen.getByRole('radio', { name: 'Track' })).toBeChecked()); expect(screen.getByRole('radio', { name: '-16 LUFS' })).toBeChecked(); await fireEvent.click(screen.getByRole('radio', { name: 'Album' })); await waitFor(() => expect(putNormalization).toHaveBeenCalledWith({ mode: 'album', target_lufs: -16, boost: 'headroom' }) ); await fireEvent.click(screen.getByRole('checkbox', { name: /boost quiet tracks/i })); await waitFor(() => expect(putNormalization).toHaveBeenLastCalledWith({ mode: 'album', target_lufs: -16, boost: 'limiter' }) ); // The last value seen is cached for the player's first track of a session. expect(JSON.parse(localStorage.getItem('minstrel:normalization') ?? 'null')).toEqual({ mode: 'album', target_lufs: -16, boost: 'limiter' }); }); test('a failed save puts the previous choice back and says so', async () => { vi.mocked(getNormalization).mockResolvedValue({ mode: 'auto', target_lufs: -18, boost: 'headroom' }); vi.mocked(putNormalization).mockRejectedValue(new Error('offline')); render(NormalizationSetting); await waitFor(() => expect(screen.getByRole('radio', { name: 'Auto' })).toBeChecked()); await fireEvent.click(screen.getByRole('radio', { name: 'Off' })); await waitFor(() => expect(pushToast).toHaveBeenCalledWith('Could not save volume leveling.', 'error')); expect(normalization.value.mode).toBe('auto'); expect(screen.getByRole('radio', { name: 'Auto' })).toBeChecked(); }); test('off hides the target and boost controls', async () => { vi.mocked(getNormalization).mockResolvedValue({ mode: 'off', target_lufs: -18, boost: 'headroom' }); render(NormalizationSetting); await waitFor(() => expect(screen.getByRole('radio', { name: 'Off' })).toBeChecked()); expect(screen.queryByRole('radio', { name: '-18 LUFS' })).toBeNull(); expect(screen.queryByRole('checkbox')).toBeNull(); }); });