Skip to content

Commit

Permalink
Kyc/wall 1322/revamp poa section (binary-com#9623)
Browse files Browse the repository at this point in the history
* feat: 🍱 added visual assets

* Kyc/wall 1325/revamp poa section (#6)

* feat: ✨ added new component

* feat: ✅ added testcases

* feat: account page revamp, cfd poa remove, account poa reuse

* refactor: simplified && condition

* chore: modal alignment styles

* fix: failing tests

* refactor: some ts issues resolve

* refactor: poa container TS migration

* chore: styles clarifications

* refactor: poa form ts migration, code refactor

* fix: ts ignore for cfd build

* fix: commented code

* fix: failing test

* chore: code refactoring

* chore: recreating PR for kyc-WALL-1322-revamp-poa-section

* chore: incorporated review comments

* chore: review comments

* chore: review comments2

* chore: remove unused variable

* chore: cfd-poa testcases

* refactor: review comments

* chore: review comments

* ref: Incorporated review somments

* chore: review coment

* chore: review comments

* chore: review comments addressing

* fix: failing test

* chore: styles code refactor

* chore: spaces fix

* refactor: file descriptions map array

* chore: review comments

* chore: review comments

* chore: review comments

* chore: compare account flow fix

* chore: review comments

* chore: review comments

* chore: review comments

* chore: review comments incorporating

* fix: styling discrepancies

* fix: back button condition

* chore: remove back button

* fix: failing test cfd-poa

* refactor: localize change to component

* refactor: 🎨 incorporated Localize component

* chore: remove unused css and types

* chore: wrong description on examples

* fix: styles for resubmit message

* fix: submitting error poa page

* chore: mobing submit error to the top

* fix: wrong message after submitting documents

* refactor: boolean instead !!

* chore: added gif as supported file

* fix: failing test

* fix: resolve path

---------

Co-authored-by: Likhith Kolayari <likhith@regentmarkets.com>
Co-authored-by: Likhith Kolayari <98398322+likhith-deriv@users.noreply.github.com>
Co-authored-by: “yauheni-kryzhyk-deriv” <“yauheni@deriv.me”>
  • Loading branch information
4 people committed Sep 12, 2023
1 parent 1addf07 commit 8d9005f
Show file tree
Hide file tree
Showing 88 changed files with 1,963 additions and 2,693 deletions.
2 changes: 1 addition & 1 deletion packages/account/build/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ module.exports = function (env) {
'poi-unsupported': 'Components/poi/status/unsupported',
'poi-upload-complete': 'Components/poi/status/upload-complete',
'poi-verified': 'Components/poi/status/verified',
'proof-of-address-container': 'Sections/Verification/ProofOfAddress/proof-of-address-container.jsx',
'proof-of-address-container': 'Sections/Verification/ProofOfAddress/proof-of-address-container',
'proof-of-identity': 'Sections/Verification/ProofOfIdentity/proof-of-identity.jsx',
'proof-of-identity-container': 'Sections/Verification/ProofOfIdentity/proof-of-identity-container.jsx',
'proof-of-identity-config': 'Configs/proof-of-identity-config',
Expand Down
2 changes: 1 addition & 1 deletion packages/account/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Routes from './Containers/routes';
import ResetTradingPassword from './Containers/reset-trading-password';
import { setWebsocket } from '@deriv/shared';
import { StoreProvider } from '@deriv/stores';
import { TCoreStores } from '@deriv/stores/types';
import type { TCoreStores } from '@deriv/stores/types';

// TODO: add correct types for WS after implementing them
type TAppProps = {
Expand Down
155 changes: 155 additions & 0 deletions packages/account/src/Assets/ic-blurry-document.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
78 changes: 78 additions & 0 deletions packages/account/src/Assets/ic-cropped-document.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
58 changes: 58 additions & 0 deletions packages/account/src/Assets/ic-document-address-mismatch.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions packages/account/src/Assets/ic-document-name-mismatch.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
110 changes: 110 additions & 0 deletions packages/account/src/Assets/ic-envelop.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions packages/account/src/Assets/ic-error-badge.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 57 additions & 0 deletions packages/account/src/Assets/ic-old-issued-document.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import AddressDetails from '../address-details';
import { isDesktop, isMobile, PlatformContext, TLocationList } from '@deriv/shared';
import { isDesktop, isMobile, PlatformContext } from '@deriv/shared';
import { FormikProps, FormikValues } from 'formik';

jest.mock('@deriv/shared', () => ({
Expand Down Expand Up @@ -40,6 +40,7 @@ describe('<AddressDetails/>', () => {
getCurrentStep: jest.fn(),
goToNextStep: jest.fn(),
goToPreviousStep: jest.fn(),
has_real_account: false,
is_gb_residence: '',
is_svg: true,
onCancel: jest.fn(),
Expand Down Expand Up @@ -102,9 +103,9 @@ describe('<AddressDetails/>', () => {
expect(screen.queryByText(verification_info)).not.toBeInTheDocument();

const inputs: HTMLTextAreaElement[] = screen.getAllByRole('textbox');
expect(inputs.length).toBe(5);
expect(inputs).toHaveLength(5);
const required_fields = inputs.filter(input => input.required === true);
expect(required_fields.length).toBe(2);
expect(required_fields).toHaveLength(2);
});

it('should render AddressDetails component and trigger buttons', async () => {
Expand All @@ -116,10 +117,10 @@ describe('<AddressDetails/>', () => {
expect(screen.queryByText(verification_info)).not.toBeInTheDocument();

const inputs: HTMLTextAreaElement[] = screen.getAllByRole('textbox');
expect(inputs.length).toBe(5);
expect(inputs).toHaveLength(5);

const required_fields = inputs.filter(input => input.required === true);
expect(required_fields.length).toBe(2);
expect(required_fields).toHaveLength(2);

const previous_btn = screen.getByRole('button', { name: /previous/i });
fireEvent.click(previous_btn);
Expand Down Expand Up @@ -175,9 +176,9 @@ describe('<AddressDetails/>', () => {
expect(mock_props.onSubmitEnabledChange).toHaveBeenCalledTimes(1);

const inputs: HTMLTextAreaElement[] = screen.getAllByRole('textbox');
expect(inputs.length).toBe(5);
expect(inputs).toHaveLength(5);
const required_fields = inputs.filter(input => input.required === true);
expect(required_fields.length).toBe(0);
expect(required_fields).toHaveLength(0);

await waitFor(() => {
expect(screen.getByLabelText(address_line_1)).toBeInTheDocument();
Expand Down Expand Up @@ -209,10 +210,10 @@ describe('<AddressDetails/>', () => {
expect(screen.queryByText(use_address_info)).not.toBeInTheDocument();

const inputs: HTMLTextAreaElement[] = screen.getAllByRole('textbox');
expect(inputs.length).toBe(5);
expect(inputs).toHaveLength(5);

const required_fields = inputs.filter(input => input.required === true);
expect(required_fields.length).toBe(4);
expect(required_fields).toHaveLength(4);

expect(screen.getByLabelText(address_line_1_marked)).toBeInTheDocument();
expect(screen.getByLabelText(address_line_2_marked)).toBeInTheDocument();
Expand All @@ -235,7 +236,7 @@ describe('<AddressDetails/>', () => {
mock_props.states_list = [
{ text: 'State 1', value: 'State 1' },
{ text: 'State 2', value: 'State 2' },
] as TLocationList[];
];

render(<AddressDetails {...mock_props} />);

Expand All @@ -253,7 +254,7 @@ describe('<AddressDetails/>', () => {
mock_props.states_list = [
{ text: 'State 1', value: 'State 1' },
{ text: 'State 2', value: 'State 2' },
] as TLocationList[];
];

render(<AddressDetails {...mock_props} />);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Formik, Field, FormikProps, FormikValues } from 'formik';
import React from 'react';
import { StatesList } from '@deriv/api-types';
import {
Modal,
Autocomplete,
Expand All @@ -15,19 +16,13 @@ import {
Text,
} from '@deriv/components';
import { localize, Localize } from '@deriv/translations';
import {
isDesktop,
isMobile,
getLocation,
makeCancellablePromise,
PlatformContext,
TLocationList,
} from '@deriv/shared';
import { isDesktop, isMobile, getLocation, makeCancellablePromise, PlatformContext } from '@deriv/shared';
import { splitValidationResultTypes } from '../real-account-signup/helpers/utils';
import classNames from 'classnames';

type TAddressDetails = {
states_list: TLocationList[];
disabled_items: string[];
states_list: StatesList;
getCurrentStep?: () => number;
onSave: (current_step: number, values: FormikValues) => void;
onCancel: (current_step: number, goToPreviousStep: () => void) => void;
Expand All @@ -43,17 +38,13 @@ type TAddressDetails = {
is_svg: boolean;
is_mf?: boolean;
is_gb_residence: boolean | string;
has_real_account: boolean;
onSubmitEnabledChange: (is_submit_disabled: boolean) => void;
selected_step_ref?: React.RefObject<FormikProps<FormikValues>>;
fetchStatesList: () => Promise<unknown>;
value: FormikValues;
};

type TFormValidation = {
warnings: { [key: string]: string };
errors: { [key: string]: string };
};

type TInputField = {
name: string;
required?: boolean | string;
Expand Down Expand Up @@ -131,7 +122,7 @@ const AddressDetails = ({
return selected_step_ref?.current?.isSubmitting || (errors && Object.keys(errors).length > 0);
};

const checkSubmitStatus = (errors?: { [key: string]: string }) => {
const checkSubmitStatus = (errors?: { [key: string]: string } | FormikValues) => {
const is_submit_disabled = isSubmitDisabled(errors);

if (is_submit_disabled_ref.current !== is_submit_disabled) {
Expand All @@ -147,7 +138,7 @@ const AddressDetails = ({
};

const handleValidate = (values: FormikValues) => {
const { errors }: Partial<TFormValidation> = splitValidationResultTypes(validate(values));
const { errors } = splitValidationResultTypes(validate(values));
checkSubmitStatus(errors);
return errors;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { localize } from '@deriv/translations';
import IconWithMessage from 'Components/icon-with-message';
import IconWithMessage from '../icon-with-message';

type TDemoMessage = {
has_demo_icon?: boolean;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { isDesktop, isMobile, PlatformContext } from '@deriv/shared';
import FileUploaderContainer, { TFileUploaderContainer } from '../file-uploader-container';
import { isDesktop, isMobile } from '@deriv/shared';
import FileUploaderContainer from '../file-uploader-container';

jest.mock('@deriv/components', () => {
const original_module = jest.requireActual('@deriv/components');
Expand All @@ -20,107 +20,75 @@ jest.mock('@deriv/shared', () => ({
}));

describe('<FileUploaderContainer />', () => {
let mock_props: React.ComponentProps<typeof FileUploaderContainer>;

beforeEach(() => {
isDesktop.mockReturnValue(true);
isMobile.mockReturnValue(false);
mock_props = {
examples: '',
files_description: '',
getSocket: jest.fn(),
onFileDrop: jest.fn(),
onRef: jest.fn(),
settings: {},
};

(isDesktop as jest.Mock).mockReturnValue(true);
(isMobile as jest.Mock).mockReturnValue(false);
jest.clearAllMocks();
});

const props: TFileUploaderContainer = {
getSocket: jest.fn(),
onFileDrop: jest.fn(),
onRef: jest.fn(),
settings: {},
};

const file_size_msg = /less than 8mb/i;
const file_type_msg = /jpeg jpg png pdf gif/i;
const file_time_msg = /1 \- 6 months old/i;
const file_clear_msg = /a clear colour photo or scanned image/i;
const file_address = /issued under your name with your current address/i;
const file_size_msg = /maximum size: 8MB/i;
const file_type_msg = /supported formats: JPEG, JPG, PNG, PDF and GIF only/i;
const file_warning_msg = /remember, selfies, pictures of houses, or non-related images will be rejected./i;
const hint_msg_desktop = /drag and drop a file or click to browse your files/i;
const hint_msg_mobile = /click here to upload/i;

const runCommonTests = () => {
expect(screen.getAllByText('mockedIcon')).toHaveLength(6);
expect(screen.getByTestId('dt_file_uploader_container')).toBeInTheDocument();
expect(screen.getByText('mockedIcon')).toBeInTheDocument();
expect(screen.getByText(file_size_msg)).toBeInTheDocument();
expect(screen.getByText(file_type_msg)).toBeInTheDocument();
expect(screen.getByText(file_time_msg)).toBeInTheDocument();
expect(screen.getByText(file_clear_msg)).toBeInTheDocument();
expect(screen.getByText(file_address)).toBeInTheDocument();
expect(screen.getByText(file_warning_msg)).toBeInTheDocument();
};
it('should render FileUploaderContainer component', () => {
render(<FileUploaderContainer {...props} />);
expect(screen.getByTestId('dt_file_uploader_container')).toBeInTheDocument();
});

it('should render FileUploaderContainer component if getSocket is not passed as prop', () => {
render(<FileUploaderContainer {...props} />);
expect(screen.getByTestId('dt_file_uploader_container')).toBeInTheDocument();
});

it('should not render FileUploaderContainer when is_appstore is true in desktop', () => {
render(
<PlatformContext.Provider value={{ is_appstore: true }}>
<FileUploaderContainer {...props} />
</PlatformContext.Provider>
);
expect(screen.queryByTestId('dt_file_uploader_container')).not.toBeInTheDocument();
});

it('should show icons and description when is_appstore is true in desktop', () => {
render(
<PlatformContext.Provider value={{ is_appstore: true }}>
<FileUploaderContainer {...props} />
</PlatformContext.Provider>
);
it('should render FileUploaderContainer component and show descriptions', () => {
render(<FileUploaderContainer {...mock_props} />);
runCommonTests();
});

it('should show description when is_appstore false in desktop', () => {
render(
<PlatformContext.Provider value={{ is_appstore: false }}>
<FileUploaderContainer {...props} />
</PlatformContext.Provider>
);
it('should render FileUploaderContainer component if getSocket is not passed as prop', () => {
delete mock_props.getSocket;
render(<FileUploaderContainer {...mock_props} />);
runCommonTests();
});

it('should show description when is_appstore true in mobile', () => {
isMobile.mockReturnValue(true);
isDesktop.mockReturnValue(false);
it('files description and examples should be shown when passed', () => {
mock_props.files_description = <div>Files description</div>;
mock_props.examples = <div>Files failure examples</div>;

render(
<PlatformContext.Provider value={{ is_appstore: true }}>
<FileUploaderContainer {...props} />
</PlatformContext.Provider>
);
runCommonTests();
render(<FileUploaderContainer {...mock_props} />);
expect(screen.getByText('Files description')).toBeInTheDocument();
expect(screen.getByText('Files failure examples')).toBeInTheDocument();
});

it('should not show description if is_description_enabled is false)', () => {
isMobile.mockReturnValue(true);
isDesktop.mockReturnValue(false);
it('should show hint message for desktop', () => {
render(<FileUploaderContainer {...mock_props} />);
expect(screen.getByText(hint_msg_desktop)).toBeInTheDocument();
expect(screen.queryByText(hint_msg_mobile)).not.toBeInTheDocument();
});

render(
<PlatformContext.Provider value={{ is_appstore: true }}>
<FileUploaderContainer {...props} is_description_enabled={false} />
</PlatformContext.Provider>
);
it('should show hint message for mobile', () => {
(isMobile as jest.Mock).mockReturnValue(true);
(isDesktop as jest.Mock).mockReturnValue(false);

expect(screen.getByText('mockedIcon')).toBeInTheDocument();
expect(screen.queryByText(file_size_msg)).not.toBeInTheDocument();
expect(screen.queryByText(file_type_msg)).not.toBeInTheDocument();
expect(screen.queryByText(file_time_msg)).not.toBeInTheDocument();
expect(screen.queryByText(file_clear_msg)).not.toBeInTheDocument();
expect(screen.queryByText(file_address)).not.toBeInTheDocument();
render(<FileUploaderContainer {...mock_props} />);
expect(screen.getByText(hint_msg_mobile)).toBeInTheDocument();
expect(screen.queryByText(hint_msg_desktop)).not.toBeInTheDocument();
});

it('should call ref function on rendering the component', () => {
render(
<PlatformContext.Provider value={{ is_appstore: true }}>
<FileUploaderContainer {...props} />
</PlatformContext.Provider>
);
render(<FileUploaderContainer {...mock_props} />);

expect(props.onRef).toHaveBeenCalled();
expect(mock_props.onRef).toHaveBeenCalled();
});
});
Loading

0 comments on commit 8d9005f

Please sign in to comment.