From 1fe5b37b7594c5dc20b3b9b68143135b0640951d Mon Sep 17 00:00:00 2001 From: Wojciech Brygola <141034155+wojciech-deriv@users.noreply.github.com> Date: Thu, 25 Jan 2024 04:27:25 +0000 Subject: [PATCH] [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 --- packages/api/src/APIProvider.tsx | 2 ++ packages/api/src/hooks/useAuthorize.ts | 15 +++++++++++---- .../crypto-payment-redirection.spec.tsx | 6 +++++- .../component-tests/mocks/mockWalletsAuthorize.ts | 6 +++--- .../wallets-carousel-content.spec.tsx | 14 +++++++++++--- 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/packages/api/src/APIProvider.tsx b/packages/api/src/APIProvider.tsx index 3abb1c917d95..b05aa092f008 100644 --- a/packages/api/src/APIProvider.tsx +++ b/packages/api/src/APIProvider.tsx @@ -30,6 +30,7 @@ type APIContextData = { send: TSendFunction; subscribe: TSubscribeFunction; unsubscribe: TUnsubscribeFunction; + queryClient: QueryClient; }; const APIContext = createContext(null); @@ -229,6 +230,7 @@ const APIProvider = ({ children, standalone = false }: PropsWithChildren diff --git a/packages/api/src/hooks/useAuthorize.ts b/packages/api/src/hooks/useAuthorize.ts index f8c708e05698..48343dc54e12 100644 --- a/packages/api/src/hooks/useAuthorize.ts +++ b/packages/api/src/hooks/useAuthorize.ts @@ -1,4 +1,4 @@ -import { useCallback, useMemo } from 'react'; +import { useCallback, useMemo, useState } from 'react'; import { getActiveAuthTokenIDFromLocalStorage, getActiveLoginIDFromLocalStorage } from '@deriv/utils'; import useInvalidateQuery from '../useInvalidateQuery'; import useQuery from '../useQuery'; @@ -10,7 +10,9 @@ import { useAPIContext } from '../APIProvider'; const useAuthorize = () => { const current_token = getActiveAuthTokenIDFromLocalStorage(); const invalidate = useInvalidateQuery(); - const { switchEnvironment } = useAPIContext(); + const { switchEnvironment, queryClient } = useAPIContext(); + + const [currentLoginID, setCurrentLoginID] = useState(getActiveLoginIDFromLocalStorage()); const { data, ...rest } = useQuery('authorize', { payload: { authorize: current_token || '' }, @@ -33,10 +35,14 @@ const useAuthorize = () => { if (active_loginid !== loginid) { localStorage.setItem('active_loginid', loginid); switchEnvironment(active_loginid); - invalidate('authorize'); + // whenever we change the loginid, we need to invalidate all queries + // as there might be ongoing queries against previous loginid + // and we really do not want data from previous loginid, to be mixed with current loginid + queryClient.cancelQueries(); + setCurrentLoginID(loginid); } }, - [invalidate, switchEnvironment] + [invalidate, switchEnvironment, currentLoginID] ); return { @@ -44,6 +50,7 @@ const useAuthorize = () => { data: modified_authorize, /** Function to switch to another account */ switchAccount, + currentLoginID, ...rest, }; }; diff --git a/packages/wallets/component-tests/crypto-payment-redirection.spec.tsx b/packages/wallets/component-tests/crypto-payment-redirection.spec.tsx index 9c083f650538..15edbdd8a155 100644 --- a/packages/wallets/component-tests/crypto-payment-redirection.spec.tsx +++ b/packages/wallets/component-tests/crypto-payment-redirection.spec.tsx @@ -22,9 +22,13 @@ test.describe('Wallets - Crypto withdrawal', () => { page, state: { accounts: DEFAULT_WALLET_ACCOUNTS, - currentToken: 'a1-x0000000000000000000000000004', + currentToken: 'a1-x0000000000000000000000000001', }, }); + + await page.goto(`${baseURL}/wallets`); + + await page.click('.wallets-accordion:nth-child(2) .wallets-accordion__dropdown'); }); test('render withdrawal form with all elements', async ({ baseURL, page }) => { diff --git a/packages/wallets/component-tests/mocks/mockWalletsAuthorize.ts b/packages/wallets/component-tests/mocks/mockWalletsAuthorize.ts index 0bd2c6ba89bd..f50cbde3006c 100644 --- a/packages/wallets/component-tests/mocks/mockWalletsAuthorize.ts +++ b/packages/wallets/component-tests/mocks/mockWalletsAuthorize.ts @@ -205,10 +205,10 @@ export default function mockWalletsAuthorize(context: Context) { throw new Error('authorize has not been prepopulated'); } - const accountByToken = context.state.accounts.find(account => account.token === context.state.currentToken); - const accountByAuthorise = context.state.accounts.find(account => account.token === context.request.authorize); + context.state.currentToken = context.request.authorize || context.state.currentToken; + const currentAccount = context.state.accounts.find(account => account.token === context.state.currentToken); context.response.authorize.account_list = ACCOUNTS_LIST; - context.response.authorize.loginid = accountByToken?.id || accountByAuthorise.id; + context.response.authorize.loginid = currentAccount?.id; } } diff --git a/packages/wallets/component-tests/wallets-carousel-content.spec.tsx b/packages/wallets/component-tests/wallets-carousel-content.spec.tsx index 04439b665a86..96ae7e4dcaf1 100644 --- a/packages/wallets/component-tests/wallets-carousel-content.spec.tsx +++ b/packages/wallets/component-tests/wallets-carousel-content.spec.tsx @@ -6,7 +6,7 @@ import { mockProposalOpenContract } from './mocks/mockProposalOpenContract'; import mockWalletsAuthorize, { DEFAULT_WALLET_ACCOUNTS } from './mocks/mockWalletsAuthorize'; import mockWalletsLoggedIn from './mocks/mockWalletsLoggedIn'; -const CAROUSEL_SELECTOR = '.wallets-carousel-content__container'; +const CAROUSEL_SELECTOR = '.wallets-carousel-content__container .wallets-card:nth-child(1)'; // swipe function async function swipeLeft(mobilePage: Page) { @@ -91,17 +91,25 @@ test.describe('Wallets - Mobile carousel', () => { test('renders progress bar with active item and updates it when swiping', async ({ baseURL }) => { await mobilePage.goto(`${baseURL}/wallets`); - const activeProgressBarItem = await mobilePage.locator('.wallets-progress-bar div:nth-child(2)'); + const activeProgressBarItem = await mobilePage.locator('.wallets-progress-bar div:nth-child(1)'); const progressBarItemClass = await activeProgressBarItem.getAttribute('class'); expect(progressBarItemClass).toContain('wallets-progress-bar-active'); + // swipe left await swipeLeft(mobilePage); - const activeProgressBarItem2 = await mobilePage.locator('.wallets-progress-bar div:nth-child(3)'); + const activeProgressBarItem2 = await mobilePage.locator('.wallets-progress-bar div:nth-child(2)'); const progressBarItemClass2 = await activeProgressBarItem2.getAttribute('class'); expect(progressBarItemClass2).toContain('wallets-progress-bar-active'); + + await swipeLeft(mobilePage); + + const activeProgressBarItem3 = await mobilePage.locator('.wallets-progress-bar div:nth-child(3)'); + const progressBarItemClass3 = await activeProgressBarItem3.getAttribute('class'); + + expect(progressBarItemClass3).toContain('wallets-progress-bar-active'); }); test('switches account when clicking on progress bar', async ({ baseURL }) => {