diff --git a/frontend/src/components/forms/settings/__tests__/StreamSettingsForm.test.jsx b/frontend/src/components/forms/settings/__tests__/StreamSettingsForm.test.jsx index 25ee46aa..d960e498 100644 --- a/frontend/src/components/forms/settings/__tests__/StreamSettingsForm.test.jsx +++ b/frontend/src/components/forms/settings/__tests__/StreamSettingsForm.test.jsx @@ -7,6 +7,7 @@ vi.mock('../../../../store/settings.jsx', () => ({ default: vi.fn() })); vi.mock('../../../../store/warnings.jsx', () => ({ default: vi.fn() })); vi.mock('../../../../store/userAgents.jsx', () => ({ default: vi.fn() })); vi.mock('../../../../store/streamProfiles.jsx', () => ({ default: vi.fn() })); +vi.mock('../../../../store/outputProfiles.jsx', () => ({ default: vi.fn() })); // ── Constants mock ───────────────────────────────────────────────────────────── vi.mock('../../../../constants.js', () => ({ @@ -154,6 +155,7 @@ import useSettingsStore from '../../../../store/settings.jsx'; import useWarningsStore from '../../../../store/warnings.jsx'; import useUserAgentsStore from '../../../../store/userAgents.jsx'; import useStreamProfilesStore from '../../../../store/streamProfiles.jsx'; +import useOutputProfilesStore from '../../../../store/outputProfiles.jsx'; import { useForm } from '@mantine/form'; import { getChangedSettings, @@ -172,9 +174,8 @@ import { const mockFormValues = { default_user_agent: '1', default_stream_profile: '2', - preferred_region: 'us', - auto_import_mapped_files: false, m3u_hash_key: ['name'], + hdhr_output_profile_id: null, }; const makeFormMock = (overrides = {}) => ({ @@ -184,6 +185,7 @@ const makeFormMock = (overrides = {}) => ({ } return { value: mockFormValues[field] ?? '', onChange: vi.fn() }; }), + values: mockFormValues, setValues: vi.fn(), getValues: vi.fn(() => mockFormValues), onSubmit: vi.fn((handler) => (e) => { @@ -219,6 +221,7 @@ const setupMocks = ({ warningSuppressed = false, userAgents = makeUserAgents(), streamProfiles = makeStreamProfiles(), + outputProfiles = [], } = {}) => { const formMock = makeFormMock(formOverrides); @@ -226,7 +229,7 @@ const setupMocks = ({ vi.mocked(getStreamSettingsFormInitialValues).mockReturnValue(mockFormValues); vi.mocked(getStreamSettingsFormValidation).mockReturnValue({}); vi.mocked(parseSettings).mockReturnValue(mockFormValues); - vi.mocked(getChangedSettings).mockReturnValue({ preferred_region: 'eu' }); + vi.mocked(getChangedSettings).mockReturnValue({ default_user_agent: '1' }); vi.mocked(saveChangedSettings).mockResolvedValue(undefined); vi.mocked(rehashStreams).mockResolvedValue(undefined); @@ -243,6 +246,9 @@ const setupMocks = ({ vi.mocked(useStreamProfilesStore).mockImplementation((sel) => sel({ profiles: streamProfiles }) ); + vi.mocked(useOutputProfilesStore).mockImplementation((sel) => + sel({ profiles: outputProfiles }) + ); return { formMock }; }; @@ -285,18 +291,6 @@ describe('StreamSettingsForm', () => { expect(screen.getByTestId('default_stream_profile')).toBeInTheDocument(); }); - it('renders the Preferred Region select', () => { - render(); - expect(screen.getByTestId('preferred_region')).toBeInTheDocument(); - }); - - it('renders the Auto-Import Mapped Files switch', () => { - render(); - expect( - screen.getByTestId('auto_import_mapped_files') - ).toBeInTheDocument(); - }); - it('renders the M3U Hash Key multiselect', () => { render(); expect(screen.getByTestId('m3u_hash_key')).toBeInTheDocument(); @@ -314,12 +308,6 @@ describe('StreamSettingsForm', () => { expect(screen.getByText('HLS')).toBeInTheDocument(); }); - it('populates region options from REGION_CHOICES', () => { - render(); - expect(screen.getByText('US')).toBeInTheDocument(); - expect(screen.getByText('EU')).toBeInTheDocument(); - }); - it('does not show success alert on initial render', () => { render(); expect(screen.queryByTestId('alert')).not.toBeInTheDocument(); @@ -410,7 +398,9 @@ describe('StreamSettingsForm', () => { describe('form submission (no M3U hash key change)', () => { beforeEach(() => { // Same hash key before and after → no dialog - vi.mocked(getChangedSettings).mockReturnValue({ preferred_region: 'eu' }); + vi.mocked(getChangedSettings).mockReturnValue({ + default_user_agent: '1', + }); setupMocks(); formMock = makeFormMock(); vi.mocked(useForm).mockReturnValue(formMock); @@ -783,16 +773,10 @@ describe('StreamSettingsForm', () => { ); }); - it('calls getInputProps for preferred_region', () => { - render(); - expect(formMock.getInputProps).toHaveBeenCalledWith('preferred_region'); - }); - - it('calls getInputProps for auto_import_mapped_files with checkbox type', () => { + it('calls getInputProps for default_output_format', () => { render(); expect(formMock.getInputProps).toHaveBeenCalledWith( - 'auto_import_mapped_files', - { type: 'checkbox' } + 'default_output_format' ); }); diff --git a/frontend/src/components/forms/settings/__tests__/SystemSettingsForm.test.jsx b/frontend/src/components/forms/settings/__tests__/SystemSettingsForm.test.jsx index 4b610e54..09daace7 100644 --- a/frontend/src/components/forms/settings/__tests__/SystemSettingsForm.test.jsx +++ b/frontend/src/components/forms/settings/__tests__/SystemSettingsForm.test.jsx @@ -5,6 +5,14 @@ import SystemSettingsForm from '../SystemSettingsForm'; // ── Store mocks ──────────────────────────────────────────────────────────────── vi.mock('../../../../store/settings.jsx', () => ({ default: vi.fn() })); +// ── Constants mock ───────────────────────────────────────────────────────────── +vi.mock('../../../../constants.js', () => ({ + REGION_CHOICES: [ + { label: 'United States', value: 'US' }, + { label: 'Europe', value: 'EU' }, + ], +})); + // ── Utility mocks ────────────────────────────────────────────────────────────── vi.mock('../../../../utils/pages/SettingsUtils.js', () => ({ getChangedSettings: vi.fn(), @@ -52,6 +60,23 @@ vi.mock('@mantine/core', () => ({ ), Stack: ({ children }) =>
{children}
, + Group: ({ children }) =>
{children}
, + Select: ({ label, id, data, description }) => ( +
+ + {description &&

{description}

} + +
+ ), + Switch: ({ id }) => ( + {}} /> + ), Text: ({ children }) => {children}, Divider: () =>
, })); @@ -85,7 +110,11 @@ const setupMocks = ({ settings = makeSettings(), environment = makeEnvironment(), } = {}) => { - const formValues = { max_system_events: settings?.max_system_events ?? 100 }; + const formValues = { + max_system_events: settings?.max_system_events ?? 100, + preferred_region: '', + auto_import_mapped_files: true, + }; const formMock = { values: formValues, @@ -94,6 +123,12 @@ const setupMocks = ({ setFieldValue: vi.fn((key, value) => { formMock.values[key] = value; }), + getInputProps: vi.fn((field, opts) => { + if (opts?.type === 'checkbox') { + return { checked: formValues[field] ?? false, onChange: vi.fn() }; + } + return { value: formValues[field] ?? '', onChange: vi.fn() }; + }), onSubmit: vi.fn((handler) => handler), submitting: false, }; @@ -146,16 +181,29 @@ describe('SystemSettingsForm', () => { render(); expect( screen.getByText( - 'Number of events to retain (minimum: 10, maximum: 1000)' + 'Number of events to retain (minimum: 10, maximum: 1000). Events are displayed on the Stats page.' ) ).toBeInTheDocument(); }); - it('renders descriptive text about system events', () => { + it('renders the Preferred Region select', () => { + setupMocks(); + render(); + expect(screen.getByLabelText('Preferred Region')).toBeInTheDocument(); + }); + + it('populates region options from REGION_CHOICES', () => { + setupMocks(); + render(); + expect(screen.getByText('United States')).toBeInTheDocument(); + expect(screen.getByText('Europe')).toBeInTheDocument(); + }); + + it('renders the Auto-Import Mapped Files switch', () => { setupMocks(); render(); expect( - screen.getByText(/Configure how many system events/) + screen.getByTestId('auto_import_mapped_files') ).toBeInTheDocument(); }); @@ -194,6 +242,12 @@ describe('SystemSettingsForm', () => { getValues: vi.fn().mockReturnValue(formValues), setValues: vi.fn(), setFieldValue: vi.fn(), + getInputProps: vi.fn((field, opts) => { + if (opts?.type === 'checkbox') { + return { checked: formValues[field] ?? false, onChange: vi.fn() }; + } + return { value: formValues[field] ?? '', onChange: vi.fn() }; + }), onSubmit: vi.fn((handler) => handler), submitting: false, }; @@ -230,22 +284,34 @@ describe('SystemSettingsForm', () => { render(); expect(formMock.setValues).toHaveBeenCalledWith({ max_system_events: 100, + preferred_region: '', + auto_import_mapped_files: true, }); }); it('does not call parseSettings when settings is null', () => { + const nullFormValues = { max_system_events: 100 }; const formMock = { - values: { max_system_events: 100 }, - getValues: vi.fn().mockReturnValue({ max_system_events: 100 }), + values: nullFormValues, + getValues: vi.fn().mockReturnValue(nullFormValues), setValues: vi.fn(), setFieldValue: vi.fn(), + getInputProps: vi.fn((field, opts) => { + if (opts?.type === 'checkbox') { + return { + checked: nullFormValues[field] ?? false, + onChange: vi.fn(), + }; + } + return { value: nullFormValues[field] ?? '', onChange: vi.fn() }; + }), onSubmit: vi.fn((handler) => handler), submitting: false, }; vi.mocked(useForm).mockReturnValue(formMock); - vi.mocked(getSystemSettingsFormInitialValues).mockReturnValue({ - max_system_events: 100, - }); + vi.mocked(getSystemSettingsFormInitialValues).mockReturnValue( + nullFormValues + ); vi.mocked(useSettingsStore).mockImplementation((sel) => sel({ settings: null, environment: makeEnvironment() }) ); diff --git a/frontend/src/utils/pages/__tests__/SettingsUtils.test.js b/frontend/src/utils/pages/__tests__/SettingsUtils.test.js index 43f395d4..91417b6a 100644 --- a/frontend/src/utils/pages/__tests__/SettingsUtils.test.js +++ b/frontend/src/utils/pages/__tests__/SettingsUtils.test.js @@ -73,6 +73,7 @@ describe('SettingsUtils', () => { }; API.updateSetting.mockResolvedValue({}); + API.createSetting.mockResolvedValue({}); await SettingsUtils.saveChangedSettings(settings, changedSettings);