diff --git a/test/data/confirmations/typed_sign.ts b/test/data/confirmations/typed_sign.ts index 86067ef1f117..88985e1a52a7 100644 --- a/test/data/confirmations/typed_sign.ts +++ b/test/data/confirmations/typed_sign.ts @@ -176,3 +176,41 @@ export const permitSignatureMsg = { origin: 'https://metamask.github.io', }, } as SignatureRequestType; + +export const permitBatchSignatureMsg = { + id: '0b1787a0-1c44-11ef-b70d-e7064bd7b659', + securityAlertResponse: { + reason: 'loading', + result_type: 'validation_in_progress', + securityAlertId: 'ab21395f-2190-472f-8cfa-3d224e7529d8', + }, + status: 'unapproved', + time: 1716826404122, + type: 'eth_signTypedData', + msgParams: { + data: '{"types":{"PermitBatch":[{"name":"details","type":"PermitDetails[]"},{"name":"spender","type":"address"},{"name":"sigDeadline","type":"uint256"}],"PermitDetails":[{"name":"token","type":"address"},{"name":"amount","type":"uint160"},{"name":"expiration","type":"uint48"},{"name":"nonce","type":"uint48"}],"EIP712Domain":[{"name":"name","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}]},"domain":{"name":"Permit2","chainId":"1","verifyingContract":"0x000000000022d473030f116ddee9f6b43ac78ba3"},"primaryType":"PermitBatch","message":{"details":[{"token":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","amount":"1461501637330902918203684832716283019655932542975","expiration":"1722887542","nonce":"5"},{"token":"0xb0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","amount":"2461501637330902918203684832716283019655932542975","expiration":"1722887642","nonce":"6"}],"spender":"0x3fc91a3afd70395cd496c647d5a6cc9d4b2b7fad","sigDeadline":"1720297342"}}', + from: '0x935e73edb9ff52e23bac7f7e043a1ecd06d05477', + version: 'V4', + signatureMethod: 'eth_signTypedData_v4', + origin: 'https://metamask.github.io', + }, +} as SignatureRequestType; + +export const permitSingleSignatureMsg = { + id: '0b1787a0-1c44-11ef-b70d-e7064bd7b659', + securityAlertResponse: { + reason: 'loading', + result_type: 'validation_in_progress', + securityAlertId: 'ab21395f-2190-472f-8cfa-3d224e7529d8', + }, + status: 'unapproved', + time: 1716826404122, + type: 'eth_signTypedData', + msgParams: { + data: '{"types":{"PermitSingle":[{"name":"details","type":"PermitDetails"},{"name":"spender","type":"address"},{"name":"sigDeadline","type":"uint256"}],"PermitDetails":[{"name":"token","type":"address"},{"name":"amount","type":"uint160"},{"name":"expiration","type":"uint48"},{"name":"nonce","type":"uint48"}],"EIP712Domain":[{"name":"name","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}]},"domain":{"name":"Permit2","chainId":"1","verifyingContract":"0x000000000022d473030f116ddee9f6b43ac78ba3"},"primaryType":"PermitSingle","message":{"details":{"token":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","amount":"1461501637330902918203684832716283019655932542975","expiration":"1722887542","nonce":"5"},"spender":"0x3fc91a3afd70395cd496c647d5a6cc9d4b2b7fad","sigDeadline":"1720297342"}}', + from: '0x935e73edb9ff52e23bac7f7e043a1ecd06d05477', + version: 'V4', + signatureMethod: 'eth_signTypedData_v4', + origin: 'https://metamask.github.io', + }, +} as SignatureRequestType; diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/__snapshots__/typed-sign.test.tsx.snap b/ui/pages/confirmations/components/confirm/info/typed-sign/__snapshots__/typed-sign.test.tsx.snap index ebe7d746b36f..7b20ba3e9ddc 100644 --- a/ui/pages/confirmations/components/confirm/info/typed-sign/__snapshots__/typed-sign.test.tsx.snap +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/__snapshots__/typed-sign.test.tsx.snap @@ -65,51 +65,55 @@ exports[`TypedSignInfo correctly renders permit sign type 1`] = ` style="margin-left: auto; max-width: 100%;" >
-

- 3,000 -

+

+ 3,000 +

+
-
-
-
- -

+

- 0xCcCCc...ccccC -

+ +

+ 0xCcCCc...ccccC +

+
+
-
diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/__snapshots__/permit-simulation.test.tsx.snap b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/__snapshots__/permit-simulation.test.tsx.snap index 7e101a53d2f5..792adfd2975f 100644 --- a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/__snapshots__/permit-simulation.test.tsx.snap +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/__snapshots__/permit-simulation.test.tsx.snap @@ -65,51 +65,55 @@ exports[`PermitSimulation renders component correctly 1`] = ` style="margin-left: auto; max-width: 100%;" >
-

