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

[MMI] Add the custody status text in the transaction status (#18797)

* Added code fences

* Added code fencing

* Improved code readable and added more tests

* Improved tests

* Remove code from other PR

* Fixing code fences
This commit is contained in:
Albert Olivé 2023-04-28 13:41:16 +02:00 committed by GitHub
parent d6bf3c133f
commit b695901ff4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 225 additions and 9 deletions

View File

@ -15,7 +15,7 @@ exports[`TransactionStatusLabel Component should render PENDING properly 1`] = `
<div
class="transaction-status-label transaction-status-label--pending transaction-status-label--pending"
>
[pending]
Pending
</div>
</div>
`;
@ -33,7 +33,7 @@ exports[`TransactionStatusLabel Component should render PENDING properly when st
style="display: inline;"
tabindex="0"
>
[pending]
Pending
</div>
</div>
</div>
@ -44,7 +44,7 @@ exports[`TransactionStatusLabel Component should render QUEUED properly 1`] = `
<div
class="transaction-status-label transaction-status-label--queued transaction-status-label--queued"
>
[queued]
Queued
</div>
</div>
`;
@ -54,7 +54,7 @@ exports[`TransactionStatusLabel Component should render UNAPPROVED properly 1`]
<div
class="transaction-status-label transaction-status-label--unapproved transaction-status-label--unapproved"
>
[unapproved]
Unapproved
</div>
</div>
`;

View File

@ -1,6 +1,9 @@
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
import { useSelector } from 'react-redux';
///: END:ONLY_INCLUDE_IN
import Tooltip from '../../ui/tooltip';
import { useI18nContext } from '../../../hooks/useI18nContext';
@ -9,7 +12,15 @@ import {
TransactionStatus,
} from '../../../../shared/constants/transaction';
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
import { getTransactionStatusMap } from '../../../selectors/institutional/selectors';
import { getCurrentKeyring } from '../../../selectors';
///: END:ONLY_INCLUDE_IN
const QUEUED_PSEUDO_STATUS = 'queued';
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
const CUSTODIAN_PSEUDO_STATUS = 'inCustody';
///: END:ONLY_INCLUDE_IN
/**
* A note about status logic for this component:
@ -35,6 +46,9 @@ const statusToClassNameHash = {
[TransactionGroupStatus.cancelled]: 'transaction-status-label--cancelled',
[QUEUED_PSEUDO_STATUS]: 'transaction-status-label--queued',
[TransactionGroupStatus.pending]: 'transaction-status-label--pending',
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
[CUSTODIAN_PSEUDO_STATUS]: 'transaction-status--custodian',
///: END:ONLY_INCLUDE_IN
};
export default function TransactionStatusLabel({
@ -44,9 +58,13 @@ export default function TransactionStatusLabel({
isEarliestNonce,
className,
statusOnly,
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
custodyStatus,
custodyStatusDisplayText,
///: END:ONLY_INCLUDE_IN
}) {
const t = useI18nContext();
const tooltipText = error?.rpc?.message || error?.message;
let tooltipText = error?.rpc?.message || error?.message;
let statusKey = status;
if (pendingStatusHash[status]) {
statusKey = isEarliestNonce
@ -54,10 +72,43 @@ export default function TransactionStatusLabel({
: QUEUED_PSEUDO_STATUS;
}
const statusText =
statusKey === TransactionStatus.confirmed && !statusOnly
? date
: statusKey && t(statusKey);
let statusText = statusKey && t(statusKey);
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
statusText = custodyStatusDisplayText || t(statusKey);
///: END:ONLY_INCLUDE_IN
if (statusKey === TransactionStatus.confirmed && !statusOnly) {
statusText = date;
}
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
const transactionStatusMap = useSelector(getTransactionStatusMap);
const currentKeyring = useSelector(getCurrentKeyring);
const custodyType = currentKeyring?.type.split(' - ')[1]?.toLowerCase();
if (
custodyStatus &&
transactionStatusMap &&
transactionStatusMap[custodyType]
) {
const custodyStatusInfo = transactionStatusMap[custodyType][custodyStatus];
const shortText = custodyStatusInfo?.shortText || custodyStatus;
const longText = custodyStatusInfo?.longText;
if (error) {
tooltipText = error.message;
statusText =
custodyStatus === 'aborted'
? custodyStatusDisplayText
: t('snapResultError');
} else {
tooltipText = custodyStatusDisplayText || longText || custodyStatus;
statusText = custodyStatusDisplayText || shortText;
}
}
///: END:ONLY_INCLUDE_IN
return (
<Tooltip
@ -82,4 +133,8 @@ TransactionStatusLabel.propTypes = {
error: PropTypes.object,
isEarliestNonce: PropTypes.bool,
statusOnly: PropTypes.bool,
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
custodyStatus: PropTypes.string,
custodyStatusDisplayText: PropTypes.string,
///: END:ONLY_INCLUDE_IN
};

View File

@ -1,8 +1,20 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { renderWithProvider } from '../../../../test/lib/render-helpers';
import TransactionStatusLabel from '.';
describe('TransactionStatusLabel Component', () => {
const createMockStore = configureMockStore([thunk]);
const mockState = {
metamask: {
custodyStatusMaps: {},
identities: {},
selectedAddress: 'fakeAddress',
},
};
let store = createMockStore(mockState);
it('should render CONFIRMED properly', () => {
const confirmedProps = {
status: 'confirmed',
@ -11,6 +23,7 @@ describe('TransactionStatusLabel Component', () => {
const { container } = renderWithProvider(
<TransactionStatusLabel {...confirmedProps} />,
store,
);
expect(container).toMatchSnapshot();
@ -25,6 +38,7 @@ describe('TransactionStatusLabel Component', () => {
const { container } = renderWithProvider(
<TransactionStatusLabel {...props} />,
store,
);
expect(container).toMatchSnapshot();
@ -39,6 +53,7 @@ describe('TransactionStatusLabel Component', () => {
const { container } = renderWithProvider(
<TransactionStatusLabel {...props} />,
store,
);
expect(container).toMatchSnapshot();
@ -51,6 +66,7 @@ describe('TransactionStatusLabel Component', () => {
const { container } = renderWithProvider(
<TransactionStatusLabel {...props} />,
store,
);
expect(container).toMatchSnapshot();
@ -63,8 +79,153 @@ describe('TransactionStatusLabel Component', () => {
const { container } = renderWithProvider(
<TransactionStatusLabel {...props} />,
store,
);
expect(container).toMatchSnapshot();
});
it('should render statusText properly when is custodyStatusDisplayText is defined', () => {
const props = {
custodyStatusDisplayText: 'test',
};
const { getByText } = renderWithProvider(
<TransactionStatusLabel {...props} />,
store,
);
expect(getByText(props.custodyStatusDisplayText)).toBeVisible();
});
it('should display the correct status text and tooltip', () => {
const mockShortText = 'Short Text Test';
const mockLongText = 'Long Text Test';
const props = {
status: 'approved',
custodyStatus: 'approved',
};
const customMockStore = {
metamask: {
custodyStatusMaps: {
jupiter: {
approved: {
shortText: mockShortText,
longText: mockLongText,
},
},
},
selectedAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
identities: {
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': {
address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
name: 'Account 1',
},
},
keyrings: [
{
type: 'Custody - Jupiter',
accounts: ['0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'],
},
],
},
};
store = createMockStore(customMockStore);
const { getByText } = renderWithProvider(
<TransactionStatusLabel {...props} />,
store,
);
expect(getByText(mockShortText)).toBeVisible();
});
it('should display the error message when there is an error', () => {
const mockShortText = 'Short Text Test';
const mockLongText = 'Long Text Test';
const props = {
status: 'approved',
custodyStatus: 'approved',
error: { message: 'An error occurred' },
};
const customMockStore = {
metamask: {
custodyStatusMaps: {
jupiter: {
approved: {
shortText: mockShortText,
longText: mockLongText,
},
},
},
selectedAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
identities: {
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': {
address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
name: 'Account 1',
},
},
keyrings: [
{
type: 'Custody - Jupiter',
accounts: ['0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'],
},
],
},
};
store = createMockStore(customMockStore);
const { getByText } = renderWithProvider(
<TransactionStatusLabel {...props} />,
store,
);
expect(getByText('Error')).toBeVisible();
});
it('should display correctly the error message when there is an error and custodyStatus is aborted', () => {
const mockShortText = 'Short Text Test';
const mockLongText = 'Long Text Test';
const props = {
status: 'approved',
custodyStatus: 'aborted',
error: { message: 'An error occurred' },
custodyStatusDisplayText: 'Test',
};
const customMockStore = {
metamask: {
custodyStatusMaps: {
jupiter: {
approved: {
shortText: mockShortText,
longText: mockLongText,
},
},
},
selectedAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
identities: {
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': {
address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
name: 'Account 1',
},
},
keyrings: [
{
type: 'Custody - Jupiter',
accounts: ['0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'],
},
],
},
};
store = createMockStore(customMockStore);
const { getByText } = renderWithProvider(
<TransactionStatusLabel {...props} />,
store,
);
expect(getByText(props.custodyStatusDisplayText)).toBeVisible();
});
});