Skip to content

Commit

Permalink
fix: all regex in one file (#7217)
Browse files Browse the repository at this point in the history
**Description**

Consolidates regular expressions throughout the codeabase into a single
file

**Issue**

fixes
#[6684](https://app.zenhub.com/workspaces/metamask-mobile-5f984938ddc0e4001d4b79cb/issues/gh/metamask/metamask-mobile/6684)

**Checklist**

* [x] There is a related GitHub issue
* [x] Tests are included if applicable
* [x] Any added code is fully documented
  • Loading branch information
frankvonhoven authored Sep 25, 2023
1 parent 7c368d1 commit 481412d
Show file tree
Hide file tree
Showing 30 changed files with 719 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/* eslint-disable import/no-commonjs, import/no-nodejs-modules, import/no-nodejs-modules, no-console */
const fs = require('fs');
const path = require('path');

const { regex } = require('../../../../../../app/util/regex');
const ASSETS_FOLDER = 'assets';
const GENERATED_ASSETS_FILE = 'Icon.assets.ts';
const TYPES_FILE = 'Icon.types.ts';
Expand Down Expand Up @@ -33,7 +33,10 @@ const main = async () => {
assetFileList.forEach((fileName) => {
const filePath = path.join(__dirname, `../${ASSETS_FOLDER}/${fileName}`);
const fileContent = fs.readFileSync(filePath, { encoding: 'utf-8' });
const formattedFileContent = fileContent.replace(/black/g, 'currentColor');
const formattedFileContent = fileContent.replace(
regex.colorBlack,
'currentColor',
);
fs.writeFileSync(filePath, formattedFileContent);
});

Expand Down
8 changes: 2 additions & 6 deletions app/components/Base/Keypad/createKeypadRule.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { regex, hasDecimals } from '../../../../app/util/regex';
import { KEYS } from './constants';

const hasOneDigit = /^\d$/;
function hasDecimals(separator, decimalPlaces) {
return new RegExp(`^\\d+\\${separator}\\d{${decimalPlaces}}$`, 'g');
}

export default function createKeypadRule({
decimalSeparator = null,
decimals = null,
Expand All @@ -30,7 +26,7 @@ export default function createKeypadRule({
if (currentAmount === '0') {
return currentAmount;
}
if (hasOneDigit.test(currentAmount)) {
if (regex.hasOneDigit.test(currentAmount)) {
return '0';
}

Expand Down
3 changes: 2 additions & 1 deletion app/components/UI/AccountOverview/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
selectSelectedAddress,
} from '../../../selectors/preferencesController';
import { createAccountSelectorNavDetails } from '../../Views/AccountSelector';
import { regex } from '../../../../app/util/regex';

const createStyles = (colors) =>
StyleSheet.create({
Expand Down Expand Up @@ -315,7 +316,7 @@ class AccountOverview extends PureComponent {
onOpenPortfolio = () => {
const { navigation, browserTabs } = this.props;
const existingPortfolioTab = browserTabs.find((tab) =>
tab.url.match(new RegExp(`${AppConstants.PORTFOLIO_URL}/(?![a-z])`)),
tab.url.match(regex.portfolioUrl),
);
let existingTabId;
let newTabUrl;
Expand Down
27 changes: 15 additions & 12 deletions app/components/UI/AccountSelectorList/AccountSelector.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useAccounts } from '../../../components/hooks/useAccounts';
import { View } from 'react-native';
import { ACCOUNT_BALANCE_BY_ADDRESS_TEST_ID } from '../../../../wdio/screen-objects/testIDs/Components/AccountListComponent.testIds';
import initialBackgroundState from '../../../util/test/initial-background-state.json';
import { regex } from '../../../../app/util/regex';

const mockEngine = Engine;

Expand Down Expand Up @@ -136,15 +137,17 @@ describe('AccountSelectorList', () => {
`${ACCOUNT_BALANCE_BY_ADDRESS_TEST_ID}-${PERSONAL_ACCOUNT}`,
);

expect(within(businessAccountItem).getByText(/1 ETH/)).toBeDefined();
expect(within(businessAccountItem).getByText(/\$3200/)).toBeDefined();
expect(within(businessAccountItem).getByText(regex.eth(1))).toBeDefined();
expect(
within(businessAccountItem).getByText(regex.usd(3200)),
).toBeDefined();

expect(within(personalAccountItem).getByText(/2 ETH/)).toBeDefined();
expect(within(personalAccountItem).getByText(/\$6400/)).toBeDefined();
expect(within(personalAccountItem).getByText(regex.eth(2))).toBeDefined();
expect(
within(personalAccountItem).getByText(regex.usd(6400)),
).toBeDefined();

const accounts = getAllByTestId(
new RegExp(`${ACCOUNT_BALANCE_BY_ADDRESS_TEST_ID}`),
);
const accounts = getAllByTestId(regex.accountBalance);
expect(accounts.length).toBe(2);

expect(toJSON()).toMatchSnapshot();
Expand All @@ -166,17 +169,17 @@ describe('AccountSelectorList', () => {
});

await waitFor(async () => {
const accounts = getAllByTestId(
new RegExp(`${ACCOUNT_BALANCE_BY_ADDRESS_TEST_ID}`),
);
const accounts = getAllByTestId(regex.accountBalance);
expect(accounts.length).toBe(1);

const businessAccountItem = await queryByTestId(
`${ACCOUNT_BALANCE_BY_ADDRESS_TEST_ID}-${BUSINESS_ACCOUNT}`,
);

expect(within(businessAccountItem).getByText(/1 ETH/)).toBeDefined();
expect(within(businessAccountItem).getByText(/\$3200/)).toBeDefined();
expect(within(businessAccountItem).getByText(regex.eth(1))).toBeDefined();
expect(
within(businessAccountItem).getByText(regex.usd(3200)),
).toBeDefined();

expect(toJSON()).toMatchSnapshot();
});
Expand Down
7 changes: 4 additions & 3 deletions app/components/UI/AddCustomToken/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
TOKEN_PRECISION_WARNING_MESSAGE_ID,
} from '../../../../wdio/screen-objects/testIDs/Screens/AddCustomToken.testIds';
import { NFT_IDENTIFIER_INPUT_BOX_ID } from '../../../../wdio/screen-objects/testIDs/Screens/NFTImportScreen.testIds';
import { regex } from '../../../../app/util/regex';

const createStyles = (colors) =>
StyleSheet.create({
Expand Down Expand Up @@ -190,7 +191,7 @@ export default class AddCustomToken extends PureComponent {
const { chainId } = this.props;
const toSmartContract =
isValidTokenAddress && (await isSmartContractAddress(address, chainId));
const addressWithoutSpaces = address.replace(/\s/g, '');
const addressWithoutSpaces = address.replace(regex.addressWithSpaces, '');
if (addressWithoutSpaces.length === 0) {
this.setState({ warningAddress: strings('token.address_cant_be_empty') });
validated = false;
Expand All @@ -211,7 +212,7 @@ export default class AddCustomToken extends PureComponent {
validateCustomTokenSymbol = () => {
let validated = true;
const symbol = this.state.symbol;
const symbolWithoutSpaces = symbol.replace(/\s/g, '');
const symbolWithoutSpaces = symbol.replace(regex.addressWithSpaces, '');
if (symbolWithoutSpaces.length === 0) {
this.setState({ warningSymbol: strings('token.symbol_cant_be_empty') });
validated = false;
Expand All @@ -224,7 +225,7 @@ export default class AddCustomToken extends PureComponent {
validateCustomTokenDecimals = () => {
let validated = true;
const decimals = this.state.decimals;
const decimalsWithoutSpaces = decimals.replace(/\s/g, '');
const decimalsWithoutSpaces = decimals.replace(regex.addressWithSpaces, '');
if (decimalsWithoutSpaces.length === 0) {
this.setState({
warningDecimals: strings('token.decimals_cant_be_empty'),
Expand Down
3 changes: 2 additions & 1 deletion app/components/UI/ApproveTransactionReview/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ import { getRampNetworks } from '../../../reducers/fiatOrders';
import SkeletonText from '../Ramp/components/SkeletonText';
import InfoModal from '../../../components/UI/Swaps/components/InfoModal';
import BlockaidBanner from '../BlockaidBanner/BlockaidBanner';
import { regex } from '../../../../app/util/regex';

const { ORIGIN_DEEPLINK, ORIGIN_QR_CODE } = AppConstants.DEEPLINKS;
const POLLING_INTERVAL_ESTIMATED_L1_FEE = 30000;
Expand Down Expand Up @@ -684,7 +685,7 @@ class ApproveTransactionReview extends PureComponent {
handleCustomSpendOnInputChange = (value) => {
if (isNumber(value)) {
this.setState({
tokenSpendValue: value.replace(/[^0-9.]/g, ''),
tokenSpendValue: value.replace(regex.nonNumber, ''),
});
}
};
Expand Down
5 changes: 3 additions & 2 deletions app/components/UI/BrowserUrlBar/BrowserUrlBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import stylesheet from './BrowserUrlBar.styles';
import generateTestId from '../../../../wdio/utils/generateTestId';
import { NAVBAR_TITLE_NETWORK } from '../../../../wdio/screen-objects/testIDs/BrowserScreen/BrowserScreen.testIds';
import Url from 'url-parse';
import { regex } from '../../../../app/util/regex';

const BrowserUrlBar = ({ url, route, onPress }: BrowserUrlBarProps) => {
const getDappMainUrl = () => {
Expand All @@ -30,9 +31,9 @@ const BrowserUrlBar = ({ url, route, onPress }: BrowserUrlBarProps) => {
url.search(`${AppConstants.IPFS_OVERRIDE_PARAM}=false`) === -1 &&
Boolean(ensUrl)
) {
return ensUrl.toLowerCase().replace(/^www\./, '');
return ensUrl.toLowerCase().replace(regex.startUrl, '');
}
return urlObj.host.toLowerCase().replace(/^www\./, '');
return urlObj.host.toLowerCase().replace(regex.startUrl, '');
};

const contentProtocol = getURLProtocol(url);
Expand Down
8 changes: 3 additions & 5 deletions app/components/UI/Ramp/Views/Settings/AddActivationKey.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@ import {
import { useTheme } from '../../../../../util/theme';
import Routes from '../../../../../constants/navigation/Routes';
import { strings } from '../../../../../../locales/i18n';

import { regex } from '../../../../../../app/util/regex';
import styles from './Settings.styles';

const activationKeyRegex = /^[a-zA-Z0-9\\-]{1,32}$/;

interface AddActivationKeyParams {
onSubmit: (key: string) => void;
}
Expand Down Expand Up @@ -50,7 +48,7 @@ function AddActivationKey() {
}, [colors, navigation]);

const handleSubmit = useCallback(() => {
if (!activationKeyRegex.test(newKey)) {
if (!regex.activationKey.test(newKey)) {
return;
}
onSubmit(newKey);
Expand Down Expand Up @@ -95,7 +93,7 @@ function AddActivationKey() {
<StyledButton
key="confirm-button"
type="confirm"
disabled={!activationKeyRegex.test(newKey)}
disabled={!regex.activationKey.test(newKey)}
containerStyle={style.button}
onPress={handleSubmit}
>
Expand Down
3 changes: 2 additions & 1 deletion app/components/UI/Tokens/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ import {
import { selectDetectedTokens } from '../../../selectors/tokensController';
import { selectContractExchangeRates } from '../../../selectors/tokenRatesController';
import { selectUseTokenDetection } from '../../../selectors/preferencesController';
import { regex } from '../../../../app/util/regex';

const Tokens: React.FC<TokensI> = ({ tokens }) => {
const { colors } = useTheme();
Expand Down Expand Up @@ -415,7 +416,7 @@ const Tokens: React.FC<TokensI> = ({ tokens }) => {

const onOpenPortfolio = () => {
const existingPortfolioTab = browserTabs.find((tab: BrowserTab) =>
tab.url.match(new RegExp(`${AppConstants.PORTFOLIO_URL}/(?![a-z])`)),
tab.url.match(regex.portfolioUrl),
);
let existingTabId;
let newTabUrl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
import { selectTokensByAddress } from '../../../../selectors/tokensController';
import { selectContractExchangeRates } from '../../../../selectors/tokenRatesController';
import { selectSelectedAddress } from '../../../../selectors/preferencesController';
import { regex } from '../../../../../app/util/regex';

const createStyles = (colors) =>
StyleSheet.create({
Expand Down Expand Up @@ -362,7 +363,7 @@ class TransactionDetails extends PureComponent {
</DetailsModal.SectionTitle>
{!!transaction?.nonce && (
<Text small primary>{`#${parseInt(
transaction.nonce.replace(/^#/, ''),
transaction.nonce.replace(regex.transactionNonce, ''),
16,
)}`}</Text>
)}
Expand Down
3 changes: 2 additions & 1 deletion app/components/Views/BrowserTab/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ import {
selectSelectedAddress,
} from '../../../selectors/preferencesController';
import { IPFS_GATEWAY_DISABLED_ERROR } from './constants';
import { regex } from '../../../../app/util/regex';

const { HOMEPAGE_URL, NOTIFICATION_NAMES } = AppConstants;
const HOMEPAGE_HOST = new URL(HOMEPAGE_URL)?.hostname;
Expand Down Expand Up @@ -799,7 +800,7 @@ export const BrowserTab = (props) => {

// Stops normal loading when it's ens, instead call go to be properly set up
if (isENSUrl(url)) {
go(url.replace(/^http:\/\//, 'https://'));
go(url.replace(regex.urlHttpToHttps, 'https://'));
return false;
}

Expand Down
3 changes: 2 additions & 1 deletion app/components/Views/ChoosePassword/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import { LoginOptionsSwitch } from '../../UI/LoginOptionsSwitch';
import generateTestId from '../../../../wdio/utils/generateTestId';
import { scale } from 'react-native-size-matters';
import navigateTermsOfUse from '../../../util/termsOfUse/termsOfUse';
import { regex } from '../../../util/regex';

const createStyles = (colors) =>
StyleSheet.create({
Expand Down Expand Up @@ -554,7 +555,7 @@ class ChoosePassword extends PureComponent {
const mnemonic = await KeyringController.exportSeedPhrase(
keychainPassword,
).toString();
return JSON.stringify(mnemonic).replace(/"/g, '');
return JSON.stringify(mnemonic).replace(regex.privateCredentials, '');
};

jumpToConfirmPassword = () => {
Expand Down
5 changes: 4 additions & 1 deletion app/components/Views/ManualBackupStep1/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { CONFIRM_CHANGE_PASSWORD_INPUT_BOX_ID } from '../../../constants/test-id
import { MetaMetricsEvents } from '../../../core/Analytics';
import AnalyticsV2 from '../../../util/analyticsV2';
import { Authentication } from '../../../core';
import { regex } from '../../../../app/util/regex';

/**
* View that's shown during the second step of
Expand Down Expand Up @@ -66,7 +67,9 @@ const ManualBackupStep1 = ({ route, navigation, appTheme }) => {
const mnemonic = await KeyringController.exportSeedPhrase(
password,
).toString();
return JSON.stringify(mnemonic).replace(/"/g, '').split(' ');
return JSON.stringify(mnemonic)
.replace(regex.privateCredentials, '')
.split(' ');
};

useEffect(() => {
Expand Down
3 changes: 2 additions & 1 deletion app/components/Views/ResetPassword/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import { recreateVaultWithNewPassword } from '../../../core/Vault';
import generateTestId from '../../../../wdio/utils/generateTestId';
import Logger from '../../../util/Logger';
import { selectSelectedAddress } from '../../../selectors/preferencesController';
import { regex } from '../../../../app/util/regex';

const createStyles = (colors) =>
StyleSheet.create({
Expand Down Expand Up @@ -473,7 +474,7 @@ class ResetPassword extends PureComponent {
const mnemonic = await KeyringController.exportSeedPhrase(
keychainPassword,
).toString();
return JSON.stringify(mnemonic).replace(/"/g, '');
return JSON.stringify(mnemonic).replace(regex.privateCredentials, '');
};

jumpToConfirmPassword = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import {
SECRET_RECOVERY_PHRASE_TEXT,
} from '../../../../wdio/screen-objects/testIDs/Screens/RevelSecretRecoveryPhrase.testIds';
import { selectSelectedAddress } from '../../../selectors/preferencesController';
import { regex } from '../../../../app/util/regex';

const PRIVATE_KEY = 'private_key';

Expand Down Expand Up @@ -126,7 +127,10 @@ const RevealPrivateCredential = ({
const mnemonic = await KeyringController.exportSeedPhrase(
pswd,
).toString();
privateCredential = JSON.stringify(mnemonic).replace(/"/g, '');
privateCredential = JSON.stringify(mnemonic).replace(
regex.privateCredentials,
'',
);
} else {
privateCredential = await KeyringController.exportAccount(
pswd,
Expand Down
3 changes: 2 additions & 1 deletion app/components/Views/SendFlow/AddressList/AddressList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Text from '../../../../component-library/components/Texts/Text/Text';
import { TextVariant } from '../../../../component-library/components/Texts/Text';
import { selectChainId } from '../../../../selectors/networkController';
import { selectIdentities } from '../../../../selectors/preferencesController';
import { regex } from '../../../../../app/util/regex';

// Internal dependencies
import { AddressListProps, Contact } from './AddressList.types';
Expand Down Expand Up @@ -81,7 +82,7 @@ const AddressList: React.FC<AddressListProps> = ({

updatedContacts.forEach((contact: Contact) => {
const contactNameInitial = contact?.name?.[0];
const nameInitial = /[a-z]/i.exec(contactNameInitial);
const nameInitial = regex.nameInitial.exec(contactNameInitial);
const initial = nameInitial
? nameInitial[0].toLowerCase()
: strings('address_book.others');
Expand Down
3 changes: 2 additions & 1 deletion app/components/Views/SendFlow/Amount/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ import { selectContractBalances } from '../../../../selectors/tokenBalancesContr
import { selectSelectedAddress } from '../../../../selectors/preferencesController';
import { PREFIX_HEX_STRING } from '../../../../constants/transaction';
import Routes from '../../../../constants/navigation/Routes';
import { regex } from '../../../../../app/util/regex';

const KEYBOARD_OFFSET = Device.isSmallDevice() ? 80 : 120;

Expand Down Expand Up @@ -890,7 +891,7 @@ class Amount extends PureComponent {
hasExchangeRate,
comma;
// Remove spaces from input
inputValue = inputValue && inputValue.replace(/\s+/g, '');
inputValue = inputValue && inputValue.replace(regex.whiteSpaces, '');
// Handle semicolon for other languages
if (inputValue && inputValue.includes(',')) {
comma = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ import {
selectNetworkConfigurations,
selectProviderConfig,
} from '../../../../../selectors/networkController';
import { regex } from '../../../../../../app/util/regex';

const createStyles = (colors) =>
StyleSheet.create({
Expand Down Expand Up @@ -654,12 +655,12 @@ class NetworkSettings extends PureComponent {

// Check if it's a valid chainId format
if (chainId.startsWith('0x')) {
if (!/^0x[0-9a-f]+$/iu.test(chainId)) {
if (!regex.validChainId_hex.test(chainId)) {
errorMessage = strings('app_settings.invalid_hex_number');
} else if (!isPrefixedFormattedHexString(chainId)) {
errorMessage = strings('app_settings.invalid_hex_number_leading_zeros');
}
} else if (!/^[0-9]+$/u.test(chainId)) {
} else if (!regex.validChainId.test(chainId)) {
errorMessage = strings('app_settings.invalid_number');
} else if (chainId.startsWith('0')) {
errorMessage = strings('app_settings.invalid_number_leading_zeros');
Expand Down
Loading

0 comments on commit 481412d

Please sign in to comment.