Skip to content

Commit

Permalink
Merge branch 'evgeniy-wall-376/likhith-wall-379/verification_ux_impro…
Browse files Browse the repository at this point in the history
…vement_with_example' of https://github.com/yauheni-deriv/deriv-app into shahzaib/KYC-1/error-handling-for-onfido-flow
  • Loading branch information
shahzaib-deriv committed May 11, 2023
2 parents 6410ed5 + 62a0f7a commit f5b8fb9
Show file tree
Hide file tree
Showing 90 changed files with 4,156 additions and 23,728 deletions.
33 changes: 3 additions & 30 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,7 @@
## Changes:

Please include a summary of the change and which issue is fixed below:
- ...
Please provide a summary of the change.

## When you need to add unit test
### Screenshots:

- [ ] If this change disrupt current flow
- [ ] If this change is adding new flow

## When you need to add integration test

- [ ] If components from external libraries are being used to define the flow, e.g. @deriv/components
- [ ] If it relies on a very specific set of props with no default behavior for the current component.

## Test coverage checklist (for reviewer)

- [ ] Ensure utility / function has a test case
- [ ] Ensure all the tests are passing

## Type of change

- [ ] Bug fix
- [ ] New feature
- [ ] Update feature
- [ ] Refactor code
- [ ] Translation to code
- [ ] Translation to crowdin
- [ ] Script configuration
- [ ] Improve performance
- [ ] Style only
- [ ] Dependency update
- [ ] Documentation update
- [ ] Release
Please provide some screenshots of the change.
18 changes: 18 additions & 0 deletions .github/workflows/stale.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
permissions:
issues: write
pull-requests: write

name: 'Close stale issues and PRs'
on:
schedule:
- cron: '30 1 * * *'

jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v8
with:
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days.'
days-before-stale: 60
days-before-close: 5
2,389 changes: 1,760 additions & 629 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"lerna": "^5.5.1",
"lint-staged": "^10.4.0",
"nx": "^14.5.10",
"postcss": "^8.3.6",
"postcss": "^8.4.23",
"prettier": "^2.1.2",
"stylelint": "^13.13.1",
"stylelint-config-prettier": "^8.0.2",
Expand Down
1 change: 0 additions & 1 deletion packages/account/build/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ module.exports = function (env) {
'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',
'proof-of-identity-form-on-signup': 'Components/poi/poi-form-on-signup',
'proof-of-identity-container-for-mt5':
'Sections/Verification/ProofOfIdentity/proof-of-identity-container-for-mt5',
'poi-poa-docs-submitted': 'Components/poi-poa-docs-submitted/poi-poa-docs-submitted.jsx',
Expand Down
4 changes: 2 additions & 2 deletions packages/account/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@
"node-sass": "^7.0.1",
"postcss-loader": "^6.2.1",
"postcss-preset-env": "^7.4.3",
"postcss-scss": "^4.0.3",
"postcss-scss": "^4.0.6",
"resolve-url-loader": "^3.1.2",
"rimraf": "^3.0.2",
"sass-loader": "^12.6.0",
"sass-resources-loader": "^2.1.1",
"terser-webpack-plugin": "^5.1.1",
"typescript": "^4.6.3",
"webpack": "^5.46.0"
"webpack": "^5.81.0"
}
}
2 changes: 1 addition & 1 deletion packages/account/src/Assets/ic-poi-name-dob-example.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 48 additions & 0 deletions packages/account/src/Components/forms/form-fields.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';
import { Field } from 'formik';
import { DateOfBirthPicker, Input } from '@deriv/components';
import { toMoment } from '@deriv/shared';

export const DateOfBirthField = props => (
<Field name={props.name}>
{({ field: { value }, form: { setFieldValue, errors, touched, setTouched } }) => (
<DateOfBirthPicker
error={touched.date_of_birth && errors.date_of_birth}
onBlur={() =>
setTouched({
...touched,
date_of_birth: true,
})
}
onChange={({ target }) =>
setFieldValue(
'date_of_birth',
target?.value ? toMoment(target.value).format('YYYY-MM-DD') : '',
true
)
}
value={value}
portal_id={props.portal_id}
{...props}
/>
)}
</Field>
);

