From 57981b297cfab75e0b11c8685195ad17cbf928d5 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Fri, 29 Mar 2024 10:35:41 +0200 Subject: [PATCH] fix(a11yStatus): pass correct dependency array (#1586) --- src/hooks/useCombobox/__tests__/props.test.js | 23 +++++++++++++ src/hooks/useMultipleSelection/README.md | 2 +- .../__tests__/props.test.js | 33 +++++++++++++++++-- src/hooks/useSelect/__tests__/props.test.js | 23 +++++++++++++ src/hooks/utils.js | 4 +-- 5 files changed, 79 insertions(+), 6 deletions(-) diff --git a/src/hooks/useCombobox/__tests__/props.test.js b/src/hooks/useCombobox/__tests__/props.test.js index 71691ffe..a93a95ae 100644 --- a/src/hooks/useCombobox/__tests__/props.test.js +++ b/src/hooks/useCombobox/__tests__/props.test.js @@ -194,6 +194,29 @@ describe('props', () => { expect(getA11yStatusContainer()).not.toBeInTheDocument() }) + test('calls the function only on state changes', async () => { + const getA11yStatusMessage = jest.fn() + const {rerender} = renderCombobox({ + getA11yStatusMessage, + }) + + await changeInputValue('h') + waitForDebouncedA11yStatusUpdate() + + expect(getA11yStatusMessage).toHaveBeenCalledWith({ + inputValue: 'h', + highlightedIndex: -1, + isOpen: true, + selectedItem: null, + }) + expect(getA11yStatusMessage).toHaveBeenCalledTimes(1) + + getA11yStatusMessage.mockClear() + rerender({getA11yStatusMessage}) + + expect(getA11yStatusMessage).not.toHaveBeenCalled() + }) + test('adds a status message element with the text returned', async () => { const a11yStatusMessage1 = 'Dropdown is open' const a11yStatusMessage2 = 'Dropdown is still open' diff --git a/src/hooks/useMultipleSelection/README.md b/src/hooks/useMultipleSelection/README.md index 367583d9..5aa72939 100644 --- a/src/hooks/useMultipleSelection/README.md +++ b/src/hooks/useMultipleSelection/README.md @@ -483,7 +483,7 @@ function getA11yStatusMessage(state) { const {selectedItems} = state if (selectedItems.length === previousSelectedItemsRef.current.length) { - return + return '' } const removedSelectedItem = previousSelectedItemsRef.current.find( diff --git a/src/hooks/useMultipleSelection/__tests__/props.test.js b/src/hooks/useMultipleSelection/__tests__/props.test.js index 5294e57b..d9b64718 100644 --- a/src/hooks/useMultipleSelection/__tests__/props.test.js +++ b/src/hooks/useMultipleSelection/__tests__/props.test.js @@ -70,6 +70,33 @@ describe('props', () => { expect(getA11yStatusContainer()).not.toBeInTheDocument() }) + test('calls the function only on state changes', async () => { + const getA11yStatusMessage = jest.fn() + const selectedItems = [items[0], items[1]] + const multipleSelectionProps = { + selectedItems, + initialActiveIndex: 1, + getA11yStatusMessage, + } + const {rerender} = renderMultipleCombobox({ + multipleSelectionProps, + }) + + await keyDownOnSelectedItemAtIndex(1, '{ArrowLeft}') + waitForDebouncedA11yStatusUpdate() + + expect(getA11yStatusMessage).toHaveBeenCalledWith({ + activeIndex: 0, + selectedItems, + }) + expect(getA11yStatusMessage).toHaveBeenCalledTimes(1) + + getA11yStatusMessage.mockClear() + rerender({multipleSelectionProps: {...multipleSelectionProps, activeIndex: 0}}) + + expect(getA11yStatusMessage).not.toHaveBeenCalled() + }) + test('adds a status message element with the text returned', async () => { const a11yStatusMessage1 = 'to the left to the left' const a11yStatusMessage2 = 'to the right?' @@ -81,7 +108,7 @@ describe('props', () => { renderMultipleCombobox({ multipleSelectionProps: { selectedItems, - initialActiveIndex: 0, + initialActiveIndex: 1, getA11yStatusMessage, }, }) @@ -114,7 +141,7 @@ describe('props', () => { renderMultipleCombobox({ multipleSelectionProps: { selectedItems: [items[0], items[1]], - initialActiveIndex: 0, + initialActiveIndex: 1, getA11yStatusMessage: jest.fn().mockReturnValue('bla bla'), }, }) @@ -157,7 +184,7 @@ describe('props', () => { renderMultipleCombobox({ multipleSelectionProps: { selectedItems: [items[0], items[1]], - initialActiveIndex: 0, + initialActiveIndex: 1, getA11yStatusMessage: jest.fn().mockReturnValue('bla bla'), environment, }, diff --git a/src/hooks/useSelect/__tests__/props.test.js b/src/hooks/useSelect/__tests__/props.test.js index 814a3596..111dbf66 100644 --- a/src/hooks/useSelect/__tests__/props.test.js +++ b/src/hooks/useSelect/__tests__/props.test.js @@ -86,6 +86,29 @@ describe('props', () => { expect(getA11yStatusContainer()).not.toBeInTheDocument() }) + test('calls the function only on state changes', async () => { + const getA11yStatusMessage = jest.fn() + const {rerender} = renderSelect({ + getA11yStatusMessage, + }) + + await keyDownOnToggleButton('h') + waitForDebouncedA11yStatusUpdate() + + expect(getA11yStatusMessage).toHaveBeenCalledWith({ + inputValue: 'h', + highlightedIndex: 15, + isOpen: true, + selectedItem: null + }) + expect(getA11yStatusMessage).toHaveBeenCalledTimes(1) + + getA11yStatusMessage.mockClear() + rerender({getA11yStatusMessage}) + + expect(getA11yStatusMessage).not.toHaveBeenCalled() + }) + test('adds a status message element with the text returned', async () => { const a11yStatusMessage1 = 'Dropdown is open' const a11yStatusMessage2 = 'Dropdown is still open' diff --git a/src/hooks/utils.js b/src/hooks/utils.js index df05a17e..746ef658 100644 --- a/src/hooks/utils.js +++ b/src/hooks/utils.js @@ -411,7 +411,7 @@ function useMouseAndTouchTracker( environment.removeEventListener('touchmove', onTouchMove) environment.removeEventListener('touchend', onTouchEnd) } - // eslint-disable-next-line react-hooks/exhaustive-deps -- refs don't change + // eslint-disable-next-line react-hooks/exhaustive-deps -- refs don't change }, [environment, handleBlur]) return mouseAndTouchTrackersRef.current @@ -505,7 +505,7 @@ function useA11yMessageStatus( updateA11yStatus(status, document) // eslint-disable-next-line react-hooks/exhaustive-deps - }, [dependencyArray]) + }, dependencyArray) // Cleanup the status message container. useEffect(() => {