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

Swaps: Show a network name dynamically in a tooltip (#10882)

* Swaps: Show a network name dynamically in a tooltip

* Replace “Ethereum” with “$1”, change “Test” to “Testnet”

* Replace 이더리움 with $1

* Translate network names, use ‘Ethereum’ by default if a translation is not available yet

* Reorder messages to resolve ESLint issues

* Add a snapshot test for the FeeCard component, increase Jest threshold

* Enable snapshot testing into external .snap files in ESLint

* Add the “networkNameEthereum” key in ko/messages.json, remove default “Ethereum” value

* Throw an error if chain ID is not supported by the Swaps feature

* Use string literals when calling the `t` fn,
This commit is contained in:
Daniel 2021-04-16 14:52:32 -07:00 committed by GitHub
parent d1f8171877
commit 1b4bc46c7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 259 additions and 17 deletions

View File

@ -117,6 +117,9 @@ module.exports = {
{
files: ['ui/**/*.test.js'],
extends: ['@metamask/eslint-config-jest'],
rules: {
'jest/no-restricted-matchers': 'off',
},
},
{
files: [

View File

@ -1102,9 +1102,18 @@
"networkName": {
"message": "Network Name"
},
"networkNameBSC": {
"message": "BSC"
},
"networkNameDefinition": {
"message": "The name associated with this network."
},
"networkNameEthereum": {
"message": "Ethereum"
},
"networkNameTestnet": {
"message": "Testnet"
},
"networkSettingsChainIdDescription": {
"message": "The chain ID is used for signing transactions. It must match the chain ID returned by the network. You can enter a decimal or '0x'-prefixed hexadecimal number, but we will display the number in decimal."
},
@ -1821,7 +1830,7 @@
"description": "$1 is the number of quotes that the user can select from when opening the list of quotes on the 'view quote' screen"
},
"swapNetworkFeeSummary": {
"message": "The network fee covers the cost of processing your swap and storing it on the Ethereum network. MetaMask does not profit from this fee."
"message": "The network fee covers the cost of processing your swap and storing it on the $1 network. MetaMask does not profit from this fee."
},
"swapNewQuoteIn": {
"message": "New quotes in $1",

View File

@ -1673,7 +1673,7 @@
"description": "$1 is the number of quotes that the user can select from when opening the list of quotes on the 'view quote' screen"
},
"swapNetworkFeeSummary": {
"message": "La tarifa de la red cubre el costo de procesar su intercambio y almacenarlo en la red Ethereum. MetaMask no se beneficia de esta tarifa."
"message": "La tarifa de la red cubre el costo de procesar su intercambio y almacenarlo en la red $1. MetaMask no se beneficia de esta tarifa."
},
"swapNewQuoteIn": {
"message": "Nuevas cotizaciones en $1",

View File

@ -1673,7 +1673,7 @@
"description": "$1 is the number of quotes that the user can select from when opening the list of quotes on the 'view quote' screen"
},
"swapNetworkFeeSummary": {
"message": "La tarifa de la red cubre el costo de procesar su intercambio y almacenarlo en la red Ethereum. MetaMask no se beneficia de esta tarifa."
"message": "La tarifa de la red cubre el costo de procesar su intercambio y almacenarlo en la red $1. MetaMask no se beneficia de esta tarifa."
},
"swapNewQuoteIn": {
"message": "Nuevas cotizaciones en $1",

View File

@ -1657,7 +1657,7 @@
"description": "Provides information about the fee that metamask takes for swaps. $1 is a decimal number."
},
"swapNetworkFeeSummary": {
"message": "नेटवर्क शुल्क आपके स्वैप को संसाधित करने के शुल्क और उसे Ethereum नेटवर्क पर संग्रह करने को कवर करता है। MetaMask इस शुल्क से लाभ नहीं कमाता है।"
"message": "नेटवर्क शुल्क आपके स्वैप को संसाधित करने के शुल्क और उसे $1 नेटवर्क पर संग्रह करने को कवर करता है। MetaMask इस शुल्क से लाभ नहीं कमाता है।"
},
"swapNewQuoteIn": {
"message": "$1 में नए उद्धरण",

View File

@ -1657,7 +1657,7 @@
"description": "Provides information about the fee that metamask takes for swaps. $1 is a decimal number."
},
"swapNetworkFeeSummary": {
"message": "Biaya jaringan mencakup biaya pemrosesan penukaran Anda dan menyimpannya di jaringan Ethereum. MetaMask tidak mendapatkan keuntungan dari biaya ini."
"message": "Biaya jaringan mencakup biaya pemrosesan penukaran Anda dan menyimpannya di jaringan $1. MetaMask tidak mendapatkan keuntungan dari biaya ini."
},
"swapNewQuoteIn": {
"message": "Kuota baru di $1",

View File

@ -1679,7 +1679,7 @@
"description": "$1 is the number of quotes that the user can select from when opening the list of quotes on the 'view quote' screen"
},
"swapNetworkFeeSummary": {
"message": "La tassa di rete copre il costo di processamento dello scambio e della memorizzazione nella rete Ethereum. MetaMask non trae profitto da questa tassa."
"message": "La tassa di rete copre il costo di processamento dello scambio e della memorizzazione nella rete $1. MetaMask non trae profitto da questa tassa."
},
"swapNewQuoteIn": {
"message": "Nuove quotazioni in $1",

View File

@ -1673,7 +1673,7 @@
"description": "$1 is the number of quotes that the user can select from when opening the list of quotes on the 'view quote' screen"
},
"swapNetworkFeeSummary": {
"message": "ネットワーク手数料には、スワップの結果をEthereumネットワークに保管する費用も含まれています。MetaMaskは手数料から利益を得ません。"
"message": "ネットワーク手数料には、スワップの結果を$1ネットワークに保管する費用も含まれています。MetaMaskは手数料から利益を得ません。"
},
"swapNewQuoteIn": {
"message": "見積の有効期限 $1",

View File

@ -1000,6 +1000,9 @@
"networkName": {
"message": "네트워크 이름"
},
"networkNameEthereum": {
"message": "이더리움"
},
"networkSettingsChainIdDescription": {
"message": "체인 ID는 거래 서명에 사용합니다. 네트워크에서 반환하는 체인 ID와 일치해야 합니다. 십진수나 '0x'로 시작하는 16진수를 입력할 수 있지만, 표시될 때는 십진수로 표시됩니다."
},
@ -1654,7 +1657,7 @@
"description": "Provides information about the fee that metamask takes for swaps. $1 is a decimal number."
},
"swapNetworkFeeSummary": {
"message": "네트워크 요금에는 스왑을 처리하고 이더리움 네트워크에 보관하는 비용이 적용됩니다. MetaMask는 이 요금을 이용해 이득을 얻지 않습니다."
"message": "네트워크 요금에는 스왑을 처리하고 $1 네트워크에 보관하는 비용이 적용됩니다. MetaMask는 이 요금을 이용해 이득을 얻지 않습니다."
},
"swapNewQuoteIn": {
"message": "$1 후에 새 견적",

View File

@ -1657,7 +1657,7 @@
"description": "Provides information about the fee that metamask takes for swaps. $1 is a decimal number."
},
"swapNetworkFeeSummary": {
"message": "Сетевая комиссия покрывает стоимость обработки вашего свопа и его хранения в сети Ethereum. MetaMask не получает прибыли от этой комиссии."
"message": "Сетевая комиссия покрывает стоимость обработки вашего свопа и его хранения в сети $1. MetaMask не получает прибыли от этой комиссии."
},
"swapNewQuoteIn": {
"message": "Новые котировки в $1",

View File

@ -1654,7 +1654,7 @@
"description": "Provides information about the fee that metamask takes for swaps. $1 is a decimal number."
},
"swapNetworkFeeSummary": {
"message": "Kasama sa bayarin sa network ang gastusin sa pagproseso ng iyong pag-swap at pag-store nito sa Ethereum network. Hindi kumikita ang MetaMask mula sa bayaring ito."
"message": "Kasama sa bayarin sa network ang gastusin sa pagproseso ng iyong pag-swap at pag-store nito sa $1 network. Hindi kumikita ang MetaMask mula sa bayaring ito."
},
"swapNewQuoteIn": {
"message": "Mga bagong quote sa $1",

View File

@ -1657,7 +1657,7 @@
"description": "Provides information about the fee that metamask takes for swaps. $1 is a decimal number."
},
"swapNetworkFeeSummary": {
"message": "Phí mạng dùng để chi trả chi phí xử lý giao dịch hoán đổi của bạn và lưu trữ giao dịch đó trên mạng Ethereum. MetaMask không thu lợi từ khoản phí này."
"message": "Phí mạng dùng để chi trả chi phí xử lý giao dịch hoán đổi của bạn và lưu trữ giao dịch đó trên mạng $1. MetaMask không thu lợi từ khoản phí này."
},
"swapNewQuoteIn": {
"message": "Báo giá mới sẽ có sau $1",

View File

@ -1673,7 +1673,7 @@
"description": "$1 is the number of quotes that the user can select from when opening the list of quotes on the 'view quote' screen"
},
"swapNetworkFeeSummary": {
"message": "网络手续费包括处理您的兑换和在以太坊(Ethereum网络上存储的成本。MetaMask 不从这笔费用中获利。"
"message": "网络手续费包括处理您的兑换和在以太坊($1网络上存储的成本。MetaMask 不从这笔费用中获利。"
},
"swapNewQuoteIn": {
"message": "$1 后更新报价",

View File

@ -3,10 +3,10 @@ module.exports = {
coverageDirectory: 'jest-coverage/',
coverageThreshold: {
global: {
branches: 5.83,
functions: 8.28,
lines: 11.18,
statements: 11.21,
branches: 6.94,
functions: 8.85,
lines: 11.76,
statements: 11.78,
},
},
setupFiles: ['./test/setup.js', './test/env.js'],

View File

@ -0,0 +1,175 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`FeeCard renders the component with initial props 1`] = `
<div>
<div
class="fee-card"
>
<div
class="fee-card__savings-and-quotes-header"
>
<div
class="fee-card__savings-and-quotes-row"
>
<p
class="fee-card__savings-text"
>
[swapUsingBestQuote]
</p>
<div
class="fee-card__quote-link-container"
>
<p
class="fee-card__quote-link-text"
>
[swapNQuotes]
</p>
<div
class="fee-card__caret-right"
>
<i
class="fa fa-angle-up"
/>
</div>
</div>
</div>
</div>
<div
class="fee-card__main"
>
<div
class="fee-card__row-header"
>
<div>
<div
class="fee-card__row-header-text--bold"
>
[swapEstimatedNetworkFee]
</div>
<div
class="info-tooltip"
>
<div
class="fee-card__row-label fee-card__info-tooltip-container"
>
<div
aria-describedby="tippy-tooltip-1"
class="info-tooltip__tooltip-container fee-card__info-tooltip-content-container"
data-original-title="null"
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<img
alt=""
src="images/mm-info-icon.svg"
/>
</div>
</div>
</div>
</div>
<div>
<div
class="fee-card__row-header-secondary--bold"
/>
<div
class="fee-card__row-header-primary--bold"
/>
</div>
</div>
<div
class="fee-card__row-header"
>
<div>
<div
class="fee-card__row-header-text"
>
[swapMaxNetworkFees]
</div>
<div
class="fee-card__link"
>
[edit]
</div>
</div>
<div>
<div
class="fee-card__row-header-secondary"
/>
</div>
</div>
<div
class="fee-card__row-header"
>
<div
class="fee-card__row-label"
>
<div
class="fee-card__row-header-text"
>
[swapThisWillAllowApprove]
</div>
<div
class="info-tooltip"
>
<div>
<div
aria-describedby="tippy-tooltip-2"
class="info-tooltip__tooltip-container fee-card__info-tooltip-container"
data-original-title="null"
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<img
alt=""
src="images/mm-info-icon.svg"
/>
</div>
</div>
</div>
</div>
<div
class="fee-card__link"
>
[swapEditLimit]
</div>
</div>
<div
class="fee-card__top-bordered-row"
>
<div
class="fee-card__row-label"
>
<div
class="fee-card__row-header-text"
>
[swapQuoteIncludesRate]
</div>
<div
class="info-tooltip"
>
<div
class="fee-card__info-tooltip-container"
>
<div
aria-describedby="tippy-tooltip-3"
class="info-tooltip__tooltip-container"
data-original-title="null"
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<img
alt=""
src="images/mm-info-icon.svg"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`;

View File

@ -2,6 +2,11 @@ import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import { I18nContext } from '../../../contexts/i18n';
import InfoTooltip from '../../../components/ui/info-tooltip';
import {
MAINNET_CHAIN_ID,
BSC_CHAIN_ID,
LOCALHOST_CHAIN_ID,
} from '../../../../../shared/constants/network';
export default function FeeCard({
primaryFee,
@ -16,6 +21,7 @@ export default function FeeCard({
numberOfQuotes,
onQuotesClick,
tokenConversionRate,
chainId,
}) {
const t = useContext(I18nContext);
@ -26,6 +32,19 @@ export default function FeeCard({
bestQuoteText = t('swapBetterQuoteAvailable');
}
const getTranslatedNetworkName = () => {
switch (chainId) {
case MAINNET_CHAIN_ID:
return t('networkNameEthereum');
case BSC_CHAIN_ID:
return t('networkNameBSC');
case LOCALHOST_CHAIN_ID:
return t('networkNameTestnet');
default:
throw new Error('This network is not supported for token swaps');
}
};
return (
<div className="fee-card">
<div className="fee-card__savings-and-quotes-header">
@ -57,7 +76,7 @@ export default function FeeCard({
contentText={
<>
<p className="fee-card__info-tooltip-paragraph">
{t('swapNetworkFeeSummary')}
{t('swapNetworkFeeSummary', [getTranslatedNetworkName()])}
</p>
<p className="fee-card__info-tooltip-paragraph">
{t('swapEstimatedNetworkFeeSummary', [
@ -170,4 +189,5 @@ FeeCard.propTypes = {
onQuotesClick: PropTypes.func.isRequired,
numberOfQuotes: PropTypes.number.isRequired,
tokenConversionRate: PropTypes.number,
chainId: PropTypes.string.isRequired,
};

View File

@ -0,0 +1,31 @@
import React from 'react';
import { render } from '@testing-library/react';
import { MAINNET_CHAIN_ID } from '../../../../../shared/constants/network';
import FeeCard from './fee-card';
describe('FeeCard', () => {
const createProps = (customProps = {}) => {
return {
primaryFee: '1 ETH',
secondaryFee: '2500 USD',
hideTokenApprovalRow: false,
onFeeCardMaxRowClick: jest.fn(),
tokenApprovalTextComponent: <></>,
tokenApprovalSourceTokenSymbol: 'ABC',
onTokenApprovalClick: jest.fn(),
metaMaskFee: '0.875',
isBestQuote: true,
numberOfQuotes: 6,
onQuotesClick: jest.fn(),
tokenConversionRate: 0.015,
chainId: MAINNET_CHAIN_ID,
...customProps,
};
};
it('renders the component with initial props', () => {
const { container } = render(<FeeCard {...createProps()} />);
expect(container).toMatchSnapshot();
});
});

View File

@ -659,6 +659,7 @@ export default function ViewQuote() {
? 1
: memoizedTokenConversionRates[destinationToken.address]
}
chainId={chainId}
/>
</div>
</div>