@@ -40,6 +44,4 @@ const FundsProtection = ({ submitFundsProtection }: TFundsProtectionProps) => {
);
};
-export default connect(({ modules }: TRootStore) => ({
- submitFundsProtection: modules.cashier.deposit.submitFundsProtection,
-}))(FundsProtection);
+export default observer(FundsProtection);
diff --git a/packages/cashier/src/components/no-balance/__tests__/no-balance.spec.tsx b/packages/cashier/src/components/no-balance/__tests__/no-balance.spec.tsx
index 6999f593a0ff..413397ec2b25 100644
--- a/packages/cashier/src/components/no-balance/__tests__/no-balance.spec.tsx
+++ b/packages/cashier/src/components/no-balance/__tests__/no-balance.spec.tsx
@@ -4,21 +4,32 @@ import { createBrowserHistory } from 'history';
import { Router } from 'react-router';
import { routes } from '@deriv/shared';
import NoBalance from '../no-balance';
-
-jest.mock('Stores/connect', () => ({
- __esModule: true,
- default: 'mockedDefaultExport',
- connect: () => Component => Component,
-}));
+import { StoreProvider } from '@deriv/stores';
describe('
', () => {
const history = createBrowserHistory();
+ let mockRootStore;
+
+ beforeEach(() => {
+ mockRootStore = {
+ client: { currency: 'USD' },
+ modules: {
+ cashier: {
+ deposit: { is_deposit_locked: false },
+ general_store: { setCashierTabIndex: jest.fn() },
+ },
+ },
+ };
+ });
it('component should render', () => {
render(
-
-
+
+ ,
+ {
+ wrapper: ({ children }) =>
{children},
+ }
);
expect(screen.getByRole('heading')).toBeInTheDocument();
@@ -27,10 +38,15 @@ describe('
', () => {
});
it('must not able to make a deposit when deposit is locked', async () => {
+ mockRootStore.modules.cashier.deposit.is_deposit_locked = true;
+
render(
-
-
+
+ ,
+ {
+ wrapper: ({ children }) =>
{children},
+ }
);
expect(screen.getByRole('heading')).toBeInTheDocument();
@@ -39,12 +55,13 @@ describe('
', () => {
});
it('component should redirect to deposit page when button is clicked', () => {
- const setTabIndex = jest.fn();
-
render(
-
-
+
+ ,
+ {
+ wrapper: ({ children }) =>
{children},
+ }
);
const btn = screen.getByRole('button');
diff --git a/packages/cashier/src/components/no-balance/no-balance.tsx b/packages/cashier/src/components/no-balance/no-balance.tsx
index b9be2e56d45d..72a265fe3f4d 100644
--- a/packages/cashier/src/components/no-balance/no-balance.tsx
+++ b/packages/cashier/src/components/no-balance/no-balance.tsx
@@ -1,18 +1,22 @@
import React from 'react';
import { RouteComponentProps, withRouter } from 'react-router-dom';
+import { observer } from 'mobx-react-lite';
import { Button, Icon, Text } from '@deriv/components';
import { routes, getCurrencyDisplayCode } from '@deriv/shared';
import { localize, Localize } from '@deriv/translations';
-import { connect } from 'Stores/connect';
-import { TRootStore } from 'Types';
+import { useStore } from '@deriv/stores';
-type TNoBalanceProps = RouteComponentProps & {
- currency: string;
- is_deposit_locked: boolean;
- setTabIndex: (tab_index: number) => void;
-};
+const NoBalance = ({ history }: RouteComponentProps) => {
+ const {
+ client: { currency },
+ modules: {
+ cashier: {
+ deposit: { is_deposit_locked },
+ general_store: { setCashierTabIndex: setTabIndex },
+ },
+ },
+ } = useStore();
-const NoBalance = ({ currency, history, is_deposit_locked, setTabIndex }: TNoBalanceProps) => {
const onClickDeposit = () => {
// index of deposit tab in the cashier modal is 0
setTabIndex(0);
@@ -47,10 +51,4 @@ const NoBalance = ({ currency, history, is_deposit_locked, setTabIndex }: TNoBal
);
};
-export default withRouter(
- connect(({ client, modules }: TRootStore) => ({
- currency: client.currency,
- is_deposit_locked: modules.cashier.deposit.is_deposit_locked,
- setTabIndex: modules.cashier.general_store.setCashierTabIndex,
- }))(NoBalance)
-);
+export default observer(withRouter(NoBalance));
diff --git a/packages/cashier/src/components/recent-transaction/__tests__/recent-transaction.spec.tsx b/packages/cashier/src/components/recent-transaction/__tests__/recent-transaction.spec.tsx
index 089f7c5362f8..483c27d831d7 100644
--- a/packages/cashier/src/components/recent-transaction/__tests__/recent-transaction.spec.tsx
+++ b/packages/cashier/src/components/recent-transaction/__tests__/recent-transaction.spec.tsx
@@ -3,6 +3,7 @@ import { fireEvent, render, screen } from '@testing-library/react';
import RecentTransaction from '../recent-transaction';
import { createBrowserHistory } from 'history';
import { Router } from 'react-router';
+import { StoreProvider } from '@deriv/stores';
jest.mock('Stores/connect', () => ({
__esModule: true,
@@ -11,35 +12,51 @@ jest.mock('Stores/connect', () => ({
}));
describe('
', () => {
- const props = {
- crypto_transactions: [
- {
- address_hash: 'tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt',
- address_url:
- 'https://www.blockchain.com/btc-testnet/address/tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt',
- amount: 0.01,
- id: '262',
- is_valid_to_cancel: 1,
- status_code: 'LOCKED',
- status_message:
- "We're reviewing your withdrawal request. You may still cancel this transaction if you wish. Once we start processing, you won't be able to cancel.",
- submit_date: 1644408421,
- transaction_type: 'withdrawal',
+ let history, mockRootStore;
+ beforeEach(() => {
+ history = createBrowserHistory();
+ mockRootStore = {
+ client: {
+ currency: 'BTC',
},
- ],
- currency: 'BTC',
- onMount: jest.fn(),
- setIsCryptoTransactionsVisible: jest.fn(),
- };
+ modules: {
+ cashier: {
+ transaction_history: {
+ crypto_transactions: [
+ {
+ address_hash: 'tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt',
+ address_url:
+ 'https://www.blockchain.com/btc-testnet/address/tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt',
+ amount: 0.01,
+ id: '262',
+ is_valid_to_cancel: 1,
+ status_code: 'LOCKED',
+ status_message:
+ "We're reviewing your withdrawal request. You may still cancel this transaction if you wish. Once we start processing, you won't be able to cancel.",
+ submit_date: 1644408421,
+ transaction_type: 'withdrawal',
+ },
+ ],
+ onMount: jest.fn(),
+ setIsCryptoTransactionsVisible: jest.fn(),
+ },
+ },
+ },
+ };
+ });
- let history;
- const renderWithRouter = component => {
- history = createBrowserHistory();
- return render(
{component});
+ const renderRecentTransaction = () => {
+ return render(
+
+
+
+
+
+ );
};
it('should show proper messages', () => {
- renderWithRouter(
);
+ renderRecentTransaction();
expect(screen.getByText('Recent transactions')).toBeInTheDocument();
expect(screen.getByText('Withdrawal BTC')).toBeInTheDocument();
@@ -53,35 +70,38 @@ describe('
', () => {
});
it('should trigger onClick callback when the user clicks on "View all" button', () => {
- renderWithRouter(
);
+ renderRecentTransaction();
const view_all_btn_link = screen.getByRole('link', { name: 'View all' });
fireEvent.click(view_all_btn_link);
- expect(props.setIsCryptoTransactionsVisible).toHaveBeenCalledTimes(1);
+ expect(mockRootStore.modules.cashier.transaction_history.setIsCryptoTransactionsVisible).toHaveBeenCalledTimes(
+ 1
+ );
});
it('should show the proper icon when transaction_type is equal to "withdrawal"', () => {
- renderWithRouter(
);
+ renderRecentTransaction();
expect(screen.getByTestId('dti_icon_cashier_minus')).toBeInTheDocument();
});
it('should show the proper icon when transaction_type is equal to "deposit"', () => {
- renderWithRouter(
-
- );
+ mockRootStore.modules.cashier.transaction_history.crypto_transactions = [
+ {
+ ...mockRootStore.modules.cashier.transaction_history.crypto_transactions[0],
+ transaction_type: 'deposit',
+ status_code: 'PENDING',
+ },
+ ];
+ renderRecentTransaction();
expect(screen.getByTestId('dti_icon_cashier_add')).toBeInTheDocument();
});
it('should not show "Recent transactions" title if crypto_transactions is an empty array', () => {
- renderWithRouter(
);
+ mockRootStore.modules.cashier.transaction_history.crypto_transactions = [];
+ renderRecentTransaction();
expect(screen.queryByText('Recent transactions')).not.toBeInTheDocument();
});
diff --git a/packages/cashier/src/components/recent-transaction/recent-transaction.tsx b/packages/cashier/src/components/recent-transaction/recent-transaction.tsx
index 909b937e4914..9cab742bf13a 100644
--- a/packages/cashier/src/components/recent-transaction/recent-transaction.tsx
+++ b/packages/cashier/src/components/recent-transaction/recent-transaction.tsx
@@ -1,33 +1,25 @@
import React from 'react';
+import { observer } from 'mobx-react-lite';
import classNames from 'classnames';
import { ButtonLink, Text, Icon } from '@deriv/components';
import { Localize } from '@deriv/translations';
import { epochToMoment } from '@deriv/shared';
-import { connect } from 'Stores/connect';
-import { TRootStore } from 'Types';
import { getStatus } from 'Constants/transaction-status';
+import { useStore } from '@deriv/stores';
import './recent-transaction.scss';
-type TRecentTransactionProps = {
- crypto_transactions: {
- address_hash: string;
- status_code: string;
- submit_date: Date;
- transaction_hash: string;
- transaction_type: string;
- amount: number;
- }[];
- currency: string;
- onMount: () => void;
- setIsCryptoTransactionsVisible: (visible: boolean) => void;
-};
+const RecentTransaction = () => {
+ const {
+ client,
+ modules: {
+ cashier: { transaction_history },
+ },
+ } = useStore();
+
+ const { currency } = client;
+
+ const { crypto_transactions, onMount, setIsCryptoTransactionsVisible } = transaction_history;
-const RecentTransaction = ({
- crypto_transactions,
- currency,
- onMount,
- setIsCryptoTransactionsVisible,
-}: TRecentTransactionProps) => {
React.useEffect(() => {
onMount();
}, [onMount]);
@@ -35,7 +27,6 @@ const RecentTransaction = ({
if (!crypto_transactions.length) {
return null;
}
-
let { address_hash, submit_date, transaction_type } = crypto_transactions[0];
const { status_code, transaction_hash } = crypto_transactions[0];
const status = getStatus(transaction_hash, transaction_type, status_code);
@@ -132,9 +123,4 @@ const RecentTransaction = ({
);
};
-export default connect(({ modules, client }: TRootStore) => ({
- crypto_transactions: modules.cashier.transaction_history.crypto_transactions,
- currency: client.currency,
- onMount: modules.cashier.transaction_history.onMount,
- setIsCryptoTransactionsVisible: modules.cashier.transaction_history.setIsCryptoTransactionsVisible,
-}))(RecentTransaction);
+export default observer(RecentTransaction);
diff --git a/packages/cashier/src/components/transfer-confirm/__tests__/transfer-confirm.spec.tsx b/packages/cashier/src/components/transfer-confirm/__tests__/transfer-confirm.spec.tsx
index a823f721d407..392e6334f8fa 100644
--- a/packages/cashier/src/components/transfer-confirm/__tests__/transfer-confirm.spec.tsx
+++ b/packages/cashier/src/components/transfer-confirm/__tests__/transfer-confirm.spec.tsx
@@ -1,6 +1,16 @@
import React from 'react';
import { fireEvent, render, screen } from '@testing-library/react';
import TransferConfirm from '../transfer-confirm';
+import { StoreProvider } from '@deriv/stores';
+import { TRootStore } from '../../../types';
+import type { DeepPartial } from '@deriv/stores/types';
+
+const mockRootStore: DeepPartial
= {
+ ui: {
+ disableApp: jest.fn(),
+ enableApp: jest.fn(),
+ },
+};
jest.mock('Stores/connect', () => ({
__esModule: true,
@@ -31,7 +41,9 @@ describe('', () => {
};
it('should show proper icon, messages and buttons', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
const [back_btn, transfer_now_btn] = screen.getAllByRole('button');
@@ -62,7 +74,12 @@ describe('', () => {
code: 'code',
message: 'error_message',
}}
- />
+ />,
+ {
+ wrapper: ({ children }) => (
+ {children}
+ ),
+ }
);
expect(screen.getByText('Cashier Error')).toBeInTheDocument();
@@ -71,7 +88,9 @@ describe('', () => {
});
it('should trigger onClickBack method when the client clicks on Back button', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
const [back_btn, _] = screen.getAllByRole('button');
fireEvent.click(back_btn);
@@ -80,7 +99,9 @@ describe('', () => {
});
it('should enable Transfer now button when checkbox is checked', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
const el_checkbox = screen.getByRole('checkbox');
const [_, transfer_now_btn] = screen.getAllByRole('button');
@@ -89,7 +110,9 @@ describe('', () => {
expect(transfer_now_btn).toBeEnabled();
});
it('should show proer checkbox label text when is_payment_agent_withdraw property is equal to true/false', () => {
- const { rerender } = render();
+ const { rerender } = render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(
screen.getByLabelText('I confirm that I have verified the payment agent’s transfer information.')
@@ -103,7 +126,9 @@ describe('', () => {
});
it('should trigger onClickConfirm method when the client clicks on Transfer now button', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
const el_checkbox = screen.getByRole('checkbox');
const [_, transfer_now_btn] = screen.getAllByRole('button');
diff --git a/packages/cashier/src/pages/account-transfer/__tests__/account-transfer.spec.tsx b/packages/cashier/src/pages/account-transfer/__tests__/account-transfer.spec.tsx
index 5795d3f6c9f0..36b2c60314cd 100644
--- a/packages/cashier/src/pages/account-transfer/__tests__/account-transfer.spec.tsx
+++ b/packages/cashier/src/pages/account-transfer/__tests__/account-transfer.spec.tsx
@@ -40,6 +40,7 @@ describe('', () => {
},
modules: {
cashier: {
+ deposit: { is_deposit_locked: true },
general_store: {
setActiveTab: jest.fn(),
is_cashier_locked: false,
diff --git a/packages/cashier/src/pages/deposit/crypto-deposit/__tests__/crypto-deposit.spec.tsx b/packages/cashier/src/pages/deposit/crypto-deposit/__tests__/crypto-deposit.spec.tsx
index 1131afa1a2ac..41bf28762002 100644
--- a/packages/cashier/src/pages/deposit/crypto-deposit/__tests__/crypto-deposit.spec.tsx
+++ b/packages/cashier/src/pages/deposit/crypto-deposit/__tests__/crypto-deposit.spec.tsx
@@ -32,7 +32,7 @@ describe('', () => {
const renderWithRouter = (component: JSX.Element, mockRootStore: TRootStore) => {
history = createBrowserHistory();
return render({component}, {
- wrapper: ({ children }) => {children},
+ wrapper: ({ children }) => {children},
});
};
diff --git a/packages/cashier/src/pages/payment-agent-transfer/__tests__/payment-agent-transfer.spec.js b/packages/cashier/src/pages/payment-agent-transfer/__tests__/payment-agent-transfer.spec.js
index 70ac900973da..a9e50cfa48fe 100644
--- a/packages/cashier/src/pages/payment-agent-transfer/__tests__/payment-agent-transfer.spec.js
+++ b/packages/cashier/src/pages/payment-agent-transfer/__tests__/payment-agent-transfer.spec.js
@@ -3,6 +3,14 @@ import { render, screen } from '@testing-library/react';
import { Router } from 'react-router';
import { createBrowserHistory } from 'history';
import PaymentAgentTransfer from '../payment-agent-transfer';
+import { StoreProvider } from '@deriv/stores';
+
+const mockRootStore = {
+ ui: {
+ is_dark_mode_on: false,
+ toggleAccountsDialog: jest.fn(),
+ },
+};
jest.mock('Stores/connect', () => ({
__esModule: true,
@@ -53,7 +61,9 @@ describe('', () => {
});
it('should render the component', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(screen.getByText('mockedPaymentAgentTransferForm')).toBeInTheDocument();
});
@@ -62,7 +72,10 @@ describe('', () => {
render(
-
+ ,
+ {
+ wrapper: ({ children }) => {children},
+ }
);
expect(
@@ -71,13 +84,17 @@ describe('', () => {
});
it('should show the loading component if in loading state', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(screen.getByText('mockedLoading')).toBeInTheDocument();
});
it('should show the cashier locked component if cashier is locked', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(screen.getByText('mockedCashierLocked')).toBeInTheDocument();
});
@@ -87,25 +104,33 @@ describe('', () => {
is_show_full_page: true,
};
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(screen.getByText('mockedError')).toBeInTheDocument();
});
it('should show the no balance component if account has no balance', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(screen.getByText('mockedNoBalance')).toBeInTheDocument();
});
it('should show the confirmation if validations are passed', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(screen.getByText('mockedPaymentAgentTransferConfirm')).toBeInTheDocument();
});
it('should show the receipt if transfer is successful', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(screen.getByText('mockedPaymentAgentTransferReceipt')).toBeInTheDocument();
});
diff --git a/packages/cashier/src/pages/payment-agent-transfer/payment-agent-transfer-confirm/__tests__/payment-agent-transfer-confirm.spec.js b/packages/cashier/src/pages/payment-agent-transfer/payment-agent-transfer-confirm/__tests__/payment-agent-transfer-confirm.spec.js
index f5e7029a0ac5..04174fc6619d 100644
--- a/packages/cashier/src/pages/payment-agent-transfer/payment-agent-transfer-confirm/__tests__/payment-agent-transfer-confirm.spec.js
+++ b/packages/cashier/src/pages/payment-agent-transfer/payment-agent-transfer-confirm/__tests__/payment-agent-transfer-confirm.spec.js
@@ -2,6 +2,14 @@ import React from 'react';
import ReactDOM from 'react-dom';
import { fireEvent, render, screen } from '@testing-library/react';
import PaymentAgentTransferConfirm from '../payment-agent-transfer-confirm.jsx';
+import { StoreProvider } from '@deriv/stores';
+
+const mockRootStore = {
+ ui: {
+ disableApp: jest.fn(),
+ enableApp: jest.fn(),
+ },
+};
jest.mock('Stores/connect', () => ({
__esModule: true,
@@ -31,14 +39,18 @@ describe('', () => {
};
it('should show proper icon and message', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(screen.getByTestId('dt_red_warning_icon')).toBeInTheDocument();
expect(screen.getByText('Check transfer information')).toBeInTheDocument();
});
it(`setIsTryTransferSuccessful method should be triggered when click on 'Back' button`, () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
const el_back_btn = screen.getByRole('button', { name: 'Back' });
fireEvent.click(el_back_btn);
@@ -47,7 +59,9 @@ describe('', () => {
});
it(`requestPaymentAgentTransfer fuction should be triggered if checkbox is enabled and the "Transfer now" button is clicked`, () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
const el_checkbox_transfer_consent = screen.getByRole('checkbox');
fireEvent.click(el_checkbox_transfer_consent);
@@ -63,7 +77,9 @@ describe('', () => {
});
it(`should show error message`, () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(screen.getByText('error_message')).toBeInTheDocument();
});
diff --git a/packages/cashier/src/pages/payment-agent-transfer/payment-agent-transfer-form/__tests__/payment-agent-transfer-form.spec.js b/packages/cashier/src/pages/payment-agent-transfer/payment-agent-transfer-form/__tests__/payment-agent-transfer-form.spec.js
index 0a6677b04214..761bced0a61f 100644
--- a/packages/cashier/src/pages/payment-agent-transfer/payment-agent-transfer-form/__tests__/payment-agent-transfer-form.spec.js
+++ b/packages/cashier/src/pages/payment-agent-transfer/payment-agent-transfer-form/__tests__/payment-agent-transfer-form.spec.js
@@ -1,6 +1,14 @@
import React from 'react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import PaymentAgentTransferForm from '../payment-agent-transfer-form';
+import { StoreProvider } from '@deriv/stores';
+
+const mockRootStore = {
+ ui: {
+ disableApp: jest.fn(),
+ enableApp: jest.fn(),
+ },
+};
jest.mock('Stores/connect', () => ({
__esModule: true,
@@ -33,7 +41,9 @@ describe('', () => {
});
it('should render the component', () => {
- const { container } = render();
+ const { container } = render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(container.firstChild).toHaveClass('payment-agent-transfer-form__container');
});
@@ -44,7 +54,10 @@ describe('', () => {
balance={balance}
setErrorMessage={setErrorMessage}
transfer_limit={transfer_limit}
- />
+ />,
+ {
+ wrapper: ({ children }) => {children},
+ }
);
const submit_button = screen.getByRole('button');
@@ -62,7 +75,10 @@ describe('', () => {
balance={balance}
setErrorMessage={setErrorMessage}
transfer_limit={transfer_limit}
- />
+ />,
+ {
+ wrapper: ({ children }) => {children},
+ }
);
const loginid_field = container.querySelector('input[name=loginid]');
@@ -82,7 +98,10 @@ describe('', () => {
balance={balance}
setErrorMessage={setErrorMessage}
transfer_limit={transfer_limit}
- />
+ />,
+ {
+ wrapper: ({ children }) => {children},
+ }
);
const amount_field = container.querySelector('input[name=amount]');
@@ -102,7 +121,10 @@ describe('', () => {
balance={balance}
setErrorMessage={setErrorMessage}
transfer_limit={transfer_limit}
- />
+ />,
+ {
+ wrapper: ({ children }) => {children},
+ }
);
const description_field = container.querySelector('[name=description]');
diff --git a/packages/cashier/src/pages/payment-agent/__tests__/payment-agent.spec.js b/packages/cashier/src/pages/payment-agent/__tests__/payment-agent.spec.js
index c62a89a08f52..96c49a172e9d 100644
--- a/packages/cashier/src/pages/payment-agent/__tests__/payment-agent.spec.js
+++ b/packages/cashier/src/pages/payment-agent/__tests__/payment-agent.spec.js
@@ -3,6 +3,14 @@ import { render, screen } from '@testing-library/react';
import { Router } from 'react-router';
import { createBrowserHistory } from 'history';
import PaymentAgent from '../payment-agent';
+import { StoreProvider } from '@deriv/stores';
+
+const mockRootStore = {
+ ui: {
+ is_dark_mode_on: false,
+ toggleAccountsDialog: jest.fn(),
+ },
+};
jest.mock('Stores/connect', () => ({
__esModule: true,
@@ -33,14 +41,18 @@ describe('', () => {
};
it('should render the payment agent list', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(props.setPaymentAgentActiveTabIndex).toHaveBeenCalledWith(0);
expect(screen.getByText('mockedPaymentAgentList')).toBeInTheDocument();
});
it('should render the loading component if in loading state', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(screen.getByText('mockedLoading')).toBeInTheDocument();
});
@@ -51,7 +63,10 @@ describe('', () => {
render(
-
+ ,
+ {
+ wrapper: ({ children }) => {children},
+ }
);
expect(
@@ -60,7 +75,9 @@ describe('', () => {
});
it('should show the cashier locked component if cashier is locked', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(screen.getByText('mockedCashierLocked')).toBeInTheDocument();
});
@@ -73,7 +90,9 @@ describe('', () => {
});
it('should set the active tab index accordingly', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(props.setPaymentAgentActiveTabIndex).toHaveBeenCalledWith(1);
});
diff --git a/packages/cashier/src/pages/payment-agent/payment-agent-listed-withdraw-form/__tests__/payment-agent-listed-withdraw-form.spec.js b/packages/cashier/src/pages/payment-agent/payment-agent-listed-withdraw-form/__tests__/payment-agent-listed-withdraw-form.spec.js
index 14ca7a7e6ac4..3a4203bc992c 100644
--- a/packages/cashier/src/pages/payment-agent/payment-agent-listed-withdraw-form/__tests__/payment-agent-listed-withdraw-form.spec.js
+++ b/packages/cashier/src/pages/payment-agent/payment-agent-listed-withdraw-form/__tests__/payment-agent-listed-withdraw-form.spec.js
@@ -3,6 +3,14 @@ import ReactDOM from 'react-dom';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import PaymentAgentListedWithdrawForm from '../payment-agent-listed-withdraw-form';
import { validNumber } from '@deriv/shared';
+import { StoreProvider } from '@deriv/stores';
+
+const mockRootStore = {
+ ui: {
+ is_dark_mode_on: false,
+ toggleAccountsDialog: jest.fn(),
+ },
+};
jest.mock('Stores/connect.js', () => ({
__esModule: true,
@@ -76,7 +84,9 @@ describe('', () => {
};
it('should render the component', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(screen.getByText('Withdrawal amount')).toBeInTheDocument();
expect(screen.getByText('USD')).toBeInTheDocument();
@@ -88,7 +98,9 @@ describe('', () => {
});
it('should show loader when is_loading equal to true or there is no payment agents', () => {
- const { rerender } = render();
+ const { rerender } = render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(screen.getByText('Loading')).toBeInTheDocument();
@@ -99,7 +111,9 @@ describe('', () => {
it('should show error message, if amount is not valid', async () => {
validNumber.mockReturnValue({ is_ok: false, message: 'error_message' });
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
const el_input_amount = screen.getByLabelText('Enter amount');
const el_continue_btn = screen.getByRole('button', { name: 'Continue' });
@@ -113,7 +127,9 @@ describe('', () => {
});
it('should show Insufficient balance error', async () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
const el_input_amount = screen.getByLabelText('Enter amount');
const el_continue_btn = screen.getByRole('button', { name: 'Continue' });
@@ -126,7 +142,9 @@ describe('', () => {
});
it('should trigger requestTryPaymentAgentWithdraw, when all data are valid', async () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
const el_input_amount = screen.getByLabelText('Enter amount');
const el_continue_btn = screen.getByRole('button', { name: 'Continue' });
diff --git a/packages/cashier/src/pages/payment-agent/payment-agent-unlisted-withdraw-form/__tests__/payment-agent-withdraw-form.spec.js b/packages/cashier/src/pages/payment-agent/payment-agent-unlisted-withdraw-form/__tests__/payment-agent-withdraw-form.spec.js
index c6dcd75b3c7c..325b0f25038c 100644
--- a/packages/cashier/src/pages/payment-agent/payment-agent-unlisted-withdraw-form/__tests__/payment-agent-withdraw-form.spec.js
+++ b/packages/cashier/src/pages/payment-agent/payment-agent-unlisted-withdraw-form/__tests__/payment-agent-withdraw-form.spec.js
@@ -3,6 +3,14 @@ import ReactDOM from 'react-dom';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import PaymentAgentUnlistedWithdrawForm from '../payment-agent-unlisted-withdraw-form';
import { isMobile, validNumber } from '@deriv/shared';
+import { StoreProvider } from '@deriv/stores';
+
+const mockRootStore = {
+ ui: {
+ disableApp: jest.fn(),
+ enableApp: jest.fn(),
+ },
+};
jest.mock('Stores/connect', () => ({
__esModule: true,
@@ -40,7 +48,9 @@ describe('', () => {
};
it('should render the component', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(screen.getByTestId('dt-back-arrow-icon')).toBeInTheDocument();
expect(screen.getByText('Back to list')).toBeInTheDocument();
@@ -53,7 +63,9 @@ describe('', () => {
});
it('should trigger onclick callback when arrow back button was clicked', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
const el_back_arrow_icon = screen.getByTestId('dt-back-arrow-icon');
fireEvent.click(el_back_arrow_icon);
@@ -63,7 +75,9 @@ describe('', () => {
it('should show different error messages', async () => {
validNumber.mockReturnValue({ is_ok: false, message: 'error_message' });
- const { rerender } = render();
+ const { rerender } = render(, {
+ wrapper: ({ children }) => {children},
+ });
const el_input_account_number = screen.getByLabelText('Enter the payment agent account number');
const el_input_amount = screen.getByLabelText('Enter amount');
@@ -94,7 +108,9 @@ describe('', () => {
});
it('should trigger requestTryPaymentAgentWithdraw, when all data are valid', async () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
const el_input_account_number = screen.getByLabelText('Enter the payment agent account number');
const el_input_amount = screen.getByLabelText('Enter amount');
@@ -115,7 +131,9 @@ describe('', () => {
it('should show PaymentAgentDisclaimer in mobile view', () => {
isMobile.mockReturnValue(true);
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
expect(screen.getByText('PaymentAgentDisclaimer')).toBeInTheDocument();
});
diff --git a/packages/cashier/src/pages/payment-agent/payment-agent-withdraw-confirm/__tests__/payment-agent-withdraw-confirm.spec.js b/packages/cashier/src/pages/payment-agent/payment-agent-withdraw-confirm/__tests__/payment-agent-withdraw-confirm.spec.js
index 0cd2103d2b0f..46e3199d8b34 100644
--- a/packages/cashier/src/pages/payment-agent/payment-agent-withdraw-confirm/__tests__/payment-agent-withdraw-confirm.spec.js
+++ b/packages/cashier/src/pages/payment-agent/payment-agent-withdraw-confirm/__tests__/payment-agent-withdraw-confirm.spec.js
@@ -2,6 +2,14 @@ import React from 'react';
import ReactDOM from 'react-dom';
import { fireEvent, render, screen } from '@testing-library/react';
import PaymentAgentWithdrawConfirm from '../payment-agent-withdraw-confirm';
+import { StoreProvider } from '@deriv/stores';
+
+const mockRootStore = {
+ ui: {
+ disableApp: jest.fn(),
+ enableApp: jest.fn(),
+ },
+};
jest.mock('Stores/connect', () => ({
__esModule: true,
@@ -33,7 +41,9 @@ describe('', () => {
};
it('should show proper messages and buttons', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
const [back_btn, transfer_now_btn] = screen.getAllByRole('button');
@@ -59,7 +69,10 @@ describe('', () => {
code: 'code',
message: 'error_message',
}}
- />
+ />,
+ {
+ wrapper: ({ children }) => {children},
+ }
);
expect(screen.getByText('Cashier Error')).toBeInTheDocument();
@@ -68,7 +81,9 @@ describe('', () => {
});
it('should trigger setIsTryWithdrawSuccessful method when the client clicks on Back button', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
const [back_btn, _] = screen.getAllByRole('button');
fireEvent.click(back_btn);
@@ -77,7 +92,9 @@ describe('', () => {
});
it('should enable Transfer now button when checkbox is checked', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
const el_checkbox = screen.getByRole('checkbox');
const [_, transfer_now_btn] = screen.getAllByRole('button');
@@ -87,7 +104,9 @@ describe('', () => {
});
it('should trigger requestPaymentAgentWithdraw method when the client clicks on Transfer now button', () => {
- render();
+ render(, {
+ wrapper: ({ children }) => {children},
+ });
const el_checkbox = screen.getByRole('checkbox');
const [_, transfer_now_btn] = screen.getAllByRole('button');
diff --git a/packages/components/src/components/button-link/button-link.tsx b/packages/components/src/components/button-link/button-link.tsx
index 3d9976c05607..6508041021ec 100644
--- a/packages/components/src/components/button-link/button-link.tsx
+++ b/packages/components/src/components/button-link/button-link.tsx
@@ -4,7 +4,7 @@ import { Link } from 'react-router-dom';
type TButtonLinkProps = Omit, 'size'> & {
to: string;
- size: 'small' | 'medium' | 'large';
+ size?: 'small' | 'medium' | 'large';
};
const ButtonLink = ({
diff --git a/packages/components/src/components/send-email-template/send-email-template.tsx b/packages/components/src/components/send-email-template/send-email-template.tsx
index ff77bfa1318b..c7a299692fb3 100644
--- a/packages/components/src/components/send-email-template/send-email-template.tsx
+++ b/packages/components/src/components/send-email-template/send-email-template.tsx
@@ -32,7 +32,7 @@ const SendEmailTemplate = ({
const [is_email_not_received_clicked, setIsEmailNotReceivedClicked] = React.useState(false);
const [is_resend_btn_disabled, setIsResendBtnDisabled] = React.useState(false);
const [resend_email_btn_text, setResendEmailBtnText] = React.useState(txt_resend);
- const { is_appstore } = React.useContext<{ is_appstore?: boolean }>(PlatformContext);
+ const { is_appstore } = React.useContext<{ is_pre_appstore: boolean; is_appstore: boolean }>(PlatformContext);
const timeout_limit = resend_timeout || 60;
let resend_interval: number;
diff --git a/packages/shared/src/utils/platform/platform-context.tsx b/packages/shared/src/utils/platform/platform-context.tsx
index aba2bfbc2d68..c01a64a92eb9 100644
--- a/packages/shared/src/utils/platform/platform-context.tsx
+++ b/packages/shared/src/utils/platform/platform-context.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-export const PlatformContext = React.createContext({});
+export const PlatformContext = React.createContext({} as { is_pre_appstore: boolean; is_appstore: boolean });
PlatformContext.displayName = 'DerivAppStorePlatformContext';
From c4a17e7eb22e8645c5cd409a6222bd285585c43f Mon Sep 17 00:00:00 2001
From: amina-deriv <84661147+amina-deriv@users.noreply.github.com>
Date: Wed, 14 Dec 2022 10:36:29 +0400
Subject: [PATCH 13/22] Amina/ 83129/fix: Compare_accounts_modal_is_broken
(#7138)
* fix: compare accounts modal
* fix: function_param_name
---
.../Containers/mt5-compare-table-content.tsx | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/packages/cfd/src/Containers/mt5-compare-table-content.tsx b/packages/cfd/src/Containers/mt5-compare-table-content.tsx
index 89db52a24fc1..f44913262ad0 100644
--- a/packages/cfd/src/Containers/mt5-compare-table-content.tsx
+++ b/packages/cfd/src/Containers/mt5-compare-table-content.tsx
@@ -310,9 +310,18 @@ const DMT5CompareModalContent = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
- const getAvailableAccountsContent = (_content: TModalContentProps[]) => {
- if (!is_logged_in) return _content;
- return _content.map(row_data => {
+ const getAvailableAccountsContent = (modal_content: TModalContentProps[]) => {
+ if (!is_logged_in) {
+ if (show_eu_related) {
+ return modal_content;
+ }
+ const mt5_data = modal_content.map(item => {
+ const { derivx, ...rest } = item.values; // eslint-disable-line @typescript-eslint/no-unused-vars
+ return { ...item, values: rest };
+ });
+ return mt5_data;
+ }
+ return modal_content.map(row_data => {
const available_accounts_values = Object.entries(row_data.values).reduce(
(acc, [key, value]) => (available_accounts_keys.includes(key) ? { ...acc, [key]: value } : acc),
{} as TValues
@@ -348,8 +357,8 @@ const DMT5CompareModalContent = ({
});
};
- const getAvailableAccountsFooterButtons = (_footer_button_data: TFooterButtonData[]) => {
- return _footer_button_data.filter(data => available_accounts_keys.includes(data.action));
+ const getAvailableAccountsFooterButtons = (footer_button_data: TFooterButtonData[]) => {
+ return footer_button_data.filter(data => available_accounts_keys.includes(data.action));
};
const openPersonalDetailsFormOrPasswordForm = (type_of_account: { category: string; type: string }) =>
!has_submitted_personal_details ? toggleCFDPersonalDetailsModal(true) : openPasswordModal(type_of_account);
From 9f4f61d26d2dee1150c1cf98826a6bd01814ebff Mon Sep 17 00:00:00 2001
From: aizad-deriv <103104395+aizad-deriv@users.noreply.github.com>
Date: Wed, 14 Dec 2022 14:47:24 +0800
Subject: [PATCH 14/22] Aizad/fix: added help centre inside mobile drawer
(#7074)
* fix: added help centre inside mobile drawer
* fix: add help centre inside a function
* fix: resolve code
---
.../Layout/Header/toggle-menu-drawer.jsx | 68 +++++++++++--------
1 file changed, 40 insertions(+), 28 deletions(-)
diff --git a/packages/core/src/App/Components/Layout/Header/toggle-menu-drawer.jsx b/packages/core/src/App/Components/Layout/Header/toggle-menu-drawer.jsx
index 27c2cad3ab00..8acda1f08143 100644
--- a/packages/core/src/App/Components/Layout/Header/toggle-menu-drawer.jsx
+++ b/packages/core/src/App/Components/Layout/Header/toggle-menu-drawer.jsx
@@ -314,6 +314,21 @@ const ToggleMenuDrawer = React.forwardRef(
);
};
+
+ const HelpCentreRoute = has_border_bottom => {
+ return (
+
+
+
+ );
+ };
+
const { pathname: route } = useLocation();
const history = useHistory();
@@ -489,15 +504,7 @@ const ToggleMenuDrawer = React.forwardRef(
{is_logged_in && (
-
-
-
+ {HelpCentreRoute()}
{
- e.preventDefault();
- toggleTheme(!is_dark_mode);
- }}
- >
-
-
-
- {localize('Dark theme')}
-
- toggleTheme(!is_dark_mode)}
- is_enabled={is_dark_mode}
- />
-
-
+
+ {
+ e.preventDefault();
+ toggleTheme(!is_dark_mode);
+ }}
+ >
+
+
+
+ {localize('Dark theme')}
+
+ toggleTheme(!is_dark_mode)}
+ is_enabled={is_dark_mode}
+ />
+
+
+ {HelpCentreRoute(true)}
+
}
{liveChat.isReady && (
From 63a4fb12d26f12b32abf973dcfefd7c4eee54742 Mon Sep 17 00:00:00 2001
From: mitra-deriv <64970259+mitra-deriv@users.noreply.github.com>
Date: Wed, 14 Dec 2022 15:33:09 +0800
Subject: [PATCH 15/22] Mitra/81286/show whatsapp to all countries (#6961)
* feat: :sparkles: show whatsapp to all countries
* fix: :bug: close mobile drawer once clicked on whatsapp
* fix: :bug: circle ci test failure
---
.../App/Components/Elements/WhatsApp/whatsapp.tsx | 13 ++-----------
.../Components/Layout/Header/toggle-menu-drawer.jsx | 8 ++------
.../Layout/header/dashboard-platform-header.jsx | 4 ----
.../App/Containers/Layout/header/default-header.jsx | 4 ----
packages/core/src/Stores/client-store.js | 9 ---------
5 files changed, 4 insertions(+), 34 deletions(-)
diff --git a/packages/core/src/App/Components/Elements/WhatsApp/whatsapp.tsx b/packages/core/src/App/Components/Elements/WhatsApp/whatsapp.tsx
index 9e9398761297..3f99d3eac049 100644
--- a/packages/core/src/App/Components/Elements/WhatsApp/whatsapp.tsx
+++ b/packages/core/src/App/Components/Elements/WhatsApp/whatsapp.tsx
@@ -1,21 +1,14 @@
import React from 'react';
import { Popover, Icon } from '@deriv/components';
import { localize } from '@deriv/translations';
-import { connect } from 'Stores/connect';
import useLiveChat from 'App/Components/Elements/LiveChat/use-livechat';
import { whatsapp_url } from '@deriv/shared';
-type TWhatsAppProps = {
- can_have_whatsapp: boolean;
-};
-
-const WhatsApp = ({ can_have_whatsapp }: TWhatsAppProps) => {
+const WhatsApp = () => {
const liveChat = useLiveChat();
if (!liveChat.isReady) return null;
- if (!can_have_whatsapp) return null;
-
return (
{
);
};
-export default connect(({ client }) => ({
- can_have_whatsapp: client.can_have_whatsapp,
-}))(WhatsApp);
+export default WhatsApp;
diff --git a/packages/core/src/App/Components/Layout/Header/toggle-menu-drawer.jsx b/packages/core/src/App/Components/Layout/Header/toggle-menu-drawer.jsx
index 8acda1f08143..3add6eb68d8b 100644
--- a/packages/core/src/App/Components/Layout/Header/toggle-menu-drawer.jsx
+++ b/packages/core/src/App/Components/Layout/Header/toggle-menu-drawer.jsx
@@ -549,9 +549,7 @@ const ToggleMenuDrawer = React.forwardRef(
href={whatsapp_url}
target='_blank'
rel='noopener noreferrer'
- onClick={() => {
- toggleDrawer();
- }}
+ onClick={toggleDrawer}
>
{localize('WhatsApp')}
@@ -669,11 +667,9 @@ const ToggleMenuDrawer = React.forwardRef(
{
- toggleDrawer();
- }}
>
{localize('WhatsApp')}
diff --git a/packages/core/src/App/Containers/Layout/header/dashboard-platform-header.jsx b/packages/core/src/App/Containers/Layout/header/dashboard-platform-header.jsx
index 1d8e5f6cbf62..e3f27794be3e 100644
--- a/packages/core/src/App/Containers/Layout/header/dashboard-platform-header.jsx
+++ b/packages/core/src/App/Containers/Layout/header/dashboard-platform-header.jsx
@@ -96,7 +96,6 @@ const AccountBalance = ({ balance, currency }) => {
const DashboardPlatformHeader = ({
account_status,
- can_have_whatsapp,
app_routing_history,
balance,
currency,
@@ -140,7 +139,6 @@ const DashboardPlatformHeader = ({
ref={toggle_menu_drawer_ref}
should_allow_authentication={should_allow_authentication}
account_status={account_status}
- can_have_whatsapp={can_have_whatsapp}
enableApp={enableApp}
disableApp={disableApp}
location={location}
@@ -205,7 +203,6 @@ const DashboardPlatformHeader = ({
DashboardPlatformHeader.propTypes = {
account_status: PropTypes.object,
- can_have_whatsapp: PropTypes.bool,
app_routing_history: PropTypes.array,
balance: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
currency: PropTypes.string,
@@ -235,7 +232,6 @@ DashboardPlatformHeader.propTypes = {
export default connect(({ client, common, modules, notifications, ui }) => ({
account_status: client.account_status,
- can_have_whatsapp: client.can_have_whatsapp,
app_routing_history: common.app_routing_history,
balance: client.balance,
currency: client.currency,
diff --git a/packages/core/src/App/Containers/Layout/header/default-header.jsx b/packages/core/src/App/Containers/Layout/header/default-header.jsx
index 2cdf5f33547d..92e2bd17855f 100644
--- a/packages/core/src/App/Containers/Layout/header/default-header.jsx
+++ b/packages/core/src/App/Containers/Layout/header/default-header.jsx
@@ -18,7 +18,6 @@ import { Localize } from '@deriv/translations';
const DefaultHeader = ({
acc_switcher_disabled_message,
account_status,
- can_have_whatsapp,
account_type,
addNotificationMessage,
app_routing_history,
@@ -173,7 +172,6 @@ const DefaultHeader = ({
ref={toggle_menu_drawer_ref}
should_allow_authentication={should_allow_authentication}
account_status={account_status}
- can_have_whatsapp={can_have_whatsapp}
enableApp={enableApp}
disableApp={disableApp}
location={location}
@@ -272,7 +270,6 @@ DefaultHeader.propTypes = {
account_type: PropTypes.string,
should_allow_authentication: PropTypes.bool,
account_status: PropTypes.object,
- can_have_whatsapp: PropTypes.bool,
addNotificationMessage: PropTypes.func,
app_routing_history: PropTypes.array,
balance: PropTypes.string,
@@ -322,7 +319,6 @@ export default connect(({ client, common, ui, menu, modules, notifications }) =>
changeCurrentLanguage: common.changeCurrentLanguage,
acc_switcher_disabled_message: ui.account_switcher_disabled_message,
account_status: client.account_status,
- can_have_whatsapp: client.can_have_whatsapp,
account_type: client.account_type,
should_allow_authentication: client.should_allow_authentication,
addNotificationMessage: notifications.addNotificationMessage,
diff --git a/packages/core/src/Stores/client-store.js b/packages/core/src/Stores/client-store.js
index d92fb5db4bd5..1b8cb1a4fff9 100644
--- a/packages/core/src/Stores/client-store.js
+++ b/packages/core/src/Stores/client-store.js
@@ -273,7 +273,6 @@ export default class ClientStore extends BaseStore {
can_have_mlt_account: computed,
can_have_mx_account: computed,
can_have_mf_account: computed,
- can_have_whatsapp: computed,
can_upgrade: computed,
can_upgrade_to: computed,
virtual_account_loginid: computed,
@@ -892,14 +891,6 @@ export default class ClientStore extends BaseStore {
return countries;
}
- get can_have_whatsapp() {
- const country = this.residence || this.clients_country;
- const allowed_countries = ['za', 'ng'];
- const is_allowed_country = allowed_countries.includes(country);
-
- return is_allowed_country;
- }
-
get can_upgrade() {
return this.upgrade_info && (this.upgrade_info.can_upgrade || this.upgrade_info.can_open_multi);
}
From 60d3dd3e2d195be3515def7cbc88c61ad7200573 Mon Sep 17 00:00:00 2001
From: aizad-deriv <103104395+aizad-deriv@users.noreply.github.com>
Date: Thu, 15 Dec 2022 10:09:25 +0800
Subject: [PATCH 16/22] Aizad/83093/tin msg (#7164)
* fix: tax identification number field spacing
* fix: use rem
---
.../Profile/PersonalDetails/personal-details.jsx | 7 ++++++-
packages/account/src/Styles/account.scss | 14 ++++++++------
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/packages/account/src/Sections/Profile/PersonalDetails/personal-details.jsx b/packages/account/src/Sections/Profile/PersonalDetails/personal-details.jsx
index 3c462f4adc49..e66fbcdce99d 100644
--- a/packages/account/src/Sections/Profile/PersonalDetails/personal-details.jsx
+++ b/packages/account/src/Sections/Profile/PersonalDetails/personal-details.jsx
@@ -922,7 +922,12 @@ export const PersonalDetailsForm = ({
)}
{'tax_identification_number' in values && (
-