Skip to content

Commit

Permalink
Akmal / fix: add sell error modals in reports package (deriv-com#14689)
Browse files Browse the repository at this point in the history
* fix: add sell error modals in reports package

* feat: trigger deployment

* fix: remove unused component and test cases

* fix: swtich to Localize
  • Loading branch information
akmal-deriv authored and vinu-deriv committed May 28, 2024
1 parent 3824fe2 commit 3c29e76
Show file tree
Hide file tree
Showing 23 changed files with 1,038 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import AccountVerificationPendingModal from '../account-verification-pending-modal';

describe('<AccountVerificationPendingModal />', () => {
let modal_root_el: HTMLDivElement;

beforeAll(() => {
modal_root_el = document.createElement('div');
modal_root_el.setAttribute('id', 'modal_root');
document.body.appendChild(modal_root_el);
});

afterAll(() => {
document.body.removeChild(modal_root_el);
});

const mock_props: React.ComponentProps<typeof AccountVerificationPendingModal> = {
is_visible: true,
onConfirm: jest.fn(),
};

const modal_heading = /Pending verification/;
const modal_desc =
/You cannot trade as your documents are still under review. We will notify you by email once your verification is approved./i;

it('should render the component AccountVerificationPendingModal if is_visible is true', () => {
render(<AccountVerificationPendingModal {...mock_props} />);

expect(screen.getByRole('heading', { name: modal_heading })).toBeInTheDocument();
expect(screen.getByText(modal_desc)).toBeInTheDocument();

const confirm_ok_btn = screen.getByRole('button', { name: /OK/i });
expect(confirm_ok_btn).toBeInTheDocument();
expect(confirm_ok_btn).toBeEnabled();
});

it('should call onConfirm when clicking on OK button', () => {
render(<AccountVerificationPendingModal {...mock_props} />);

const confirm_ok_btn = screen.getByRole('button', { name: /OK/i });
userEvent.click(confirm_ok_btn);
expect(mock_props.onConfirm).toBeCalledTimes(1);
});

it('should not render the component if is_visible is false ', () => {
render(<AccountVerificationPendingModal {...mock_props} is_visible={false} />);

expect(screen.queryByRole('heading', { name: modal_heading })).not.toBeInTheDocument();
expect(screen.queryByText(modal_desc)).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: /OK/i })).not.toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import { Button, Modal } from '@deriv/components';
import { Localize } from '@deriv/translations';

type TAccountVerificationPendingModalProps = {
is_visible: boolean;
onConfirm: () => void;
};

const AccountVerificationPendingModal = ({ is_visible, onConfirm }: TAccountVerificationPendingModalProps) => (
<Modal
small
is_open={is_visible}
title={<Localize i18n_default_text='Pending verification' />}
toggleModal={onConfirm}
className='account-verification-pending-modal'
>
<Modal.Body>
<Localize i18n_default_text='You cannot trade as your documents are still under review. We will notify you by email once your verification is approved.' />
</Modal.Body>
<Modal.Footer>
<Button has_effect onClick={onConfirm} primary large>
<Localize i18n_default_text='OK' />
</Button>
</Modal.Footer>
</Modal>
);

export default AccountVerificationPendingModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import AccountVerificationPendingModal from './account-verification-pending-modal';

export default AccountVerificationPendingModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { render, screen } from '@testing-library/react';
import MarketUnavailableModal from '../market-unavailable';
import { mockStore } from '@deriv/stores';
import ReportsProviders from '../../../../../reports-providers';

const mock_props = {
onCancel: jest.fn(),
onConfirm: jest.fn(),
};

describe('MarketUnavailableModal', () => {
it('should render modal component', () => {
const mock_root_store = mockStore({ ui: { has_only_forward_starting_contracts: true } });

(ReactDOM.createPortal as jest.Mock) = jest.fn(component => {
return component;
});

render(<MarketUnavailableModal {...mock_props} />, {
wrapper: ({ children }) => <ReportsProviders store={mock_root_store}>{children}</ReportsProviders>,
});

expect(screen.getByText(/This market is not yet/i)).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import MarketUnavailableModal from './market-unavailable';

export default MarketUnavailableModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react';
import { Dialog } from '@deriv/components';
import { getPlatformSettings } from '@deriv/shared';
import { localize, Localize } from '@deriv/translations';
import { observer, useStore } from '@deriv/stores';

type TMarketUnavailableModalProps = {
is_loading?: boolean;
onCancel: () => void;
onConfirm: () => void;
};

const MarketUnavailableModal = observer(({ is_loading, onCancel, onConfirm }: TMarketUnavailableModalProps) => {
const { ui } = useStore();
const { disableApp, enableApp, has_only_forward_starting_contracts: is_visible } = ui;

return (
<Dialog
className='market-unavailable-modal'
title={<Localize i18n_default_text='We’re working on it' />}
confirm_button_text={localize('Stay on {{platform_name_trader}}', {
platform_name_trader: getPlatformSettings('trader').name,
})}
cancel_button_text={localize('Go to {{platform_name_smarttrader}}', {
platform_name_smarttrader: getPlatformSettings('smarttrader').name,
})}
onConfirm={onConfirm}
onCancel={onCancel}
is_mobile_full_width={false}
is_visible={is_visible}
disableApp={disableApp}
enableApp={enableApp}
is_loading={is_loading}
>
<Localize
i18n_default_text='This market is not yet available on {{platform_name_trader}}, but it is on {{platform_name_smarttrader}}.'
values={{
platform_name_trader: getPlatformSettings('trader').name,
platform_name_smarttrader: getPlatformSettings('smarttrader').name,
}}
/>
</Dialog>
);
});

export default MarketUnavailableModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import React from 'react';
import { createBrowserHistory } from 'history';
import { Router } from 'react-router-dom';
import { screen, render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { routes } from '@deriv/shared';
import { useStore } from '@deriv/stores';
import AccountVerificationRequiredModal from '../account-verification-required-modal';

type TModal = React.FC<{
children: React.ReactNode;
is_open: boolean;
title: string;
height: string;
}> & {
Body?: React.FC<{
children: React.ReactNode;
}>;
Footer?: React.FC<{
children: React.ReactNode;
}>;
};

jest.mock('@deriv/stores', () => ({
...jest.requireActual('@deriv/stores'),
observer: jest.fn(x => x),
useStore: jest.fn(() => ({
ui: {
is_mobile: true,
},
})),
}));

jest.mock('@deriv/shared', () => ({
...jest.requireActual('@deriv/shared'),
isMobile: jest.fn(() => true),
}));

jest.mock('@deriv/components', () => {
const original_module = jest.requireActual('@deriv/components');
const Modal: TModal = jest.fn(({ children, is_open, title, height }) => {
if (is_open) {
return (
<div data-testid='modal'>
<h3>{title}</h3>
<p>{height}</p>
{children}
</div>
);
}
return null;
});
Modal.Body = jest.fn(({ children }) => <div>{children}</div>);
Modal.Footer = jest.fn(({ children }) => <div>{children}</div>);

return {
...original_module,
Modal,
};
});
describe('<AccountVerificationRequiredModal />', () => {
let mocked_props: React.ComponentProps<typeof AccountVerificationRequiredModal>;
const history = createBrowserHistory();
const renderWithRouter = (component: React.ReactElement) => {
return render(<Router history={history}>{component}</Router>);
};

beforeEach(() => {
mocked_props = {
onConfirm: jest.fn(),
is_visible: true,
};
});
it('height should be auto if isMobile is true', () => {
render(<AccountVerificationRequiredModal {...mocked_props} />);
expect(screen.getByText('auto')).toBeInTheDocument();
});
it('height should be 220px if isMobile is false', () => {
(useStore as jest.Mock).mockReturnValue({
ui: {
is_mobile: false,
},
});
render(<AccountVerificationRequiredModal {...mocked_props} />);
expect(screen.getByText('220px')).toBeInTheDocument();
});
it('should render modal title, modal description, and submit button.', () => {
render(<AccountVerificationRequiredModal {...mocked_props} />);
expect(screen.getByText(/account verification required/i)).toBeInTheDocument();
expect(
screen.getByText(
/Please submit your proof of identity and proof of address to verify your account and continue trading./i
)
).toBeInTheDocument();
expect(screen.getByText(/submit proof/i)).toBeInTheDocument();
});
it('should return null when is_visible is false', () => {
mocked_props.is_visible = false;
const { container } = render(<AccountVerificationRequiredModal {...mocked_props} />);
expect(container).toBeEmptyDOMElement();
});
it('should navigate to proof_of_identity url on clicking on submit button', () => {
renderWithRouter(<AccountVerificationRequiredModal {...mocked_props} />);
const submit_proof_button = screen.getByText(/submit proof/i);
userEvent.click(submit_proof_button);
expect(history.location.pathname).toBe(routes.proof_of_identity);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React from 'react';
import { screen, render } from '@testing-library/react';
import AuthorizationRequiredModal from '../authorization-required-modal';
import { redirectToLogin, redirectToSignUp } from '@deriv/shared';
import userEvent from '@testing-library/user-event';

type TModal = React.FC<{
children: React.ReactNode;
is_open: boolean;
title: string;
}> & {
Body?: React.FC<{
children: React.ReactNode;
}>;
Footer?: React.FC<{
children: React.ReactNode;
}>;
};

jest.mock('@deriv/components', () => {
const original_module = jest.requireActual('@deriv/components');
const Modal: TModal = jest.fn(({ children, is_open, title }) => {
if (is_open) {
return (
<div data-testid='modal'>
<h3>{title}</h3>
{children}
</div>
);
}
return null;
});
Modal.Body = jest.fn(({ children }) => <div>{children}</div>);
Modal.Footer = jest.fn(({ children }) => <div>{children}</div>);

return {
...original_module,
Modal,
};
});

jest.mock('@deriv/shared', () => ({
...jest.requireActual('@deriv/shared'),
redirectToLogin: jest.fn(),
redirectToSignUp: jest.fn(),
}));

describe('<AuthorizationRequiredModal />', () => {
const mocked_props = {
is_visible: true,
toggleModal: jest.fn(),
is_logged_in: true,
is_appstore: true,
};

it('modal title, modal description, log in button, and signup button to be rendered', () => {
render(<AuthorizationRequiredModal {...mocked_props} />);
expect(screen.getByText(/start trading with us/i)).toBeInTheDocument();
expect(screen.getByText(/Log in or create a free account to place a trade/i)).toBeInTheDocument();
expect(screen.getByText('Log in')).toBeInTheDocument();
expect(screen.getByText(/create free account/i)).toBeInTheDocument();
});
it('redirectToLogin should be called when Log in button is clicked', () => {
render(<AuthorizationRequiredModal {...mocked_props} />);
userEvent.click(screen.getByText('Log in'));
expect(redirectToLogin).toHaveBeenCalled();
});
it('redirectToSignUp should be called when Log in button is clicked', () => {
render(<AuthorizationRequiredModal {...mocked_props} />);
userEvent.click(screen.getByText(/create free account/i));
expect(redirectToSignUp).toHaveBeenCalled();
});
it('should return null when is_visible is false', () => {
mocked_props.is_visible = false;
const { container } = render(<AuthorizationRequiredModal {...mocked_props} />);
expect(container).toBeEmptyDOMElement();
});
});
Loading

0 comments on commit 3c29e76

Please sign in to comment.