Skip to content

Commit

Permalink
fix: 🎨 resolved TS migration issues (#27)
Browse files Browse the repository at this point in the history
* fix: 🎨 resolved TS migration issues

* feat: ✅ added testcaes

* refactor: idv forms to useFormikContext to reduce prop drilling (#26)

* refactor: idv forms to useFormikContext to reduce prop drilling

* refactor: removed unused props from personal-details

* feat: resolved the issues with idv testcases

* feat: 🎨 incorporated image change based on status

---------

Co-authored-by: Shahzaib <shahzaib@deriv.com>
  • Loading branch information
likhith-deriv and shahzaib-deriv committed May 23, 2023
1 parent c7d4caa commit 673637d
Show file tree
Hide file tree
Showing 14 changed files with 352 additions and 217 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
125 changes: 125 additions & 0 deletions packages/account/src/Components/forms/__tests__/idv-form.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import React from 'react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import IDVForm from '../idv-form';
import { Formik } from 'formik';
import { isDesktop, isMobile } from '@deriv/shared';

jest.mock('Helpers/utils', () => ({
...jest.requireActual('Helpers/utils'),
getDocumentData: jest.fn((country_code, key) => {
const data = {
tc: {
document_1: {
new_display_name: '',
example_format: '5436454364243',
sample_image: '',
},
document_2: {
new_display_name: '',
example_format: 'A-52431',
sample_image: '',
},
},
};
return data[country_code][key];
}),
}));

jest.mock('formik', () => ({
...jest.requireActual('formik'),
useFormikContext: jest.fn(() => ({
values: {
document_type: {
// display_name: 'Test document 1 name',
// format: '5436454364243',
// id: '1',
// value: 'Test document 1 name',
},
document_number: '',
},
errors: {},
touched: {},
setFieldValue: jest.fn(),
setFieldTouched: jest.fn(),
validateForm: jest.fn(),
validateField: jest.fn(),
handleBlur: jest.fn(),
handleChange: jest.fn(),
})),
}));

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

describe('<IDVForm/>', () => {
const mock_props = {
selected_country: {
value: 'tc',
identity: {
services: {
idv: {
documents_supported: {
document_1: {
display_name: 'Test document 1 name',
format: '5436454364243',
},
document_2: {
display_name: 'Test document 2 name',
format: 'A54321',
},
},
has_visual_sample: '1',
},
},
},
},
};

const mock_values = {
document_type: {
display_name: 'Test document 1 name',
format: '5436454364243',
id: '1',
value: 'document_1',
},
document_number: '5436454364243',
};

it('should render IDVForm component', () => {
render(<IDVForm {...mock_props} />, {
wrapper: ({ children }) => (
<Formik initialValues={mock_values} onSubmit={() => undefined}>
{() => children}
</Formik>
),
});

const document_type_input = screen.getByLabelText('Choose the document type');
const document_number_input = screen.getByPlaceholderText('Enter your document number');

expect(document_type_input).toBeInTheDocument();
expect(document_number_input).toBeInTheDocument();
});

it('Should change the document type value when document type is changed', async () => {
render(<IDVForm {...mock_props} />, {
wrapper: ({ children }) => (
<Formik initialValues={mock_values} onSubmit={() => undefined}>
{() => children}
</Formik>
),
});

const document_type_input = screen.getByLabelText('Choose the document type');

fireEvent.click(document_type_input);
expect(await screen.findByText('Test document 1 name')).toBeInTheDocument();
fireEvent.blur(document_type_input);
await waitFor(() => {
expect(screen.queryByText('Test document 1 name')).not.toBeInTheDocument();
});
});
});
23 changes: 6 additions & 17 deletions packages/account/src/Components/forms/idv-form.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import classNames from 'classnames';
import { Field, FormikProps, FormikHandlers, FieldProps } from 'formik';
import { Field, FormikProps, FieldProps, useFormikContext } from 'formik';
import { ResidenceList } from '@deriv/api-types';
import { localize } from '@deriv/translations';
import { formatInput, IDV_NOT_APPLICABLE_OPTION } from '@deriv/shared';
Expand All @@ -27,28 +27,18 @@ type TIDVForm = {
selected_country: ResidenceList[0];
hide_hint?: boolean;
class_name?: string;
can_skip_document_verification: boolean;
} & Partial<FormikHandlers> &
FormikProps<TFormProps>;
can_skip_document_verification?: boolean;
};

const IDVForm = ({
errors,
touched,
values,
handleBlur,
handleChange,
setFieldValue,
class_name,
selected_country,
hide_hint,
can_skip_document_verification = false,
}: TIDVForm) => {
const IDVForm = ({ class_name, selected_country, hide_hint, can_skip_document_verification = false }: TIDVForm) => {
const [document_list, setDocumentList] = React.useState<TDocumentList>([]);
const [document_image, setDocumentImage] = React.useState<string | null>(null);
const [selected_doc, setSelectedDoc] = React.useState('');

const { documents_supported: document_data, has_visual_sample } = selected_country?.identity?.services?.idv ?? {};

const { errors, touched, values, handleBlur, handleChange, setFieldValue }: FormikProps<TFormProps> =
useFormikContext();
const default_document = {
id: '',
text: '',
Expand Down Expand Up @@ -156,7 +146,6 @@ const IDVForm = ({
<div className='document-dropdown'>
<Autocomplete
{...field}
name='document_type'
data-lpignore='true'
error={touched.document_type && errors.document_type}
autoComplete='off'
Expand Down
34 changes: 20 additions & 14 deletions packages/account/src/Components/forms/personal-details-form.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Field } from 'formik';
import { Field, useFormikContext } from 'formik';
import classNames from 'classnames';
import {
Autocomplete,
Expand All @@ -16,24 +16,16 @@ import { getLegalEntityName, isDesktop, isMobile, routes, validPhone } from '@de
import { Localize, localize } from '@deriv/translations';
import FormSubHeader from 'Components/form-sub-header';
import PoiNameDobExample from 'Assets/ic-poi-name-dob-example.svg';
import PoiNameMismatchExample from 'Assets/ic-poi-name-mismatch-example.svg';
import PoiDobMismatchExample from 'Assets/ic-poi-dob-mismatch-example.svg';
import InlineNoteWithIcon from 'Components/inline-note-with-icon';
import FormBodySection from 'Components/form-body-section';
import { DateOfBirthField, FormInputField } from 'Components/forms/form-fields';
import { Link } from 'react-router-dom';
import { getEmploymentStatusList } from 'Sections/Assessment/FinancialAssessment/financial-information-list';
import { isFieldImmutable } from 'Helpers/utils';

const PersonalDetailsForm = ({
errors,
touched,
values,
setFieldValue,
handleChange,
handleBlur,
warning_items,
setFieldTouched,
...props
}) => {
const PersonalDetailsForm = props => {
const {
is_virtual,
is_mf,
Expand All @@ -51,20 +43,34 @@ const PersonalDetailsForm = ({
is_rendered_for_onfido,
should_close_tooltip,
setShouldCloseTooltip,
warning_items,
status,
} = props;
const autocomplete_value = 'none';
const PoiNameDobExampleIcon = PoiNameDobExample;

const [is_tax_residence_popover_open, setIsTaxResidencePopoverOpen] = React.useState(false);
const [is_tin_popover_open, setIsTinPopoverOpen] = React.useState(false);

const { errors, touched, values, setFieldValue, handleChange, handleBlur, setFieldTouched } = useFormikContext();

React.useEffect(() => {
if (should_close_tooltip) {
handleToolTipStatus();
setShouldCloseTooltip(false);
}
}, [should_close_tooltip, handleToolTipStatus, setShouldCloseTooltip]);

const imageLoader = () => {
switch (status) {
case 'POI_NAME_MISMATCH':
return <PoiNameMismatchExample />;
case 'POI_DOB_MISMATCH':
return <PoiDobMismatchExample />;
default:
return <PoiNameDobExample />;
}
};

const getNameAndDobLabels = () => {
const is_asterisk_needed = is_svg || is_mf || is_rendered_for_onfido || is_qualified_for_idv;
const first_name_label = is_appstore || is_asterisk_needed ? localize('First name*') : localize('First name');
Expand Down Expand Up @@ -118,7 +124,7 @@ const PersonalDetailsForm = ({
)}
<FormBodySection
has_side_note={(is_qualified_for_idv || is_rendered_for_onfido) && !should_hide_helper_image}
side_note={<PoiNameDobExampleIcon />}
side_note={imageLoader()}
>
<fieldset className='account-form__fieldset'>
{'salutation' in values && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { fireEvent, render, screen, waitFor, within } from '@testing-library/rea
import { isDesktop, isMobile, PlatformContext } from '@deriv/shared';
import { splitValidationResultTypes } from '../../real-account-signup/helpers/utils';
import PersonalDetails from '../personal-details';
import { shouldShowIdentityInformation, isDocumentTypeValid, isAdditionalDocumentValid } from 'Helpers/utils';

jest.mock('Assets/ic-poi-name-dob-example.svg', () => jest.fn(() => 'PoiNameDobExampleImage'));

Expand All @@ -26,6 +27,13 @@ jest.mock('../../real-account-signup/helpers/utils.ts', () => ({
})),
}));

jest.mock('Helpers/utils', () => ({
...jest.requireActual('Helpers/utils'),
isDocumentTypeValid: jest.fn(() => undefined),
shouldShowIdentityInformation: jest.fn(() => false),
isAdditionalDocumentValid: jest.fn(() => undefined),
}));

const mock_warnings = {};
const mock_errors = {
account_opening_reason: 'Account opening reason is required.',
Expand Down Expand Up @@ -744,4 +752,92 @@ describe('<PersonalDetails/>', () => {
const el_tax_residence = screen.getByTestId('selected_value');
expect(el_tax_residence).toHaveTextContent('Malta');
});

it('should validate idv values when a document type is selected', async () => {
shouldShowIdentityInformation.mockReturnValue(true);
const new_props = {
...props,
is_mf: false,
value: {
...props.value,
document_type: {
value: 'national_id',
text: 'National ID',
},
document_number: '123456789',
},
residence_list: [
{
value: 'tc',
identity: {
services: {
idv: {
documents_supported: {
document_1: {
display_name: 'Test document 1 name',
format: '5436454364243',
},
document_2: {
display_name: 'Test document 2 name',
format: 'A54321',
},
},
has_visual_sample: true,
},
},
},
},
],
};
renderwithRouter(<PersonalDetails {...new_props} />);

await waitFor(() => {
expect(isDocumentTypeValid).toHaveBeenCalled();
expect(isAdditionalDocumentValid).not.toHaveBeenCalled();
});
});

it('should validate idv values along with additional docuement number when a document type is selected', async () => {
shouldShowIdentityInformation.mockReturnValue(true);
const new_props = {
...props,
is_mf: false,
value: {
...props.value,
document_type: {
value: 'national_id',
text: 'National ID',
additional: '12345',
},
document_number: '123456789',
},
residence_list: [
{
value: 'tc',
identity: {
services: {
idv: {
documents_supported: {
document_1: {
display_name: 'Test document 1 name',
format: '5436454364243',
},
document_2: {
display_name: 'Test document 2 name',
format: 'A54321',
},
},
has_visual_sample: true,
},
},
},
},
],
};
renderwithRouter(<PersonalDetails {...new_props} />);

await waitFor(() => {
expect(isAdditionalDocumentValid).toHaveBeenCalled();
});
});
});
Loading

0 comments on commit 673637d

Please sign in to comment.