0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

fix(ui): verification-code iteration fix (#2917)

This commit is contained in:
simeng-li 2023-01-12 16:22:47 +08:00 committed by GitHub
parent d6aeaf9b0e
commit 4130291359
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 95 additions and 50 deletions

View file

@ -30,6 +30,7 @@ const Toast = ({ message, duration = 3000, callback }: Props) => {
return ( return (
<ReactModal <ReactModal
shouldFocusAfterRender={false}
// For styling use // For styling use
// eslint-disable-next-line jsx-a11y/aria-role // eslint-disable-next-line jsx-a11y/aria-role
role="toast" role="toast"

View file

@ -6,7 +6,7 @@ describe('VerificationCode Component', () => {
const onChange = jest.fn(); const onChange = jest.fn();
beforeEach(() => { beforeEach(() => {
onChange.mockClear(); jest.clearAllMocks();
}); });
it('render with value', () => { it('render with value', () => {
@ -80,9 +80,11 @@ describe('VerificationCode Component', () => {
const inputElements = container.querySelectorAll('input'); const inputElements = container.querySelectorAll('input');
if (inputElements[2]) { if (inputElements[2]) {
fireEvent.input(inputElements[2], { target: { value: 'a' } }); for (const value of ['a', 'e', '+', '-', '.']) {
fireEvent.input(inputElements[2], { target: { value } });
expect(onChange).not.toBeCalled(); expect(onChange).not.toBeCalled();
} }
}
}); });
it('replace old value with new input char', () => { it('replace old value with new input char', () => {
@ -124,14 +126,14 @@ describe('VerificationCode Component', () => {
} }
}); });
it('onPasteHandler', () => { describe('onPasteHandler', () => {
it('full update', () => {
const input = ['1', '2', '3', '4', '5', '6']; const input = ['1', '2', '3', '4', '5', '6'];
const { container } = render( const { container } = render(
<VerificationCode name="passcode" value={input} onChange={onChange} /> <VerificationCode name="passcode" value={input} onChange={onChange} />
); );
const inputElements = container.querySelectorAll('input'); const inputElements = container.querySelectorAll('input');
// Full update
if (inputElements[0]) { if (inputElements[0]) {
fireEvent.paste(inputElements[0], { fireEvent.paste(inputElements[0], {
clipboardData: { clipboardData: {
@ -140,8 +142,15 @@ describe('VerificationCode Component', () => {
}); });
expect(onChange).toBeCalledWith(['7', '8', '9', '0', '1', '2']); expect(onChange).toBeCalledWith(['7', '8', '9', '0', '1', '2']);
} }
});
it('partial update', () => {
const input = ['1', '2', '3', '4', '5', '6'];
const { container } = render(
<VerificationCode name="passcode" value={input} onChange={onChange} />
);
const inputElements = container.querySelectorAll('input');
// Partial update
if (inputElements[2]) { if (inputElements[2]) {
fireEvent.paste(inputElements[2], { fireEvent.paste(inputElements[2], {
clipboardData: { clipboardData: {
@ -150,8 +159,15 @@ describe('VerificationCode Component', () => {
}); });
expect(onChange).toBeCalledWith(['1', '2', '7', '8', '9', '6']); expect(onChange).toBeCalledWith(['1', '2', '7', '8', '9', '6']);
} }
});
it('overLength partial update', () => {
const input = ['1', '2', '3', '4', '5', '6'];
const { container } = render(
<VerificationCode name="passcode" value={input} onChange={onChange} />
);
const inputElements = container.querySelectorAll('input');
// OverLength update
if (inputElements[4]) { if (inputElements[4]) {
fireEvent.paste(inputElements[4], { fireEvent.paste(inputElements[4], {
clipboardData: { clipboardData: {
@ -160,10 +176,32 @@ describe('VerificationCode Component', () => {
}); });
expect(onChange).toBeCalledWith(['1', '2', '3', '4', '7', '8']); expect(onChange).toBeCalledWith(['1', '2', '3', '4', '7', '8']);
} }
});
onChange.mockClear(); it('filter numeric past data', () => {
const input = ['1', '2', '3', '4', '5', '6'];
const { container } = render(
<VerificationCode name="passcode" value={input} onChange={onChange} />
);
const inputElements = container.querySelectorAll('input');
if (inputElements[0]) {
fireEvent.paste(inputElements[0], {
clipboardData: {
getData: () => 'test input 124 343',
},
});
expect(onChange).toBeCalledWith(['1', '2', '4', '3', '4', '3']);
}
});
it('Non-numeric past data', () => {
const input = ['1', '2', '3', '4', '5', '6'];
const { container } = render(
<VerificationCode name="passcode" value={input} onChange={onChange} />
);
const inputElements = container.querySelectorAll('input');
// Non-numeric past data
if (inputElements[0]) { if (inputElements[0]) {
fireEvent.paste(inputElements[0], { fireEvent.paste(inputElements[0], {
clipboardData: { clipboardData: {
@ -173,4 +211,5 @@ describe('VerificationCode Component', () => {
expect(onChange).not.toBeCalled(); expect(onChange).not.toBeCalled();
} }
}); });
});
}); });

View file

@ -105,7 +105,7 @@ const VerificationCode = ({
clipboardData, clipboardData,
} = event; } = event;
const data = clipboardData.getData('text'); const data = clipboardData.getData('text').match(/\d/g)?.join('') ?? '';
// Unrecognized target input field // Unrecognized target input field
if (!dataset.id) { if (!dataset.id) {
@ -160,6 +160,10 @@ const VerificationCode = ({
event.preventDefault(); event.preventDefault();
nextTarget?.focus(); nextTarget?.focus();
break; break;
case '+':
case '-':
case 'e':
case '.':
case 'ArrowUp': case 'ArrowUp':
case 'ArrowDown': case 'ArrowDown':
event.preventDefault(); event.preventDefault();
@ -175,7 +179,7 @@ const VerificationCode = ({
if (value.length === 0) { if (value.length === 0) {
inputReferences.current[0]?.focus(); inputReferences.current[0]?.focus();
} }
}, [value, onChange]); }, [value]);
return ( return (
<div className={className}> <div className={className}>

View file

@ -71,9 +71,10 @@ const VerificationCode = ({ type, method, className, hasPasswordButton, target }
<TextLink <TextLink
className={styles.link} className={styles.link}
text="description.resend_passcode" text="description.resend_passcode"
onClick={() => { onClick={async () => {
clearErrorMessage(); clearErrorMessage();
void onResendVerificationCode(); await onResendVerificationCode();
setCode([]);
}} }}
/> />
)} )}