From caa3ef8d2fa650f52997c7b661a74a9d5cbca9cd Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Fri, 27 Oct 2023 13:31:40 +0200 Subject: [PATCH] fix(behaviour): clear completion on "reset" (#1215) * chore(test): add real attributes to playground input * test(debouncing): prevent unrealistic behaviour * fix(behaviour): clear completion on "reset" * chore: use right word in comment --- .../src/__tests__/completion.test.ts | 31 +++++++++++++++++++ .../src/__tests__/debouncing.test.ts | 25 +++++++++++++-- .../src/__tests__/metadata.test.ts | 9 ++++-- packages/autocomplete-core/src/onKeyDown.ts | 2 +- .../autocomplete-core/src/stateReducer.ts | 1 + .../createAlgoliaInsightsPlugin.test.ts | 9 ++++++ test/utils/createPlayground.ts | 31 ++++++++++++++++++- 7 files changed, 102 insertions(+), 6 deletions(-) diff --git a/packages/autocomplete-core/src/__tests__/completion.test.ts b/packages/autocomplete-core/src/__tests__/completion.test.ts index 8b7c28f3d..f88e38a6c 100644 --- a/packages/autocomplete-core/src/__tests__/completion.test.ts +++ b/packages/autocomplete-core/src/__tests__/completion.test.ts @@ -161,4 +161,35 @@ describe('completion', () => { }) ); }); + + test('clears completion on "reset"', () => { + const { inputElement, resetElement } = createPlayground( + createAutocomplete, + { + openOnFocus: true, + initialState: { + collections: [ + createCollection({ + source: { + getItemInputValue({ item }) { + return item.label; + }, + }, + items: [{ label: '1' }, { label: '2' }], + }), + ], + }, + } + ); + inputElement.focus(); + + userEvent.type(inputElement, 'Some text to make sure reset shows'); + expect(inputElement).toHaveValue('Some text to make sure reset shows'); + + userEvent.type(inputElement, '{arrowdown}'); + expect(inputElement).toHaveValue('1'); + + resetElement.click(); + expect(inputElement).toHaveValue(''); + }); }); diff --git a/packages/autocomplete-core/src/__tests__/debouncing.test.ts b/packages/autocomplete-core/src/__tests__/debouncing.test.ts index f4bd90e08..5ece55717 100644 --- a/packages/autocomplete-core/src/__tests__/debouncing.test.ts +++ b/packages/autocomplete-core/src/__tests__/debouncing.test.ts @@ -42,15 +42,31 @@ describe('debouncing', () => { ); }); - test('triggers subsequent queries after reopening the panel', async () => { + test('triggers subsequent queries after closing and reopening the panel', async () => { const onStateChange = jest.fn(); const getItems = jest.fn(({ query }) => [{ label: query }]); const { inputElement } = createPlayground(createAutocomplete, { onStateChange, + openOnFocus: true, getSources: () => debounced([createSource({ getItems })]), }); - userEvent.type(inputElement, 'abc{esc}'); + inputElement.focus(); + userEvent.type(inputElement, 'ab'); + await defer(noop, delay); + + expect(onStateChange).toHaveBeenLastCalledWith( + expect.objectContaining({ + state: expect.objectContaining({ + status: 'idle', + isOpen: true, + }), + }) + ); + expect(getItems).toHaveBeenCalledTimes(1); + expect(inputElement).toHaveValue('ab'); + + userEvent.type(inputElement, 'c{esc}'); expect(onStateChange).toHaveBeenLastCalledWith( expect.objectContaining({ @@ -60,8 +76,11 @@ describe('debouncing', () => { }), }) ); + expect(getItems).toHaveBeenCalledTimes(1); + expect(inputElement).toHaveValue('abc'); userEvent.type(inputElement, 'def'); + expect(inputElement).toHaveValue('abcdef'); await defer(noop, delay); @@ -78,6 +97,8 @@ describe('debouncing', () => { }), }) ); + expect(getItems).toHaveBeenCalledTimes(2); + expect(inputElement).toHaveValue('abcdef'); }); }); diff --git a/packages/autocomplete-core/src/__tests__/metadata.test.ts b/packages/autocomplete-core/src/__tests__/metadata.test.ts index fdbe64b12..c64025012 100644 --- a/packages/autocomplete-core/src/__tests__/metadata.test.ts +++ b/packages/autocomplete-core/src/__tests__/metadata.test.ts @@ -73,7 +73,7 @@ describe('metadata', () => { ).content ) ).toEqual({ - options: { 'autocomplete-core': ['environment'] }, + options: { 'autocomplete-core': ['environment', 'onStateChange'] }, plugins: [], ua: [{ segment: 'autocomplete-core', version }], }); @@ -111,7 +111,12 @@ describe('metadata', () => { ).content ).options ).toEqual({ - 'autocomplete-core': ['openOnFocus', 'placeholder', 'environment'], + 'autocomplete-core': [ + 'openOnFocus', + 'placeholder', + 'environment', + 'onStateChange', + ], }); }); diff --git a/packages/autocomplete-core/src/onKeyDown.ts b/packages/autocomplete-core/src/onKeyDown.ts index 64a1d4944..d5663bd63 100644 --- a/packages/autocomplete-core/src/onKeyDown.ts +++ b/packages/autocomplete-core/src/onKeyDown.ts @@ -114,7 +114,7 @@ export function onKeyDown({ } else if (event.key === 'Tab') { store.dispatch('blur', null); - // Hitting the `Escape` key signals the end of a user interaction with the + // Hitting the `Tab` key signals the end of a user interaction with the // autocomplete. At this point, we should ignore any requests that are still // pending and could reopen the panel once they resolve, because that would // result in an unsolicited UI behavior. diff --git a/packages/autocomplete-core/src/stateReducer.ts b/packages/autocomplete-core/src/stateReducer.ts index ced4cfea2..fbd017de6 100644 --- a/packages/autocomplete-core/src/stateReducer.ts +++ b/packages/autocomplete-core/src/stateReducer.ts @@ -129,6 +129,7 @@ export const stateReducer: Reducer = (state, action) => { ? action.props.defaultActiveItemId : null, status: 'idle', + completion: null, query: '', }; } diff --git a/packages/autocomplete-plugin-algolia-insights/src/__tests__/createAlgoliaInsightsPlugin.test.ts b/packages/autocomplete-plugin-algolia-insights/src/__tests__/createAlgoliaInsightsPlugin.test.ts index bd5f2580c..b76d8c080 100644 --- a/packages/autocomplete-plugin-algolia-insights/src/__tests__/createAlgoliaInsightsPlugin.test.ts +++ b/packages/autocomplete-plugin-algolia-insights/src/__tests__/createAlgoliaInsightsPlugin.test.ts @@ -242,6 +242,9 @@ describe('createAlgoliaInsightsPlugin', () => {
+