diff --git a/src/renderer/__helpers__/test-utils.tsx b/src/renderer/__helpers__/test-utils.tsx index b631e63d0..248081d0f 100644 --- a/src/renderer/__helpers__/test-utils.tsx +++ b/src/renderer/__helpers__/test-utils.tsx @@ -8,20 +8,23 @@ import { mockAuth, mockSettings } from '../__mocks__/state-mocks'; import { AppContext, type AppContextState } from '../context/App'; +import { type FiltersStore, useFiltersStore } from '../stores'; + export { navigateMock } from './vitest.setup'; export type DeepPartial = { [K in keyof T]?: DeepPartial }; const EMPTY_APP_CONTEXT: TestAppContext = {}; -interface RenderOptions extends Partial { - initialEntries?: string[]; -} - /** * Test context */ type TestAppContext = Partial; +interface RenderOptions extends TestAppContext { + initialEntries?: string[]; + filters?: Partial; +} + /** * Props for the AppContextProvider wrapper */ @@ -83,7 +86,7 @@ function AppContextProvider({ - + {children} @@ -93,15 +96,20 @@ function AppContextProvider({ } /** - * Custom render that wraps components with AppContextProvider by default. + * Custom render that wraps components with all providers needed for testing: + * MemoryRouter, AppContext, and Zustand stores. * * Usage: - * renderWithAppContext(, { auth, settings, ... }) + * renderWithProviders(, { notifications, accounts, settings, filters, ... }) */ -export function renderWithAppContext( +export function renderWithProviders( ui: ReactElement, - { initialEntries, ...context }: RenderOptions = {}, + { initialEntries, filters, ...context }: RenderOptions = {}, ) { + if (filters) { + useFiltersStore.setState(filters); + } + return render(ui, { wrapper: ({ children }) => ( diff --git a/src/renderer/components/AllRead.test.tsx b/src/renderer/components/AllRead.test.tsx index 1f474a42e..3b2fc8af6 100644 --- a/src/renderer/components/AllRead.test.tsx +++ b/src/renderer/components/AllRead.test.tsx @@ -1,17 +1,16 @@ import { act } from '@testing-library/react'; -import { renderWithAppContext } from '../__helpers__/test-utils'; +import { renderWithProviders } from '../__helpers__/test-utils'; import { mockSettings } from '../__mocks__/state-mocks'; -import { useFiltersStore } from '../stores'; import { AllRead } from './AllRead'; describe('renderer/components/AllRead.tsx', () => { it('should render itself & its children - no filters', async () => { - let tree: ReturnType | null = null; + let tree: ReturnType | null = null; await act(async () => { - tree = renderWithAppContext(, { + tree = renderWithProviders(, { settings: { ...mockSettings, }, @@ -22,15 +21,16 @@ describe('renderer/components/AllRead.tsx', () => { }); it('should render itself & its children - with filters', async () => { - useFiltersStore.setState({ reasons: ['author'] }); - - let tree: ReturnType | null = null; + let tree: ReturnType | null = null; await act(async () => { - tree = renderWithAppContext(, { + tree = renderWithProviders(, { settings: { ...mockSettings, }, + filters: { + reasons: ['author'], + }, }); }); diff --git a/src/renderer/components/GlobalShortcuts.test.tsx b/src/renderer/components/GlobalShortcuts.test.tsx index 360aec5fe..921111603 100644 --- a/src/renderer/components/GlobalShortcuts.test.tsx +++ b/src/renderer/components/GlobalShortcuts.test.tsx @@ -1,6 +1,6 @@ import userEvent from '@testing-library/user-event'; -import { navigateMock, renderWithAppContext } from '../__helpers__/test-utils'; +import { navigateMock, renderWithProviders } from '../__helpers__/test-utils'; import * as comms from '../utils/system/comms'; import * as links from '../utils/system/links'; @@ -14,7 +14,7 @@ describe('components/GlobalShortcuts.tsx', () => { describe('key bindings', () => { describe('ignores keys that are not valid', () => { it('ignores B key', async () => { - renderWithAppContext(); + renderWithProviders(); await userEvent.keyboard('b'); @@ -24,7 +24,7 @@ describe('components/GlobalShortcuts.tsx', () => { describe('home', () => { it('navigates home when pressing H key', async () => { - renderWithAppContext(); + renderWithProviders(); await userEvent.keyboard('h'); @@ -38,7 +38,7 @@ describe('components/GlobalShortcuts.tsx', () => { .mockImplementation(vi.fn()); it('opens primary account GitHub notifications webpage when pressing N while logged in', async () => { - renderWithAppContext(, { + renderWithProviders(, { isLoggedIn: true, }); @@ -48,7 +48,7 @@ describe('components/GlobalShortcuts.tsx', () => { }); it('does not open primary account GitHub notifications webpage when logged out', async () => { - renderWithAppContext(, { + renderWithProviders(, { isLoggedIn: false, }); @@ -60,7 +60,7 @@ describe('components/GlobalShortcuts.tsx', () => { describe('focus mode', () => { it('toggles focus when pressing W while logged in', async () => { - renderWithAppContext(, { + renderWithProviders(, { updateSetting: updateSettingMock, isLoggedIn: true, }); @@ -71,7 +71,7 @@ describe('components/GlobalShortcuts.tsx', () => { }); it('does not toggle focus mode when loading', async () => { - renderWithAppContext(, { + renderWithProviders(, { updateSetting: updateSettingMock, status: 'loading', isLoggedIn: true, @@ -83,7 +83,7 @@ describe('components/GlobalShortcuts.tsx', () => { }); it('does not toggle focus mode when logged out', async () => { - renderWithAppContext(, { + renderWithProviders(, { updateSetting: updateSettingMock, isLoggedIn: false, }); @@ -96,7 +96,7 @@ describe('components/GlobalShortcuts.tsx', () => { describe('filters', () => { it('toggles filters when pressing F while logged in', async () => { - renderWithAppContext(, { + renderWithProviders(, { isLoggedIn: true, }); @@ -106,7 +106,7 @@ describe('components/GlobalShortcuts.tsx', () => { }); it('does not toggle filters when logged out', async () => { - renderWithAppContext(, { + renderWithProviders(, { isLoggedIn: false, }); @@ -122,7 +122,7 @@ describe('components/GlobalShortcuts.tsx', () => { .mockImplementation(vi.fn()); it('opens primary account GitHub issues webpage when pressing I while logged in', async () => { - renderWithAppContext(, { + renderWithProviders(, { isLoggedIn: true, }); @@ -132,7 +132,7 @@ describe('components/GlobalShortcuts.tsx', () => { }); it('does not open primary account GitHub issues webpage when logged out', async () => { - renderWithAppContext(, { + renderWithProviders(, { isLoggedIn: false, }); @@ -148,7 +148,7 @@ describe('components/GlobalShortcuts.tsx', () => { .mockImplementation(vi.fn()); it('opens primary account GitHub pull requests webpage when pressing N while logged in', async () => { - renderWithAppContext(, { + renderWithProviders(, { isLoggedIn: true, }); @@ -158,7 +158,7 @@ describe('components/GlobalShortcuts.tsx', () => { }); it('does not open primary account GitHub pull requests webpage when logged out', async () => { - renderWithAppContext(, { + renderWithProviders(, { isLoggedIn: false, }); @@ -170,7 +170,7 @@ describe('components/GlobalShortcuts.tsx', () => { describe('refresh', () => { it('refreshes notifications when pressing R key', async () => { - renderWithAppContext(, { + renderWithProviders(, { fetchNotifications: fetchNotificationsMock, }); @@ -181,7 +181,7 @@ describe('components/GlobalShortcuts.tsx', () => { }); it('does not refresh when status is loading', async () => { - renderWithAppContext(, { + renderWithProviders(, { status: 'loading', }); @@ -193,7 +193,7 @@ describe('components/GlobalShortcuts.tsx', () => { describe('settings', () => { it('toggles settings when pressing S while logged in', async () => { - renderWithAppContext(, { + renderWithProviders(, { isLoggedIn: true, }); @@ -203,7 +203,7 @@ describe('components/GlobalShortcuts.tsx', () => { }); it('does not toggle settings when logged out', async () => { - renderWithAppContext(, { + renderWithProviders(, { isLoggedIn: false, }); @@ -215,7 +215,7 @@ describe('components/GlobalShortcuts.tsx', () => { describe('accounts', () => { it('navigates to accounts when pressing A on settings route', async () => { - renderWithAppContext(, { + renderWithProviders(, { initialEntries: ['/settings'], isLoggedIn: true, }); @@ -226,7 +226,7 @@ describe('components/GlobalShortcuts.tsx', () => { }); it('does not trigger accounts when not on settings route', async () => { - renderWithAppContext(, { + renderWithProviders(, { isLoggedIn: true, }); @@ -238,7 +238,7 @@ describe('components/GlobalShortcuts.tsx', () => { describe('quit app', () => { it('quits the app when pressing Q on settings route', async () => { - renderWithAppContext(, { + renderWithProviders(, { initialEntries: ['/settings'], isLoggedIn: true, }); @@ -249,7 +249,7 @@ describe('components/GlobalShortcuts.tsx', () => { }); it('does not quit the app when not on settings route', async () => { - renderWithAppContext(, { + renderWithProviders(, { isLoggedIn: true, }); @@ -261,7 +261,7 @@ describe('components/GlobalShortcuts.tsx', () => { describe('modifiers', () => { it('ignores shortcuts when typing in an input', async () => { - renderWithAppContext( + renderWithProviders( <> @@ -281,7 +281,7 @@ describe('components/GlobalShortcuts.tsx', () => { }); it('ignores shortcuts when typing in a textarea', async () => { - renderWithAppContext( + renderWithProviders( <>