1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 09:57:02 +01:00

Fixing connect custody flow (#19802)

* Fixing connect custody flow

* Finished fixing mmi connect flow

* Fixed test

* updated snapshot

* Finished fixing tests
This commit is contained in:
Albert Olivé 2023-06-30 12:41:28 +02:00 committed by GitHub
parent 6bb5e6941d
commit 59980f1b27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 186 additions and 268 deletions

View File

@ -2368,19 +2368,38 @@ export default class MetamaskController extends EventEmitter {
...getPermissionBackgroundApiMethods(permissionController), ...getPermissionBackgroundApiMethods(permissionController),
///: BEGIN:ONLY_INCLUDE_IN(build-mmi) ///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
connectCustodyAddresses: connectCustodyAddresses: this.mmiController.connectCustodyAddresses.bind(
this.mmiController.connectCustodyAddresses.bind(this), this.mmiController,
getCustodianAccounts: this.mmiController.getCustodianAccounts.bind(this), ),
getCustodianAccounts: this.mmiController.getCustodianAccounts.bind(
this.mmiController,
),
getCustodianAccountsByAddress: getCustodianAccountsByAddress:
this.mmiController.getCustodianAccountsByAddress.bind(this), this.mmiController.getCustodianAccountsByAddress.bind(
this.mmiController,
),
getCustodianTransactionDeepLink: getCustodianTransactionDeepLink:
this.mmiController.getCustodianTransactionDeepLink.bind(this), this.mmiController.getCustodianTransactionDeepLink.bind(
this.mmiController,
),
getCustodianConfirmDeepLink: getCustodianConfirmDeepLink:
this.mmiController.getCustodianConfirmDeepLink.bind(this), this.mmiController.getCustodianConfirmDeepLink.bind(this.mmiController),
getCustodianSignMessageDeepLink: getCustodianSignMessageDeepLink:
this.mmiController.getCustodianSignMessageDeepLink.bind(this), this.mmiController.getCustodianSignMessageDeepLink.bind(
getCustodianToken: this.mmiController.getCustodianToken.bind(this), this.mmiController,
getCustodianJWTList: this.mmiController.getCustodianJWTList.bind(this), ),
getCustodianToken: this.mmiController.getCustodianToken.bind(
this.mmiController,
),
getCustodianJWTList: this.mmiController.getCustodianJWTList.bind(
this.mmiController,
),
getAllCustodianAccountsWithToken:
this.mmiController.getAllCustodianAccountsWithToken.bind(
this.mmiController,
),
setCustodianNewRefreshToken:
this.mmiController.setCustodianNewRefreshToken.bind(this.mmiController),
setWaitForConfirmDeepLinkDialog: setWaitForConfirmDeepLinkDialog:
this.custodyController.setWaitForConfirmDeepLinkDialog.bind( this.custodyController.setWaitForConfirmDeepLinkDialog.bind(
this.custodyController, this.custodyController,
@ -2393,8 +2412,6 @@ export default class MetamaskController extends EventEmitter {
this.custodyController.getCustodianConnectRequest.bind( this.custodyController.getCustodianConnectRequest.bind(
this.custodyController, this.custodyController,
), ),
getAllCustodianAccountsWithToken:
this.mmiController.getAllCustodianAccountsWithToken.bind(this),
getMmiConfiguration: getMmiConfiguration:
this.mmiConfigurationController.getConfiguration.bind( this.mmiConfigurationController.getConfiguration.bind(
this.mmiConfigurationController, this.mmiConfigurationController,
@ -2415,12 +2432,10 @@ export default class MetamaskController extends EventEmitter {
this.institutionalFeaturesController.syncReportsInProgress.bind( this.institutionalFeaturesController.syncReportsInProgress.bind(
this.institutionalFeaturesController, this.institutionalFeaturesController,
), ),
removeConnectInstitutionalFeature: removeConnectInstitutionalFeature:
this.institutionalFeaturesController.removeConnectInstitutionalFeature.bind( this.institutionalFeaturesController.removeConnectInstitutionalFeature.bind(
this.institutionalFeaturesController, this.institutionalFeaturesController,
), ),
getComplianceHistoricalReportsByAddress: getComplianceHistoricalReportsByAddress:
this.institutionalFeaturesController.getComplianceHistoricalReportsByAddress.bind( this.institutionalFeaturesController.getComplianceHistoricalReportsByAddress.bind(
this.institutionalFeaturesController, this.institutionalFeaturesController,
@ -2429,8 +2444,6 @@ export default class MetamaskController extends EventEmitter {
this.institutionalFeaturesController.removeAddTokenConnectRequest.bind( this.institutionalFeaturesController.removeAddTokenConnectRequest.bind(
this.institutionalFeaturesController, this.institutionalFeaturesController,
), ),
setCustodianNewRefreshToken:
this.mmiController.setCustodianNewRefreshToken.bind(this),
///: END:ONLY_INCLUDE_IN ///: END:ONLY_INCLUDE_IN
///: BEGIN:ONLY_INCLUDE_IN(snaps) ///: BEGIN:ONLY_INCLUDE_IN(snaps)

View File

@ -5,10 +5,10 @@ import PulseLoader from '../../../components/ui/pulse-loader';
import { CUSTODY_ACCOUNT_ROUTE } from '../../../helpers/constants/routes'; import { CUSTODY_ACCOUNT_ROUTE } from '../../../helpers/constants/routes';
import { import {
AlignItems, AlignItems,
DISPLAY, Display,
TextColor, TextColor,
TEXT_ALIGN, TextAlign,
FLEX_DIRECTION, FlexDirection,
} from '../../../helpers/constants/design-system'; } from '../../../helpers/constants/design-system';
import { BUILT_IN_NETWORKS } from '../../../../shared/constants/network'; import { BUILT_IN_NETWORKS } from '../../../../shared/constants/network';
import { I18nContext } from '../../../contexts/i18n'; import { I18nContext } from '../../../contexts/i18n';
@ -23,8 +23,12 @@ import {
Button, Button,
BUTTON_SIZES, BUTTON_SIZES,
BUTTON_VARIANT, BUTTON_VARIANT,
Box,
} from '../../../components/component-library'; } from '../../../components/component-library';
import Box from '../../../components/ui/box'; import {
complianceActivated,
getInstitutionalConnectRequests,
} from '../../../ducks/institutional/institutional';
const ConfirmAddCustodianToken = () => { const ConfirmAddCustodianToken = () => {
const t = useContext(I18nContext); const t = useContext(I18nContext);
@ -34,59 +38,12 @@ const ConfirmAddCustodianToken = () => {
const mmiActions = mmiActionsFactory(); const mmiActions = mmiActionsFactory();
const mostRecentOverviewPage = useSelector(getMostRecentOverviewPage); const mostRecentOverviewPage = useSelector(getMostRecentOverviewPage);
const connectRequests = useSelector( const connectRequests = useSelector(getInstitutionalConnectRequests);
(state) => state.metamask.institutionalFeatures?.connectRequests, const isComplianceActivated = useSelector(complianceActivated);
);
const complianceActivated = useSelector((state) =>
Boolean(state.metamask.institutionalFeatures?.complianceProjectId),
);
const [showMore, setShowMore] = useState(false); const [showMore, setShowMore] = useState(false);
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [connectError, setConnectError] = useState(''); const [connectError, setConnectError] = useState('');
const handleConnectError = (e) => {
let errorMessage = e.message;
if (!errorMessage) {
errorMessage = 'Connection error';
}
setConnectError(errorMessage);
setIsLoading(false);
};
const renderSelectedToken = () => {
const connectRequest = connectRequests ? connectRequests[0] : undefined;
return (
<Box
paddingTop={2}
paddingBottom={2}
display={DISPLAY.FLEX}
flexDirection={FLEX_DIRECTION.ROW}
alignItems={AlignItems.center}
>
<Text>
{showMore && connectRequest?.token
? connectRequest?.token
: `...${connectRequest?.token.slice(-9)}`}
</Text>
{!showMore && (
<Box paddingLeft={2}>
<ButtonLink
rel="noopener noreferrer"
onClick={() => {
setShowMore(true);
}}
>
{t('showMore')}
</ButtonLink>
</Box>
)}
</Box>
);
};
const connectRequest = connectRequests ? connectRequests[0] : undefined; const connectRequest = connectRequests ? connectRequests[0] : undefined;
if (!connectRequest) { if (!connectRequest) {
@ -148,7 +105,31 @@ const ConfirmAddCustodianToken = () => {
marginLeft={4} marginLeft={4}
className="add_custodian_token_confirm__token" className="add_custodian_token_confirm__token"
> >
{renderSelectedToken()} <Box
paddingTop={2}
paddingBottom={2}
display={Display.Flex}
flexDirection={FlexDirection.Row}
alignItems={AlignItems.center}
>
<Text>
{showMore && connectRequest?.token
? connectRequest?.token
: `...${connectRequest?.token.slice(-9)}`}
</Text>
{!showMore && (
<Box paddingLeft={2}>
<ButtonLink
rel="noopener noreferrer"
onClick={() => {
setShowMore(true);
}}
>
{t('showMore')}
</ButtonLink>
</Box>
)}
</Box>
</Box> </Box>
{connectRequest.apiUrl && ( {connectRequest.apiUrl && (
<Box> <Box>
@ -168,9 +149,9 @@ const ConfirmAddCustodianToken = () => {
)} )}
</Box> </Box>
{!complianceActivated && ( {!isComplianceActivated && (
<Box marginTop={4} data-testid="connect-custodian-token-error"> <Box marginTop={4} data-testid="connect-custodian-token-error">
<Text data-testid="error-message" textAlign={TEXT_ALIGN.CENTER}> <Text data-testid="error-message" textAlign={TextAlign.Center}>
{connectError} {connectError}
</Text> </Text>
</Box> </Box>
@ -180,19 +161,19 @@ const ConfirmAddCustodianToken = () => {
{isLoading ? ( {isLoading ? (
<PulseLoader /> <PulseLoader />
) : ( ) : (
<Box display={DISPLAY.FLEX} gap={4}> <Box display={Display.Flex} gap={4}>
<Button <Button
block block
variant={BUTTON_VARIANT.SECONDARY} variant={BUTTON_VARIANT.SECONDARY}
size={BUTTON_SIZES.LG} size={BUTTON_SIZES.LG}
data-testid="cancel-btn" data-testid="cancel-btn"
onClick={() => { onClick={async () => {
mmiActions.removeAddTokenConnectRequest({ await mmiActions.removeAddTokenConnectRequest({
origin: connectRequest.origin, origin: connectRequest.origin,
apiUrl: connectRequest.apiUrl, apiUrl: connectRequest.apiUrl,
token: connectRequest.token, token: connectRequest.token,
}); });
history.push(mostRecentOverviewPage);
trackEvent({ trackEvent({
category: 'MMI', category: 'MMI',
event: 'Custodian onboarding', event: 'Custodian onboarding',
@ -230,17 +211,21 @@ const ConfirmAddCustodianToken = () => {
custodianName = connectRequest.environment; custodianName = connectRequest.environment;
} }
await mmiActions.setCustodianConnectRequest({ await dispatch(
token: connectRequest.token, mmiActions.setCustodianConnectRequest({
apiUrl: connectRequest.apiUrl, token: connectRequest.token,
custodianName, apiUrl: connectRequest.apiUrl,
custodianType: connectRequest.service, custodianName,
}); custodianType: connectRequest.service,
mmiActions.removeAddTokenConnectRequest({ }),
);
await mmiActions.removeAddTokenConnectRequest({
origin: connectRequest.origin, origin: connectRequest.origin,
apiUrl: connectRequest.apiUrl, apiUrl: connectRequest.apiUrl,
token: connectRequest.token, token: connectRequest.token,
}); });
trackEvent({ trackEvent({
category: 'MMI', category: 'MMI',
event: 'Custodian onboarding', event: 'Custodian onboarding',
@ -250,9 +235,17 @@ const ConfirmAddCustodianToken = () => {
apiUrl: connectRequest.apiUrl, apiUrl: connectRequest.apiUrl,
}, },
}); });
history.push(CUSTODY_ACCOUNT_ROUTE); history.push(CUSTODY_ACCOUNT_ROUTE);
} catch (e) { } catch (e) {
handleConnectError(e); let errorMessage = e.message;
if (!errorMessage) {
errorMessage = 'Connection error';
}
setConnectError(errorMessage);
setIsLoading(false);
} }
}} }}
> >

View File

@ -1,6 +1,24 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`CustodyPage renders CustodyPage 1`] = ` exports[`CustodyPage renders CustodyPage 1`] = `
<div>
<div
class="pulse-loader"
>
<div
class="pulse-loader__loading-dot-one"
/>
<div
class="pulse-loader__loading-dot-two"
/>
<div
class="pulse-loader__loading-dot-three"
/>
</div>
</div>
`;
exports[`CustodyPage renders CustodyPage 2`] = `
<div> <div>
@ -70,115 +88,6 @@ exports[`CustodyPage renders CustodyPage 1`] = `
</ul> </ul>
</div> </div>
</div> </div>
</div>
`;
exports[`CustodyPage renders CustodyPage 2`] = `
<div>
<div
class="mm-box mm-box--padding-4 mm-box--display-flex mm-box--flex-direction-column mm-box--background-color-background-default"
style="box-shadow: var(--shadow-size-xs) var(--color-shadow-default);"
>
<div
class="mm-box mm-box--margin-top-4 mm-box--margin-bottom-4 mm-box--display-flex mm-box--align-items-center"
>
<button
aria-label="Back"
class="box mm-button-icon mm-button-icon--size-sm box--display-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-icon-default box--background-color-transparent box--rounded-lg"
>
<span
class="box mm-icon mm-icon--size-sm box--display-inline-block box--flex-direction-row box--color-inherit"
style="mask-image: url('./images/icons/arrow-left.svg');"
/>
</button>
<p
class="box mm-text mm-text--body-md box--flex-direction-row box--color-text-default"
>
Back
</p>
</div>
<h4
class="box mm-text mm-text--body-md box--flex-direction-row box--color-text-default"
>
<div
class="mm-box mm-box--display-flex mm-box--align-items-center"
>
<p
class="box mm-text mm-text--body-md box--margin-left-2 box--flex-direction-row box--color-text-default"
/>
</div>
</h4>
<p
class="box mm-text mm-text--body-md box--margin-top-4 box--flex-direction-row box--color-text-default"
>
Enter your token or add a new token
</p>
<div
class="mm-box mm-box--padding-bottom-7"
>
<div
class="mm-box jwt-url-form mm-box--margin-bottom-8 mm-box--display-flex mm-box--flex-direction-column mm-box--align-items-flex-start"
>
<div
class="mm-box jwt-url-form__jwt-container mm-box--margin-top-4 mm-box--margin-bottom-4 mm-box--display-flex mm-box--flex-direction-column mm-box--align-items-center mm-box--width-full"
>
<div
class="mm-box mm-box--width-full"
>
<p
class="box mm-text jwt-url-form__instruction mm-text--body-md box--margin-bottom-4 box--display-block box--flex-direction-row box--color-text-default"
>
Paste or drop your token here:
</p>
<textarea
class="jwt-url-form__input-jwt"
data-testid="jwt-input"
id="jwt-box"
>
token
</textarea>
</div>
</div>
<div
class="mm-box mm-box--width-full"
>
<p
class="box mm-text jwt-url-form__instruction mm-text--body-md box--display-block box--flex-direction-row box--color-text-default"
>
API URL
</p>
<div
class="mm-box mm-box--margin-top-4"
>
<input
class="jwt-url-form__input"
data-testid="jwt-api-url-input"
id="api-url-box"
value="url"
/>
</div>
</div>
</div>
<div
class="mm-box mm-box--padding-0 mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-center"
>
<button
class="box mm-text mm-button-base mm-button-base--size-md mm-button-base--block mm-button-secondary mm-text--body-md box--margin-right-4 box--padding-right-4 box--padding-left-4 box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-primary-default box--background-color-transparent box--rounded-pill box--border-color-primary-default box--border-style-solid box--border-width-1"
>
Cancel
</button>
<button
class="box mm-text mm-button-base mm-button-base--size-md mm-button-base--block mm-button-primary mm-text--body-md box--padding-right-4 box--padding-left-4 box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-primary-inverse box--background-color-primary-default box--rounded-pill"
data-testid="jwt-form-connect-button"
>
Connect
</button>
</div>
</div>
</div>
</div> </div>
`; `;

View File

@ -44,6 +44,7 @@ import { getCurrentChainId } from '../../../selectors';
import { getMMIConfiguration } from '../../../selectors/institutional/selectors'; import { getMMIConfiguration } from '../../../selectors/institutional/selectors';
import CustodyAccountList from '../connect-custody/account-list'; import CustodyAccountList from '../connect-custody/account-list';
import JwtUrlForm from '../../../components/institutional/jwt-url-form'; import JwtUrlForm from '../../../components/institutional/jwt-url-form';
import PulseLoader from '../../../components/ui/pulse-loader/pulse-loader';
const CustodyPage = () => { const CustodyPage = () => {
const t = useI18nContext(); const t = useI18nContext();
@ -55,6 +56,7 @@ const CustodyPage = () => {
const currentChainId = useSelector(getCurrentChainId); const currentChainId = useSelector(getCurrentChainId);
const { custodians } = useSelector(getMMIConfiguration); const { custodians } = useSelector(getMMIConfiguration);
const [loading, setLoading] = useState(true);
const [selectedAccounts, setSelectedAccounts] = useState({}); const [selectedAccounts, setSelectedAccounts] = useState({});
const [selectedCustodianName, setSelectedCustodianName] = useState(''); const [selectedCustodianName, setSelectedCustodianName] = useState('');
const [selectedCustodianImage, setSelectedCustodianImage] = useState(null); const [selectedCustodianImage, setSelectedCustodianImage] = useState(null);
@ -200,12 +202,12 @@ const CustodyPage = () => {
); );
const getCustodianAccounts = useCallback( const getCustodianAccounts = useCallback(
async (token, custody, getNonImportedAccounts) => { async (token, getNonImportedAccounts) => {
return await dispatch( return await dispatch(
mmiActions.getCustodianAccounts( mmiActions.getCustodianAccounts(
token, token,
apiUrl, apiUrl,
custody || selectedCustodianType, selectedCustodianType,
getNonImportedAccounts, getNonImportedAccounts,
), ),
); );
@ -218,12 +220,8 @@ const CustodyPage = () => {
// If you have one JWT already, but no dropdown yet, currentJwt is null! // If you have one JWT already, but no dropdown yet, currentJwt is null!
const jwt = currentJwt || jwtList[0]; const jwt = currentJwt || jwtList[0];
setConnectError(''); setConnectError('');
const accountsValue = await getCustodianAccounts( const accountsValue = await getCustodianAccounts(jwt, true);
jwt,
apiUrl,
selectedCustodianType,
true,
);
setAccounts(accountsValue); setAccounts(accountsValue);
trackEvent({ trackEvent({
category: 'MMI', category: 'MMI',
@ -245,15 +243,16 @@ const CustodyPage = () => {
handleConnectError, handleConnectError,
jwtList, jwtList,
selectedCustodianName, selectedCustodianName,
selectedCustodianType,
trackEvent, trackEvent,
]); ]);
useEffect(() => { useEffect(() => {
setLoading(true);
const fetchConnectRequest = async () => { const fetchConnectRequest = async () => {
const connectRequestValue = await dispatch( const connectRequestValue = await dispatch(
mmiActions.getCustodianConnectRequest(), mmiActions.getCustodianConnectRequest(),
); );
setChainId(parseInt(currentChainId, 16)); setChainId(parseInt(currentChainId, 16));
// check if it's empty object // check if it's empty object
@ -266,15 +265,22 @@ const CustodyPage = () => {
setSelectedCustodianType(connectRequestValue.custodianType); setSelectedCustodianType(connectRequestValue.custodianType);
setSelectedCustodianName(connectRequestValue.custodianName); setSelectedCustodianName(connectRequestValue.custodianName);
setApiUrl(connectRequestValue.apiUrl); setApiUrl(connectRequestValue.apiUrl);
connect();
} }
}; };
// call the function const handleFetchConnectRequest = async () => {
fetchConnectRequest() try {
// make sure to catch any error await fetchConnectRequest();
.catch(console.error); setLoading(false);
}, [dispatch, connect, currentChainId, mmiActions]); } catch (error) {
console.error(error);
setLoading(false);
}
};
handleFetchConnectRequest();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => { useEffect(() => {
const handleNetworkChange = async () => { const handleNetworkChange = async () => {
@ -282,14 +288,7 @@ const CustodyPage = () => {
const jwt = currentJwt || jwtList[0]; const jwt = currentJwt || jwtList[0];
if (jwt && jwt.length) { if (jwt && jwt.length) {
setAccounts( setAccounts(await getCustodianAccounts(jwt, true));
await getCustodianAccounts(
jwt,
apiUrl,
selectedCustodianType,
true,
),
);
} }
} }
}; };
@ -341,6 +340,10 @@ const CustodyPage = () => {
} }
}; };
if (loading) {
return <PulseLoader />;
}
return ( return (
<> <>
{connectError && ( {connectError && (
@ -348,7 +351,6 @@ const CustodyPage = () => {
{connectError} {connectError}
</Text> </Text>
)} )}
{selectError && ( {selectError && (
<Text textAlign={TextAlign.Center} marginTop={3} padding={[2, 7, 5]}> <Text textAlign={TextAlign.Center} marginTop={3} padding={[2, 7, 5]}>
{selectError} {selectError}
@ -397,7 +399,6 @@ const CustodyPage = () => {
</Box> </Box>
</Box> </Box>
) : null} ) : null}
{!accounts && selectedCustodianType && ( {!accounts && selectedCustodianType && (
<> <>
<Box <Box
@ -485,7 +486,6 @@ const CustodyPage = () => {
</Box> </Box>
</> </>
)} )}
{accounts && accounts.length > 0 && ( {accounts && accounts.length > 0 && (
<> <>
<Box <Box
@ -541,6 +541,10 @@ const CustodyPage = () => {
selectedAccounts={selectedAccounts} selectedAccounts={selectedAccounts}
onAddAccounts={async () => { onAddAccounts={async () => {
try { try {
const selectedCustodian = custodians.find(
(custodian) => custodian.name === selectedCustodianName,
);
await dispatch( await dispatch(
mmiActions.connectCustodyAddresses( mmiActions.connectCustodyAddresses(
selectedCustodianType, selectedCustodianType,
@ -548,17 +552,7 @@ const CustodyPage = () => {
selectedAccounts, selectedAccounts,
), ),
); );
const selectedCustodian = custodians.find(
(custodian) => custodian.name === selectedCustodianName,
);
history.push({
pathname: CUSTODY_ACCOUNT_DONE_ROUTE,
state: {
imgSrc: selectedCustodian.iconUrl,
title: t('custodianAccountAddedTitle'),
description: t('custodianAccountAddedDesc'),
},
});
trackEvent({ trackEvent({
category: 'MMI', category: 'MMI',
event: 'Custodial accounts connected', event: 'Custodial accounts connected',
@ -568,6 +562,15 @@ const CustodyPage = () => {
chainId, chainId,
}, },
}); });
history.push({
pathname: CUSTODY_ACCOUNT_DONE_ROUTE,
state: {
imgSrc: selectedCustodian.iconUrl,
title: t('custodianAccountAddedTitle'),
description: t('custodianAccountAddedDesc'),
},
});
} catch (e) { } catch (e) {
setSelectError(e.message); setSelectError(e.message);
} }
@ -598,7 +601,6 @@ const CustodyPage = () => {
/> />
</> </>
)} )}
{accounts && accounts.length === 0 && ( {accounts && accounts.length === 0 && (
<Box <Box
data-testid="custody-accounts-empty" data-testid="custody-accounts-empty"
@ -609,11 +611,11 @@ const CustodyPage = () => {
marginBottom={2} marginBottom={2}
fontWeight={FontWeight.Bold} fontWeight={FontWeight.Bold}
color={TextColor.textDefault} color={TextColor.textDefault}
variant={TextVariant.bodySm} variant={TextVariant.bodyLgMedium}
> >
{t('allCustodianAccountsConnectedTitle')} {t('allCustodianAccountsConnectedTitle')}
</Text> </Text>
<Text variant={TextVariant.bodyXs}> <Text variant={TextVariant.bodyMd}>
{t('allCustodianAccountsConnectedSubtitle')} {t('allCustodianAccountsConnectedSubtitle')}
</Text> </Text>

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import configureMockStore from 'redux-mock-store'; import configureMockStore from 'redux-mock-store';
import { fireEvent, waitFor, screen } from '@testing-library/react'; import { fireEvent, waitFor, screen, act } from '@testing-library/react';
import thunk from 'redux-thunk'; import thunk from 'redux-thunk';
import { renderWithProvider } from '../../../../test/lib/render-helpers'; import { renderWithProvider } from '../../../../test/lib/render-helpers';
import CustodyPage from '.'; import CustodyPage from '.';
@ -16,8 +16,8 @@ const mockedGetCustodianConnectRequest = jest.fn().mockReturnValue({
custodian: 'saturn', custodian: 'saturn',
token: 'token', token: 'token',
apiUrl: 'url', apiUrl: 'url',
custodianType: 'JSON-RPC', custodianType: undefined,
custodianName: 'Saturn', custodianName: 'saturn',
}); });
jest.mock('../../../store/institutional/institution-background', () => ({ jest.mock('../../../store/institutional/institution-background', () => ({
@ -85,29 +85,19 @@ describe('CustodyPage', function () {
}); });
}); });
it('calls getCustodianJwtList on custody select when connect btn is click', async () => { it('calls getCustodianJwtList on custody select when connect btn is click and clicks connect button and shows the jwt form', async () => {
const { getByTestId } = renderWithProvider(<CustodyPage />, store); act(() => {
renderWithProvider(<CustodyPage />, store);
const custodyBtn = getByTestId('custody-connect-button');
await waitFor(() => {
fireEvent.click(custodyBtn);
}); });
await waitFor(() => { await waitFor(() => {
expect(mockedGetCustodianJWTList).toHaveBeenCalled(); const custodyBtn = screen.getByTestId('custody-connect-button');
});
});
it('clicks connect button and shows the jwt form', async () => {
const { getByTestId } = renderWithProvider(<CustodyPage />, store);
const custodyBtn = getByTestId('custody-connect-button');
await waitFor(() => {
fireEvent.click(custodyBtn); fireEvent.click(custodyBtn);
}); });
await waitFor(() => { await waitFor(() => {
expect(screen.getByTestId('jwt-form-connect-button')).toBeInTheDocument(); expect(screen.getByTestId('jwt-form-connect-button')).toBeInTheDocument();
expect(mockedGetCustodianJWTList).toHaveBeenCalled();
}); });
}); });
}); });

View File

@ -117,7 +117,6 @@ describe('Institution Actions', () => {
'newApiUrl', 'newApiUrl',
); );
connectCustodyAddresses(jest.fn()); connectCustodyAddresses(jest.fn());
setWaitForConfirmDeepLinkDialog(jest.fn());
expect(connectCustodyAddresses).toBeDefined(); expect(connectCustodyAddresses).toBeDefined();
expect(setWaitForConfirmDeepLinkDialog).toBeDefined(); expect(setWaitForConfirmDeepLinkDialog).toBeDefined();
}); });

View File

@ -91,14 +91,17 @@ export function mmiActionsFactory() {
}; };
} }
function createAction(name: string, payload: any) { function createAction(name: string, payload: any): Promise<void> {
return () => { return new Promise((resolve, reject) => {
callBackgroundMethod(name, [payload], (err) => { callBackgroundMethod(name, [payload], (error) => {
if (isErrorWithMessage(err)) { if (error) {
throw new Error(err.message); reject(error);
return;
} }
resolve();
}); });
}; });
} }
return { return {
@ -190,18 +193,27 @@ export function mmiActionsFactory() {
createAction('syncReportsInProgress', { address, historicalReports }), createAction('syncReportsInProgress', { address, historicalReports }),
removeConnectInstitutionalFeature: (origin: string, projectId: string) => removeConnectInstitutionalFeature: (origin: string, projectId: string) =>
createAction('removeConnectInstitutionalFeature', { origin, projectId }), createAction('removeConnectInstitutionalFeature', { origin, projectId }),
removeAddTokenConnectRequest: ( removeAddTokenConnectRequest: ({
origin: string, origin,
apiUrl: string, apiUrl,
token: string, token,
) => }: {
origin: string;
apiUrl: string;
token: string;
}) =>
createAction('removeAddTokenConnectRequest', { origin, apiUrl, token }), createAction('removeAddTokenConnectRequest', { origin, apiUrl, token }),
setCustodianConnectRequest: ( setCustodianConnectRequest: ({
token: string, token,
apiUrl: string, apiUrl,
custodianType: string, custodianType,
custodianName: string, custodianName,
) => }: {
token: string;
apiUrl: string;
custodianType: string;
custodianName: string;
}) =>
createAsyncAction('setCustodianConnectRequest', [ createAsyncAction('setCustodianConnectRequest', [
{ token, apiUrl, custodianType, custodianName }, { token, apiUrl, custodianType, custodianName },
]), ]),