- 30 -

+

+ 30 +

+
-
-
-
- -

+

- 0xCcCCc...ccccC -

+ +

+ 0xCcCCc...ccccC +

+
+
-
diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/permit-simulation.test.tsx b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/permit-simulation.test.tsx index bb86010ce07a..46c3212fb997 100644 --- a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/permit-simulation.test.tsx +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/permit-simulation.test.tsx @@ -1,19 +1,31 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; +import { act } from 'react-dom/test-utils'; import { getMockTypedSignConfirmStateForRequest } from '../../../../../../../../test/data/confirmations/helper'; import { renderWithConfirmContextProvider } from '../../../../../../../../test/lib/confirmations/render-helpers'; import { permitSignatureMsg } from '../../../../../../../../test/data/confirmations/typed_sign'; import PermitSimulation from './permit-simulation'; +jest.mock('../../../../../../../store/actions', () => { + return { + getTokenStandardAndDetails: jest.fn().mockResolvedValue({ decimals: 2 }), + }; +}); + describe('PermitSimulation', () => { - it('renders component correctly', () => { + it('renders component correctly', async () => { const state = getMockTypedSignConfirmStateForRequest(permitSignatureMsg); const mockStore = configureMockStore([])(state); - const { container } = renderWithConfirmContextProvider( - , - mockStore, - ); - expect(container).toMatchSnapshot(); + + await act(async () => { + const { container, findByText } = renderWithConfirmContextProvider( + , + mockStore, + ); + + expect(await findByText('30')).toBeInTheDocument(); + expect(container).toMatchSnapshot(); + }); }); }); diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/permit-simulation.tsx b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/permit-simulation.tsx index b1551b2def14..98f41f72dda9 100644 --- a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/permit-simulation.tsx +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/permit-simulation.tsx @@ -1,65 +1,56 @@ -import { NameType } from '@metamask/name-controller'; -import React, { useMemo } from 'react'; +import React from 'react'; -import { calcTokenAmount } from '../../../../../../../../shared/lib/transactions-controller-utils'; +import { Box } from '../../../../../../../components/component-library'; +import { PrimaryType } from '../../../../../../../../shared/constants/signatures'; import { parseTypedDataMessage } from '../../../../../../../../shared/modules/transaction.utils'; -import useTokenExchangeRate from '../../../../../../../components/app/currency-input/hooks/useTokenExchangeRate'; -import Name from '../../../../../../../components/app/name/name'; -import { Box, Text } from '../../../../../../../components/component-library'; -import Tooltip from '../../../../../../../components/ui/tooltip'; import { - BackgroundColor, - BlockSize, - BorderRadius, Display, - TextAlign, + FlexDirection, } from '../../../../../../../helpers/constants/design-system'; -import { shortenString } from '../../../../../../../helpers/utils/util'; import { useI18nContext } from '../../../../../../../hooks/useI18nContext'; import { SignatureRequestType } from '../../../../../types/confirm'; import { useConfirmContext } from '../../../../../context/confirm'; -import { IndividualFiatDisplay } from '../../../../simulation-details/fiat-display'; -import { - formatAmount, - formatAmountMaxPrecision, -} from '../../../../simulation-details/formatAmount'; import StaticSimulation from '../../shared/static-simulation/static-simulation'; +import PermitSimulationValueDisplay from './value-display/value-display'; + +function extractTokenDetailsByPrimaryType( + message: Record, + primaryType: PrimaryType, +): object[] | unknown { + let tokenDetails; + + switch (primaryType) { + case PrimaryType.PermitBatch: + case PrimaryType.PermitSingle: + tokenDetails = message?.details; + break; + case PrimaryType.PermitBatchTransferFrom: + case PrimaryType.PermitTransferFrom: + tokenDetails = message?.permitted; + break; + default: + break; + } + + const isNonArrayObject = tokenDetails && !Array.isArray(tokenDetails); + + return isNonArrayObject ? [tokenDetails] : tokenDetails; +} -const PermitSimulation: React.FC<{ - tokenDecimals: number; -}> = ({ tokenDecimals }) => { +const PermitSimulation: React.FC = () => { const t = useI18nContext(); const { currentConfirmation } = useConfirmContext() as { currentConfirmation: SignatureRequestType; }; + const msgData = currentConfirmation.msgParams?.data; const { domain: { verifyingContract }, - message: { value }, - } = parseTypedDataMessage(currentConfirmation.msgParams?.data as string); + message, + primaryType, + } = parseTypedDataMessage(msgData as string); - const exchangeRate = useTokenExchangeRate(verifyingContract); - - const fiatValue = useMemo(() => { - if (exchangeRate && value) { - const tokenAmount = calcTokenAmount(value, tokenDecimals); - return exchangeRate.times(tokenAmount).toNumber(); - } - return undefined; - }, [exchangeRate, value]); - - const { tokenValue, tokenValueMaxPrecision } = useMemo(() => { - if (!value) { - return { tokenValue: null, tokenValueMaxPrecision: null }; - } - - const tokenAmount = calcTokenAmount(value, tokenDecimals); - - return { - tokenValue: formatAmount('en-US', tokenAmount), - tokenValueMaxPrecision: formatAmountMaxPrecision('en-US', tokenAmount), - }; - }, [tokenDecimals, value]); + const tokenDetails = extractTokenDetailsByPrimaryType(message, primaryType); return ( - - - - - {shortenString(tokenValue || '', { - truncatedCharLimit: 15, - truncatedStartChars: 15, - truncatedEndChars: 0, - skipCharacterInEnd: true, - })} - - - - - - - {fiatValue && ( - + Array.isArray(tokenDetails) ? ( + + {tokenDetails.map( + ( + { token, amount }: { token: string; amount: string }, + i: number, + ) => ( + + ), )} - + ) : ( + + ) } /> ); diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/__snapshots__/value-display.test.tsx.snap b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/__snapshots__/value-display.test.tsx.snap new file mode 100644 index 000000000000..022ff8b6dbc2 --- /dev/null +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/__snapshots__/value-display.test.tsx.snap @@ -0,0 +1,56 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`PermitSimulationValueDisplay renders component correctly 1`] = ` +
+
+
+
+
+
+

+ 0.432 +

+
+
+
+
+
+ +

+ 0xA0b86...6eB48 +

+
+
+
+
+
+
+`; diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/value-display.test.tsx b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/value-display.test.tsx new file mode 100644 index 000000000000..f6af7357502d --- /dev/null +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/value-display.test.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import { act } from 'react-dom/test-utils'; +import configureMockStore from 'redux-mock-store'; + +import mockState from '../../../../../../../../../test/data/mock-state.json'; +import { renderWithProvider } from '../../../../../../../../../test/lib/render-helpers'; +import PermitSimulationValueDisplay from './value-display'; + +jest.mock('../../../../../../../../store/actions', () => { + return { + getTokenStandardAndDetails: jest.fn().mockResolvedValue({ decimals: 4 }), + }; +}); + +describe('PermitSimulationValueDisplay', () => { + it('renders component correctly', async () => { + const mockStore = configureMockStore([])(mockState); + + await act(async () => { + const { container, findByText } = renderWithProvider( + , + mockStore, + ); + + expect(await findByText('0.432')).toBeInTheDocument(); + expect(container).toMatchSnapshot(); + }); + }); +}); diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/value-display.tsx b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/value-display.tsx new file mode 100644 index 000000000000..d0cd9c529d0e --- /dev/null +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/value-display.tsx @@ -0,0 +1,121 @@ +import React, { useMemo } from 'react'; +import { NameType } from '@metamask/name-controller'; +import { captureException } from '@sentry/browser'; +import { getTokenStandardAndDetails } from '../../../../../../../../store/actions'; +import { shortenString } from '../../../../../../../../helpers/utils/util'; + +import { calcTokenAmount } from '../../../../../../../../../shared/lib/transactions-controller-utils'; +import useTokenExchangeRate from '../../../../../../../../components/app/currency-input/hooks/useTokenExchangeRate'; +import { IndividualFiatDisplay } from '../../../../../simulation-details/fiat-display'; +import { + formatAmount, + formatAmountMaxPrecision, +} from '../../../../../simulation-details/formatAmount'; +import { useAsyncResult } from '../../../../../../../../hooks/useAsyncResult'; + +import { + Box, + Text, +} from '../../../../../../../../components/component-library'; +import Tooltip from '../../../../../../../../components/ui/tooltip'; +import { + BackgroundColor, + BlockSize, + BorderRadius, + Display, + JustifyContent, + TextAlign, +} from '../../../../../../../../helpers/constants/design-system'; +import Name from '../../../../../../../../components/app/name/name'; + +const getTokenDecimals = async (tokenContract: string) => { + const tokenDetails = await getTokenStandardAndDetails(tokenContract); + const tokenDecimals = tokenDetails?.decimals; + + return parseInt(tokenDecimals ?? '0', 10); +}; + +const PermitSimulationValueDisplay: React.FC<{ + primaryType?: string; + tokenContract: string; + value: number | string; +}> = ({ primaryType, tokenContract, value }) => { + const exchangeRate = useTokenExchangeRate(tokenContract); + + const { value: tokenDecimals } = useAsyncResult( + async () => await getTokenDecimals(tokenContract), + [tokenContract], + ); + + const fiatValue = useMemo(() => { + if (exchangeRate && value) { + const tokenAmount = calcTokenAmount(value, tokenDecimals); + return exchangeRate.times(tokenAmount).toNumber(); + } + return undefined; + }, [exchangeRate, tokenDecimals, value]); + + const { tokenValue, tokenValueMaxPrecision } = useMemo(() => { + if (!value) { + return { tokenValue: null, tokenValueMaxPrecision: null }; + } + + const tokenAmount = calcTokenAmount(value, tokenDecimals); + + return { + tokenValue: formatAmount('en-US', tokenAmount), + tokenValueMaxPrecision: formatAmountMaxPrecision('en-US', tokenAmount), + }; + }, [tokenDecimals, value]); + + /** Temporary error capturing as we are building out Permit Simulations */ + if (!tokenContract) { + captureException( + new Error( + `PermitSimulationValueDisplay: Token contract address is missing where primaryType === ${primaryType}`, + ), + ); + return null; + } + + return ( + + + + + + {shortenString(tokenValue || '', { + truncatedCharLimit: 15, + truncatedStartChars: 15, + truncatedEndChars: 0, + skipCharacterInEnd: true, + })} + + + + + + + {fiatValue && } + + + ); +}; + +export default PermitSimulationValueDisplay; diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign.tsx b/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign.tsx index a0a64e3956ec..88d9d93a32ef 100644 --- a/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign.tsx +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign.tsx @@ -60,9 +60,7 @@ const TypedSignInfo: React.FC = () => { return ( <> - {isPermit && useTransactionSimulations && ( - - )} + {isPermit && useTransactionSimulations && } {isPermit && ( <> diff --git a/ui/pages/confirmations/components/confirm/row/dataTree.tsx b/ui/pages/confirmations/components/confirm/row/dataTree.tsx index 2b38ccee5663..f728b9d5dfa9 100644 --- a/ui/pages/confirmations/components/confirm/row/dataTree.tsx +++ b/ui/pages/confirmations/components/confirm/row/dataTree.tsx @@ -73,12 +73,10 @@ const getTokenDecimalsOfDataTree = async ( return undefined; } - const decimals = parseInt( - (await getTokenStandardAndDetails(tokenContract))?.decimals ?? '0', - 10, - ); + const tokenDetails = await getTokenStandardAndDetails(tokenContract); + const tokenDecimals = tokenDetails?.decimals; - return decimals; + return parseInt(tokenDecimals ?? '0', 10); }; export const DataTree = ({ diff --git a/ui/pages/confirmations/confirm/__snapshots__/confirm.test.tsx.snap b/ui/pages/confirmations/confirm/__snapshots__/confirm.test.tsx.snap index 82859fd5c17f..a90c43d7d783 100644 --- a/ui/pages/confirmations/confirm/__snapshots__/confirm.test.tsx.snap +++ b/ui/pages/confirmations/confirm/__snapshots__/confirm.test.tsx.snap @@ -1,6 +1,203 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Confirm matches snapshot for signature - personal sign type 1`] = ` +
+
+
+
+
+
+
+
+
+
+ Chain 5 logo +
+
+
+

+ Test Account +

+

+ Chain 5 +

+
+
+
+
+
+
+ +
+
+
+
+
+
+
+

+ Signature request +

+

+ Only confirm this message if you approve the content and trust the requesting site. +

+
+
+
+

+ Request from +

+
+
+ +
+
+
+
+

+ metamask.github.io +

+
+
+
+
+
+
+

+ Message +

+
+
+

+ Example \`personal_sign\` message +

+
+
+
+
+
+ +
+
+
+`; + +exports[`Confirm should match snapshot for signature - typed sign - V4 - PermitBatch 1`] = `
- Test Account -

+ />

- Signature request + Spending cap request

- Only confirm this message if you approve the content and trust the requesting site. + This site wants permission to spend your tokens.

- Request from + Estimated changes

-
-

- metamask.github.io -

-
-
-
-
-
-
-

- Message -

-
-
-

- Example \`personal_sign\` message -

-
+
+

+ You're giving the spender permission to spend this many tokens from your account. +

+
+
+
+
+

+ Spending cap +

+
+
+
+
+
+
+
+
+

+ 14,615,016,373,... +

+
+
+
+
+
+ +

+ 0xA0b86...6eB48 +

+
+
+
+
+
+
+
+
+
+
+

+ 24,615,016,373,... +

+
+
+
+
+
+ +

+ 0xb0B86...6EB48 +

+
+
+
+
+
+
+
+
+
+
+
+
+

+ Spender +

+
+
+
+ +

+ 0x3fC91...b7FAD +

+
+
+
+
+
+
+

+ Request from +

+
+
+ +
+
+
+
+

+ metamask.github.io +

+
+
+
+
+

+ Interacting with +

+
+
+
+ +

+ 0x00000...78BA3 +

+
+
+
+
+
+
+
+

+ Message +

+
+
+
+
+

+ Primary type: +

+
+
+

+ PermitBatch +

+
+
+
+
+
+
+

+ Details: +

+
+
+
+
+

+ 0: +

+
+
+
+
+

+ Token: +

+
+
+
+ +

+ 0xA0b86...6eB48 +

+
+
+
+
+
+

+ Amount: +

+
+
+
+
+

+ 14,615,016,373,... +

+
+
+
+
+
+
+

+ Expiration: +

+
+
+

+ 20 January 1970, 22:34 +

+
+
+
+
+

+ Nonce: +

+
+
+

+ 5 +

+
+
+
+
+
+
+

+ 1: +

+
+
+
+
+

+ Token: +

+
+
+
+ +

+ 0xb0B86...6EB48 +

+
+
+
+
+
+

+ Amount: +

+
+
+
+
+

+ 24,615,016,373,... +

+
+
+
+
+
+
+

+ Expiration: +

+
+
+

+ 20 January 1970, 22:34 +

+
+
+
+
+

+ Nonce: +

+
+
+

+ 6 +

+
+
+
+
+
+
+
+
+

+ Spender: +

+
+
+
+ +

+ 0x3fC91...b7FAD +

+
+
+
+
+
+

+ SigDeadline: +

+
+
+

+ 20 January 1970, 21:51 +

+
+
+
+
+
+
+
+
+
+ +
+
+
+`; + +exports[`Confirm should match snapshot for signature - typed sign - V4 - PermitSingle 1`] = ` +
+
+
+
+
+
+
+
+
+ + + + + +
+
+
+
+ C +
+
+
+

+

+ Chain 5 +

+
+
+
+
+
+
+ +
+
+
+
+
+
+
+

+ Spending cap request +

+

+ This site wants permission to spend your tokens. +

+
+
+
+

+ Estimated changes +

+
+
+ +
+
+
+
+

+ You're giving the spender permission to spend this many tokens from your account. +

+
+
+
+
+

+ Spending cap +

+
+
+
+
+
+
+
+
+

+ 14,615,016,373,... +

+
+
+
+
+
+ +

+ 0xA0b86...6eB48 +

+
+
+
+
+
+
+
+
+
+
+
+
+

+ Spender +

+
+
+
+ +

+ 0x3fC91...b7FAD +

+
+
+
+
+
+
+

+ Request from +

+
+
+ +
+
+
+
+

+ metamask.github.io +

+
+
+
+
+

+ Interacting with +

+
+
+
+ +

+ 0x00000...78BA3 +

+
+
+
+
+
+
+
+

+ Message +

+
+
+
+
+

+ Primary type: +

+
+
+

+ PermitSingle +

+
+
+
+
+
+
+

+ Details: +

+
+
+
+
+

+ Token: +

+
+
+
+ +

+ 0xA0b86...6eB48 +

+
+
+
+
+
+

+ Amount: +

+
+
+
+
+

+ 14,615,016,373,... +

+
+
+
+
+
+
+

+ Expiration: +

+
+
+

+ 20 January 1970, 22:34 +

+
+
+
+
+

+ Nonce: +

+
+
+

+ 5 +

+
+
+
+
+
+
+

+ Spender: +

+
+
+
+ +

+ 0x3fC91...b7FAD +

+
+
+
+
+
+

+ SigDeadline: +

+
+
+

+ 20 January 1970, 21:51 +

+
+
+
+
+
@@ -253,48 +2063,16 @@ exports[`Confirm should match snapshot for signature - typed sign - V4 1`] = `
-
- - - - - -
-
+ />
- C + Chain 5 logo
+ />

+ />

+ />

+ />

+ />

+ />

+ />

-

- 30 -

+

+ 30 +

+
-
-
-
- -

+

- 0xCcCCc...ccccC -

+ +

+ 0xCcCCc...ccccC +

+
+
-
diff --git a/ui/pages/confirmations/confirm/confirm.test.tsx b/ui/pages/confirmations/confirm/confirm.test.tsx index 7182fb7ef165..0b10976ab48c 100644 --- a/ui/pages/confirmations/confirm/confirm.test.tsx +++ b/ui/pages/confirmations/confirm/confirm.test.tsx @@ -6,6 +6,8 @@ import { act } from '@testing-library/react'; import { orderSignatureMsg, permitSignatureMsg, + permitSingleSignatureMsg, + permitBatchSignatureMsg, } from '../../../../test/data/confirmations/typed_sign'; import mockState from '../../../../test/data/mock-state.json'; import { @@ -34,11 +36,14 @@ describe('Confirm', () => { it('should render', () => { const mockStore = configureMockStore(middleware)(mockState); - const { container } = renderWithConfirmContextProvider( - , - mockStore, - ); - expect(container).toBeDefined(); + + act(() => { + const { container } = renderWithConfirmContextProvider( + , + mockStore, + ); + expect(container).toBeDefined(); + }); }); it('should match snapshot for signature - typed sign - permit', async () => { @@ -68,14 +73,17 @@ describe('Confirm', () => { expect(container).toMatchSnapshot(); }); - it('matches snapshot for signature - personal sign type', () => { + it('matches snapshot for signature - personal sign type', async () => { const mockStatePersonalSign = getMockPersonalSignConfirmState(); const mockStore = configureMockStore(middleware)(mockStatePersonalSign); - const { container } = renderWithConfirmContextProvider( - , - mockStore, - ); - expect(container).toMatchSnapshot(); + + await act(async () => { + const { container } = await renderWithConfirmContextProvider( + , + mockStore, + ); + expect(container).toMatchSnapshot(); + }); }); it('should match snapshot signature - typed sign - order', async () => { @@ -110,10 +118,63 @@ describe('Confirm', () => { it('should match snapshot for signature - typed sign - V4', async () => { const mockStateTypedSign = getMockTypedSignConfirmState(); const mockStore = configureMockStore(middleware)(mockStateTypedSign); - const { container } = renderWithConfirmContextProvider( - , - mockStore, + + await act(async () => { + const { container } = await renderWithConfirmContextProvider( + , + mockStore, + ); + expect(container).toMatchSnapshot(); + }); + }); + + it('should match snapshot for signature - typed sign - V4 - PermitSingle', async () => { + const mockStateTypedSign = getMockTypedSignConfirmStateForRequest( + permitSingleSignatureMsg, + { + metamask: { useTransactionSimulations: true }, + }, ); - expect(container).toMatchSnapshot(); + const mockStore = configureMockStore(middleware)(mockStateTypedSign); + + jest.spyOn(actions, 'getTokenStandardAndDetails').mockResolvedValue({ + decimals: '2', + standard: 'erc20', + }); + + await act(async () => { + const { container, findByText } = await renderWithConfirmContextProvider( + , + mockStore, + ); + + expect(await findByText('1,461,501,637,3...')).toBeInTheDocument(); + expect(container).toMatchSnapshot(); + }); + }); + + it('should match snapshot for signature - typed sign - V4 - PermitBatch', async () => { + const mockStateTypedSign = getMockTypedSignConfirmStateForRequest( + permitBatchSignatureMsg, + { + metamask: { useTransactionSimulations: true }, + }, + ); + const mockStore = configureMockStore(middleware)(mockStateTypedSign); + + jest.spyOn(actions, 'getTokenStandardAndDetails').mockResolvedValue({ + decimals: '2', + standard: 'erc20', + }); + + await act(async () => { + const { container, findByText } = await renderWithConfirmContextProvider( + , + mockStore, + ); + + expect(await findByText('1,461,501,637,3...')).toBeInTheDocument(); + expect(container).toMatchSnapshot(); + }); }); });