Skip to content

Commit

Permalink
Likhith/wall 1714/enhance error message handling for poi (deriv-com#1…
Browse files Browse the repository at this point in the history
…1977)

* fix: ✅ updated testcases

* fix: failing tests

* refactor: code and ts fixes

* fix: display of IDV error

* chore: add duplication account error

* refactor: added undefined check to response data

* chore: review comments

* chore: review comments

* fix: ⬆️ upgraded SDK and handled language change

* fix: ♻️ incorporated review comments

* fix: ♻️ refactored code to remove useRef

* fix: barriers test fix form master

* fix: barriers test

* chore: refactored object.freeze to as const

* chore: optional chaining to document type

* chore: update spec file for idv-form

* test: update personal-details spec

* chore: review comments

* refactor: ♻️ incorporated hooks to handle business logic

* refactor: css structure

* fix: barriers test

* fix: ⚰️ removed unwanted code

* test: 🔥 removed mocked tokens

* chore: 📝 Added documentation for UseNotificationEvent hook

* fix: 💄 incorporated styling

* fix: ♻️ incorporated review comments

* refactor: rename properties

* refactor: remove is_appstore from tests

* fix: ♻️ incorporated review comments

* refactor: styles refactor

* fix: ⚡ reduced duplicate data

* fix: incorporated review comments

* fix: ♻️ incorporated review comments

* chore: Trigger Build

* fix: 🚚 modified path

* chore: remove unused fila and variable, updated icons

* revert: 🍻 removed icon changes

* refactor: removed formatting

* fix: removed assignment of default values

* fix: 🐛 unable to select a new doc supporting country

* fix: 🐛 resolved re-render issue

* fix: ⚡ resolved message issue

* refactor: 🚚 renamed varibales

* fix: 🧪 failing testcase

* fix: 🐛 resolved issues with failure messages

* fix: 🐛 resolved issue with DIEL accounts

* fix: 🐛 fixed issue for DIEL clients

* fix: styling issues

* fix: ts error for format-response

* build: 📌 updated package-lock after updating onfido-sdk-ui

* fix: 🚚 fixed path

* fix: 🚚 fixed path

* fix: 🐛 resolved styling bugs

* fix: 🐛 resolved styling bugs

* fix: ♻️ removed default values

* fix: 🔥 incorporated new styles to fix icon size

* fix: 🔥 incorporated new styles to fix icon size

* fix: ✅ fixed failing testcase

* fix: 💚 eslint issues

* fix: ⚡ incorporated platform language change

* fix: removed store

* fix: layout styles

* fix: style issues

* fix: styles

* fix: moved common styles to core

* refactor: incorporated review comments

* fix: 💄 updated styles

* fix: 🐛 reverted code

* fix: 🐛 reverted code

* refactor: incorporated review comments

* fix: 🐛 Onfido SDK language code conversion

* fix: migrated hooks

* revert: logic for generating code

* chore: adding missing testcases

* fix: recatored Onfido constants

* fix: onfido screen css issues

* fix: removed package-lock to resolve merge error

* Merge branch 'master' into likhith/KYC-363/onfido-sdk-updation

* chore: added package-lock

* Merge branch 'master' into combined/wall-400/IDV-error-message-handled

* chore: Trigger Build

* fix: bug: /WEBREL-1358/personal-details page and poa page css issue

* fix: layout button

* fix: layout button

* fix: mt5 next button not getting enabled

* fix: resolved issue with button

* fix: resolved issue with button

* fix: resolved missing dropdown

* fix: removed console

* fix: incorporated review comments

* feat: ✨ incorporated new images and merged checkbox feature

* feat: ✨ incorporated new images and merged checkbox feature

* refactor: split components

* fix: idv failed document type

* fix: removed duplicate import

* fix: incorporated error message scenario

* fix: styling as per new figma

* fix: styling as per new figma

* fix: spacing between fields

* fix: spacing between fields

* fix: spacing between fields

* fix: incorporated new error code and styles as per new figma

* fix: incorporated new error code and styles as per new figma