export const FormInputField = ({ name, optional = false, warn, ...props }) => (
<Field name={name}>
{({ field, form: { errors, touched } }) => (
<Input
type='text'
required={!optional}
name={name}
autoComplete='off'
maxLength={props.maxLength || 30}
error={touched[field.name] && errors[field.name]}
warn={warn}
{...field}
{...props}
/>
)}
</Field>
);
4 changes: 2 additions & 2 deletions packages/account/src/Components/forms/idv-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const IDVForm = ({

const { selected_country } = props;

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

React.useEffect(() => {
const document_types = Object.keys(document_data);
Expand Down Expand Up @@ -111,7 +111,7 @@ const IDVForm = ({
document_name === 'document_number' ? values.document_type : values.document_type.additional;
let current_input: string | null = null;
current_input = example_format.includes('-')
? formatInput(example_format, current_input || e.target.value, '-')
? formatInput(example_format, current_input ?? e.target.value, '-')
: e.target.value;
setFieldValue(document_name, current_input, true);
};
Expand Down
49 changes: 2 additions & 47 deletions packages/account/src/Components/forms/personal-details-form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,67 +7,22 @@ import {
Dropdown,
DesktopWrapper,
MobileWrapper,
DateOfBirthPicker,
Input,
Popover,
RadioGroup,
SelectNative,
Text,
} from '@deriv/components';
import { getLegalEntityName, isDesktop, isMobile, routes, toMoment, validPhone } from '@deriv/shared';
import { getLegalEntityName, isDesktop, isMobile, routes, validPhone } from '@deriv/shared';
import { Localize, localize } from '@deriv/translations';
import FormSubHeader from 'Components/form-sub-header';
import PoiNameDobExample from 'Assets/ic-poi-name-dob-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 DateOfBirthField = props => (
<Field name={props.name}>
{({ field: { value }, form: { setFieldValue, errors, touched, setTouched } }) => (
<DateOfBirthPicker
error={touched.date_of_birth && errors.date_of_birth}
onBlur={() =>
setTouched({
...touched,
date_of_birth: true,
})
}
onChange={({ target }) =>
setFieldValue(
'date_of_birth',
target?.value ? toMoment(target.value).format('YYYY-MM-DD') : '',
true
)
}
value={value}
portal_id={props.portal_id}
{...props}
/>
)}
</Field>
);

const FormInputField = ({ name, optional = false, warn, ...props }) => (
<Field name={name}>
{({ field, form: { errors, touched } }) => (
<Input
type='text'
required={!optional}
name={name}
autoComplete='off'
maxLength={props.maxLength || 30}
error={touched[field.name] && errors[field.name]}
warn={warn}
{...field}
{...props}
/>
)}
</Field>
);

const PersonalDetailsForm = ({
errors,
touched,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ import {
} from '@deriv/components';
import { isDesktop, isMobile, PlatformContext, IDV_NOT_APPLICABLE_OPTION } from '@deriv/shared';
import { localize, Localize } from '@deriv/translations';
import { shouldShowIdentityInformation, documentAdditionalError, getRegex } from 'Helpers/utils';
import {
shouldShowIdentityInformation,
documentAdditionalError,
getRegex,
removeUndefinedProperties,
} from 'Helpers/utils';
import { splitValidationResultTypes } from '../real-account-signup/helpers/utils';
import IDVForm from '../forms/idv-form';
import PersonalDetailsForm from '../forms/personal-details-form';
Expand Down Expand Up @@ -74,37 +79,50 @@ const PersonalDetails = ({

const shouldHideHelperImage = document_id => document_id === IDV_NOT_APPLICABLE_OPTION.id;

const isDocumentTypeValid = document_type => {
if (!document_type?.text) {
return localize('Please select a document type.');
}
return undefined;
};

const isAdditionalDocumentValid = (document_type, document_additional) => {
const error_message = documentAdditionalError(document_additional, document_type.additional?.format);
if (error_message) {
return localize(error_message) + getExampleFormat(document_type.additional?.example_format);
}
return undefined;
};

const isDocumentNumberValid = (document_number, document_type) => {
const is_document_number_invalid = document_number === document_type.example_format;
if (!document_number) {
return localize('Please enter your document number. ') + getExampleFormat(document_type.example_format);
} else if (is_document_number_invalid) {
return localize('Please enter a valid ID number.');
}
const format_regex = getRegex(document_type.value);
if (!format_regex.test(document_number)) {
return localize('Please enter the correct format. ') + getExampleFormat(document_type.example_format);
}
return undefined;
};

const validateIDV = values => {
const errors = {};
const { document_type, document_number, document_additional } = values;
if (document_type.id === IDV_NOT_APPLICABLE_OPTION.id) return errors;

errors.document_type = isDocumentTypeValid(document_type);

const needs_additional_document = !!document_type.additional;
const is_document_number_invalid = document_number === document_type.example_format;
if (!document_type || !document_type.text) {
errors.document_type = localize('Please select a document type.');
}
if (!shouldHideHelperImage(document_type?.id)) {
if (needs_additional_document) {
const error_message = documentAdditionalError(document_additional, document_type.additional?.format);
if (error_message)
errors.document_additional =
localize(error_message) + getExampleFormat(document_type.additional?.example_format);
}

if (!document_number) {
errors.document_number =
localize('Please enter your document number. ') + getExampleFormat(document_type.example_format);
} else if (is_document_number_invalid) {
errors.document_number = localize('Please enter a valid ID number.');
} else {
const format_regex = getRegex(document_type.value);
if (!format_regex.test(document_number)) {
errors.document_number =
localize('Please enter the correct format. ') + getExampleFormat(document_type.example_format);
}
}
if (needs_additional_document) {
errors.document_additional = isAdditionalDocumentValid(document_type, document_additional);
}
return errors;

errors.document_number = isDocumentNumberValid(document_number, document_type);
return removeUndefinedProperties(errors);
};

const handleValidate = values => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ jest.mock('@deriv/shared', () => ({
formatInput: jest.fn(() => '5436454364243'),
WS: {
send: jest.fn(() => Promise.resolve({ error: '' })),
setSettings: jest.fn(() => Promise.resolve({ error: '' })),
authorized: {
storage: {
getSettings: jest.fn(() => Promise.resolve({ error: '' })),
},
},
},
}));

Expand All @@ -58,14 +64,15 @@ describe('<IdvDocumentSubmit/>', () => {
},
},
is_from_external: false,
account_settings: {},
getChangeableFields: jest.fn(() => []),
};

it('should render IdvDocumentSubmit component', () => {
render(<IdvDocumentSubmit {...mock_props} />);

expect(screen.getByText(/verify your identity/i)).toBeInTheDocument();
expect(screen.getByText(/Please select the document type and enter the ID number/i)).toBeInTheDocument();
expect(screen.getByText('DocumentSubmitLogo')).toBeInTheDocument();
expect(screen.getByText(/Identity verification/i)).toBeInTheDocument();
expect(screen.getByText(/details/i)).toBeInTheDocument();
expect(screen.queryByText('New ID type name')).not.toBeInTheDocument();
expect(screen.queryByText('Please select a document type.')).not.toBeInTheDocument();

Expand Down Expand Up @@ -105,9 +112,6 @@ describe('<IdvDocumentSubmit/>', () => {
isDesktop.mockReturnValue(false);
isMobile.mockReturnValue(true);

const selected_doc_msg =
'Please ensure all your personal details are the same as in your chosen document. If you wish to update your personal details, go to account settings.';

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

const verifyBtn = screen.getByRole('button', { name: /verify/i });
Expand All @@ -118,11 +122,9 @@ describe('<IdvDocumentSubmit/>', () => {
const document_number_input = screen.getByPlaceholderText('Enter your document number');
expect(document_number_input.name).toBe('document_number');
expect(document_number_input).toBeDisabled();
expect(screen.queryByText(selected_doc_msg)).not.toBeInTheDocument();

fireEvent.change(document_type_input, { target: { value: 'Test document 2 name' } });
expect(document_number_input).not.toBeDisabled();
expect(screen.getByText(selected_doc_msg)).toBeInTheDocument();
expect(screen.queryByText(/please enter the correct format/i)).not.toBeInTheDocument();

fireEvent.blur(document_number_input);
Expand Down
Loading

0 comments on commit f5b8fb9

Please sign in to comment.