diff --git a/.changeset/great-files-shave.md b/.changeset/great-files-shave.md new file mode 100644 index 0000000000..271a8e8955 --- /dev/null +++ b/.changeset/great-files-shave.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Fixed an issue where `EntityOwnerPicker` failed to filter options when the input text contained uppercase characters. diff --git a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.test.tsx b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.test.tsx index b8c8e58d32..87c5c9a002 100644 --- a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.test.tsx +++ b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.test.tsx @@ -362,6 +362,76 @@ describe('', () => { owners: new EntityOwnerFilter(['group:default/team-b']), }); }); + + it('calls fetch with lowercased input and displays results', async () => { + const updateFilters = jest.fn(); + const someOwnerEntities: Entity[] = [ + { + apiVersion: '1', + kind: 'Group', + metadata: { + name: 'some-owner', + }, + }, + { + apiVersion: '1', + kind: 'Group', + metadata: { + name: 'some-owner-2', + }, + spec: { + profile: { + displayName: 'Some Owner 2', + }, + }, + }, + ]; + mockCatalogApi.queryEntities.mockImplementation(async _request => { + const totalItems = 2; + return { + items: someOwnerEntities, + pageInfo: { + nextCursor: '', + }, + totalItems, + }; + }); + await renderInTestApp( + + + + + , + ); + + expect(mockCatalogApi.getEntitiesByRefs).not.toHaveBeenCalled(); + expect(updateFilters).toHaveBeenLastCalledWith({ + owners: undefined, + }); + + const input = screen.getByRole('textbox'); + fireEvent.change(input, { target: { value: 'Some-Owner' } }); + + await waitFor(() => + expect(screen.getByText('some-owner')).toBeInTheDocument(), + ); + expect(mockCatalogApi.queryEntities).toHaveBeenLastCalledWith( + expect.objectContaining({ + fullTextFilter: expect.objectContaining({ + term: 'some-owner', + }), + }), + ); + + fireEvent.click(screen.getByText('some-owner')); + expect(updateFilters).toHaveBeenLastCalledWith({ + owners: new EntityOwnerFilter(['group:default/some-owner']), + }); + }); }); describe('', () => { diff --git a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx index 247a3784f4..ed200c77c4 100644 --- a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx +++ b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx @@ -146,7 +146,11 @@ export const EntityOwnerPicker = (props?: EntityOwnerPickerProps) => { mode, initialSelectedOwnersRefs: selectedOwners, }); - useDebouncedEffect(() => handleFetch({ text }), [text, handleFetch], 250); + useDebouncedEffect( + () => handleFetch({ text: text.toLocaleLowerCase('en-US') }), + [text, handleFetch], + 250, + ); const availableOwners = value?.items || [];