Skip to content

Commit

Permalink
Thisyahlen/WALL-1020/ List of wallets according to authorize and bala…
Browse files Browse the repository at this point in the history
…nce (#9010)

* chore: add balance from response, switching and refactor

* fix: test and verification only for eu users

* fix: tests

* fix: modal first, then switch account

* fix: refactor logic to hooks

* fix: refactor to use wallet_account instead of data

* redeploy: vercel

* fix: refactor test

* fix: tests and address comments

* fix: use debounce instead of settimeout

* fix: refactor tests and hooks

* fix: use landing_company_name instead of shortcode

* fix: test title

* fix: scroll to active wallet upon click

* fix: resolve test and comments

* fix: test

* fix: tests again
  • Loading branch information
thisyahlen-deriv committed Jun 30, 2023
1 parent dcb1f33 commit ea06eb4
Show file tree
Hide file tree
Showing 31 changed files with 704 additions and 632 deletions.
33 changes: 32 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion packages/appstore/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,17 @@
"@deriv/cashier": "^1.0.0",
"@deriv/components": "^1.0.0",
"@deriv/cfd": "^1.0.0",
"@deriv/hooks": "^1.0.0",
"@deriv/shared": "^1.0.0",
"@deriv/stores": "^1.0.0",
"@testing-library/jest-dom": "^5.12.0",
"@deriv/hooks": "^1.0.0",
"@deriv/trader": "^3.8.0",
"@deriv/translations": "^1.0.0",
"@deriv/hooks": "^1.0.0",
"@deriv/ui": "^0.8.0",
"classnames": "^2.2.6",
"formik": "^2.1.4",
"lodash.debounce": "^4.0.8",
"mobx": "^6.6.1",
"mobx-react-lite": "^3.4.0",
"object.fromentries": "^2.0.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { render, screen, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom';
import userEvent from '@testing-library/user-event';
import { mockStore, StoreProvider } from '@deriv/stores';
import { TCoreStores } from '@deriv/stores/types';
import Wallet from '../wallet';
import { TWalletAccount } from 'Types';

const mockedRootStore = mockStore({
modules: {
Expand All @@ -14,79 +14,85 @@ const mockedRootStore = mockStore({
},
});

jest.mock('react-transition-group', () => ({
CSSTransition: jest.fn(({ children }) => <div>{children}</div>),
}));

jest.mock('@deriv/account', () => ({
...jest.requireActual('@deriv/account'),
getStatusBadgeConfig: jest.fn(() => ({ icon: '', text: '' })),
}));

jest.mock('@deriv/hooks', () => ({
...jest.requireActual('@deriv/hooks'),
useWalletModalActionHandler: jest.fn(() => ({ setWalletModalActiveTabIndex: jest.fn(), handleAction: jest.fn() })),
}));

jest.mock('./../currency-switcher-container', () => jest.fn(({ children }) => <div>{children}</div>));
jest.mock('./../../wallet-content', () => jest.fn(() => <span>wallet test content</span>));

let wallet_account: TCoreStores['client']['accounts'][0];

describe('<Wallets />', () => {
let mocked_props: TWalletAccount;
beforeEach(() => {
wallet_account = {
balance: 10415.24,
mocked_props = {
is_demo: false,
currency: 'USD',
landing_company_shortcode: 'svg',
is_virtual: 1,
loginid: 'CRW12345',
// @ts-expect-error This should be fixed when we remove the mock transactions
gradient_class: 'demo',
landing_company_name: 'svg',
balance: 10000,
loginid: 'CR123123',
is_malta_wallet: false,
is_selected: false,
gradient_header_class: 'wallet-header__usd-bg',
gradient_card_class: 'wallet-card__usd-bg',
};
});

it('Check class for NOT demo', () => {
wallet_account.is_virtual = 0;

const { container } = render(
<StoreProvider store={mockedRootStore}>
<Wallet wallet_account={wallet_account} />
<Wallet wallet_account={mocked_props} />
</StoreProvider>
);

expect(container.childNodes[0]).toHaveClass('wallet');
expect(container.childNodes[0]).not.toHaveClass('wallet__demo');
});

it('Check class for demo', () => {
mocked_props.is_demo = true;
const { container } = render(
<StoreProvider store={mockedRootStore}>
<Wallet wallet_account={wallet_account} />
<Wallet wallet_account={mocked_props} />
</StoreProvider>
);

expect(container.childNodes[0]).toHaveClass('wallet');
expect(container.childNodes[0]).toHaveClass('wallet__demo');
});

it('Should show content when clicking on arrow icon', async () => {
const Wrapper = () => {
const [is_open, wrapperSetIsOpen] = React.useState(false);
return (
<StoreProvider store={mockedRootStore}>
<Wallet wallet_account={wallet_account} active={is_open} setActive={wrapperSetIsOpen} />
</StoreProvider>
);
};
it('Should show content when button is clicked ', async () => {
mocked_props.is_demo = true;
render(
<StoreProvider store={mockedRootStore}>
<Wallet wallet_account={mocked_props} />
</StoreProvider>
);

render(<Wrapper />);
const arrow_icon = screen.getByTestId('dt_arrow');

expect(screen.queryByText('wallet test content')).not.toBeInTheDocument();
userEvent.click(arrow_icon);
await waitFor(() => {
mockedRootStore.client.loginid = 'CR123123';
});
expect(screen.queryByText('wallet test content')).toBeInTheDocument();
});

it('Check for demo wallet header', () => {
mocked_props.is_demo = true;
render(
<StoreProvider store={mockedRootStore}>
<Wallet wallet_account={wallet_account} />
<Wallet wallet_account={mocked_props} />
</StoreProvider>
);
const currency_card = screen.queryByTestId(`dt_demo`);

expect(currency_card).toBeInTheDocument();
});
});
45 changes: 20 additions & 25 deletions packages/appstore/src/components/containers/wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,36 @@ import classNames from 'classnames';
import WalletHeader from 'Components/wallet-header';
import WalletContent from 'Components/wallet-content';
import { CSSTransition } from 'react-transition-group';
import { formatMoney } from '@deriv/shared';
import { TWalletCurrency, TWalletShortcode, TWalletAccount } from 'Types';
import { observer } from '@deriv/stores';
import { TWalletAccount } from 'Types';
import './wallet.scss';

type TWallet = {
wallet_account: TWalletAccount;
active: boolean;
setActive: (is_open: boolean) => void;
};

const Wallet = React.memo(({ wallet_account, active, setActive }: TWallet) => {
const is_demo = wallet_account.is_virtual;
const shortcode =
wallet_account.landing_company_shortcode === 'maltainvest' ? 'malta' : wallet_account.landing_company_shortcode;
const Wallet = observer(({ wallet_account }: TWallet) => {
const headerRef = React.useRef<HTMLDivElement>(null);

return (
<div
className={classNames('wallet', {
wallet__demo: is_demo,
})}
>
<WalletHeader
account_type={is_demo ? 'demo' : 'real'}
balance={formatMoney(wallet_account.currency, wallet_account.balance, true)}
gradient_class={wallet_account.gradient_card_class}
currency={wallet_account.currency as TWalletCurrency}
shortcode={shortcode as TWalletShortcode}
is_open_wallet={active}
setIsOpen={setActive}
/>
<CSSTransition appear in={active} timeout={240} classNames='wallet__content-transition' unmountOnExit>
<WalletContent is_demo={!!is_demo} is_eu={shortcode === 'malta'} wallet_account={wallet_account} />
<div ref={headerRef} className={classNames('wallet', { wallet__demo: wallet_account.is_demo })}>
<WalletHeader wallet_account={wallet_account} />
<CSSTransition
appear
in={wallet_account.is_selected}
timeout={240}
onEntered={() => {
if (headerRef?.current) {
headerRef.current.style.scrollMargin = '20px';
headerRef.current.scrollIntoView({ behavior: 'smooth' });
}
}}
classNames='wallet__content-transition'
unmountOnExit
>
<WalletContent wallet_account={wallet_account} />
</CSSTransition>
</div>
);
});
Wallet.displayName = 'Wallet';
export default Wallet;
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { render, screen, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { BrowserRouter } from 'react-router-dom';
import WalletModalBody from '../wallet-modal-body';
import { mockStore, StoreProvider } from '@deriv/stores';

jest.mock('Components/wallet-transfer', () => jest.fn(() => <div>WalletTransfer</div>));
jest.mock('Components/fiat-transaction-list', () => jest.fn(() => <div>Transactions</div>));
Expand All @@ -12,12 +13,10 @@ describe('WalletModalBody', () => {

beforeEach(() => {
mocked_props = {
active_tab_index: 0,
contentScrollHandler: jest.fn(),
is_dark: false,
is_demo: true,
is_mobile: false,
setActiveTabIndex: jest.fn(),
setIsWalletNameVisible: jest.fn(),
is_wallet_name_visible: true,
wallet_type: 'demo',
Expand All @@ -29,34 +28,72 @@ describe('WalletModalBody', () => {
};

it('Should render proper tabs for demo wallet', () => {
renderWithRouter(<WalletModalBody {...mocked_props} />);
const mocked_store = mockStore({
traders_hub: {
active_modal_tab: 'Transfer',
},
});
renderWithRouter(
<StoreProvider store={mocked_store}>
<WalletModalBody {...mocked_props} />
</StoreProvider>
);

expect(screen.getByText('Transfer')).toBeInTheDocument();
expect(screen.getByText('Transactions')).toBeInTheDocument();
expect(screen.getByText('Reset balance')).toBeInTheDocument();
});

it('Should render proper content under the Transfer tab', () => {
mocked_props.active_tab_index = 1;
renderWithRouter(<WalletModalBody {...mocked_props} />);
mocked_props.wallet_type = 'real';
const mocked_store = mockStore({
traders_hub: {
active_modal_tab: 'Withdraw',
},
});
renderWithRouter(
<StoreProvider store={mocked_store}>
<WalletModalBody {...mocked_props} />
</StoreProvider>
);

const el_transfer_tab = screen.getByText('Transfer');
userEvent.click(el_transfer_tab);

expect(screen.getByText('WalletTransfer')).toBeInTheDocument();
expect(screen.getByText('Transfer')).toBeInTheDocument();
});

it('Should trigger setActiveTabIndex callback when the user clicked on the tab', () => {
renderWithRouter(<WalletModalBody {...mocked_props} />);
it('Should trigger setWalletModalActiveTab callback when the user clicked on the tab', () => {
mocked_props.wallet_type = 'real';
const mocked_store = mockStore({
traders_hub: {
active_modal_tab: 'Deposit',
},
});
renderWithRouter(
<StoreProvider store={mocked_store}>
<WalletModalBody {...mocked_props} />
</StoreProvider>
);

const el_transactions_tab = screen.getByText('Transactions');
userEvent.click(el_transactions_tab);

expect(mocked_props.setActiveTabIndex).toHaveBeenCalledTimes(1);
expect(mocked_store.traders_hub.setWalletModalActiveTab).toHaveBeenCalledTimes(1);
});

it('Should trigger contentScrollHandler callback when the user scrolls the content', () => {
renderWithRouter(<WalletModalBody {...mocked_props} />);
mocked_props.wallet_type = 'real';
const mocked_store = mockStore({
traders_hub: {
active_modal_tab: 'Deposit',
},
});
renderWithRouter(
<StoreProvider store={mocked_store}>
<WalletModalBody {...mocked_props} />
</StoreProvider>
);

const el_themed_scrollbars = screen.getByTestId('dt_themed_scrollbars');
fireEvent.scroll(el_themed_scrollbars);
Expand Down
Loading

0 comments on commit ea06eb4

Please sign in to comment.