diff --git a/src/__testing__/UserSearchFieldInput.test.tsx b/src/__testing__/UserSearchFieldInput.test.tsx new file mode 100644 index 000000000..f6e421caa --- /dev/null +++ b/src/__testing__/UserSearchFieldInput.test.tsx @@ -0,0 +1,68 @@ +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; +import React from 'react'; +import UserSearchField from '../custom/UserSearchField/UserSearchFieldInput'; +import { SistentThemeProvider } from '../theme'; + +// Regression guard for the user-picker type-ahead. +// +// The picker is a controlled MUI Autocomplete. In MUI v9 the `renderInput` +// params expose the native wiring (value, onChange, onKeyDown, focus +// handlers and the anchor ref from `getInputProps`) under +// `params.slotProps.htmlInput`. If the TextField is handed an explicit +// `slotProps` object that omits `htmlInput`, that object REPLACES the one +// spread from `{...params}` and the input is silently disconnected from the +// Autocomplete: keystrokes no longer reach `onInputChange`, the search never +// fires and the suggestion list never opens. These tests assert the wiring +// survives so the type-ahead keeps working. + +type FieldProps = React.ComponentProps; + +const renderWithTheme = (ui: React.ReactElement) => + render({ui}); + +const jane = { + userId: 'u-jane', + firstName: 'Jane', + lastName: 'Doe', + email: 'jane@example.com' +}; + +const renderField = (overrides: Partial = {}) => { + const props: FieldProps = { + usersData: [], + setUsersData: jest.fn(), + currentUserData: null, + searchedUsers: [jane], + isUserSearchLoading: false, + fetchSearchedUsers: jest.fn(), + usersSearch: '', + setUsersSearch: jest.fn(), + ...overrides + }; + const utils = renderWithTheme(); + const input = screen.getByRole('combobox') as HTMLInputElement; + return { props, input, ...utils }; +}; + +describe('UserSearchField type-ahead wiring', () => { + it('forwards keystrokes to the search callback', () => { + const { props, input } = renderField(); + + fireEvent.change(input, { target: { value: 'jane' } }); + + // Only reachable when the Autocomplete's htmlInput slot is forwarded to + // the TextField; a dropped slot leaves the input inert and this stays 0. + expect(props.fetchSearchedUsers).toHaveBeenCalledWith('jane'); + }); + + it('opens the suggestion list with matching users as the query is typed', async () => { + const { input } = renderField({ usersSearch: 'jane' }); + + fireEvent.change(input, { target: { value: 'jane' } }); + + await waitFor(() => { + expect(screen.queryByText('jane@example.com')).not.toBeNull(); + }); + expect(screen.queryByText('Jane Doe')).not.toBeNull(); + }); +}); diff --git a/src/custom/DashboardWidgets/GettingStartedWidget/TeamSearchField.tsx b/src/custom/DashboardWidgets/GettingStartedWidget/TeamSearchField.tsx index 7a1b8d1fd..5517a4b74 100644 --- a/src/custom/DashboardWidgets/GettingStartedWidget/TeamSearchField.tsx +++ b/src/custom/DashboardWidgets/GettingStartedWidget/TeamSearchField.tsx @@ -147,6 +147,7 @@ const TeamSearchField: React.FC = ({ helperText={error ? 'Team Already Selected' : ''} fullWidth slotProps={{ + ...params.slotProps, input: { ...params.slotProps?.input, endAdornment: isLoading ? : null diff --git a/src/custom/InputSearchField/InputSearchField.tsx b/src/custom/InputSearchField/InputSearchField.tsx index 0ab226111..7fa941688 100644 --- a/src/custom/InputSearchField/InputSearchField.tsx +++ b/src/custom/InputSearchField/InputSearchField.tsx @@ -128,7 +128,9 @@ const InputSearchField: React.FC = ({ helperText={error} fullWidth slotProps={{ + ...params.slotProps, inputLabel: { + ...params.slotProps?.inputLabel, style: { fontFamily: 'inherit' } diff --git a/src/custom/UserSearchField/UserSearchField.tsx b/src/custom/UserSearchField/UserSearchField.tsx index d74f50144..c9215b369 100644 --- a/src/custom/UserSearchField/UserSearchField.tsx +++ b/src/custom/UserSearchField/UserSearchField.tsx @@ -156,12 +156,11 @@ const UserShareSearch: React.FC = ({ } }} slotProps={{ + ...params.slotProps, input: { ...params.slotProps?.input, endAdornment: ( - <> - {searchUserLoading ? : null} - + <>{searchUserLoading ? : null} ) } }} diff --git a/src/custom/UserSearchField/UserSearchFieldInput.tsx b/src/custom/UserSearchField/UserSearchFieldInput.tsx index f229345e7..c0858afbb 100644 --- a/src/custom/UserSearchField/UserSearchFieldInput.tsx +++ b/src/custom/UserSearchField/UserSearchFieldInput.tsx @@ -183,7 +183,9 @@ const UserSearchField: React.FC = ({ error={!!error} helperText={error} slotProps={{ + ...params.slotProps, inputLabel: { + ...params.slotProps?.inputLabel, style: { fontFamily: 'inherit' }