mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-28 23:06:37 +01:00
[MMI] Confirm-add-institutional-feature page (#18321)
* Added confirm add institutional feature page * Finished implementing component * Added all institutional ducks * Fixed tests * Removed ducks and console log * Fixed snapshots * Fixed messages json * Changed method name and using useEffect * Replace useEffect hook with a simple if statement to check if connectRequest exists and add null return statement to avoid warnings * Remove unneeded dependency * Added back useEffect and added a extra check to return null if connectRequest is false * Fixed eslint problem * Fixed all issues commented in the pr
This commit is contained in:
parent
b9c5120332
commit
c52d2131d3
24
app/_locales/en/messages.json
generated
24
app/_locales/en/messages.json
generated
@ -654,6 +654,12 @@
|
|||||||
"coingecko": {
|
"coingecko": {
|
||||||
"message": "CoinGecko"
|
"message": "CoinGecko"
|
||||||
},
|
},
|
||||||
|
"complianceActivatedDesc": {
|
||||||
|
"message": "You can now use compliance in MetaMask Institutional. Receiving AML/CFT analysis within the confirmation screen on all the addresses you interact with."
|
||||||
|
},
|
||||||
|
"complianceActivatedTitle": {
|
||||||
|
"message": "Your compliance feature is activated"
|
||||||
|
},
|
||||||
"complianceBlurb0": {
|
"complianceBlurb0": {
|
||||||
"message": "DeFi raises AML/CFT risk for institutions, given the decentralised pools and pseudonymous counterparties."
|
"message": "DeFi raises AML/CFT risk for institutions, given the decentralised pools and pseudonymous counterparties."
|
||||||
},
|
},
|
||||||
@ -780,6 +786,9 @@
|
|||||||
"connectingToSepolia": {
|
"connectingToSepolia": {
|
||||||
"message": "Connecting to Sepolia test network"
|
"message": "Connecting to Sepolia test network"
|
||||||
},
|
},
|
||||||
|
"connectionError": {
|
||||||
|
"message": "Connection error"
|
||||||
|
},
|
||||||
"contactUs": {
|
"contactUs": {
|
||||||
"message": "Contact us"
|
"message": "Contact us"
|
||||||
},
|
},
|
||||||
@ -1707,6 +1716,9 @@
|
|||||||
"holdToRevealTitle": {
|
"holdToRevealTitle": {
|
||||||
"message": "Keep your SRP safe"
|
"message": "Keep your SRP safe"
|
||||||
},
|
},
|
||||||
|
"id": {
|
||||||
|
"message": "Id"
|
||||||
|
},
|
||||||
"ignoreAll": {
|
"ignoreAll": {
|
||||||
"message": "Ignore all"
|
"message": "Ignore all"
|
||||||
},
|
},
|
||||||
@ -1812,6 +1824,9 @@
|
|||||||
"install": {
|
"install": {
|
||||||
"message": "Install"
|
"message": "Install"
|
||||||
},
|
},
|
||||||
|
"institutionalFeatures": {
|
||||||
|
"message": "Institutional Features"
|
||||||
|
},
|
||||||
"insufficientBalance": {
|
"insufficientBalance": {
|
||||||
"message": "Insufficient balance."
|
"message": "Insufficient balance."
|
||||||
},
|
},
|
||||||
@ -2141,6 +2156,9 @@
|
|||||||
"mmiAddToken": {
|
"mmiAddToken": {
|
||||||
"message": "The page at $1 would like to authorise the following custodian token in MetaMask Institutional"
|
"message": "The page at $1 would like to authorise the following custodian token in MetaMask Institutional"
|
||||||
},
|
},
|
||||||
|
"mmiAuthenticate": {
|
||||||
|
"message": "The page at $1 would like to authorise the following project’s compliance settings in MetaMask Institutional"
|
||||||
|
},
|
||||||
"mobileSyncWarning": {
|
"mobileSyncWarning": {
|
||||||
"message": "The 'Sync with extension' feature is temporarily disabled. If you want to use your extension wallet on MetaMask mobile, then on your mobile app: go back to the wallet setup options and select the 'Import with Secret Recovery Phrase' option. Use your extension wallet's secret phrase to then import your wallet into mobile."
|
"message": "The 'Sync with extension' feature is temporarily disabled. If you want to use your extension wallet on MetaMask mobile, then on your mobile app: go back to the wallet setup options and select the 'Import with Secret Recovery Phrase' option. Use your extension wallet's secret phrase to then import your wallet into mobile."
|
||||||
},
|
},
|
||||||
@ -3065,6 +3083,12 @@
|
|||||||
"proceedWithTransaction": {
|
"proceedWithTransaction": {
|
||||||
"message": "I want to proceed anyway"
|
"message": "I want to proceed anyway"
|
||||||
},
|
},
|
||||||
|
"projectIdInvalid": {
|
||||||
|
"message": "Provided Project ID is invalid"
|
||||||
|
},
|
||||||
|
"projectName": {
|
||||||
|
"message": "Project Name"
|
||||||
|
},
|
||||||
"proposedApprovalLimit": {
|
"proposedApprovalLimit": {
|
||||||
"message": "Proposed approval limit"
|
"message": "Proposed approval limit"
|
||||||
},
|
},
|
||||||
|
@ -32,6 +32,9 @@ const CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE = '/confirm-add-suggested-token';
|
|||||||
const NEW_ACCOUNT_ROUTE = '/new-account';
|
const NEW_ACCOUNT_ROUTE = '/new-account';
|
||||||
const IMPORT_ACCOUNT_ROUTE = '/new-account/import';
|
const IMPORT_ACCOUNT_ROUTE = '/new-account/import';
|
||||||
const CONNECT_HARDWARE_ROUTE = '/new-account/connect';
|
const CONNECT_HARDWARE_ROUTE = '/new-account/connect';
|
||||||
|
///: BEGIN:ONLY_INCLUDE_IN(mmi)
|
||||||
|
const INSTITUTIONAL_FEATURES_DONE_ROUTE = '/institutional-features/done';
|
||||||
|
///: END:ONLY_INCLUDE_IN
|
||||||
const SEND_ROUTE = '/send';
|
const SEND_ROUTE = '/send';
|
||||||
const TOKEN_DETAILS = '/token-details';
|
const TOKEN_DETAILS = '/token-details';
|
||||||
const CONNECT_ROUTE = '/connect';
|
const CONNECT_ROUTE = '/connect';
|
||||||
@ -124,6 +127,9 @@ const PATH_NAME_MAP = {
|
|||||||
[NEW_ACCOUNT_ROUTE]: 'New Account Page',
|
[NEW_ACCOUNT_ROUTE]: 'New Account Page',
|
||||||
[IMPORT_ACCOUNT_ROUTE]: 'Import Account Page',
|
[IMPORT_ACCOUNT_ROUTE]: 'Import Account Page',
|
||||||
[CONNECT_HARDWARE_ROUTE]: 'Connect Hardware Wallet Page',
|
[CONNECT_HARDWARE_ROUTE]: 'Connect Hardware Wallet Page',
|
||||||
|
///: BEGIN:ONLY_INCLUDE_IN(mmi)
|
||||||
|
[INSTITUTIONAL_FEATURES_DONE_ROUTE]: 'Institutional features done',
|
||||||
|
///: END:ONLY_INCLUDE_IN
|
||||||
[SEND_ROUTE]: 'Send Page',
|
[SEND_ROUTE]: 'Send Page',
|
||||||
[`${TOKEN_DETAILS}/:address`]: 'Token Details Page',
|
[`${TOKEN_DETAILS}/:address`]: 'Token Details Page',
|
||||||
[`${CONNECT_ROUTE}/:id`]: 'Connect To Site Confirmation Page',
|
[`${CONNECT_ROUTE}/:id`]: 'Connect To Site Confirmation Page',
|
||||||
@ -180,6 +186,9 @@ export {
|
|||||||
NEW_ACCOUNT_ROUTE,
|
NEW_ACCOUNT_ROUTE,
|
||||||
IMPORT_ACCOUNT_ROUTE,
|
IMPORT_ACCOUNT_ROUTE,
|
||||||
CONNECT_HARDWARE_ROUTE,
|
CONNECT_HARDWARE_ROUTE,
|
||||||
|
///: BEGIN:ONLY_INCLUDE_IN(mmi)
|
||||||
|
INSTITUTIONAL_FEATURES_DONE_ROUTE,
|
||||||
|
///: END:ONLY_INCLUDE_IN
|
||||||
SEND_ROUTE,
|
SEND_ROUTE,
|
||||||
TOKEN_DETAILS,
|
TOKEN_DETAILS,
|
||||||
CONFIRM_TRANSACTION_ROUTE,
|
CONFIRM_TRANSACTION_ROUTE,
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Confirm Add Institutional Feature opens confirm institutional sucessfully 1`] = `
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="box page-container box--flex-direction-row"
|
||||||
|
data-testid="confirm-add-institutional-feature"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="box page-container__header box--flex-direction-row"
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
class="box mm-text page-container__title mm-text--body-md box--flex-direction-row box--color-text-default"
|
||||||
|
>
|
||||||
|
Institutional Features
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
class="box mm-text page-container__subtitle mm-text--body-md box--flex-direction-row box--color-text-default"
|
||||||
|
>
|
||||||
|
The page at origin would like to authorise the following project’s compliance settings in MetaMask Institutional
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="box page-container__content box--flex-direction-row"
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
class="box mm-text mm-text--body-sm box--margin-top-3 box--margin-right-8 box--margin-left-8 box--flex-direction-row box--color-text-default"
|
||||||
|
>
|
||||||
|
Project Name
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
class="box mm-text mm-text--body-lg-medium mm-text--overflow-wrap-break-word box--margin-top-1 box--margin-right-8 box--margin-bottom-1 box--margin-left-8 box--flex-direction-row box--color-text-default"
|
||||||
|
>
|
||||||
|
projectName
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
class="box mm-text mm-text--body-xs mm-text--overflow-wrap-break-word box--margin-right-8 box--margin-left-8 box--flex-direction-row box--color-text-muted"
|
||||||
|
>
|
||||||
|
Id
|
||||||
|
:
|
||||||
|
projectId
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="box page-container__footer box--flex-direction-row"
|
||||||
|
>
|
||||||
|
<footer>
|
||||||
|
<button
|
||||||
|
class="button btn--rounded btn-default btn--large"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="button btn--rounded btn-primary btn--large"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
Confirm
|
||||||
|
</button>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
@ -0,0 +1,208 @@
|
|||||||
|
import React, { useState, useContext, useEffect } from 'react';
|
||||||
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||||
|
import Button from '../../../components/ui/button';
|
||||||
|
import PulseLoader from '../../../components/ui/pulse-loader';
|
||||||
|
import { INSTITUTIONAL_FEATURES_DONE_ROUTE } from '../../../helpers/constants/routes';
|
||||||
|
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
||||||
|
import { getMostRecentOverviewPage } from '../../../ducks/history/history';
|
||||||
|
import { Text } from '../../../components/component-library';
|
||||||
|
import {
|
||||||
|
TextColor,
|
||||||
|
TextVariant,
|
||||||
|
OVERFLOW_WRAP,
|
||||||
|
TEXT_ALIGN,
|
||||||
|
} from '../../../helpers/constants/design-system';
|
||||||
|
import Box from '../../../components/ui/box';
|
||||||
|
import { mmiActionsFactory } from '../../../store/institutional/institution-background';
|
||||||
|
|
||||||
|
export default function ConfirmAddInstitutionalFeature({ history }) {
|
||||||
|
const t = useI18nContext();
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const mmiActions = mmiActionsFactory();
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [connectError, setConnectError] = useState('');
|
||||||
|
const mostRecentOverviewPage = useSelector(getMostRecentOverviewPage);
|
||||||
|
const connectRequests = useSelector(
|
||||||
|
(state) => state.metamask.institutionalFeatures?.connectRequests,
|
||||||
|
);
|
||||||
|
|
||||||
|
const trackEvent = useContext(MetaMetricsContext);
|
||||||
|
const connectRequest = connectRequests[0];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!connectRequest) {
|
||||||
|
history.push(mostRecentOverviewPage);
|
||||||
|
}
|
||||||
|
}, [connectRequest, history, mostRecentOverviewPage]);
|
||||||
|
|
||||||
|
if (!connectRequest) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const serviceLabel = connectRequest.labels.find(
|
||||||
|
(label) => label.key === 'service',
|
||||||
|
);
|
||||||
|
|
||||||
|
const sendEvent = ({ actions, service }) => {
|
||||||
|
trackEvent({
|
||||||
|
category: 'MMI',
|
||||||
|
event: 'Institutional feature connection',
|
||||||
|
properties: {
|
||||||
|
actions,
|
||||||
|
service,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleConnectError = ({ message }) => {
|
||||||
|
let error = message;
|
||||||
|
if (message.startsWith('401')) {
|
||||||
|
error = t('projectIdInvalid');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!error) {
|
||||||
|
error = t('connectionError');
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsLoading(false);
|
||||||
|
setConnectError(error);
|
||||||
|
sendEvent({ actions: 'Institutional feature RPC error' });
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeConnectInstitutionalFeature = ({ actions, service, push }) => {
|
||||||
|
dispatch(
|
||||||
|
mmiActions.removeConnectInstitutionalFeature({
|
||||||
|
origin: connectRequest.origin,
|
||||||
|
projectId: connectRequest.token.projectId,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
sendEvent({ actions, service });
|
||||||
|
history.push(push);
|
||||||
|
};
|
||||||
|
|
||||||
|
const confirmAddInstitutionalFeature = async () => {
|
||||||
|
setIsLoading(true);
|
||||||
|
setConnectError('');
|
||||||
|
|
||||||
|
try {
|
||||||
|
await dispatch(
|
||||||
|
mmiActions.setComplianceAuthData({
|
||||||
|
clientId: connectRequest.token.clientId,
|
||||||
|
projectId: connectRequest.token.projectId,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
removeConnectInstitutionalFeature({
|
||||||
|
actions: 'Institutional feature RPC confirm',
|
||||||
|
service: serviceLabel.value,
|
||||||
|
push: {
|
||||||
|
pathname: INSTITUTIONAL_FEATURES_DONE_ROUTE,
|
||||||
|
state: {
|
||||||
|
imgSrc: 'images/compliance-logo.png',
|
||||||
|
title: t('complianceActivatedTitle'),
|
||||||
|
description: t('complianceActivatedDesc'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
handleConnectError(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sendEvent({
|
||||||
|
actions: 'Institutional feature RPC request',
|
||||||
|
service: serviceLabel.value,
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
className="page-container"
|
||||||
|
data-testid="confirm-add-institutional-feature"
|
||||||
|
>
|
||||||
|
<Box className="page-container__header">
|
||||||
|
<Text className="page-container__title">
|
||||||
|
{t('institutionalFeatures')}
|
||||||
|
</Text>
|
||||||
|
<Text className="page-container__subtitle">
|
||||||
|
{t('mmiAuthenticate', [connectRequest.origin, serviceLabel.value])}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
<Box className="page-container__content">
|
||||||
|
<Text
|
||||||
|
variant={TextVariant.bodySm}
|
||||||
|
marginTop={3}
|
||||||
|
marginRight={8}
|
||||||
|
marginBottom={0}
|
||||||
|
marginLeft={8}
|
||||||
|
>
|
||||||
|
{t('projectName')}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
variant={TextVariant.bodyLgMedium}
|
||||||
|
color={TextColor.textDefault}
|
||||||
|
marginTop={1}
|
||||||
|
marginRight={8}
|
||||||
|
marginBottom={1}
|
||||||
|
marginLeft={8}
|
||||||
|
overflowWrap={OVERFLOW_WRAP.BREAK_WORD}
|
||||||
|
>
|
||||||
|
{connectRequest?.token?.projectName}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
variant={TextVariant.bodyXs}
|
||||||
|
marginRight={8}
|
||||||
|
marginLeft={8}
|
||||||
|
overflowWrap={OVERFLOW_WRAP.BREAK_WORD}
|
||||||
|
color={TextColor.textMuted}
|
||||||
|
>
|
||||||
|
{t('id')}: {connectRequest?.token?.projectId}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
{connectError && (
|
||||||
|
<Text
|
||||||
|
textAlign={TEXT_ALIGN.CENTER}
|
||||||
|
marginTop={4}
|
||||||
|
data-testid="connect-error-message"
|
||||||
|
>
|
||||||
|
{connectError}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Box className="page-container__footer">
|
||||||
|
{isLoading ? (
|
||||||
|
<footer>
|
||||||
|
<PulseLoader />
|
||||||
|
</footer>
|
||||||
|
) : (
|
||||||
|
<footer>
|
||||||
|
<Button
|
||||||
|
type="default"
|
||||||
|
large
|
||||||
|
onClick={() => {
|
||||||
|
removeConnectInstitutionalFeature({
|
||||||
|
actions: 'Institutional feature RPC cancel',
|
||||||
|
service: serviceLabel.value,
|
||||||
|
push: mostRecentOverviewPage,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t('cancel')}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
large
|
||||||
|
onClick={confirmAddInstitutionalFeature}
|
||||||
|
>
|
||||||
|
{t('confirm')}
|
||||||
|
</Button>
|
||||||
|
</footer>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfirmAddInstitutionalFeature.propTypes = {
|
||||||
|
history: PropTypes.object,
|
||||||
|
};
|
@ -0,0 +1,57 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Provider } from 'react-redux';
|
||||||
|
import configureStore from '../../../store/store';
|
||||||
|
import testData from '../../../../.storybook/test-data';
|
||||||
|
import ConfirmAddInstitutionalFeature from '.';
|
||||||
|
|
||||||
|
const customData = {
|
||||||
|
...testData,
|
||||||
|
metamask: {
|
||||||
|
provider: {
|
||||||
|
type: 'test',
|
||||||
|
},
|
||||||
|
institutionalFeatures: {
|
||||||
|
complianceProjectId: '',
|
||||||
|
connectRequests: [
|
||||||
|
{
|
||||||
|
labels: [
|
||||||
|
{
|
||||||
|
key: 'service',
|
||||||
|
value: 'test',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
origin: 'origin',
|
||||||
|
token: {
|
||||||
|
projectName: 'projectName',
|
||||||
|
projectId: 'projectId',
|
||||||
|
clientId: 'clientId',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
preferences: {
|
||||||
|
useNativeCurrencyAsPrimaryCurrency: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const store = configureStore(customData);
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Pages/Institutional/ConfirmAddInstitutionalFeature',
|
||||||
|
decorators: [(story) => <Provider store={store}>{story()}</Provider>],
|
||||||
|
component: ConfirmAddInstitutionalFeature,
|
||||||
|
args: {
|
||||||
|
history: {
|
||||||
|
push: () => {
|
||||||
|
/**/
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DefaultStory = (args) => (
|
||||||
|
<ConfirmAddInstitutionalFeature {...args} />
|
||||||
|
);
|
||||||
|
|
||||||
|
DefaultStory.storyName = 'ConfirmAddInstitutionalFeature';
|
@ -0,0 +1,122 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { fireEvent, screen } from '@testing-library/react';
|
||||||
|
import configureMockStore from 'redux-mock-store';
|
||||||
|
import thunk from 'redux-thunk';
|
||||||
|
import { renderWithProvider } from '../../../../test/lib/render-helpers';
|
||||||
|
import mockState from '../../../../test/data/mock-state.json';
|
||||||
|
import ConfirmAddInstitutionalFeature from '.';
|
||||||
|
|
||||||
|
const mockRemoveConnectInstitutionalFeature = jest
|
||||||
|
.fn()
|
||||||
|
.mockReturnValue({ type: 'TYPE' });
|
||||||
|
|
||||||
|
let mockSetComplianceAuthData = jest.fn().mockReturnValue({ type: 'TYPE' });
|
||||||
|
|
||||||
|
jest.mock('../../../store/institutional/institution-background', () => ({
|
||||||
|
mmiActionsFactory: () => ({
|
||||||
|
setComplianceAuthData: mockSetComplianceAuthData,
|
||||||
|
removeConnectInstitutionalFeature: mockRemoveConnectInstitutionalFeature,
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const connectRequests = [
|
||||||
|
{
|
||||||
|
labels: [
|
||||||
|
{
|
||||||
|
key: 'service',
|
||||||
|
value: 'test',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
origin: 'origin',
|
||||||
|
token: {
|
||||||
|
projectName: 'projectName',
|
||||||
|
projectId: 'projectId',
|
||||||
|
clientId: 'clientId',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const props = {
|
||||||
|
history: {
|
||||||
|
push: jest.fn(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const render = ({ newState } = {}) => {
|
||||||
|
const state = {
|
||||||
|
...mockState,
|
||||||
|
metamask: {
|
||||||
|
provider: {
|
||||||
|
type: 'test',
|
||||||
|
},
|
||||||
|
institutionalFeatures: {
|
||||||
|
complianceProjectId: '',
|
||||||
|
connectRequests,
|
||||||
|
},
|
||||||
|
preferences: {
|
||||||
|
useNativeCurrencyAsPrimaryCurrency: true,
|
||||||
|
},
|
||||||
|
...newState,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const middlewares = [thunk];
|
||||||
|
const mockStore = configureMockStore(middlewares);
|
||||||
|
const store = mockStore(state);
|
||||||
|
|
||||||
|
return renderWithProvider(
|
||||||
|
<ConfirmAddInstitutionalFeature {...props} />,
|
||||||
|
store,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('Confirm Add Institutional Feature', function () {
|
||||||
|
it('opens confirm institutional sucessfully', () => {
|
||||||
|
const { container } = render();
|
||||||
|
expect(container).toMatchSnapshot();
|
||||||
|
expect(
|
||||||
|
screen.getByText(`Id: ${connectRequests[0].token.projectId}`),
|
||||||
|
).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('runs removeConnectInstitutionalFeature on cancel click', () => {
|
||||||
|
render();
|
||||||
|
fireEvent.click(screen.queryByText('Cancel'));
|
||||||
|
expect(mockRemoveConnectInstitutionalFeature).toHaveBeenCalledTimes(1);
|
||||||
|
expect(mockRemoveConnectInstitutionalFeature).toHaveBeenCalledWith({
|
||||||
|
origin: connectRequests[0].origin,
|
||||||
|
projectId: connectRequests[0].token.projectId,
|
||||||
|
});
|
||||||
|
expect(props.history.push).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('runs setComplianceAuthData on confirm click', () => {
|
||||||
|
render();
|
||||||
|
fireEvent.click(screen.queryByText('Confirm'));
|
||||||
|
expect(mockSetComplianceAuthData).toHaveBeenCalledTimes(1);
|
||||||
|
expect(mockSetComplianceAuthData).toHaveBeenCalledWith({
|
||||||
|
clientId: connectRequests[0].token.clientId,
|
||||||
|
projectId: connectRequests[0].token.projectId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles error', () => {
|
||||||
|
mockSetComplianceAuthData = jest
|
||||||
|
.fn()
|
||||||
|
.mockReturnValue(new Error('Async error message'));
|
||||||
|
const { queryByTestId } = render();
|
||||||
|
fireEvent.click(screen.queryByText('Confirm'));
|
||||||
|
expect(queryByTestId('connect-error-message')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not render without connectRequest', () => {
|
||||||
|
const newState = {
|
||||||
|
institutionalFeatures: {
|
||||||
|
connectRequests: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const { queryByTestId } = render({ newState });
|
||||||
|
expect(
|
||||||
|
queryByTestId('confirm-add-institutional-feature'),
|
||||||
|
).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,3 @@
|
|||||||
|
import ConfirmAddInstitutionalFeature from './confirm-add-institutional-feature';
|
||||||
|
|
||||||
|
export default ConfirmAddInstitutionalFeature;
|
Loading…
Reference in New Issue
Block a user