Skip to content

Commit 1fe5b37

Browse files
[WALL] wojtek/removed potential source of race hazards (#13079)
* feat: fixed tests after fixing authorise * feat: updated authorise to prevent requesting previous token * feat: updated authorize in order to avoid duplicated calls * feat: cancelled all the requests before switching to new account
1 parent e089089 commit 1fe5b37

File tree

5 files changed

+32
-11
lines changed

5 files changed

+32
-11
lines changed

packages/api/src/APIProvider.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type APIContextData = {
3030
send: TSendFunction;
3131
subscribe: TSubscribeFunction;
3232
unsubscribe: TUnsubscribeFunction;
33+
queryClient: QueryClient;
3334
};
3435

3536
const APIContext = createContext<APIContextData | null>(null);
@@ -229,6 +230,7 @@ const APIProvider = ({ children, standalone = false }: PropsWithChildren<TAPIPro
229230
send,
230231
subscribe,
231232
unsubscribe,
233+
queryClient,
232234
}}
233235
>
234236
<QueryClientProvider client={queryClient}>

packages/api/src/hooks/useAuthorize.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useCallback, useMemo } from 'react';
1+
import { useCallback, useMemo, useState } from 'react';
22
import { getActiveAuthTokenIDFromLocalStorage, getActiveLoginIDFromLocalStorage } from '@deriv/utils';
33
import useInvalidateQuery from '../useInvalidateQuery';
44
import useQuery from '../useQuery';
@@ -10,7 +10,9 @@ import { useAPIContext } from '../APIProvider';
1010
const useAuthorize = () => {
1111
const current_token = getActiveAuthTokenIDFromLocalStorage();
1212
const invalidate = useInvalidateQuery();
13-
const { switchEnvironment } = useAPIContext();
13+
const { switchEnvironment, queryClient } = useAPIContext();
14+
15+
const [currentLoginID, setCurrentLoginID] = useState(getActiveLoginIDFromLocalStorage());
1416

1517
const { data, ...rest } = useQuery('authorize', {
1618
payload: { authorize: current_token || '' },
@@ -33,17 +35,22 @@ const useAuthorize = () => {
3335
if (active_loginid !== loginid) {
3436
localStorage.setItem('active_loginid', loginid);
3537
switchEnvironment(active_loginid);
36-
invalidate('authorize');
38+
// whenever we change the loginid, we need to invalidate all queries
39+
// as there might be ongoing queries against previous loginid
40+
// and we really do not want data from previous loginid, to be mixed with current loginid
41+
queryClient.cancelQueries();
42+
setCurrentLoginID(loginid);
3743
}
3844
},
39-
[invalidate, switchEnvironment]
45+
[invalidate, switchEnvironment, currentLoginID]
4046
);
4147

4248
return {
4349
/** The authorize response. */
4450
data: modified_authorize,
4551
/** Function to switch to another account */
4652
switchAccount,
53+
currentLoginID,
4754
...rest,
4855
};
4956
};

packages/wallets/component-tests/crypto-payment-redirection.spec.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,13 @@ test.describe('Wallets - Crypto withdrawal', () => {
2222
page,
2323
state: {
2424
accounts: DEFAULT_WALLET_ACCOUNTS,
25-
currentToken: 'a1-x0000000000000000000000000004',
25+
currentToken: 'a1-x0000000000000000000000000001',
2626
},
2727
});
28+
29+
await page.goto(`${baseURL}/wallets`);
30+
31+
await page.click('.wallets-accordion:nth-child(2) .wallets-accordion__dropdown');
2832
});
2933

3034
test('render withdrawal form with all elements', async ({ baseURL, page }) => {

packages/wallets/component-tests/mocks/mockWalletsAuthorize.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,10 @@ export default function mockWalletsAuthorize(context: Context) {
205205
throw new Error('authorize has not been prepopulated');
206206
}
207207

208-
const accountByToken = context.state.accounts.find(account => account.token === context.state.currentToken);
209-
const accountByAuthorise = context.state.accounts.find(account => account.token === context.request.authorize);
208+
context.state.currentToken = context.request.authorize || context.state.currentToken;
209+
const currentAccount = context.state.accounts.find(account => account.token === context.state.currentToken);
210210

211211
context.response.authorize.account_list = ACCOUNTS_LIST;
212-
context.response.authorize.loginid = accountByToken?.id || accountByAuthorise.id;
212+
context.response.authorize.loginid = currentAccount?.id;
213213
}
214214
}

packages/wallets/component-tests/wallets-carousel-content.spec.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { mockProposalOpenContract } from './mocks/mockProposalOpenContract';
66
import mockWalletsAuthorize, { DEFAULT_WALLET_ACCOUNTS } from './mocks/mockWalletsAuthorize';
77
import mockWalletsLoggedIn from './mocks/mockWalletsLoggedIn';
88

9-
const CAROUSEL_SELECTOR = '.wallets-carousel-content__container';
9+
const CAROUSEL_SELECTOR = '.wallets-carousel-content__container .wallets-card:nth-child(1)';
1010

1111
// swipe function
1212
async function swipeLeft(mobilePage: Page) {
@@ -91,17 +91,25 @@ test.describe('Wallets - Mobile carousel', () => {
9191

9292
test('renders progress bar with active item and updates it when swiping', async ({ baseURL }) => {
9393
await mobilePage.goto(`${baseURL}/wallets`);
94-
const activeProgressBarItem = await mobilePage.locator('.wallets-progress-bar div:nth-child(2)');
94+
const activeProgressBarItem = await mobilePage.locator('.wallets-progress-bar div:nth-child(1)');
9595
const progressBarItemClass = await activeProgressBarItem.getAttribute('class');
9696

9797
expect(progressBarItemClass).toContain('wallets-progress-bar-active');
9898

99+
// swipe left
99100
await swipeLeft(mobilePage);
100101

101-
const activeProgressBarItem2 = await mobilePage.locator('.wallets-progress-bar div:nth-child(3)');
102+
const activeProgressBarItem2 = await mobilePage.locator('.wallets-progress-bar div:nth-child(2)');
102103
const progressBarItemClass2 = await activeProgressBarItem2.getAttribute('class');
103104

104105
expect(progressBarItemClass2).toContain('wallets-progress-bar-active');
106+
107+
await swipeLeft(mobilePage);
108+
109+
const activeProgressBarItem3 = await mobilePage.locator('.wallets-progress-bar div:nth-child(3)');
110+
const progressBarItemClass3 = await activeProgressBarItem3.getAttribute('class');
111+
112+
expect(progressBarItemClass3).toContain('wallets-progress-bar-active');
105113
});
106114

107115
test('switches account when clicking on progress bar', async ({ baseURL }) => {

0 commit comments

Comments
 (0)