Skip to content

Commit 6a0f24f

Browse files
committed
refactor: app context helper
Signed-off-by: Adam Setch <[email protected]>
1 parent 8e67ab4 commit 6a0f24f

File tree

1 file changed

+77
-175
lines changed

1 file changed

+77
-175
lines changed

src/renderer/context/App.test.tsx

Lines changed: 77 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,44 @@ import * as comms from '../utils/comms';
1212
import * as notifications from '../utils/notifications/notifications';
1313
import * as storage from '../utils/storage';
1414
import * as tray from '../utils/tray';
15-
import { AppContext, AppProvider } from './App';
15+
import { AppContext, type AppContextState, AppProvider } from './App';
1616
import { defaultSettings } from './defaults';
1717

1818
jest.mock('../hooks/useNotifications');
1919

20+
// Helper to render a button that calls a context method when clicked
21+
const renderContextButton = (
22+
contextMethodName: keyof AppContextState,
23+
...args: unknown[]
24+
) => {
25+
const TestComponent = () => {
26+
const context = useContext(AppContext);
27+
const method = context[contextMethodName];
28+
return (
29+
<button
30+
data-testid="context-method-button"
31+
onClick={() => {
32+
if (typeof method === 'function') {
33+
(method as (...args: unknown[]) => void)(...args);
34+
}
35+
}}
36+
type="button"
37+
>
38+
{String(contextMethodName)}
39+
</button>
40+
);
41+
};
42+
43+
const result = renderWithAppContext(
44+
<AppProvider>
45+
<TestComponent />
46+
</AppProvider>,
47+
);
48+
49+
const button = result.getByTestId('context-method-button');
50+
return { ...result, button };
51+
};
52+
2053
describe('renderer/context/App.tsx', () => {
2154
beforeEach(() => {
2255
jest.useFakeTimers();
@@ -28,7 +61,7 @@ describe('renderer/context/App.tsx', () => {
2861
});
2962

3063
describe('notification methods', () => {
31-
const mockSetTrayIconColorAndTitle = jest
64+
const setTrayIconColorAndTitleSpy = jest
3265
.spyOn(tray, 'setTrayIconColorAndTitle')
3366
.mockImplementation(jest.fn());
3467

@@ -93,117 +126,59 @@ describe('renderer/context/App.tsx', () => {
93126
});
94127

95128
it('should call fetchNotifications', async () => {
96-
const TestComponent = () => {
97-
const { fetchNotifications } = useContext(AppContext);
98-
99-
return (
100-
<button onClick={fetchNotifications} type="button">
101-
Test Case
102-
</button>
103-
);
104-
};
105-
106-
const { getByText } = renderWithAppContext(
107-
<AppProvider>
108-
<TestComponent />
109-
</AppProvider>,
110-
);
129+
const { button } = renderContextButton('fetchNotifications');
111130

112131
mockFetchNotifications.mockReset();
113132

114-
fireEvent.click(getByText('Test Case'));
133+
fireEvent.click(button);
115134

116135
expect(mockFetchNotifications).toHaveBeenCalledTimes(1);
117136
});
118137

119138
it('should call markNotificationsAsRead', async () => {
120-
const TestComponent = () => {
121-
const { markNotificationsAsRead } = useContext(AppContext);
122-
123-
return (
124-
<button
125-
onClick={() => markNotificationsAsRead([mockSingleNotification])}
126-
type="button"
127-
>
128-
Test Case
129-
</button>
130-
);
131-
};
132-
133-
const { getByText } = renderWithAppContext(
134-
<AppProvider>
135-
<TestComponent />
136-
</AppProvider>,
137-
);
139+
const { button } = renderContextButton('markNotificationsAsRead', [
140+
mockSingleNotification,
141+
]);
138142

139-
fireEvent.click(getByText('Test Case'));
143+
fireEvent.click(button);
140144

141145
expect(mockMarkNotificationsAsRead).toHaveBeenCalledTimes(1);
142146
expect(mockMarkNotificationsAsRead).toHaveBeenCalledWith(
143147
mockDefaultState,
144148
[mockSingleNotification],
145149
);
146-
expect(mockSetTrayIconColorAndTitle).toHaveBeenCalledTimes(1);
150+
expect(setTrayIconColorAndTitleSpy).toHaveBeenCalledTimes(1);
147151
});
148152

149153
it('should call markNotificationsAsDone', async () => {
150-
const TestComponent = () => {
151-
const { markNotificationsAsDone } = useContext(AppContext);
152-
153-
return (
154-
<button
155-
onClick={() => markNotificationsAsDone([mockSingleNotification])}
156-
type="button"
157-
>
158-
Test Case
159-
</button>
160-
);
161-
};
162-
163-
const { getByText } = renderWithAppContext(
164-
<AppProvider>
165-
<TestComponent />
166-
</AppProvider>,
167-
);
154+
const { button } = renderContextButton('markNotificationsAsDone', [
155+
mockSingleNotification,
156+
]);
168157

169-
fireEvent.click(getByText('Test Case'));
158+
fireEvent.click(button);
170159

171160
expect(mockMarkNotificationsAsDone).toHaveBeenCalledTimes(1);
172161
expect(mockMarkNotificationsAsDone).toHaveBeenCalledWith(
173162
mockDefaultState,
174163
[mockSingleNotification],
175164
);
176-
expect(mockSetTrayIconColorAndTitle).toHaveBeenCalledTimes(1);
165+
expect(setTrayIconColorAndTitleSpy).toHaveBeenCalledTimes(1);
177166
});
178167

179168
it('should call unsubscribeNotification', async () => {
180-
const TestComponent = () => {
181-
const { unsubscribeNotification } = useContext(AppContext);
182-
183-
return (
184-
<button
185-
onClick={() => unsubscribeNotification(mockSingleNotification)}
186-
type="button"
187-
>
188-
Test Case
189-
</button>
190-
);
191-
};
192-
193-
const { getByText } = renderWithAppContext(
194-
<AppProvider>
195-
<TestComponent />
196-
</AppProvider>,
169+
const { button } = renderContextButton(
170+
'unsubscribeNotification',
171+
mockSingleNotification,
197172
);
198173

199-
fireEvent.click(getByText('Test Case'));
174+
fireEvent.click(button);
200175

201176
expect(mockUnsubscribeNotification).toHaveBeenCalledTimes(1);
202177
expect(mockUnsubscribeNotification).toHaveBeenCalledWith(
203178
mockDefaultState,
204179
mockSingleNotification,
205180
);
206-
expect(mockSetTrayIconColorAndTitle).toHaveBeenCalledTimes(1);
181+
expect(setTrayIconColorAndTitleSpy).toHaveBeenCalledTimes(1);
207182
});
208183
});
209184

@@ -224,31 +199,12 @@ describe('renderer/context/App.tsx', () => {
224199
it('should call loginWithPersonalAccessToken', async () => {
225200
apiRequestAuthSpy.mockResolvedValueOnce(null);
226201

227-
const TestComponent = () => {
228-
const { loginWithPersonalAccessToken } = useContext(AppContext);
229-
230-
return (
231-
<button
232-
onClick={() =>
233-
loginWithPersonalAccessToken({
234-
hostname: 'github.com' as Hostname,
235-
token: '123-456' as Token,
236-
})
237-
}
238-
type="button"
239-
>
240-
Test Case
241-
</button>
242-
);
243-
};
244-
245-
const { getByText } = renderWithAppContext(
246-
<AppProvider>
247-
<TestComponent />
248-
</AppProvider>,
249-
);
202+
const { button } = renderContextButton('loginWithPersonalAccessToken', {
203+
hostname: 'github.com' as Hostname,
204+
token: '123-456' as Token,
205+
});
250206

251-
fireEvent.click(getByText('Test Case'));
207+
fireEvent.click(button);
252208

253209
await waitFor(() =>
254210
expect(mockFetchNotifications).toHaveBeenCalledTimes(1),
@@ -277,27 +233,14 @@ describe('renderer/context/App.tsx', () => {
277233
.spyOn(storage, 'saveState')
278234
.mockImplementation(jest.fn());
279235

280-
const TestComponent = () => {
281-
const { updateSetting } = useContext(AppContext);
282-
283-
return (
284-
<button
285-
onClick={() => updateSetting('participating', true)}
286-
type="button"
287-
>
288-
Test Case
289-
</button>
290-
);
291-
};
292-
293-
const { getByText } = renderWithAppContext(
294-
<AppProvider>
295-
<TestComponent />
296-
</AppProvider>,
236+
const { button } = renderContextButton(
237+
'updateSetting',
238+
'participating',
239+
true,
297240
);
298241

299242
act(() => {
300-
fireEvent.click(getByText('Test Case'));
243+
fireEvent.click(button);
301244
});
302245

303246
expect(mockSaveState).toHaveBeenCalledWith({
@@ -313,36 +256,23 @@ describe('renderer/context/App.tsx', () => {
313256

314257
it('should call updateSetting and set auto launch(openAtStartup)', async () => {
315258
const setAutoLaunchSpy = jest.spyOn(comms, 'setAutoLaunch');
316-
const mockSaveState = jest
259+
const saveStateSpy = jest
317260
.spyOn(storage, 'saveState')
318261
.mockImplementation(jest.fn());
319262

320-
const TestComponent = () => {
321-
const { updateSetting } = useContext(AppContext);
322-
323-
return (
324-
<button
325-
onClick={() => updateSetting('openAtStartup', true)}
326-
type="button"
327-
>
328-
Test Case
329-
</button>
330-
);
331-
};
332-
333-
const { getByText } = renderWithAppContext(
334-
<AppProvider>
335-
<TestComponent />
336-
</AppProvider>,
263+
const { button } = renderContextButton(
264+
'updateSetting',
265+
'openAtStartup',
266+
true,
337267
);
338268

339269
act(() => {
340-
fireEvent.click(getByText('Test Case'));
270+
fireEvent.click(button);
341271
});
342272

343273
expect(setAutoLaunchSpy).toHaveBeenCalledWith(true);
344274

345-
expect(mockSaveState).toHaveBeenCalledWith({
275+
expect(saveStateSpy).toHaveBeenCalledWith({
346276
auth: {
347277
accounts: [],
348278
} as AuthState,
@@ -354,31 +284,17 @@ describe('renderer/context/App.tsx', () => {
354284
});
355285

356286
it('should clear filters back to default', async () => {
357-
const mockSaveState = jest
287+
const saveStateSpy = jest
358288
.spyOn(storage, 'saveState')
359289
.mockImplementation(jest.fn());
360290

361-
const TestComponent = () => {
362-
const { clearFilters } = useContext(AppContext);
363-
364-
return (
365-
<button onClick={() => clearFilters()} type="button">
366-
Test Case
367-
</button>
368-
);
369-
};
370-
371-
const { getByText } = renderWithAppContext(
372-
<AppProvider>
373-
<TestComponent />
374-
</AppProvider>,
375-
);
291+
const { button } = renderContextButton('clearFilters');
376292

377293
act(() => {
378-
fireEvent.click(getByText('Test Case'));
294+
fireEvent.click(button);
379295
});
380296

381-
expect(mockSaveState).toHaveBeenCalledWith({
297+
expect(saveStateSpy).toHaveBeenCalledWith({
382298
auth: {
383299
accounts: [],
384300
} as AuthState,
@@ -395,31 +311,17 @@ describe('renderer/context/App.tsx', () => {
395311
});
396312

397313
it('should call resetSettings', async () => {
398-
const mockSaveState = jest
314+
const saveStateSpy = jest
399315
.spyOn(storage, 'saveState')
400316
.mockImplementation(jest.fn());
401317

402-
const TestComponent = () => {
403-
const { resetSettings } = useContext(AppContext);
404-
405-
return (
406-
<button onClick={() => resetSettings()} type="button">
407-
Test Case
408-
</button>
409-
);
410-
};
411-
412-
const { getByText } = renderWithAppContext(
413-
<AppProvider>
414-
<TestComponent />
415-
</AppProvider>,
416-
);
318+
const { button } = renderContextButton('resetSettings');
417319

418320
act(() => {
419-
fireEvent.click(getByText('Test Case'));
321+
fireEvent.click(button);
420322
});
421323

422-
expect(mockSaveState).toHaveBeenCalledWith({
324+
expect(saveStateSpy).toHaveBeenCalledWith({
423325
auth: {
424326
accounts: [],
425327
} as AuthState,

0 commit comments

Comments
 (0)