Skip to content

Commit

Permalink
Merge pull request binary-com#116 from Dhruv-deriv/dhruv/MT5PasswordM…
Browse files Browse the repository at this point in the history
…odal-Styling/TRAH-3963

Dhruv/mt5 password modal styling/trah 3963
  • Loading branch information
amina-deriv committed Aug 29, 2024
2 parents d1a8831 + e051d0b commit 0f39395
Show file tree
Hide file tree
Showing 5 changed files with 317 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2092,6 +2092,7 @@
flex-direction: row;
}
}

&__create-password {
padding: 0 1.2rem;

Expand Down
4 changes: 2 additions & 2 deletions packages/cfd/src/Containers/cfd-password-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ import { useCfdStore } from '../Stores/Modules/CFD/Helpers/useCfdStores';
import { CFD_PLATFORMS, CATEGORY } from '../Helpers/cfd-config';
import classNames from 'classnames';
import { getDxCompanies, getMtCompanies, TDxCompanies, TMtCompanies } from '../Stores/Modules/CFD/Helpers/cfd-config';
import '../sass/cfd.scss';

import { useGetDefaultMT5Jurisdiction } from '@deriv/hooks';

const MT5CreatePassword = makeLazyLoader(
() => moduleLoader(() => import('./mt5-create-password')),
() => moduleLoader(() => import('./mt5-create-password/mt5-create-password')),
() => <div />
)();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import React from 'react';
import { Router } from 'react-router';
import { createBrowserHistory } from 'history';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import MT5CreatePassword from '../mt5-create-password';
import { mockStore } from '@deriv/stores';
import CFDProviders from '../../../cfd-providers';

jest.mock('@deriv/components', () => ({
...jest.requireActual('@deriv/components'),
Icon: jest.fn(({ icon }) => <div>{icon}</div>),
useDevice: () => ({ isMobile: false }),
}));

jest.mock('@deriv/quill-icons', () => ({
...jest.requireActual('@deriv/quill-icons'),
DerivLightDmt5PasswordIcon: () => 'DerivLightDmt5PasswordIcon',
}));

jest.mock('@deriv/shared', () => ({
...jest.requireActual('@deriv/shared'),
getErrorMessages: jest.fn().mockReturnValue({
password_warnings: '',
password: jest.fn().mockReturnValue('Password should have lower and uppercase English letters with numbers.'),
}),
validPassword: jest.fn().mockReturnValue(true),
isDesktop: jest.fn().mockReturnValue(true),
DBVI_COMPANY_NAMES: {
svg: { name: 'Sample Company', licence_name: 'Sample Licence' },
other: { name: 'Other Company', licence_name: 'Other Licence' },
},
}));

describe('<MT5CreatePassword/>', () => {
const mockFn = jest.fn();
const mockSubmitMt5Password = jest.fn();
const history = createBrowserHistory();
let modalRoot;

let mockRootStore = {
modules: {
cfd: {
error_message: '',
account_title: '',
account_type: {},
getAccountStatus: mockFn,
new_account_response: {},
jurisdiction_selected_shortcode: 'svg',
setProduct: jest.fn(),
},
},
};

const default_props = {
password: '',
platform: 'mt5',
error_message: '',
validatePassword: jest.fn(),
onSubmit: jest.fn(),
need_tnc: true,
};

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

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

it('should render MT5CreatePassword component', async () => {
render(
<Router history={history}>
<MT5CreatePassword {...default_props} />
</Router>,
{
wrapper: ({ children }) => <CFDProviders store={mockStore(mockRootStore)}>{children}</CFDProviders>,
}
);

expect(await screen.findByTestId('dt_mt5_create_password')).toBeInTheDocument();
});

it('should display IcMt5OnePassword icon in the component', async () => {
render(
<Router history={history}>
<MT5CreatePassword {...default_props} />
</Router>,
{
wrapper: ({ children }) => <CFDProviders store={mockStore(mockRootStore)}>{children}</CFDProviders>,
}
);
expect(await screen.findByText('DerivLightDmt5PasswordIcon')).toBeInTheDocument();
});

it('should display password field for user to enter the password and hold the entered value', async () => {
const user_input = 'zo8lAet#2q01Ih';

render(
<Router history={history}>
<MT5CreatePassword {...default_props} />
</Router>,
{
wrapper: ({ children }) => <CFDProviders store={mockStore(mockRootStore)}>{children}</CFDProviders>,
}
);
const password_input = await screen.findByTestId('dt_mt5_password');
fireEvent.change(password_input, { target: { value: user_input } });
await waitFor(() => {
expect(password_input.value).toBe(user_input);
});
});

it('should display password requirements message', async () => {
render(
<Router history={history}>
<MT5CreatePassword {...default_props} />
</Router>,
{
wrapper: ({ children }) => <CFDProviders store={mockStore(mockRootStore)}>{children}</CFDProviders>,
}
);

expect(await screen.findByText(/This password works for all your Deriv MT5 accounts./i)).toBeInTheDocument();
});

it('should show TNC checkbox when need_tnc is true', async () => {
render(
<Router history={history}>
<MT5CreatePassword {...default_props} need_tnc={true} />
</Router>,
{
wrapper: ({ children }) => <CFDProviders store={mockStore(mockRootStore)}>{children}</CFDProviders>,
}
);
const checkbox = await screen.findByRole('checkbox');
expect(checkbox).toBeInTheDocument();
});

it('should call onSubmit when form is submitted', async () => {
const user_input = 'zo8lAet#2q01Ih';
const onSubmit = jest.fn();
const validatePassword = jest.fn().mockReturnValue({});

render(
<Router history={history}>
<MT5CreatePassword
{...default_props}
password={user_input}
onSubmit={onSubmit}
validatePassword={validatePassword}
/>
</Router>,
{
wrapper: ({ children }) => <CFDProviders store={mockStore(mockRootStore)}>{children}</CFDProviders>,
}
);

const passwordInput = await screen.findByTestId('dt_mt5_password');
const submitButton = await screen.findByRole('button', { name: /Create account/i });

expect(passwordInput).toBeInTheDocument();
expect(submitButton).toBeInTheDocument();

fireEvent.change(passwordInput, { target: { value: user_input } });
fireEvent.click(submitButton);

await waitFor(() => {
expect(onSubmit).toHaveBeenCalled();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
.dc-modal__container_mt5-password-modal,
.dc-mobile-dialog__mt5-password-modal {
display: flex;
flex-direction: column;
justify-content: flex-start;

&__description {
text-transform: none;
margin-top: 1rem;
top: 2rem;
position: relative;
padding: 1.3rem;
}

&__body {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
}

.mt5-password-field {
margin-bottom: 1rem;
}

.mt5-input-element {
width: 100%;
margin-bottom: 1rem;
}
}

.mt5-password-modal {
form {
@include mobile-or-tablet-screen {
height: 100%;
}
}
&__warning {
padding: 2.5rem;
max-width: 50rem;
align-self: center;
&-text {
border-radius: 0.8rem;
padding: 0.8rem;
background-color: var(--status-warning);
}
}
&__message {
max-width: 32rem;
margin: auto;
line-height: 1.43;
}
&__content {
@include mobile-or-tablet-screen {
overflow-y: auto;
overflow-x: hidden;
height: 100%;
width: 100%;
padding: 0;
justify-content: space-between;
}
}
&__create-password {
padding: 0 1.2rem;

&-content {
display: flex;
flex-direction: column;
width: 100%;
align-items: center;
padding-bottom: 1rem;

@include mobile-or-tablet-screen {
height: 100%;
padding: 1.6rem;
}
}

&-title {
margin-top: 2.4rem;
margin-bottom: 0.8rem;
}
&-description {
max-width: 30rem;
margin-bottom: 1.6rem;
}
}

&__mt5-input-element {
width: 100%;
margin-bottom: 1rem;
}
&-tnc {
&--bottom {
@include mobile-or-tablet-screen {
margin-top: auto;
margin-bottom: 7.5rem;
}
}
}
&__checkbox {
display: flex;
align-self: baseline;
margin-inline-start: -0.8rem;
}
&-info,
&__checkbox {
.dc-icon {
margin-inline-start: 0;
}
}
&__submit-button {
align-items: center;
align-self: flex-end;
justify-content: flex-end;
width: 100%;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { Formik, FormikErrors, FormikHelpers } from 'formik';
import { FormSubmitButton, Icon, PasswordInput, PasswordMeter, Text } from '@deriv/components';
import { getCFDPlatformLabel, getCFDPlatformNames, getErrorMessages } from '@deriv/shared';
import { Localize, localize } from '@deriv/translations';
import { useCfdStore } from '../Stores/Modules/CFD/Helpers/useCfdStores';
import { CATEGORY, CFD_PLATFORMS } from '../Helpers/cfd-config';
import '../sass/cfd.scss';
import CfdPasswordModalTnc from './cfd-password-modal-tnc';
import { useCfdStore } from '../../Stores/Modules/CFD/Helpers/useCfdStores';
import { CATEGORY, CFD_PLATFORMS } from '../../Helpers/cfd-config';
import { DerivLightDmt5PasswordIcon } from '@deriv/quill-icons';
import './mt5-create-password.scss';
import '../../sass/cfd.scss';
import CfdPasswordModalTnc from '../cfd-password-modal-tnc';
// first MT5 password

export type TCFDPasswordFormValues = { password: string };
Expand Down Expand Up @@ -68,21 +70,25 @@ const MT5CreatePassword = ({
validateForm,
}) => (
<form onSubmit={handleSubmit}>
<div className='mt5_password'>
<div
className='cfd-password-modal__content dc-modal__container_cfd-password-modal__body'
data-testid='dt_create_password'
>
<div className='cfd-password-modal__create-password-content'>
<Icon icon='IcMt5OnePassword' width='100' height='100' />
</div>
<Text size='xs' align='left' className='cfd-password-modal__create-password-description'>
<div
className='mt5-password-modal__content dc-modal__container_mt5-password-modal__body'
data-testid='dt_mt5_create_password'
>
<div className='mt5-password-modal__create-password-content'>
<DerivLightDmt5PasswordIcon height='150px' width='150px' />

<Text
size='xs'
align='left'
className='mt5-password-modal__create-password-description'
color='var(--text-prominent)'
>
<Localize
i18n_default_text='Create a password for your {{platform}} account:'
values={{ platform: getCFDPlatformNames(platform) }}
/>
</Text>
<div className='input-element'>
<div className='mt5-password-modal__mt5-input-element'>
<PasswordMeter
input={values.password}
has_error={!!(touched.password && errors.password)}
Expand Down Expand Up @@ -125,6 +131,8 @@ const MT5CreatePassword = ({
onCheck={() => setChecked(prev => !prev)}
need_tnc={need_tnc}
/>
</div>
<div className='mt5-password-modal__submit-button'>
<FormSubmitButton
is_disabled={!values.password || !checked || Object.keys(errors).length > 0}
is_loading={isSubmitting}
Expand Down

0 comments on commit 0f39395

Please sign in to comment.