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

fix: support alerts confirmation page without pending transactions (#18983)

This commit is contained in:
OGPoyraz 2023-05-19 14:13:34 +02:00 committed by GitHub
parent fd8b81def0
commit 99bd28d1d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 971 additions and 22 deletions

View File

@ -6,10 +6,10 @@
// subset of files to check against these targets.
module.exports = {
global: {
lines: 70.26,
branches: 57.91,
statements: 69.59,
functions: 62.97,
lines: 71.12,
branches: 58.94,
statements: 70.58,
functions: 63.84,
},
transforms: {
branches: 100,

View File

@ -91,10 +91,12 @@ const alertStateReducer = produce((state, action) => {
*
* @param {object} pendingConfirmation - a pending confirmation waiting for
* user approval
* @param {object} state - The state object consist of required info to determine alerts.
* @param state.unapprovedTxsCount
* @returns {[alertState: object, dismissAlert: Function]} A tuple with
* the current alert state and function to dismiss an alert by id
*/
function useAlertState(pendingConfirmation) {
function useAlertState(pendingConfirmation, { unapprovedTxsCount } = {}) {
const [alertState, dispatch] = useReducer(alertStateReducer, {});
/**
@ -108,7 +110,8 @@ function useAlertState(pendingConfirmation) {
useEffect(() => {
let isMounted = true;
if (pendingConfirmation) {
getTemplateAlerts(pendingConfirmation).then((alerts) => {
getTemplateAlerts(pendingConfirmation, { unapprovedTxsCount }).then(
(alerts) => {
if (isMounted && alerts.length > 0) {
dispatch({
type: 'set',
@ -116,12 +119,13 @@ function useAlertState(pendingConfirmation) {
alerts,
});
}
});
},
);
}
return () => {
isMounted = false;
};
}, [pendingConfirmation]);
}, [pendingConfirmation, unapprovedTxsCount]);
const dismissAlert = useCallback(
(alertId) => {
@ -169,14 +173,16 @@ export default function ConfirmationPage({
getUnapprovedTemplatedConfirmations,
isEqual,
);
const unapprovedTxsCount = useSelector(getUnapprovedTxCount);
const [currentPendingConfirmation, setCurrentPendingConfirmation] =
useState(0);
const pendingConfirmation = pendingConfirmations[currentPendingConfirmation];
const originMetadata = useOriginMetadata(pendingConfirmation?.origin) || {};
const [alertState, dismissAlert] = useAlertState(pendingConfirmation);
const [alertState, dismissAlert] = useAlertState(pendingConfirmation, {
unapprovedTxsCount,
});
const [templateState] = useTemplateState(pendingConfirmation);
const [showWarningModal, setShowWarningModal] = useState(false);
const unnaprovedTxsCount = useSelector(getUnapprovedTxCount);
const [inputStates, setInputStates] = useState({});
const setInputState = (key, value) => {
@ -385,7 +391,6 @@ export default function ConfirmationPage({
<ConfirmationFooter
alerts={
alertState[pendingConfirmation.id] &&
unnaprovedTxsCount > 0 &&
Object.values(alertState[pendingConfirmation.id])
.filter((alert) => alert.dismissed === false)
.map((alert, idx, filtered) => (

View File

@ -0,0 +1,489 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`add-ethereum-chain confirmation should match snapshot 1`] = `
<div>
<div
class="confirmation-page"
>
<div
class="confirmation-page__content"
>
<div
class="box box--margin-top-2 box--flex-direction-row box--justify-content-center box--display-flex"
>
<div
class="network-display chip chip--with-left-icon chip--border-color-border-muted chip--background-color-undefined chip--max-content"
data-testid="network-display"
>
<div
class="chip__left-icon"
>
<span
class="loading-indicator"
>
<img
alt="Attempting to connect to blockchain."
class="loading-indicator__spinner"
src="images/loading.svg"
title="Attempting to connect to blockchain."
/>
</span>
</div>
<span
class="box box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography chip__label typography--h7 typography--weight-normal typography--style-normal typography--color-text-default"
>
Test initial state
</span>
</div>
</div>
<h3
class="box box--md:margin-4 box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography typography--h3 typography--weight-bold typography--style-normal typography--align-center typography--color-text-default"
>
Allow this site to add a network?
</h3>
<h6
class="box box--md:margin-4 box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography typography--h7 typography--weight-normal typography--style-normal typography--align-center typography--color-text-default"
>
This will allow this network to be used within MetaMask.
</h6>
<h6
class="box box--margin-top-1 box--margin-bottom-1 box--display-flex box--flex-direction-column box--align-items-center typography typography--h7 typography--weight-normal typography--style-normal typography--color-text-default"
>
<b>
MetaMask does not verify custom networks.
</b>
<span>
Learn about
<a
href="https://metamask.zendesk.com/hc/en-us/articles/4404424659995"
target="__blank"
>
scams and network security risks
</a>
.
</span>
</h6>
<div
class="box box--margin-6 box--padding-4 box--padding-bottom-3 box--flex-direction-row box--rounded-lg box--border-color-border-muted box--border-style-solid box--border-width-1"
>
<dl
class="definition-list"
>
<dt
class="box box--margin-bottom-1 box--flex-direction-row typography definition-list__term typography--h6 typography--weight-bold typography--style-normal typography--color-text-default"
>
Network name
<div>
<div
aria-describedby="tippy-tooltip-1"
class="definition-list__tooltip-wrapper"
data-original-title="The name associated with this network."
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<span
class="box mm-icon mm-icon--size-sm box--margin-left-1 box--display-inline-block box--flex-direction-row box--color-icon-default"
style="mask-image: url('./images/icons/info.svg');"
/>
</div>
</div>
</dt>
<dd
class="box box--margin-bottom-2 box--flex-direction-row typography definition-list__definition typography--h6 typography--weight-normal typography--style-normal typography--color-text-alternative typography--overflowwrap-break-word"
>
Test chain
</dd>
<dt
class="box box--margin-bottom-1 box--flex-direction-row typography definition-list__term typography--h6 typography--weight-bold typography--style-normal typography--color-text-default"
>
Network URL
<div>
<div
aria-describedby="tippy-tooltip-2"
class="definition-list__tooltip-wrapper"
data-original-title="The URL used to access this network."
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<span
class="box mm-icon mm-icon--size-sm box--margin-left-1 box--display-inline-block box--flex-direction-row box--color-icon-default"
style="mask-image: url('./images/icons/info.svg');"
/>
</div>
</div>
</dt>
<dd
class="box box--margin-bottom-2 box--flex-direction-row typography definition-list__definition typography--h6 typography--weight-normal typography--style-normal typography--color-text-alternative typography--overflowwrap-break-word"
>
https://rpcurl.test.chain
</dd>
<dt
class="box box--margin-bottom-1 box--flex-direction-row typography definition-list__term typography--h6 typography--weight-bold typography--style-normal typography--color-text-default"
>
Chain ID
<div>
<div
aria-describedby="tippy-tooltip-3"
class="definition-list__tooltip-wrapper"
data-original-title="The chain ID used to sign transactions for this network."
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<span
class="box mm-icon mm-icon--size-sm box--margin-left-1 box--display-inline-block box--flex-direction-row box--color-icon-default"
style="mask-image: url('./images/icons/info.svg');"
/>
</div>
</div>
</dt>
<dd
class="box box--margin-bottom-2 box--flex-direction-row typography definition-list__definition typography--h6 typography--weight-normal typography--style-normal typography--color-text-alternative typography--overflowwrap-break-word"
>
39321
</dd>
<dt
class="box box--margin-bottom-1 box--flex-direction-row typography definition-list__term typography--h6 typography--weight-bold typography--style-normal typography--color-text-default"
>
Currency symbol
<div>
<div
aria-describedby="tippy-tooltip-4"
class="definition-list__tooltip-wrapper"
data-original-title="The ticker symbol displayed for this networks currency."
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<span
class="box mm-icon mm-icon--size-sm box--margin-left-1 box--display-inline-block box--flex-direction-row box--color-icon-default"
style="mask-image: url('./images/icons/info.svg');"
/>
</div>
</div>
</dt>
<dd
class="box box--margin-bottom-2 box--flex-direction-row typography definition-list__definition typography--h6 typography--weight-normal typography--style-normal typography--color-text-alternative typography--overflowwrap-break-word"
>
TST
</dd>
</dl>
<a
class="button btn-link truncated-definition-list__view-more"
role="button"
tabindex="0"
>
View all details
</a>
</div>
</div>
<div
class="confirmation-footer"
>
<div
class="confirmation-footer__actions"
>
<button
class="button btn--rounded btn-secondary"
role="button"
tabindex="0"
>
Cancel
</button>
<button
class="button btn--rounded btn-primary"
role="button"
tabindex="0"
>
Approve
</button>
</div>
</div>
</div>
</div>
`;
exports[`add-ethereum-chain confirmation should match snapshot 2`] = `
<div>
<div
class="confirmation-page"
>
<div
class="confirmation-page__content"
>
<div
class="box box--margin-top-2 box--flex-direction-row box--justify-content-center box--display-flex"
>
<div
class="network-display chip chip--with-left-icon chip--border-color-border-muted chip--background-color-undefined chip--max-content"
data-testid="network-display"
>
<div
class="chip__left-icon"
>
<span
class="loading-indicator"
>
<img
alt="Attempting to connect to blockchain."
class="loading-indicator__spinner"
src="images/loading.svg"
title="Attempting to connect to blockchain."
/>
</span>
</div>
<span
class="box box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography chip__label typography--h7 typography--weight-normal typography--style-normal typography--color-text-default"
>
Test initial state
</span>
</div>
</div>
<h3
class="box box--md:margin-4 box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography typography--h3 typography--weight-bold typography--style-normal typography--align-center typography--color-text-default"
>
Allow this site to add a network?
</h3>
<h6
class="box box--md:margin-4 box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography typography--h7 typography--weight-normal typography--style-normal typography--align-center typography--color-text-default"
>
This will allow this network to be used within MetaMask.
</h6>
<h6
class="box box--margin-top-1 box--margin-bottom-1 box--display-flex box--flex-direction-column box--align-items-center typography typography--h7 typography--weight-normal typography--style-normal typography--color-text-default"
>
<b>
MetaMask does not verify custom networks.
</b>
<span>
Learn about
<a
href="https://metamask.zendesk.com/hc/en-us/articles/4404424659995"
target="__blank"
>
scams and network security risks
</a>
.
</span>
</h6>
<div
class="box box--margin-6 box--padding-4 box--padding-bottom-3 box--flex-direction-row box--rounded-lg box--border-color-border-muted box--border-style-solid box--border-width-1"
>
<dl
class="definition-list"
>
<dt
class="box box--margin-bottom-1 box--flex-direction-row typography definition-list__term typography--h6 typography--weight-bold typography--style-normal typography--color-text-default"
>
Network name
<div>
<div
aria-describedby="tippy-tooltip-1"
class="definition-list__tooltip-wrapper"
data-original-title="The name associated with this network."
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<span
class="box mm-icon mm-icon--size-sm box--margin-left-1 box--display-inline-block box--flex-direction-row box--color-icon-default"
style="mask-image: url('./images/icons/info.svg');"
/>
</div>
</div>
</dt>
<dd
class="box box--margin-bottom-2 box--flex-direction-row typography definition-list__definition typography--h6 typography--weight-normal typography--style-normal typography--color-text-alternative typography--overflowwrap-break-word"
>
Test chain
</dd>
<dt
class="box box--margin-bottom-1 box--flex-direction-row typography definition-list__term typography--h6 typography--weight-bold typography--style-normal typography--color-text-default"
>
Network URL
<div>
<div
aria-describedby="tippy-tooltip-2"
class="definition-list__tooltip-wrapper"
data-original-title="The URL used to access this network."
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<span
class="box mm-icon mm-icon--size-sm box--margin-left-1 box--display-inline-block box--flex-direction-row box--color-icon-default"
style="mask-image: url('./images/icons/info.svg');"
/>
</div>
</div>
</dt>
<dd
class="box box--margin-bottom-2 box--flex-direction-row typography definition-list__definition typography--h6 typography--weight-normal typography--style-normal typography--color-text-alternative typography--overflowwrap-break-word"
>
https://rpcurl.test.chain
</dd>
<dt
class="box box--margin-bottom-1 box--flex-direction-row typography definition-list__term typography--h6 typography--weight-bold typography--style-normal typography--color-text-default"
>
Chain ID
<div>
<div
aria-describedby="tippy-tooltip-3"
class="definition-list__tooltip-wrapper"
data-original-title="The chain ID used to sign transactions for this network."
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<span
class="box mm-icon mm-icon--size-sm box--margin-left-1 box--display-inline-block box--flex-direction-row box--color-icon-default"
style="mask-image: url('./images/icons/info.svg');"
/>
</div>
</div>
</dt>
<dd
class="box box--margin-bottom-2 box--flex-direction-row typography definition-list__definition typography--h6 typography--weight-normal typography--style-normal typography--color-text-alternative typography--overflowwrap-break-word"
>
39321
</dd>
<dt
class="box box--margin-bottom-1 box--flex-direction-row typography definition-list__term typography--h6 typography--weight-bold typography--style-normal typography--color-text-default"
>
Currency symbol
<div>
<div
aria-describedby="tippy-tooltip-4"
class="definition-list__tooltip-wrapper"
data-original-title="The ticker symbol displayed for this networks currency."
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<span
class="box mm-icon mm-icon--size-sm box--margin-left-1 box--display-inline-block box--flex-direction-row box--color-icon-default"
style="mask-image: url('./images/icons/info.svg');"
/>
</div>
</div>
</dt>
<dd
class="box box--margin-bottom-2 box--flex-direction-row typography definition-list__definition typography--h6 typography--weight-normal typography--style-normal typography--color-text-alternative typography--overflowwrap-break-word"
>
TST
</dd>
</dl>
<a
class="button btn-link truncated-definition-list__view-more"
role="button"
tabindex="0"
>
View all details
</a>
</div>
</div>
<div
class="confirmation-footer"
>
<div
class="callout callout--warning callout--multiple callout--dismissible callout--first"
>
<svg
class="info-icon info-icon--warning"
fill="none"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M15.75 8C15.75 3.75 12.25 0.25 8 0.25C3.71875 0.25 0.25 3.75 0.25 8C0.25 12.2812 3.71875 15.75 8 15.75C12.25 15.75 15.75 12.2812 15.75 8ZM8 9.5625C8.78125 9.5625 9.4375 10.2188 9.4375 11C9.4375 11.8125 8.78125 12.4375 8 12.4375C7.1875 12.4375 6.5625 11.8125 6.5625 11C6.5625 10.2188 7.1875 9.5625 8 9.5625ZM6.625 4.40625C6.59375 4.1875 6.78125 4 7 4H8.96875C9.1875 4 9.375 4.1875 9.34375 4.40625L9.125 8.65625C9.09375 8.875 8.9375 9 8.75 9H7.21875C7.03125 9 6.875 8.875 6.84375 8.65625L6.625 4.40625Z"
/>
</svg>
<p
class="box box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography callout__content typography--p typography--weight-normal typography--style-normal typography--color-text-default"
>
<span>
This custom network is not recognized
</span>
</p>
<button
class="box mm-button-icon mm-button-icon--size-sm callout__close-button box--display-inline-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/close.svg');"
/>
</button>
</div>
<div
class="callout callout--warning callout--multiple callout--dismissible callout--last"
>
<svg
class="info-icon info-icon--warning"
fill="none"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M15.75 8C15.75 3.75 12.25 0.25 8 0.25C3.71875 0.25 0.25 3.75 0.25 8C0.25 12.2812 3.71875 15.75 8 15.75C12.25 15.75 15.75 12.2812 15.75 8ZM8 9.5625C8.78125 9.5625 9.4375 10.2188 9.4375 11C9.4375 11.8125 8.78125 12.4375 8 12.4375C7.1875 12.4375 6.5625 11.8125 6.5625 11C6.5625 10.2188 7.1875 9.5625 8 9.5625ZM6.625 4.40625C6.59375 4.1875 6.78125 4 7 4H8.96875C9.1875 4 9.375 4.1875 9.34375 4.40625L9.125 8.65625C9.09375 8.875 8.9375 9 8.75 9H7.21875C7.03125 9 6.875 8.875 6.84375 8.65625L6.625 4.40625Z"
/>
</svg>
<p
class="box box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography callout__content typography--p typography--weight-normal typography--style-normal typography--color-text-default"
>
<span>
<span>
We recommend that you
<a
href="https://metamask.zendesk.com/hc/en-us/articles/360057142392"
tabindex="0"
target="__blank"
>
verify the network details
</a>
before proceeding.
</span>
</span>
</p>
<button
class="box mm-button-icon mm-button-icon--size-sm callout__close-button box--display-inline-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/close.svg');"
/>
</button>
</div>
<div
class="confirmation-footer__actions"
>
<button
class="button btn--rounded btn-secondary"
role="button"
tabindex="0"
>
Cancel
</button>
<button
class="button btn--rounded btn-primary"
role="button"
tabindex="0"
>
Approve
</button>
</div>
</div>
</div>
</div>
`;

View File

@ -0,0 +1,280 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`switch-ethereum-chain confirmation should match snapshot 1`] = `
<div>
<div
class="confirmation-page"
>
<div
class="confirmation-page__content"
>
<div
class="box box--margin-top-2 box--flex-direction-row box--justify-content-center box--display-flex"
>
<div
class="network-display chip chip--with-left-icon chip--border-color-border-muted chip--background-color-undefined chip--max-content"
data-testid="network-display"
>
<div
class="chip__left-icon"
>
<span
class="loading-indicator"
>
<img
alt="Attempting to connect to blockchain."
class="loading-indicator__spinner"
src="images/loading.svg"
title="Attempting to connect to blockchain."
/>
</span>
</div>
<span
class="box box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography chip__label typography--h7 typography--weight-normal typography--style-normal typography--color-text-default"
>
Test initial state
</span>
</div>
</div>
<h3
class="box box--md:margin-2 box--margin-top-1 box--margin-bottom-1 box--sm:padding-4 box--lg:padding-4 box--flex-direction-row typography typography--h3 typography--weight-normal typography--style-normal typography--align-center typography--color-text-default"
>
Allow this site to switch the network?
</h3>
<h6
class="box box--margin-top-1 box--margin-bottom-1 box--sm:padding-4 box--lg:padding-4 box--flex-direction-row typography typography--h7 typography--weight-normal typography--style-normal typography--align-center typography--color-text-alternative"
>
This will switch the selected network within MetaMask to a previously added network:
</h6>
<div
class="box box--flex-direction-row box--justify-content-center box--display-flex"
>
<div
class="box confirmation-network-switch box--margin-top-8 box--display-flex box--flex-direction-row box--justify-content-center box--height-full"
>
<div
class="box confirmation-network-switch__icon box--display-block box--flex-direction-row"
>
<div
class="confirmation-network-switch__unknown-icon"
>
<i
class="fa fa-question fa-2x"
/>
</div>
<h6
class="box box--margin-top-1 box--margin-bottom-1 box--display-flex box--flex-direction-row box--justify-content-center typography typography--h6 typography--weight-normal typography--style-normal typography--align-center typography--color-text-default"
>
Test initial state
</h6>
</div>
<div
class="box confirmation-network-switch__center-icon box--display-flex box--flex-direction-row box--justify-content-center box--align-items-center"
>
<i
class="fa fa-angle-right fa-lg confirmation-network-switch__check"
/>
<div
class="confirmation-network-switch__dashed-line"
/>
</div>
<div
class="box confirmation-network-switch__icon box--display-block box--flex-direction-row"
>
<div
class="confirmation-network-switch__unknown-icon"
>
<i
class="fa fa-question fa-2x"
/>
</div>
<h6
class="box box--margin-top-1 box--margin-bottom-1 box--display-flex box--flex-direction-row box--justify-content-center typography typography--h6 typography--weight-normal typography--style-normal typography--align-center typography--color-text-default"
>
Test chain
</h6>
</div>
</div>
</div>
</div>
<div
class="confirmation-footer"
>
<div
class="confirmation-footer__actions"
>
<button
class="button btn--rounded btn-secondary"
role="button"
tabindex="0"
>
Cancel
</button>
<button
class="button btn--rounded btn-primary"
role="button"
tabindex="0"
>
Switch network
</button>
</div>
</div>
</div>
</div>
`;
exports[`switch-ethereum-chain confirmation should match snapshot 2`] = `<div />`;
exports[`switch-ethereum-chain confirmation should show alert if there are pending txs 1`] = `
<div>
<div
class="confirmation-page"
>
<div
class="confirmation-page__content"
>
<div
class="box box--margin-top-2 box--flex-direction-row box--justify-content-center box--display-flex"
>
<div
class="network-display chip chip--with-left-icon chip--border-color-border-muted chip--background-color-undefined chip--max-content"
data-testid="network-display"
>
<div
class="chip__left-icon"
>
<span
class="loading-indicator"
>
<img
alt="Attempting to connect to blockchain."
class="loading-indicator__spinner"
src="images/loading.svg"
title="Attempting to connect to blockchain."
/>
</span>
</div>
<span
class="box box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography chip__label typography--h7 typography--weight-normal typography--style-normal typography--color-text-default"
>
Test initial state
</span>
</div>
</div>
<h3
class="box box--md:margin-2 box--margin-top-1 box--margin-bottom-1 box--sm:padding-4 box--lg:padding-4 box--flex-direction-row typography typography--h3 typography--weight-normal typography--style-normal typography--align-center typography--color-text-default"
>
Allow this site to switch the network?
</h3>
<h6
class="box box--margin-top-1 box--margin-bottom-1 box--sm:padding-4 box--lg:padding-4 box--flex-direction-row typography typography--h7 typography--weight-normal typography--style-normal typography--align-center typography--color-text-alternative"
>
This will switch the selected network within MetaMask to a previously added network:
</h6>
<div
class="box box--flex-direction-row box--justify-content-center box--display-flex"
>
<div
class="box confirmation-network-switch box--margin-top-8 box--display-flex box--flex-direction-row box--justify-content-center box--height-full"
>
<div
class="box confirmation-network-switch__icon box--display-block box--flex-direction-row"
>
<div
class="confirmation-network-switch__unknown-icon"
>
<i
class="fa fa-question fa-2x"
/>
</div>
<h6
class="box box--margin-top-1 box--margin-bottom-1 box--display-flex box--flex-direction-row box--justify-content-center typography typography--h6 typography--weight-normal typography--style-normal typography--align-center typography--color-text-default"
>
Test initial state
</h6>
</div>
<div
class="box confirmation-network-switch__center-icon box--display-flex box--flex-direction-row box--justify-content-center box--align-items-center"
>
<i
class="fa fa-angle-right fa-lg confirmation-network-switch__check"
/>
<div
class="confirmation-network-switch__dashed-line"
/>
</div>
<div
class="box confirmation-network-switch__icon box--display-block box--flex-direction-row"
>
<div
class="confirmation-network-switch__unknown-icon"
>
<i
class="fa fa-question fa-2x"
/>
</div>
<h6
class="box box--margin-top-1 box--margin-bottom-1 box--display-flex box--flex-direction-row box--justify-content-center typography typography--h6 typography--weight-normal typography--style-normal typography--align-center typography--color-text-default"
>
Test chain
</h6>
</div>
</div>
</div>
</div>
<div
class="confirmation-footer"
>
<div
class="callout callout--warning callout--dismissible callout--first callout--last"
>
<svg
class="info-icon info-icon--warning"
fill="none"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M15.75 8C15.75 3.75 12.25 0.25 8 0.25C3.71875 0.25 0.25 3.75 0.25 8C0.25 12.2812 3.71875 15.75 8 15.75C12.25 15.75 15.75 12.2812 15.75 8ZM8 9.5625C8.78125 9.5625 9.4375 10.2188 9.4375 11C9.4375 11.8125 8.78125 12.4375 8 12.4375C7.1875 12.4375 6.5625 11.8125 6.5625 11C6.5625 10.2188 7.1875 9.5625 8 9.5625ZM6.625 4.40625C6.59375 4.1875 6.78125 4 7 4H8.96875C9.1875 4 9.375 4.1875 9.34375 4.40625L9.125 8.65625C9.09375 8.875 8.9375 9 8.75 9H7.21875C7.03125 9 6.875 8.875 6.84375 8.65625L6.625 4.40625Z"
/>
</svg>
<p
class="box box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography callout__content typography--p typography--weight-normal typography--style-normal typography--color-text-default"
>
<span>
Switching networks will cancel all pending confirmations
</span>
</p>
<button
class="box mm-button-icon mm-button-icon--size-sm callout__close-button box--display-inline-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/close.svg');"
/>
</button>
</div>
<div
class="confirmation-footer__actions"
>
<button
class="button btn--rounded btn-secondary"
role="button"
tabindex="0"
>
Cancel
</button>
<button
class="button btn--rounded btn-primary"
role="button"
tabindex="0"
>
Switch network
</button>
</div>
</div>
</div>
</div>
`;

View File

@ -32,6 +32,7 @@ const UNRECOGNIZED_CHAIN = {
const MISMATCHED_CHAIN_RECOMMENDATION = {
id: 'MISMATCHED_CHAIN_RECOMMENDATION',
severity: SEVERITIES.WARNING,
content: {
element: 'span',
children: {

View File

@ -0,0 +1,72 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { waitFor } from '@testing-library/react';
import { renderWithProvider } from '../../../../test/lib/render-helpers';
import { MESSAGE_TYPE } from '../../../../shared/constants/app';
import Confirmation from '../confirmation';
jest.mock('../../../../shared/lib/fetch-with-cache');
const middleware = [thunk];
const mockApprovalId = 1;
const mockApproval = {
id: mockApprovalId,
origin: 'https://test-dapp.metamask.io',
requestData: {
rpcUrl: 'https://rpcurl.test.chain',
rpcPrefs: {
blockExplorerUrl: 'https://blockexplorer.test.chain',
},
chainName: 'Test chain',
ticker: 'TST',
chainId: '0x9999',
nickname: 'Test chain',
},
};
const mockBaseStore = {
metamask: {
pendingApprovals: {
[mockApprovalId]: mockApproval,
},
subjectMetadata: {},
providerConfig: {
type: 'rpc',
rpcUrl: 'http://example-custom-rpc.metamask.io',
chainId: '0x9999',
nickname: 'Test initial state',
},
},
};
describe('add-ethereum-chain confirmation', () => {
it('should match snapshot', async () => {
const testStore = {
metamask: {
...mockBaseStore.metamask,
pendingApprovals: {
[mockApprovalId]: {
...mockApproval,
type: MESSAGE_TYPE.ADD_ETHEREUM_CHAIN,
},
},
},
};
const store = configureMockStore(middleware)(testStore);
const { container, getByText } = renderWithProvider(
<Confirmation />,
store,
);
await waitFor(() => {
expect(
getByText('MetaMask does not verify custom networks.'),
).toBeInTheDocument();
expect(container.querySelector('.callout')).toBeDefined();
expect(container).toMatchSnapshot();
});
});
});

View File

@ -53,10 +53,11 @@ const ALLOWED_TEMPLATE_KEYS = [
* alertState state object.
*
* @param {object} pendingApproval - the object representing the confirmation
* @param {object} state - The state object consist of required info to determine alerts.
*/
export async function getTemplateAlerts(pendingApproval) {
export async function getTemplateAlerts(pendingApproval, state) {
const fn = APPROVAL_TEMPLATES[pendingApproval.type]?.getAlerts;
const results = fn ? await fn(pendingApproval) : [];
const results = fn ? await fn(pendingApproval, state) : [];
if (!Array.isArray(results)) {
throw new Error(`Template alerts must be an array, received: ${results}`);
}

View File

@ -20,8 +20,12 @@ const PENDING_TX_DROP_NOTICE = {
},
};
async function getAlerts() {
return [PENDING_TX_DROP_NOTICE];
async function getAlerts(_pendingApproval, state) {
const alerts = [];
if (state.unapprovedTxsCount > 0) {
alerts.push(PENDING_TX_DROP_NOTICE);
}
return alerts;
}
function getValues(pendingApproval, t, actions) {

View File

@ -0,0 +1,97 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { waitFor } from '@testing-library/react';
import { renderWithProvider } from '../../../../test/lib/render-helpers';
import { MESSAGE_TYPE } from '../../../../shared/constants/app';
import Confirmation from '../confirmation';
jest.mock('../../../../shared/lib/fetch-with-cache');
const middleware = [thunk];
const mockApprovalId = 1;
const mockApproval = {
id: mockApprovalId,
origin: 'https://test-dapp.metamask.io',
requestData: {
rpcUrl: 'https://rpcurl.test.chain',
rpcPrefs: {
blockExplorerUrl: 'https://blockexplorer.test.chain',
},
chainName: 'Test chain',
ticker: 'TST',
chainId: '0x9999',
nickname: 'Test chain',
},
};
const mockBaseStore = {
metamask: {
pendingApprovals: {
[mockApprovalId]: mockApproval,
},
subjectMetadata: {},
providerConfig: {
type: 'rpc',
rpcUrl: 'http://example-custom-rpc.metamask.io',
chainId: '0x9999',
nickname: 'Test initial state',
},
},
};
describe('switch-ethereum-chain confirmation', () => {
it('should match snapshot', async () => {
const testStore = {
metamask: {
...mockBaseStore.metamask,
pendingApprovals: {
[mockApprovalId]: {
...mockApproval,
type: MESSAGE_TYPE.SWITCH_ETHEREUM_CHAIN,
},
},
},
};
const store = configureMockStore(middleware)(testStore);
const { container } = renderWithProvider(<Confirmation />, store);
await waitFor(() => {
expect(container.querySelector('.callout')).toBeFalsy();
expect(container).toMatchSnapshot();
});
});
it('should show alert if there are pending txs', async () => {
const testStore = {
metamask: {
...mockBaseStore.metamask,
pendingApprovals: {
[mockApprovalId]: {
...mockApproval,
type: MESSAGE_TYPE.SWITCH_ETHEREUM_CHAIN,
},
},
unapprovedTxs: {
1: {
id: 1,
},
},
},
};
const store = configureMockStore(middleware)(testStore);
const { getByText, container } = renderWithProvider(
<Confirmation />,
store,
);
await waitFor(() => {
expect(
getByText('Switching networks will cancel all pending confirmations'),
).toBeInTheDocument();
expect(container).toMatchSnapshot();
});
});
});