CreateImageWizard: Package search reset buttons and typeahead filter

Resolves #604. The available and chosen package search inputs now have a
reset button which resets the search and list elements to their default
states. This fixes a cosmetic issue related to the focus-visible width
being smaller than the search input width. This is accomplished by passing
an onClear prop to the search input.

The functions used to add all and selected packages were split from two
functions into four functions. The functions appear similiar but this is only
superficial; the logic is actually quite different and there is very
little code reuse. Four separate functions will be easier to understand and
maintain.

This commit includes several other modifications:
1. The chosen package search is now a typeahead filter. This brings it
   in line with PatternFly dual list selector examples.
2. The available package search button has changed to be in line with
   the PatternFly <SearchInput /> component examples.
3. Package sorting behavior is now consistent. Previously, packages would be
   sorted if 'add all' was used but not if 'add selected' was used. Now
   the default behavior is to always sort the package list.
This commit is contained in:
lucasgarfield 2022-03-28 16:57:34 +02:00 committed by jkozol
parent cc6a96c05d
commit fa7b0ca553
2 changed files with 184 additions and 84 deletions

View file

@ -96,7 +96,7 @@ const mockPkgResultEmpty = {
const searchForAvailablePackages = async (searchbox, searchTerm) => {
userEvent.type(searchbox, searchTerm);
await act(async() => {
screen.getByTestId('search-available-pkgs-button').click();
screen.getByRole('button', { name: /search button for available packages/i }).click();
});
};
@ -106,10 +106,6 @@ const searchForChosenPackages = async (searchbox, searchTerm) => {
} else {
userEvent.type(searchbox, searchTerm);
}
await act(async() => {
screen.getByTestId('search-chosen-pkgs-button').click();
});
};
// mock the insights dependency
@ -786,8 +782,9 @@ describe('Step Packages', () => {
screen.getByRole('button', { name: /Add all/ }).click();
searchboxChosen.click();
await searchForChosenPackages(searchboxChosen, 'asdf');
screen.getByText('No packages found');
userEvent.type(searchboxChosen, 'asdf');
expect(screen.getAllByText('No packages found').length === 2);
// We need to clear this input in order to not have sideeffects on other tests
await searchForChosenPackages(searchboxChosen, '');
});
@ -878,6 +875,65 @@ describe('Step Packages', () => {
expect(secondItem).toHaveTextContent('lib-testlib-test package summary');
expect(thirdItem).toHaveTextContent('Z-testZ-test package summary');
});
test('available packages can be reset', async () => {
await setUp();
const searchbox = screen.getAllByRole('textbox')[0];
searchbox.click();
const getPackages = jest
.spyOn(api, 'getPackages')
.mockImplementation(() => Promise.resolve(mockPkgResult));
await searchForAvailablePackages(searchbox, 'test');
expect(getPackages).toHaveBeenCalledTimes(1);
const availablePackagesList = screen.getByTestId('available-pkgs-list');
const availablePackagesItems = within(availablePackagesList).getAllByRole('option');
expect(availablePackagesItems).toHaveLength(3);
screen.getByRole('button', { name: /clear available packages search/i }).click();
screen.getByText('Search above to add additionalpackages to your image');
});
test('chosen packages can be reset after filtering', async () => {
await setUp();
const availableSearchbox = screen.getAllByRole('textbox')[0];
availableSearchbox.click();
const getPackages = jest
.spyOn(api, 'getPackages')
.mockImplementation(() => Promise.resolve(mockPkgResult));
await searchForAvailablePackages(availableSearchbox, 'test');
expect(getPackages).toHaveBeenCalledTimes(1);
const availablePackagesList = screen.getByTestId('available-pkgs-list');
const availablePackagesItems = within(availablePackagesList).getAllByRole('option');
expect(availablePackagesItems).toHaveLength(3);
screen.getByRole('button', { name: /Add all/ }).click();
const chosenPackagesList = screen.getByTestId('chosen-pkgs-list');
let chosenPackagesItems = within(chosenPackagesList).getAllByRole('option');
expect(chosenPackagesItems).toHaveLength(3);
const chosenSearchbox = screen.getAllByRole('textbox')[1];
chosenSearchbox.click();
await searchForChosenPackages(chosenSearchbox, 'Pkg');
chosenPackagesItems = within(chosenPackagesList).getAllByRole('option');
// eslint-disable-next-line jest-dom/prefer-in-document
expect(chosenPackagesItems).toHaveLength(1);
screen.getByRole('button', { name: /clear chosen packages search/i }).click();
chosenPackagesItems = within(chosenPackagesList).getAllByRole('option');
expect(chosenPackagesItems).toHaveLength(3);
});
});
describe('Step Review', () => {