* feat: incorporated idv-error codes

* Merge branch 'master' into likhith/kyc-195/display-idv-error-messages

* fix: reverted changes

* Incorporate poi context (#55)

* chore: incorporate POIContext to keep track of submission

* chore: reset poi context state upon route change

* refactor: added reset for all path

* fix: changed testcases

---------

Co-authored-by: Likhith Kolayari <likhith@regentmarkets.com>

* fix: incorporated Onfido error messages

* chore: removed dead code

* fix: incorporated review comments

* fix: incorporated review comments

* fix: import paths

* fix: Onfido error for failed selfie check

* fix: incorporated missing status code

* fix: button width

* fix: Error text for Failure of IDV

* fix: changed icon badge

* fix: onfido check in POI

* fix: failing testcase

* fix: user flow for POI

* fix: layout for Expired scenario in onfido

* fix: styling of erro message

* fix: code smells

* chore: trigger rebuild

* fix: issue with checkbox

* fix: removed unused import

* fix: added keyboard event

* fix: resolved build failure

* Merge branch 'master' into likhith/KYC-363/onfido-sdk-updation

* fix: Onfido styles

* fix: resolved code-smells

* fix: resolved code smells

* fix: code styling

* fix: review comments

* Merge remote-tracking branch 'upstream/master' into likhith/WALL-1714/enhance-error-message-handling-for-poi

* Merge remote-tracking branch 'upstream/master' into likhith/WALL-1714/enhance-error-message-handling-for-poi

* Merge remote-tracking branch 'upstream/master' into likhith/WALL-1714/enhance-error-message-handling-for-poi

* chore: trigger rebuild

---------

Co-authored-by: “yauheni-kryzhyk-deriv” <“yauheni@deriv.me”>
Co-authored-by: Shahzaib <shahzaib@deriv.com>
  • Loading branch information
3 people authored Dec 4, 2023
1 parent a9b4860 commit e148070
Show file tree
Hide file tree
Showing 23 changed files with 688 additions and 324 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from 'react';
import { fireEvent, render, screen } from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Icon } from '@deriv/components';
import { StoreProvider, mockStore } from '@deriv/stores';
import IconMessageList from '../icon-message-list';

