Skip to content

Commit 6cbfa9d

Browse files
committed
chore: improve check scope solution
1 parent 86b8269 commit 6cbfa9d

File tree

3 files changed

+62
-72
lines changed

3 files changed

+62
-72
lines changed

src/routes/Settings.test.tsx

+40-50
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1+
import { fireEvent, render } from '@testing-library/react';
12
import React from 'react';
2-
import TestRenderer, { act } from 'react-test-renderer';
3-
import { render, fireEvent } from '@testing-library/react';
43
import { MemoryRouter } from 'react-router-dom';
4+
import TestRenderer, { act } from 'react-test-renderer';
55

66
const { ipcRenderer } = require('electron');
77

8-
import { SettingsRoute } from './Settings';
9-
import { AppContext } from '../context/App';
8+
import { AxiosResponse } from 'axios';
109
import { mockAccounts, mockSettings } from '../__mocks__/mock-state';
10+
import { AppContext } from '../context/App';
11+
import * as apiRequests from '../utils/api-requests';
1112
import Constants from '../utils/constants';
13+
import { SettingsRoute } from './Settings';
1214

1315
const mockNavigate = jest.fn();
1416
jest.mock('react-router-dom', () => ({
@@ -20,8 +22,7 @@ describe('routes/Settings.tsx', () => {
2022
const updateSetting = jest.fn();
2123

2224
beforeEach(() => {
23-
mockNavigate.mockReset();
24-
updateSetting.mockReset();
25+
jest.clearAllMocks();
2526
});
2627

2728
it('should render itself & its children', async () => {
@@ -77,7 +78,12 @@ describe('routes/Settings.tsx', () => {
7778

7879
await act(async () => {
7980
const { getByLabelText: getByLabelTextLocal } = render(
80-
<AppContext.Provider value={{ settings: mockSettings, accounts: mockAccounts }}>
81+
<AppContext.Provider
82+
value={{
83+
settings: mockSettings,
84+
accounts: mockAccounts,
85+
}}
86+
>
8187
<MemoryRouter>
8288
<SettingsRoute />
8389
</MemoryRouter>
@@ -261,7 +267,12 @@ describe('routes/Settings.tsx', () => {
261267

262268
await act(async () => {
263269
const { getByLabelText: getByLabelTextLocal } = render(
264-
<AppContext.Provider value={{ settings: mockSettings, accounts: mockAccounts }}>
270+
<AppContext.Provider
271+
value={{
272+
settings: mockSettings,
273+
accounts: mockAccounts,
274+
}}
275+
>
265276
<MemoryRouter>
266277
<SettingsRoute />
267278
</MemoryRouter>
@@ -298,27 +309,19 @@ describe('routes/Settings.tsx', () => {
298309

299310
it('should be able to enable colors', async () => {
300311
let getByLabelText;
301-
jest.mock('../utils/api-requests', () => ({
302-
...jest.requireActual('../utils/api-requests'),
303-
apiRequestAuth: jest.fn().mockResolvedValue({
304-
headers: {
305-
'x-oauth-scopes': Constants.AUTH_SCOPE.join(', '),
306-
'access-control-allow-headers': 'Authorization',
307-
'access-control-allow-origin': '*',
308-
'access-control-expose-headers': 'X-OAuth-Scopes',
309-
'cache-control': 'private, max-age=60, s-maxage=60',
310-
'content-encoding': 'gzip',
311-
'content-security-policy': "default-src 'none'",
312-
'content-type': 'application/json; charset=utf-8',
313-
server: 'GitHub.com',
314-
'strict-transport-security':
315-
'max-age=31536000; includeSubdomains; preload',
316-
vary: 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding, Accept, X-Requested-With',
317-
},
318-
}),
319-
}));
312+
let findByLabelText;
313+
314+
jest.spyOn(apiRequests, 'apiRequestAuth').mockResolvedValue({
315+
headers: {
316+
'x-oauth-scopes': Constants.AUTH_SCOPE.join(', '),
317+
},
318+
} as unknown as AxiosResponse);
319+
320320
await act(async () => {
321-
const { getByLabelText: getByLabelTextLocal } = render(
321+
const {
322+
getByLabelText: getByLabelTextLocal,
323+
findByLabelText: findByLabelTextLocal,
324+
} = render(
322325
<AppContext.Provider
323326
value={{
324327
settings: mockSettings,
@@ -332,34 +335,25 @@ describe('routes/Settings.tsx', () => {
332335
</AppContext.Provider>,
333336
);
334337
getByLabelText = getByLabelTextLocal;
338+
findByLabelText = findByLabelTextLocal;
335339
});
336340

337-
// await act(async () => {
338-
// expect(getByLabelText('Use GitHub-like state colors')).toBeDefined();
339-
// });
341+
await findByLabelText('Use GitHub-like state colors');
340342

341-
// await act(async () => {
342-
await act(
343-
() =>
344-
// waitFor(() =>
345-
fireEvent.click(getByLabelText('Use GitHub-like state colors')),
346-
// ),
347-
);
343+
fireEvent.click(getByLabelText('Use GitHub-like state colors'));
348344

349345
expect(updateSetting).toHaveBeenCalledTimes(1);
350346
expect(updateSetting).toHaveBeenCalledWith('colors', true);
351347
});
352348

353349
it('should not be able to disable colors', async () => {
354350
let queryByLabelText;
355-
jest.mock('../utils/helpers', () => ({
356-
...jest.requireActual('../utils/helpers'),
357-
apiRequestAuth: jest.fn().mockResolvedValue({
358-
headers: {
359-
'x-oauth-scopes': 'repo, notifications',
360-
},
361-
}),
362-
}));
351+
352+
jest.spyOn(apiRequests, 'apiRequestAuth').mockResolvedValue({
353+
headers: {
354+
'x-oauth-scopes': 'read:user, notifications',
355+
},
356+
} as unknown as AxiosResponse);
363357

364358
await act(async () => {
365359
const { queryByLabelText: queryByLabelLocal } = render(
@@ -377,10 +371,6 @@ describe('routes/Settings.tsx', () => {
377371
queryByLabelText = queryByLabelLocal;
378372
});
379373

380-
console.log(
381-
queryByLabelText('Use GitHub-like state colors (requires re-auth)'),
382-
);
383-
384374
expect(
385375
queryByLabelText('Use GitHub-like state colors (requires re-auth)'),
386376
).toBeDefined();

src/routes/Settings.tsx

+21-21
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
1-
import React, { useCallback, useContext, useState, useEffect } from 'react';
1+
import { ArrowLeftIcon } from '@primer/octicons-react';
22
import { ipcRenderer } from 'electron';
3+
import React, {
4+
useCallback,
5+
useContext,
6+
useEffect,
7+
useMemo,
8+
useState,
9+
} from 'react';
310
import { useNavigate } from 'react-router-dom';
4-
import { ArrowLeftIcon } from '@primer/octicons-react';
511

6-
import { AppContext } from '../context/App';
7-
import { Appearance } from '../types';
812
import { FieldCheckbox } from '../components/fields/Checkbox';
913
import { FieldRadioGroup } from '../components/fields/RadioGroup';
14+
import { AppContext } from '../context/App';
1015
import { IconAddAccount } from '../icons/AddAccount';
1116
import { IconLogOut } from '../icons/Logout';
1217
import { IconQuit } from '../icons/Quit';
13-
import { updateTrayIcon } from '../utils/comms';
14-
import { setAppearance } from '../utils/appearance';
18+
import { Appearance } from '../types';
1519
import { apiRequestAuth } from '../utils/api-requests';
16-
import { generateGitHubAPIUrl } from '../utils/helpers';
20+
import { setAppearance } from '../utils/appearance';
21+
import { updateTrayIcon } from '../utils/comms';
1722
import Constants from '../utils/constants';
23+
import { generateGitHubAPIUrl } from '../utils/helpers';
1824

1925
export const SettingsRoute: React.FC = () => {
2026
const { accounts, settings, updateSetting, logout } = useContext(AppContext);
@@ -32,28 +38,22 @@ export const SettingsRoute: React.FC = () => {
3238
ipcRenderer.invoke('get-app-version').then((result: string) => {
3339
setAppVersion(result);
3440
});
41+
}, []);
3542

43+
useMemo(() => {
3644
(async () => {
3745
const response = await apiRequestAuth(
3846
`${generateGitHubAPIUrl(Constants.DEFAULT_AUTH_OPTIONS.hostname)}`,
3947
'GET',
4048
accounts.token,
4149
);
4250

43-
console.log(JSON.stringify(response.headers));
44-
const missingScopes = Constants.AUTH_SCOPE.filter((scope) => {
45-
return !response.headers['x-oauth-scopes'].includes(scope);
46-
});
47-
if (missingScopes.length > 0) {
48-
new Notification('Gitify - Permissions', {
49-
body:
50-
'You need to grant all the permissions to use this app. Missing scopes: ' +
51-
missingScopes.join(', ') +
52-
'.',
53-
});
54-
} else setColorScope(true);
51+
console.info("Token's scopes:", response.headers['x-oauth-scopes']);
52+
53+
if (response.headers['x-oauth-scopes'].includes('repo'))
54+
setColorScope(true);
5555
})();
56-
}, []);
56+
}, [accounts.token]);
5757

5858
ipcRenderer.on('update-native-theme', (_, updatedAppearance: Appearance) => {
5959
if (settings.appearance === Appearance.SYSTEM) {
@@ -110,7 +110,7 @@ export const SettingsRoute: React.FC = () => {
110110
<FieldCheckbox
111111
name="colors"
112112
label={`Use GitHub-like state colors${
113-
!colorScope ? ' (requires re-auth)' : ''
113+
!colorScope ? ' (requires repo scope)' : ''
114114
}`}
115115
checked={colorScope && settings.colors}
116116
onChange={(evt) => updateSetting('colors', evt.target.checked)}

src/routes/__snapshots__/Settings.test.tsx.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ exports[`routes/Settings.tsx should render itself & its children 1`] = `
146146
}
147147
}
148148
>
149-
Use GitHub-like state colors (requires re-auth)
149+
Use GitHub-like state colors (requires repo scope)
150150
</label>
151151
</div>
152152
</div>

0 commit comments

Comments
 (0)