From 909c2e1463420eaf728e6898e28dbee35a7f147e Mon Sep 17 00:00:00 2001 From: daledah Date: Mon, 23 Dec 2024 14:26:59 +0700 Subject: [PATCH 1/2] fix: focused background is not updated --- src/components/SelectionList/BaseListItem.tsx | 2 + .../SelectionList/BaseSelectionList.tsx | 9 +++ tests/unit/BaseSelectionListTest.tsx | 66 +++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 tests/unit/BaseSelectionListTest.tsx diff --git a/src/components/SelectionList/BaseListItem.tsx b/src/components/SelectionList/BaseListItem.tsx index 38df5efaee7b..8e06fc8dc243 100644 --- a/src/components/SelectionList/BaseListItem.tsx +++ b/src/components/SelectionList/BaseListItem.tsx @@ -108,6 +108,8 @@ function BaseListItem({ wrapperStyle={pressableWrapperStyle} > ( isFocused, }); + useEffect(() => { + const selectedItemIndex = flattenedSections.allOptions.findIndex((option) => option.isSelected); + if (selectedItemIndex === -1 || selectedItemIndex === focusedIndex) { + return; + } + setFocusedIndex(selectedItemIndex); + // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps + }, [flattenedSections]); + const clearInputAfterSelect = useCallback(() => { onChangeText?.(''); }, [onChangeText]); diff --git a/tests/unit/BaseSelectionListTest.tsx b/tests/unit/BaseSelectionListTest.tsx new file mode 100644 index 000000000000..101ff0c74ef1 --- /dev/null +++ b/tests/unit/BaseSelectionListTest.tsx @@ -0,0 +1,66 @@ +import {fireEvent, render, screen} from '@testing-library/react-native'; +import BaseSelectionList from '@components/SelectionList/BaseSelectionList'; +import RadioListItem from '@components/SelectionList/RadioListItem'; +import type {ListItem} from '@components/SelectionList/types'; +import type Navigation from '@libs/Navigation/Navigation'; + +type BaseSelectionListSections = { + sections: TItem[]; +}; + +const mockSections = Array.from({length: 10}, (_, index) => ({ + text: `Item ${index}`, + keyForList: `${index}`, + isSelected: index === 1, +})); + +jest.mock('@react-navigation/native', () => { + const actualNav = jest.requireActual('@react-navigation/native'); + return { + ...actualNav, + useIsFocused: jest.fn(), + useFocusEffect: jest.fn(), + }; +}); + +describe('BaseSelectionList', () => { + const onSelectRowMock = jest.fn(); + + function BaseListItemRenderer(props: BaseSelectionListSections) { + const {sections} = props; + const focusedKey = sections.find((item) => item.isSelected)?.keyForList; + return ( + + ); + } + + it('should handle item press correctly', () => { + render(); + fireEvent.press(screen.getByTestId('base-list-item-1')); + expect(onSelectRowMock).toHaveBeenCalledWith({ + ...mockSections.at(1), + shouldAnimateInHighlight: false, + }); + }); + + it('should update focused item when sections are updated from BE', () => { + const updatedMockSections = mockSections.map((section) => ({ + ...section, + isSelected: section.keyForList === '2', + })); + const {rerender} = render(); + expect(screen.getByTestId('base-list-item-1')).toHaveAccessibilityState({ + selected: true, + }); + rerender(); + expect(screen.getByTestId('base-list-item-2')).toHaveAccessibilityState({ + selected: true, + }); + }); +}); From 72a038ca1647ed9e58a6ac6c2bb18319e00bf063 Mon Sep 17 00:00:00 2001 From: daledah Date: Wed, 25 Dec 2024 16:04:39 +0700 Subject: [PATCH 2/2] feat: move base list item test ID to CONST.ts --- src/CONST.ts | 2 ++ src/components/SelectionList/BaseListItem.tsx | 2 +- tests/unit/BaseSelectionListTest.tsx | 7 ++++--- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 53197d41b85e..1abd76bb3616 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -6448,6 +6448,8 @@ const CONST = { }, MIGRATED_USER_WELCOME_MODAL: 'migratedUserWelcomeModal', + + BASE_LIST_ITEM_TEST_ID: 'base-list-item-', } as const; type Country = keyof typeof CONST.ALL_COUNTRIES; diff --git a/src/components/SelectionList/BaseListItem.tsx b/src/components/SelectionList/BaseListItem.tsx index 8e06fc8dc243..57fd457b4b00 100644 --- a/src/components/SelectionList/BaseListItem.tsx +++ b/src/components/SelectionList/BaseListItem.tsx @@ -108,7 +108,7 @@ function BaseListItem({ wrapperStyle={pressableWrapperStyle} > = { sections: TItem[]; @@ -42,7 +43,7 @@ describe('BaseSelectionList', () => { it('should handle item press correctly', () => { render(); - fireEvent.press(screen.getByTestId('base-list-item-1')); + fireEvent.press(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}1`)); expect(onSelectRowMock).toHaveBeenCalledWith({ ...mockSections.at(1), shouldAnimateInHighlight: false, @@ -55,11 +56,11 @@ describe('BaseSelectionList', () => { isSelected: section.keyForList === '2', })); const {rerender} = render(); - expect(screen.getByTestId('base-list-item-1')).toHaveAccessibilityState({ + expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}1`)).toHaveAccessibilityState({ selected: true, }); rerender(); - expect(screen.getByTestId('base-list-item-2')).toHaveAccessibilityState({ + expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}2`)).toHaveAccessibilityState({ selected: true, }); });