From e421c007ccbc76603391be2fa6fbc5e8aaf20a1f Mon Sep 17 00:00:00 2001
From: Nick Sandstrom <32273437+nick4810@users.noreply.github.com>
Date: Sat, 14 Mar 2026 07:56:05 -0700
Subject: [PATCH] Conforming to style guide
---
.../__tests__/DvrSettingsForm.test.jsx | 96 +++++++++----
.../settings/__tests__/NavOrderForm.test.jsx | 2 +-
.../__tests__/NetworkAccessForm.test.jsx | 68 +++++++---
.../__tests__/ProxySettingsForm.test.jsx | 32 +++--
.../__tests__/StreamSettingsForm.test.jsx | 128 ++++++++++++------
.../__tests__/SystemSettingsForm.test.jsx | 59 ++++++--
.../__tests__/UiSettingsForm.test.jsx | 90 ++++++++----
7 files changed, 339 insertions(+), 136 deletions(-)
diff --git a/frontend/src/components/forms/settings/__tests__/DvrSettingsForm.test.jsx b/frontend/src/components/forms/settings/__tests__/DvrSettingsForm.test.jsx
index ad86f1e0..f3293051 100644
--- a/frontend/src/components/forms/settings/__tests__/DvrSettingsForm.test.jsx
+++ b/frontend/src/components/forms/settings/__tests__/DvrSettingsForm.test.jsx
@@ -125,13 +125,17 @@ const mockFormValues = {
const makeFormMock = (overrides = {}) => ({
getInputProps: vi.fn((field, opts) => {
- if (opts?.type === 'checkbox') return { checked: mockFormValues[field] ?? false, onChange: vi.fn() };
+ if (opts?.type === 'checkbox')
+ return { checked: mockFormValues[field] ?? false, onChange: vi.fn() };
return { value: mockFormValues[field] ?? '', onChange: vi.fn() };
}),
setValues: vi.fn(),
setFieldValue: vi.fn(),
getValues: vi.fn(() => mockFormValues),
- onSubmit: vi.fn((handler) => (e) => { e?.preventDefault?.(); return handler(); }),
+ onSubmit: vi.fn((handler) => (e) => {
+ e?.preventDefault?.();
+ return handler();
+ }),
...overrides,
});
@@ -229,7 +233,9 @@ describe('DvrSettingsForm', () => {
expect(screen.getByTestId('tv_template')).toBeInTheDocument();
expect(screen.getByTestId('tv_fallback_template')).toBeInTheDocument();
expect(screen.getByTestId('movie_template')).toBeInTheDocument();
- expect(screen.getByTestId('movie_fallback_template')).toBeInTheDocument();
+ expect(
+ screen.getByTestId('movie_fallback_template')
+ ).toBeInTheDocument();
});
});
@@ -250,7 +256,9 @@ describe('DvrSettingsForm', () => {
it('shows "No custom comskip.ini uploaded." when no config exists', async () => {
render();
await waitFor(() => {
- expect(screen.getByText('No custom comskip.ini uploaded.')).toBeInTheDocument();
+ expect(
+ screen.getByText('No custom comskip.ini uploaded.')
+ ).toBeInTheDocument();
});
});
@@ -261,7 +269,9 @@ describe('DvrSettingsForm', () => {
});
render();
await waitFor(() => {
- expect(screen.getByText('Using /app/docker/comskip.ini')).toBeInTheDocument();
+ expect(
+ screen.getByText('Using /app/docker/comskip.ini')
+ ).toBeInTheDocument();
});
});
});
@@ -306,7 +316,9 @@ describe('DvrSettingsForm', () => {
it('handles getComskipConfig error gracefully', async () => {
vi.mocked(getComskipConfig).mockRejectedValue(new Error('network error'));
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
+ const consoleSpy = vi
+ .spyOn(console, 'error')
+ .mockImplementation(() => {});
render();
await waitFor(() => {
expect(consoleSpy).toHaveBeenCalledWith(
@@ -357,8 +369,13 @@ describe('DvrSettingsForm', () => {
fireEvent.submit(screen.getByText('Save').closest('form'));
await waitFor(() => {
- expect(getChangedSettings).toHaveBeenCalledWith(mockFormValues, makeSettings());
- expect(saveChangedSettings).toHaveBeenCalledWith(makeSettings(), { pre_offset_minutes: 5 });
+ expect(getChangedSettings).toHaveBeenCalledWith(
+ mockFormValues,
+ makeSettings()
+ );
+ expect(saveChangedSettings).toHaveBeenCalledWith(makeSettings(), {
+ pre_offset_minutes: 5,
+ });
});
});
@@ -373,8 +390,12 @@ describe('DvrSettingsForm', () => {
});
it('does not show success alert when saveChangedSettings throws', async () => {
- vi.mocked(saveChangedSettings).mockRejectedValue(new Error('save failed'));
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
+ vi.mocked(saveChangedSettings).mockRejectedValue(
+ new Error('save failed')
+ );
+ const consoleSpy = vi
+ .spyOn(console, 'error')
+ .mockImplementation(() => {});
render();
fireEvent.submit(screen.getByText('Save').closest('form'));
@@ -400,11 +421,17 @@ describe('DvrSettingsForm', () => {
});
it('calls uploadComskipIni with the selected file', async () => {
- const mockFile = new File(['content'], 'comskip.ini', { type: 'text/plain' });
- vi.mocked(uploadComskipIni).mockResolvedValue({ path: '/uploaded/comskip.ini' });
+ const mockFile = new File(['content'], 'comskip.ini', {
+ type: 'text/plain',
+ });
+ vi.mocked(uploadComskipIni).mockResolvedValue({
+ path: '/uploaded/comskip.ini',
+ });
render();
- fireEvent.change(screen.getByTestId('file-input'), { target: { files: [mockFile] } });
+ fireEvent.change(screen.getByTestId('file-input'), {
+ target: { files: [mockFile] },
+ });
await waitFor(() => {
fireEvent.click(screen.getByText('Upload comskip.ini'));
@@ -416,11 +443,17 @@ describe('DvrSettingsForm', () => {
});
it('shows success notification after successful upload', async () => {
- const mockFile = new File(['content'], 'comskip.ini', { type: 'text/plain' });
- vi.mocked(uploadComskipIni).mockResolvedValue({ path: '/uploaded/comskip.ini' });
+ const mockFile = new File(['content'], 'comskip.ini', {
+ type: 'text/plain',
+ });
+ vi.mocked(uploadComskipIni).mockResolvedValue({
+ path: '/uploaded/comskip.ini',
+ });
render();
- fireEvent.change(screen.getByTestId('file-input'), { target: { files: [mockFile] } });
+ fireEvent.change(screen.getByTestId('file-input'), {
+ target: { files: [mockFile] },
+ });
await waitFor(() => {
fireEvent.click(screen.getByText('Upload comskip.ini'));
@@ -428,17 +461,26 @@ describe('DvrSettingsForm', () => {
await waitFor(() => {
expect(showNotification).toHaveBeenCalledWith(
- expect.objectContaining({ title: 'comskip.ini uploaded', color: 'green' })
+ expect.objectContaining({
+ title: 'comskip.ini uploaded',
+ color: 'green',
+ })
);
});
});
it('sets comskip_custom_path form field after successful upload', async () => {
- const mockFile = new File(['content'], 'comskip.ini', { type: 'text/plain' });
- vi.mocked(uploadComskipIni).mockResolvedValue({ path: '/uploaded/comskip.ini' });
+ const mockFile = new File(['content'], 'comskip.ini', {
+ type: 'text/plain',
+ });
+ vi.mocked(uploadComskipIni).mockResolvedValue({
+ path: '/uploaded/comskip.ini',
+ });
render();
- fireEvent.change(screen.getByTestId('file-input'), { target: { files: [mockFile] } });
+ fireEvent.change(screen.getByTestId('file-input'), {
+ target: { files: [mockFile] },
+ });
await waitFor(() => {
fireEvent.click(screen.getByText('Upload comskip.ini'));
@@ -453,12 +495,18 @@ describe('DvrSettingsForm', () => {
});
it('handles upload error gracefully', async () => {
- const mockFile = new File(['content'], 'comskip.ini', { type: 'text/plain' });
+ const mockFile = new File(['content'], 'comskip.ini', {
+ type: 'text/plain',
+ });
vi.mocked(uploadComskipIni).mockRejectedValue(new Error('upload failed'));
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
+ const consoleSpy = vi
+ .spyOn(console, 'error')
+ .mockImplementation(() => {});
render();
- fireEvent.change(screen.getByTestId('file-input'), { target: { files: [mockFile] } });
+ fireEvent.change(screen.getByTestId('file-input'), {
+ target: { files: [mockFile] },
+ });
await waitFor(() => {
fireEvent.click(screen.getByText('Upload comskip.ini'));
@@ -480,4 +528,4 @@ describe('DvrSettingsForm', () => {
expect(uploadComskipIni).not.toHaveBeenCalled();
});
});
-});
\ No newline at end of file
+});
diff --git a/frontend/src/components/forms/settings/__tests__/NavOrderForm.test.jsx b/frontend/src/components/forms/settings/__tests__/NavOrderForm.test.jsx
index 5cbf603e..3fb91a43 100644
--- a/frontend/src/components/forms/settings/__tests__/NavOrderForm.test.jsx
+++ b/frontend/src/components/forms/settings/__tests__/NavOrderForm.test.jsx
@@ -64,7 +64,7 @@ vi.mock('@dnd-kit/modifiers', () => ({
// Mock Mantine components
vi.mock('@mantine/core', () => ({
Box: ({ children, ...props }) =>
{title}
@@ -98,7 +98,9 @@ vi.mock('@mantine/core', () => ({
aria-label={label}
multiple
onChange={(e) => {
- const selected = Array.from(e.target.selectedOptions).map((o) => o.value);
+ const selected = Array.from(e.target.selectedOptions).map(
+ (o) => o.value
+ );
rest.onChange?.(selected);
}}
value={rest.value ?? []}
@@ -212,12 +214,12 @@ const makeStreamProfiles = () => [
];
const setupMocks = ({
- settings = makeSettings(),
- formOverrides = {},
- warningSuppressed = false,
- userAgents = makeUserAgents(),
- streamProfiles = makeStreamProfiles(),
- } = {}) => {
+ settings = makeSettings(),
+ formOverrides = {},
+ warningSuppressed = false,
+ userAgents = makeUserAgents(),
+ streamProfiles = makeStreamProfiles(),
+} = {}) => {
const formMock = makeFormMock(formOverrides);
vi.mocked(useForm).mockReturnValue(formMock);
@@ -290,7 +292,9 @@ describe('StreamSettingsForm', () => {
it('renders the Auto-Import Mapped Files switch', () => {
render(
);
- expect(screen.getByTestId('auto_import_mapped_files')).toBeInTheDocument();
+ expect(
+ screen.getByTestId('auto_import_mapped_files')
+ ).toBeInTheDocument();
});
it('renders the M3U Hash Key multiselect', () => {
@@ -323,7 +327,9 @@ describe('StreamSettingsForm', () => {
it('does not show confirmation dialog on initial render', () => {
render(
);
- expect(screen.queryByTestId('confirmation-dialog')).not.toBeInTheDocument();
+ expect(
+ screen.queryByTestId('confirmation-dialog')
+ ).not.toBeInTheDocument();
});
});
@@ -429,13 +435,19 @@ describe('StreamSettingsForm', () => {
fireEvent.submit(screen.getByText('Save').closest('form'));
await waitFor(() => {
expect(screen.getByTestId('alert')).toBeInTheDocument();
- expect(screen.getByTestId('alert-title')).toHaveTextContent('Saved Successfully');
+ expect(screen.getByTestId('alert-title')).toHaveTextContent(
+ 'Saved Successfully'
+ );
});
});
it('does not show success alert when saveChangedSettings throws', async () => {
- vi.mocked(saveChangedSettings).mockRejectedValue(new Error('save failed'));
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
+ vi.mocked(saveChangedSettings).mockRejectedValue(
+ new Error('save failed')
+ );
+ const consoleSpy = vi
+ .spyOn(console, 'error')
+ .mockImplementation(() => {});
render(
);
fireEvent.submit(screen.getByText('Save').closest('form'));
@@ -449,12 +461,17 @@ describe('StreamSettingsForm', () => {
it('logs error when saveChangedSettings throws', async () => {
const error = new Error('save failed');
vi.mocked(saveChangedSettings).mockRejectedValue(error);
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
+ const consoleSpy = vi
+ .spyOn(console, 'error')
+ .mockImplementation(() => {});
render(
);
fireEvent.submit(screen.getByText('Save').closest('form'));
await waitFor(() => {
- expect(consoleSpy).toHaveBeenCalledWith('Error saving settings:', error);
+ expect(consoleSpy).toHaveBeenCalledWith(
+ 'Error saving settings:',
+ error
+ );
});
consoleSpy.mockRestore();
});
@@ -466,7 +483,9 @@ describe('StreamSettingsForm', () => {
await waitFor(() => {
expect(saveChangedSettings).toHaveBeenCalled();
});
- expect(screen.queryByTestId('confirmation-dialog')).not.toBeInTheDocument();
+ expect(
+ screen.queryByTestId('confirmation-dialog')
+ ).not.toBeInTheDocument();
});
});
@@ -501,7 +520,9 @@ describe('StreamSettingsForm', () => {
fireEvent.submit(screen.getByText('Save').closest('form'));
await waitFor(() => {
- expect(screen.getByTestId('confirm-ok')).toHaveTextContent('Save and Rehash');
+ expect(screen.getByTestId('confirm-ok')).toHaveTextContent(
+ 'Save and Rehash'
+ );
});
});
@@ -526,9 +547,7 @@ describe('StreamSettingsForm', () => {
render(
);
fireEvent.submit(screen.getByText('Save').closest('form'));
- await waitFor(() =>
- screen.getByTestId('confirmation-dialog')
- );
+ await waitFor(() => screen.getByTestId('confirmation-dialog'));
fireEvent.click(screen.getByTestId('confirm-ok'));
await waitFor(() => {
@@ -546,7 +565,9 @@ describe('StreamSettingsForm', () => {
fireEvent.click(screen.getByTestId('confirm-ok'));
await waitFor(() => {
- expect(screen.getByTestId('alert-title')).toHaveTextContent('Saved Successfully');
+ expect(screen.getByTestId('alert-title')).toHaveTextContent(
+ 'Saved Successfully'
+ );
});
});
@@ -560,7 +581,9 @@ describe('StreamSettingsForm', () => {
fireEvent.click(screen.getByTestId('confirm-ok'));
await waitFor(() => {
- expect(screen.queryByTestId('confirmation-dialog')).not.toBeInTheDocument();
+ expect(
+ screen.queryByTestId('confirmation-dialog')
+ ).not.toBeInTheDocument();
});
});
@@ -574,7 +597,9 @@ describe('StreamSettingsForm', () => {
fireEvent.click(screen.getByTestId('confirm-cancel'));
await waitFor(() => {
- expect(screen.queryByTestId('confirmation-dialog')).not.toBeInTheDocument();
+ expect(
+ screen.queryByTestId('confirmation-dialog')
+ ).not.toBeInTheDocument();
});
expect(saveChangedSettings).not.toHaveBeenCalled();
});
@@ -590,7 +615,9 @@ describe('StreamSettingsForm', () => {
await waitFor(() => {
expect(saveChangedSettings).toHaveBeenCalled();
});
- expect(screen.queryByTestId('confirmation-dialog')).not.toBeInTheDocument();
+ expect(
+ screen.queryByTestId('confirmation-dialog')
+ ).not.toBeInTheDocument();
});
});
@@ -613,7 +640,9 @@ describe('StreamSettingsForm', () => {
fireEvent.click(screen.getByText('Rehash Streams'));
await waitFor(() => {
- expect(screen.getByTestId('confirm-ok')).toHaveTextContent('Start Rehash');
+ expect(screen.getByTestId('confirm-ok')).toHaveTextContent(
+ 'Start Rehash'
+ );
});
});
@@ -636,7 +665,9 @@ describe('StreamSettingsForm', () => {
await waitFor(() => {
expect(rehashStreams).toHaveBeenCalled();
});
- expect(screen.queryByTestId('confirmation-dialog')).not.toBeInTheDocument();
+ expect(
+ screen.queryByTestId('confirmation-dialog')
+ ).not.toBeInTheDocument();
});
it('shows rehash success alert after rehash completes', async () => {
@@ -654,7 +685,9 @@ describe('StreamSettingsForm', () => {
it('does not show rehash success alert when rehashStreams throws', async () => {
setupMocks({ warningSuppressed: true });
vi.mocked(rehashStreams).mockRejectedValue(new Error('fail'));
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
+ const consoleSpy = vi
+ .spyOn(console, 'error')
+ .mockImplementation(() => {});
render(
);
fireEvent.click(screen.getByText('Rehash Streams'));
@@ -669,12 +702,17 @@ describe('StreamSettingsForm', () => {
setupMocks({ warningSuppressed: true });
const error = new Error('network error');
vi.mocked(rehashStreams).mockRejectedValue(error);
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
+ const consoleSpy = vi
+ .spyOn(console, 'error')
+ .mockImplementation(() => {});
render(
);
fireEvent.click(screen.getByText('Rehash Streams'));
await waitFor(() => {
- expect(consoleSpy).toHaveBeenCalledWith('Error rehashing streams:', error);
+ expect(consoleSpy).toHaveBeenCalledWith(
+ 'Error rehashing streams:',
+ error
+ );
});
consoleSpy.mockRestore();
});
@@ -686,7 +724,9 @@ describe('StreamSettingsForm', () => {
fireEvent.click(screen.getByTestId('confirm-cancel'));
await waitFor(() => {
- expect(screen.queryByTestId('confirmation-dialog')).not.toBeInTheDocument();
+ expect(
+ screen.queryByTestId('confirmation-dialog')
+ ).not.toBeInTheDocument();
});
expect(rehashStreams).not.toHaveBeenCalled();
});
@@ -710,7 +750,9 @@ describe('StreamSettingsForm', () => {
it('Rehash Streams button is disabled while rehashing', async () => {
let resolveRehash;
vi.mocked(rehashStreams).mockReturnValue(
- new Promise((res) => { resolveRehash = res; })
+ new Promise((res) => {
+ resolveRehash = res;
+ })
);
setupMocks({ warningSuppressed: true });
render(
);
@@ -736,7 +778,9 @@ describe('StreamSettingsForm', () => {
it('calls getInputProps for default_stream_profile', () => {
render(
);
- expect(formMock.getInputProps).toHaveBeenCalledWith('default_stream_profile');
+ expect(formMock.getInputProps).toHaveBeenCalledWith(
+ 'default_stream_profile'
+ );
});
it('calls getInputProps for preferred_region', () => {
@@ -757,4 +801,4 @@ describe('StreamSettingsForm', () => {
expect(formMock.getInputProps).toHaveBeenCalledWith('m3u_hash_key');
});
});
-});
\ No newline at end of file
+});
diff --git a/frontend/src/components/forms/settings/__tests__/SystemSettingsForm.test.jsx b/frontend/src/components/forms/settings/__tests__/SystemSettingsForm.test.jsx
index b9baa711..a3b156d5 100644
--- a/frontend/src/components/forms/settings/__tests__/SystemSettingsForm.test.jsx
+++ b/frontend/src/components/forms/settings/__tests__/SystemSettingsForm.test.jsx
@@ -53,7 +53,11 @@ vi.mock('@mantine/core', () => ({
// Imports after mocks
// ──────────────────────────────────────────────────────────────────────────────
import useSettingsStore from '../../../../store/settings.jsx';
-import { getChangedSettings, parseSettings, saveChangedSettings } from '../../../../utils/pages/SettingsUtils.js';
+import {
+ getChangedSettings,
+ parseSettings,
+ saveChangedSettings,
+} from '../../../../utils/pages/SettingsUtils.js';
import { getSystemSettingsFormInitialValues } from '../../../../utils/forms/settings/SystemSettingsFormUtils.js';
import { useForm } from '@mantine/form';
@@ -83,7 +87,9 @@ const setupMocks = ({ settings = makeSettings() } = {}) => {
vi.mocked(getSystemSettingsFormInitialValues).mockReturnValue(formValues);
vi.mocked(useSettingsStore).mockImplementation((sel) => sel({ settings }));
vi.mocked(parseSettings).mockReturnValue(formValues);
- vi.mocked(getChangedSettings).mockReturnValue({ max_system_events: settings?.max_system_events ?? 100 });
+ vi.mocked(getChangedSettings).mockReturnValue({
+ max_system_events: settings?.max_system_events ?? 100,
+ });
vi.mocked(saveChangedSettings).mockResolvedValue(undefined);
return { formMock };
@@ -122,7 +128,9 @@ describe('SystemSettingsForm', () => {
setupMocks();
render(
);
expect(
- screen.getByText('Number of events to retain (minimum: 10, maximum: 1000)')
+ screen.getByText(
+ 'Number of events to retain (minimum: 10, maximum: 1000)'
+ )
).toBeInTheDocument();
});
@@ -184,7 +192,9 @@ describe('SystemSettingsForm', () => {
const settings = makeSettings();
const { formMock } = setupMocks({ settings });
render(
);
- expect(formMock.setValues).toHaveBeenCalledWith({ max_system_events: 100 });
+ expect(formMock.setValues).toHaveBeenCalledWith({
+ max_system_events: 100,
+ });
});
it('does not call parseSettings when settings is null', () => {
@@ -197,8 +207,12 @@ describe('SystemSettingsForm', () => {
submitting: false,
};
vi.mocked(useForm).mockReturnValue(formMock);
- vi.mocked(getSystemSettingsFormInitialValues).mockReturnValue({ max_system_events: 100 });
- vi.mocked(useSettingsStore).mockImplementation((sel) => sel({ settings: null }));
+ vi.mocked(getSystemSettingsFormInitialValues).mockReturnValue({
+ max_system_events: 100,
+ });
+ vi.mocked(useSettingsStore).mockImplementation((sel) =>
+ sel({ settings: null })
+ );
vi.mocked(parseSettings).mockReturnValue({});
vi.mocked(saveChangedSettings).mockResolvedValue(undefined);
@@ -213,8 +227,13 @@ describe('SystemSettingsForm', () => {
it('calls form.setFieldValue when NumberInput changes', () => {
const { formMock } = setupMocks();
render(
);
- fireEvent.change(screen.getByTestId('number-input'), { target: { value: '200' } });
- expect(formMock.setFieldValue).toHaveBeenCalledWith('max_system_events', 200);
+ fireEvent.change(screen.getByTestId('number-input'), {
+ target: { value: '200' },
+ });
+ expect(formMock.setFieldValue).toHaveBeenCalledWith(
+ 'max_system_events',
+ 200
+ );
});
});
@@ -229,7 +248,10 @@ describe('SystemSettingsForm', () => {
fireEvent.click(screen.getByText('Save'));
await waitFor(() => {
- expect(getChangedSettings).toHaveBeenCalledWith(formMock.getValues(), settings);
+ expect(getChangedSettings).toHaveBeenCalledWith(
+ formMock.getValues(),
+ settings
+ );
expect(saveChangedSettings).toHaveBeenCalled();
});
});
@@ -247,9 +269,13 @@ describe('SystemSettingsForm', () => {
});
it('does not show success alert when saveChangedSettings throws', async () => {
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
+ const consoleSpy = vi
+ .spyOn(console, 'error')
+ .mockImplementation(() => {});
setupMocks();
- vi.mocked(saveChangedSettings).mockRejectedValue(new Error('save failed'));
+ vi.mocked(saveChangedSettings).mockRejectedValue(
+ new Error('save failed')
+ );
render(
);
fireEvent.click(screen.getByText('Save'));
@@ -263,7 +289,9 @@ describe('SystemSettingsForm', () => {
it('logs error when saveChangedSettings throws', async () => {
const error = new Error('save failed');
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
+ const consoleSpy = vi
+ .spyOn(console, 'error')
+ .mockImplementation(() => {});
setupMocks();
vi.mocked(saveChangedSettings).mockRejectedValue(error);
@@ -271,7 +299,10 @@ describe('SystemSettingsForm', () => {
fireEvent.click(screen.getByText('Save'));
await waitFor(() => {
- expect(consoleSpy).toHaveBeenCalledWith('Error saving settings:', error);
+ expect(consoleSpy).toHaveBeenCalledWith(
+ 'Error saving settings:',
+ error
+ );
});
consoleSpy.mockRestore();
});
@@ -308,4 +339,4 @@ describe('SystemSettingsForm', () => {
expect(screen.getByTestId('alert')).toBeInTheDocument();
});
});
-});
\ No newline at end of file
+});
diff --git a/frontend/src/components/forms/settings/__tests__/UiSettingsForm.test.jsx b/frontend/src/components/forms/settings/__tests__/UiSettingsForm.test.jsx
index b8c0b5ea..101f32a4 100644
--- a/frontend/src/components/forms/settings/__tests__/UiSettingsForm.test.jsx
+++ b/frontend/src/components/forms/settings/__tests__/UiSettingsForm.test.jsx
@@ -7,7 +7,9 @@ vi.mock('../../../../store/settings.jsx', () => ({ default: vi.fn() }));
// ── Hook mocks ─────────────────────────────────────────────────────────────────
vi.mock('../../../../hooks/useLocalStorage.jsx', () => ({ default: vi.fn() }));
-vi.mock('../../../../hooks/useTablePreferences.jsx', () => ({ default: vi.fn() }));
+vi.mock('../../../../hooks/useTablePreferences.jsx', () => ({
+ default: vi.fn(),
+}));
// ── Utility mocks ──────────────────────────────────────────────────────────────
vi.mock('../../../../utils/dateTimeUtils.js', () => ({
@@ -62,7 +64,10 @@ vi.mock('@mantine/core', () => ({
import useSettingsStore from '../../../../store/settings.jsx';
import useLocalStorage from '../../../../hooks/useLocalStorage.jsx';
import useTablePreferences from '../../../../hooks/useTablePreferences.jsx';
-import { buildTimeZoneOptions, getDefaultTimeZone } from '../../../../utils/dateTimeUtils.js';
+import {
+ buildTimeZoneOptions,
+ getDefaultTimeZone,
+} from '../../../../utils/dateTimeUtils.js';
import { showNotification } from '../../../../utils/notificationUtils.js';
import { saveTimeZoneSetting } from '../../../../utils/forms/settings/UiSettingsFormUtils.js';
@@ -83,13 +88,13 @@ const TZ_OPTIONS = [
];
const setupMocks = ({
- settings = makeSettings(),
- timeFormat = '12h',
- dateFormat = 'mdy',
- timeZone = DEFAULT_TZ,
- headerPinned = false,
- tableSize = 'default',
- } = {}) => {
+ settings = makeSettings(),
+ timeFormat = '12h',
+ dateFormat = 'mdy',
+ timeZone = DEFAULT_TZ,
+ headerPinned = false,
+ tableSize = 'default',
+} = {}) => {
const setTimeFormat = vi.fn();
const setDateFormat = vi.fn();
const setTimeZone = vi.fn();
@@ -102,13 +107,12 @@ const setupMocks = ({
vi.mocked(useSettingsStore).mockImplementation((sel) => sel({ settings }));
- vi.mocked(useLocalStorage)
- .mockImplementation((key, defaultVal) => {
- if (key === 'time-format') return [timeFormat, setTimeFormat];
- if (key === 'date-format') return [dateFormat, setDateFormat];
- if (key === 'time-zone') return [timeZone, setTimeZone];
- return [defaultVal, vi.fn()];
- });
+ vi.mocked(useLocalStorage).mockImplementation((key, defaultVal) => {
+ if (key === 'time-format') return [timeFormat, setTimeFormat];
+ if (key === 'date-format') return [dateFormat, setDateFormat];
+ if (key === 'time-zone') return [timeZone, setTimeZone];
+ return [defaultVal, vi.fn()];
+ });
vi.mocked(useTablePreferences).mockReturnValue({
headerPinned,
@@ -117,7 +121,13 @@ const setupMocks = ({
setTableSize,
});
- return { setTimeFormat, setDateFormat, setTimeZone, setHeaderPinned, setTableSize };
+ return {
+ setTimeFormat,
+ setDateFormat,
+ setTimeZone,
+ setHeaderPinned,
+ setTableSize,
+ };
};
// ──────────────────────────────────────────────────────────────────────────────
@@ -164,7 +174,9 @@ describe('UiSettingsForm', () => {
it('renders the switch description', () => {
setupMocks();
render(
);
- expect(screen.getByText('Keep table headers visible when scrolling')).toBeInTheDocument();
+ expect(
+ screen.getByText('Keep table headers visible when scrolling')
+ ).toBeInTheDocument();
});
it('renders Table Size select with initial value', () => {
@@ -331,7 +343,10 @@ describe('UiSettingsForm', () => {
});
render(
);
await waitFor(() => {
- expect(saveTimeZoneSetting).toHaveBeenCalledWith(DEFAULT_TZ, makeSettings({ timeZone: null }));
+ expect(saveTimeZoneSetting).toHaveBeenCalledWith(
+ DEFAULT_TZ,
+ makeSettings({ timeZone: null })
+ );
});
});
@@ -359,9 +374,13 @@ describe('UiSettingsForm', () => {
describe('error handling', () => {
it('shows error notification when saveTimeZoneSetting throws on tz change', async () => {
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
+ const consoleSpy = vi
+ .spyOn(console, 'error')
+ .mockImplementation(() => {});
setupMocks({ settings: makeSettings({ timeZone: null }), timeZone: '' });
- vi.mocked(saveTimeZoneSetting).mockRejectedValue(new Error('network error'));
+ vi.mocked(saveTimeZoneSetting).mockRejectedValue(
+ new Error('network error')
+ );
render(
);
fireEvent.change(screen.getByTestId('select-time-zone'), {
@@ -370,7 +389,10 @@ describe('UiSettingsForm', () => {
await waitFor(() => {
expect(showNotification).toHaveBeenCalledWith(
- expect.objectContaining({ color: 'red', title: 'Failed to update time zone' })
+ expect.objectContaining({
+ color: 'red',
+ title: 'Failed to update time zone',
+ })
);
});
consoleSpy.mockRestore();
@@ -378,7 +400,9 @@ describe('UiSettingsForm', () => {
it('logs error when saveTimeZoneSetting throws on tz change', async () => {
const error = new Error('network error');
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
+ const consoleSpy = vi
+ .spyOn(console, 'error')
+ .mockImplementation(() => {});
setupMocks({ settings: makeSettings({ timeZone: null }), timeZone: '' });
vi.mocked(saveTimeZoneSetting).mockRejectedValue(error);
@@ -397,15 +421,25 @@ describe('UiSettingsForm', () => {
});
it('shows error notification when saveTimeZoneSetting throws during initial sync', async () => {
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
- setupMocks({ settings: makeSettings({ timeZone: null }), timeZone: DEFAULT_TZ });
- vi.mocked(saveTimeZoneSetting).mockRejectedValue(new Error('sync failed'));
+ const consoleSpy = vi
+ .spyOn(console, 'error')
+ .mockImplementation(() => {});
+ setupMocks({
+ settings: makeSettings({ timeZone: null }),
+ timeZone: DEFAULT_TZ,
+ });
+ vi.mocked(saveTimeZoneSetting).mockRejectedValue(
+ new Error('sync failed')
+ );
render(
);
await waitFor(() => {
expect(showNotification).toHaveBeenCalledWith(
- expect.objectContaining({ color: 'red', title: 'Failed to update time zone' })
+ expect.objectContaining({
+ color: 'red',
+ title: 'Failed to update time zone',
+ })
);
});
consoleSpy.mockRestore();
@@ -421,4 +455,4 @@ describe('UiSettingsForm', () => {
expect(buildTimeZoneOptions).toHaveBeenCalledWith('America/Chicago');
});
});
-});
\ No newline at end of file
+});