jest.mock('@deriv/components', () => {
Expand All @@ -11,67 +13,61 @@ jest.mock('@deriv/components', () => {
};
});
describe('<IconMessageList/>', () => {
const messages_list = ['Sample Text1', 'Sample Text2', 'Sample Text3', 'Sample Text4'];
const messages_list = ['DataComparisonDocumentNumbers', 'CompromisedDocument', 'VisualAuthenticityFonts'];

const mock_props: React.ComponentProps<typeof IconMessageList> = {
icon: <Icon icon='sampleIcon' />,
message: 'Lorem Ipsom',
message_list: messages_list,
onContinue: jest.fn(),
};

const store_config = mockStore({ ui: { is_desktop: true } });

const renderComponent = ({ props = mock_props, store = store_config }) =>
render(
<StoreProvider store={store}>
<IconMessageList {...props} />
</StoreProvider>
);

it('should render IconMessageList component', () => {
render(<IconMessageList />);
renderComponent({});
expect(screen.getByTestId('dt_icon_message_list')).toBeInTheDocument();
});

it('should render icon passed to the component', () => {
render(<IconMessageList icon={<Icon icon='sampleIcon' />} />);
expect(screen.getByTestId('mocked_icon')).toBeInTheDocument();
renderComponent({});
expect(screen.getByText('sampleIcon')).toBeInTheDocument();
expect(screen.getByText('IcAlertDanger')).toBeInTheDocument();
});

it('should show message passed to the component', () => {
render(<IconMessageList message={'Lorem Ipsom'} />);
renderComponent({});
expect(screen.getByText(/lorem ipsom/i)).toBeInTheDocument();
});
it('when the length of message_list is less than 3, it should show messages with icons ', () => {
render(<IconMessageList message_list={['Sample Text1', 'Sample Text2']} />);
expect(screen.getByText(/Sample Text1/i)).toBeInTheDocument();
expect(screen.getByText(/Sample Text2/i)).toBeInTheDocument();
expect(screen.getAllByText(/icclosecircle/i).length).toBe(2);
});

it('should show first 3 msgs and show_more_btn when the message_list is more than 3', () => {
render(<IconMessageList message_list={messages_list} />);
expect(screen.getByText(/sample text1/i)).toBeInTheDocument();
expect(screen.getByText(/sample text2/i)).toBeInTheDocument();
expect(screen.getByText(/sample text3/i)).toBeInTheDocument();
expect(screen.queryByText(/sample text4/i)).not.toBeInTheDocument();
expect(
screen.getByRole('button', {
name: /show more/i,
})
).toBeInTheDocument();
expect(
screen.queryByRole('button', {
name: /show less/i,
})
).not.toBeInTheDocument();
});

it('should show all messages and show_less_btn when show_more btn is clicked', () => {
render(<IconMessageList message_list={messages_list} />);

const show_more_btn = screen.getByRole('button', {
name: /show more/i,
});

fireEvent.click(show_more_btn);
expect(screen.getByText(/sample text1/i)).toBeInTheDocument();
expect(screen.getByText(/sample text2/i)).toBeInTheDocument();
expect(screen.getByText(/sample text3/i)).toBeInTheDocument();
expect(screen.getByText(/sample text4/i)).toBeInTheDocument();
expect(screen.queryByRole('button', { name: /show less/i })).toBeInTheDocument();
expect(screen.queryByRole('button', { name: /show more/i })).not.toBeInTheDocument();
it('should render the messages based on Onfido Error codes', () => {
const new_props = {
...mock_props,
message_list: ['DataComparisonDocumentNumbers', 'CompromisedDocument'],
};
renderComponent({ props: new_props });
expect(screen.getByText('Your document appears to be invalid.')).toBeInTheDocument();
expect(screen.getByText('Your document failed our verification checks.')).toBeInTheDocument();
});

it('should show continue_btn if OnContinue is passed', () => {
const onContinuefn = jest.fn();
render(<IconMessageList message_list={['Sample Text1']} onContinue={onContinuefn} />);
const upload_btn = screen.queryByRole('button', { name: /upload document/i });
const new_props = {
...mock_props,
messages_list: ['DataComparisonDocumentNumbers'],
onContinue: onContinuefn,
};
renderComponent({ props: new_props });
const upload_btn = screen.queryByRole('button', { name: /verify again/i });
expect(upload_btn).toBeInTheDocument();
fireEvent.click(upload_btn);
userEvent.click(upload_btn);
expect(onContinuefn).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import ListItem from '../list-item';
import { StoreProvider, mockStore } from '@deriv/stores';

describe('<ListItem/>', () => {
const store_config = mockStore({});

const renderComponent = (props: React.ComponentProps<typeof ListItem>) =>
render(
<StoreProvider store={store_config}>
<ListItem {...props} />
</StoreProvider>
);

it('should render ListItem component', () => {
renderComponent({ text: 'test' });
expect(screen.getByText('test')).toBeInTheDocument();
});

it('should render ListItem component with index', () => {
renderComponent({ text: 'test', index: 1 });
expect(screen.getByText('1.')).toBeInTheDocument();
expect(screen.getByText('test')).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -1,44 +1,27 @@
import React from 'react';
import classNames from 'classnames';
import { localize } from '@deriv/translations';
import { Div100vhContainer, Text, Button, Icon, ThemedScrollbars } from '@deriv/components';
import { isDesktop, isMobile } from '@deriv/shared';
import { Div100vhContainer, Text, Button, ThemedScrollbars, Icon } from '@deriv/components';
import { getOnfidoError } from '@deriv/shared';
import { observer, useStore } from '@deriv/stores';
import { Localize } from '@deriv/translations';
import ListItem from './list-item';

type TListItem = {
text?: string;
};

type TMessage_list = {
message_list?: string[];
};

type TIconMessageList = TMessage_list & {
className: string;
type TIconMessageList = {
className?: string;
icon: React.ReactElement;
message: string;
message_list: Array<string>;
onContinue: () => void;
};

const ListItem = ({ text }: TListItem) => (
<div className='account-management__list-message'>
<div className='account-management__list-icon'>
<Icon icon='IcCloseCircle' color='red' />
</div>
<div className='account-management__list-text-container'>
<Text size='xs' className='account-management__list-text'>
{text}
</Text>
</div>
</div>
);

const IconMessageList = ({ className, icon, message, message_list = [], onContinue }: Partial<TIconMessageList>) => {
const has_maximum_list = message_list.length > 3;
const IconMessageList = observer(({ className, icon, message, message_list = [], onContinue }: TIconMessageList) => {
const { ui } = useStore();
const { is_mobile, is_desktop } = ui;
return (
<ThemedScrollbars is_bypassed={isMobile()}>
<ThemedScrollbars is_bypassed={is_mobile}>
<Div100vhContainer
className='account-management__message-wrapper'
is_disabled={isDesktop()}
is_disabled={is_desktop}
height_offset='110px'
>
<div
Expand All @@ -62,17 +45,31 @@ const IconMessageList = ({ className, icon, message, message_list = [], onContin
className={classNames('account-management__message', {
[`${className}__message`]: className,
})}
size={is_desktop ? 's' : 'xs'}
>
{message}
</Text>

{message_list && (
<div className='account-management__list-container'>
{has_maximum_list ? (
<MaximumList message_list={message_list} />
) : (
message_list.map((text, idx) => <ListItem key={idx} text={text} />)
)}
<div className='account-management__list-message'>
<div className='account-management__list-icon'>
<Icon icon='IcAlertDanger' color='red' />
</div>
<section>
{message_list.length < 2 ? (
<ListItem text={getOnfidoError(message_list[0])} />
) : (
message_list.map((text, idx) => (
<ListItem
key={text}
text={getOnfidoError(message_list[idx])}
index={idx + 1}
/>
))
)}
</section>
</div>
</div>
)}
{onContinue && (
Expand All @@ -81,49 +78,15 @@ const IconMessageList = ({ className, icon, message, message_list = [], onContin
className='account-management__continue'
onClick={onContinue}
large
text={localize('Upload Document')}
primary
/>
>
<Localize i18n_default_text='Verify again' />
</Button>
)}
</div>
</Div100vhContainer>
</ThemedScrollbars>
);
};

const MaximumList = ({ message_list }: TMessage_list) => {
const [show_more, setShowMore] = React.useState(false);
const maximum_list = message_list.slice(0, 3);

return show_more ? (
<React.Fragment>
{message_list.map(text => (
<ListItem key={text} text={text} />
))}
<Button
type='button'
className='account-management__list-button'
onClick={() => setShowMore(false)}
large
text={localize('Show less')}
tertiary
/>
</React.Fragment>
) : (
<React.Fragment>
{maximum_list.map(text => (
<ListItem key={text} text={text} />
))}
<Button
type='button'
className='account-management__list-button'
onClick={() => setShowMore(true)}
large
text={localize('Show more')}
tertiary
/>
</React.Fragment>
);
};
});

export default IconMessageList;
30 changes: 30 additions & 0 deletions packages/account/src/Components/icon-message-list/list-item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import { Text } from '@deriv/components';
import { observer, useStore } from '@deriv/stores';
import { Localize } from '@deriv/translations';

type TListItem = {
text: React.ReactNode;
index?: number;
};

const ListItem = observer(({ text, index }: TListItem) => {
const {
ui: { is_desktop },
} = useStore();
const text_size = is_desktop ? 'xs' : 'xxs';
return (
<div className='account-management__list-text-container'>
{index && (
<Text size={text_size} className='account-management__list-text'>
<Localize i18n_default_text='{{index}}.' values={{ index }} />{' '}
</Text>
)}
<Text size={text_size} className='account-management__list-text'>
{text}
</Text>
</div>
);
});

export default ListItem;
Loading

0 comments on commit e148070

Please sign in to comment.