Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Akmal / fix: add sell error modals in reports package #14689

Merged
merged 5 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 => {
akmal-deriv marked this conversation as resolved.
Show resolved Hide resolved
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
Loading