From 9d66d8cd906f2a23cf6739dc203bc6b6e4b2fac4 Mon Sep 17 00:00:00 2001 From: Rik Claessens Date: Fri, 12 Jul 2024 23:28:36 +0200 Subject: [PATCH 1/9] Make use of the useApp hook to retrieve search icon Signed-off-by: Rik Claessens --- .changeset/sixty-rabbits-cheat.md | 5 +++++ plugins/search-react/src/components/SearchBar/SearchBar.tsx | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 .changeset/sixty-rabbits-cheat.md diff --git a/.changeset/sixty-rabbits-cheat.md b/.changeset/sixty-rabbits-cheat.md new file mode 100644 index 0000000000..a713574c1e --- /dev/null +++ b/.changeset/sixty-rabbits-cheat.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-react': minor +--- + +Make use of the useApp hook to retrieve the specified search icon in the SearchBar diff --git a/plugins/search-react/src/components/SearchBar/SearchBar.tsx b/plugins/search-react/src/components/SearchBar/SearchBar.tsx index 254f39e48e..c6976508cc 100644 --- a/plugins/search-react/src/components/SearchBar/SearchBar.tsx +++ b/plugins/search-react/src/components/SearchBar/SearchBar.tsx @@ -18,13 +18,14 @@ import { AnalyticsContext, configApiRef, useApi, + useApp, } from '@backstage/core-plugin-api'; import IconButton from '@material-ui/core/IconButton'; import InputAdornment from '@material-ui/core/InputAdornment'; import TextField from '@material-ui/core/TextField'; import Button from '@material-ui/core/Button'; import { TextFieldProps } from '@material-ui/core/TextField'; -import SearchIcon from '@material-ui/icons/Search'; +import DefaultSearchIcon from '@material-ui/icons/Search'; import React, { ChangeEvent, ComponentType, @@ -146,6 +147,8 @@ export const SearchBarBase: ForwardRefExoticComponent = placeholder ?? `Search in ${configApi.getOptionalString('app.title') || 'Backstage'}`; + const SearchIcon = useApp().getSystemIcon('search') || DefaultSearchIcon; + const startAdornment = ( From 960b292c6878b905598cae0109c3724c01f6f431 Mon Sep 17 00:00:00 2001 From: Rik Claessens Date: Sat, 13 Jul 2024 11:31:09 +0200 Subject: [PATCH 2/9] Replace renderWithEffects with renderInTestApp to fix all existing tests Signed-off-by: Rik Claessens --- .../components/SearchBar/SearchBar.test.tsx | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/search-react/src/components/SearchBar/SearchBar.test.tsx b/plugins/search-react/src/components/SearchBar/SearchBar.test.tsx index 6fcb3ef987..bdff7ba57c 100644 --- a/plugins/search-react/src/components/SearchBar/SearchBar.test.tsx +++ b/plugins/search-react/src/components/SearchBar/SearchBar.test.tsx @@ -22,7 +22,7 @@ import { ConfigReader } from '@backstage/core-app-api'; import { MockAnalyticsApi, TestApiProvider, - renderWithEffects, + renderInTestApp, } from '@backstage/test-utils'; import { searchApiRef } from '../../api'; import { SearchContextProvider } from '../../context'; @@ -61,7 +61,7 @@ describe('SearchBar', () => { }); it('Renders without exploding', async () => { - await renderWithEffects( + await renderInTestApp( { it('Renders with custom label', async () => { const label = 'label'; - await renderWithEffects( + await renderInTestApp( { it('Renders with custom placeholder', async () => { const placeholder = 'placeholder'; - await renderWithEffects( + await renderInTestApp( { it('Renders based on initial search', async () => { const term = 'term'; - await renderWithEffects( + await renderInTestApp( { it('Updates term state when text is entered', async () => { jest.useFakeTimers(); - await renderWithEffects( + await renderInTestApp( { it('Clear button clears term state', async () => { const term = 'term'; - await renderWithEffects( + await renderInTestApp( { it('Should not show clear button', async () => { const term = 'term'; - await renderWithEffects( + await renderInTestApp( { const debounceTime = 100; - await renderWithEffects( + await renderInTestApp( { it('Does not capture analytics event if not enabled in app', async () => { const analyticsApiMock = new MockAnalyticsApi(); - await renderWithEffects( + await renderInTestApp( Date: Sat, 13 Jul 2024 11:32:19 +0200 Subject: [PATCH 3/9] Add icons as an optional property of renderInTestApp Signed-off-by: Rik Claessens --- packages/test-utils/src/testUtils/appWrappers.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/test-utils/src/testUtils/appWrappers.tsx b/packages/test-utils/src/testUtils/appWrappers.tsx index f2c1ff592e..3a55389b74 100644 --- a/packages/test-utils/src/testUtils/appWrappers.tsx +++ b/packages/test-utils/src/testUtils/appWrappers.tsx @@ -23,13 +23,14 @@ import React, { import { MemoryRouter, Route } from 'react-router-dom'; import { themes, UnifiedThemeProvider } from '@backstage/theme'; import MockIcon from '@material-ui/icons/AcUnit'; -import { createSpecializedApp } from '@backstage/core-app-api'; +import { AppIcons, createSpecializedApp } from '@backstage/core-app-api'; import { AppComponents, attachComponentData, BootErrorPageProps, createRouteRef, ExternalRouteRef, + IconComponent, RouteRef, } from '@backstage/core-plugin-api'; import { MatcherFunction, RenderResult } from '@testing-library/react'; @@ -107,6 +108,13 @@ export type TestAppOptions = { * Components to be forwarded to the `components` option of `createApp`. */ components?: Partial; + + /** + * Icons to be forwarded to the `icons` option of `createApp`. + */ + icons?: Partial & { + [key in string]: IconComponent; + }; }; function isExternalRouteRef( @@ -145,7 +153,10 @@ export function createTestAppWrapper( ), ...options.components, }, - icons: mockIcons, + icons: { + ...mockIcons, + ...options.icons, + }, plugins: [], themes: [ { From 85095afd82c12422184d008de668c5431ed048af Mon Sep 17 00:00:00 2001 From: Rik Claessens Date: Sat, 13 Jul 2024 11:40:40 +0200 Subject: [PATCH 4/9] Add test for checking if the SearchBar renders the provided custom search icon Signed-off-by: Rik Claessens --- .../components/SearchBar/SearchBar.test.tsx | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/plugins/search-react/src/components/SearchBar/SearchBar.test.tsx b/plugins/search-react/src/components/SearchBar/SearchBar.test.tsx index bdff7ba57c..3f667a4ad6 100644 --- a/plugins/search-react/src/components/SearchBar/SearchBar.test.tsx +++ b/plugins/search-react/src/components/SearchBar/SearchBar.test.tsx @@ -298,4 +298,37 @@ describe('SearchBar', () => { expect(analyticsApiMock.getEvents()).toHaveLength(0); }); + + it('Renders custom search icon', async () => { + const CustomSearchIcon = () => ( + + + + ); + + await renderInTestApp( + + + + + , + { + icons: { + search: CustomSearchIcon, + }, + }, + ); + + const queryButton = screen.getByLabelText('Query'); + + expect(queryButton).toBeInTheDocument(); + expect(queryButton.innerHTML).toContain( + '', + ); + }); }); From e460cbb02735bb82a9b9878c7577def04d99cf46 Mon Sep 17 00:00:00 2001 From: Rik Claessens Date: Sat, 13 Jul 2024 11:42:38 +0200 Subject: [PATCH 5/9] Replace renderWithEffects with renderInTestApp to fix all existing tests Signed-off-by: Rik Claessens --- .../SearchAutocomplete.test.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/search-react/src/components/SearchAutocomplete/SearchAutocomplete.test.tsx b/plugins/search-react/src/components/SearchAutocomplete/SearchAutocomplete.test.tsx index d9da187541..cc1e6c486c 100644 --- a/plugins/search-react/src/components/SearchAutocomplete/SearchAutocomplete.test.tsx +++ b/plugins/search-react/src/components/SearchAutocomplete/SearchAutocomplete.test.tsx @@ -22,7 +22,7 @@ import LabelIcon from '@material-ui/icons/Label'; import { configApiRef } from '@backstage/core-plugin-api'; import { ConfigReader } from '@backstage/core-app-api'; -import { TestApiProvider, renderWithEffects } from '@backstage/test-utils'; +import { TestApiProvider, renderInTestApp } from '@backstage/test-utils'; import { searchApiRef } from '../../api'; import { SearchAutocomplete } from './SearchAutocomplete'; @@ -44,7 +44,7 @@ describe('SearchAutocomplete', () => { }); it('Renders without exploding', async () => { - await renderWithEffects( + await renderInTestApp( { }); it('Show all options by default when focused', async () => { - await renderWithEffects( + await renderInTestApp( { }); it('Updates context with the initial value', async () => { - await renderWithEffects( + await renderInTestApp( { }); it('Updates context when value is cleared', async () => { - await renderWithEffects( + await renderInTestApp( { }); it('Updates context when an option is select', async () => { - await renderWithEffects( + await renderInTestApp( { }); it('Shows a circular progress when loading options', async () => { - await renderWithEffects( + await renderInTestApp( { }); it('Uses the default search autocomplete option component', async () => { - await renderWithEffects( + await renderInTestApp( Date: Sat, 13 Jul 2024 11:58:07 +0200 Subject: [PATCH 6/9] Add changeset for adding the icons option to TestAppOptions Signed-off-by: Rik Claessens --- .changeset/silent-eyes-lie.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/silent-eyes-lie.md diff --git a/.changeset/silent-eyes-lie.md b/.changeset/silent-eyes-lie.md new file mode 100644 index 0000000000..6b96d8fe61 --- /dev/null +++ b/.changeset/silent-eyes-lie.md @@ -0,0 +1,5 @@ +--- +'@backstage/test-utils': minor +--- + +Added the icons option to the renderInTestApp function's TestAppOptions to be forwarded to the icons option of createApp. From 6232b8f234781124e8af383659ebb94f3abdcf4e Mon Sep 17 00:00:00 2001 From: Rik Claessens Date: Sat, 13 Jul 2024 12:26:39 +0200 Subject: [PATCH 7/9] Update api reports with change in test-utils Signed-off-by: Rik Claessens --- packages/test-utils/api-report.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/test-utils/api-report.md b/packages/test-utils/api-report.md index e31a820a1c..cd0141d402 100644 --- a/packages/test-utils/api-report.md +++ b/packages/test-utils/api-report.md @@ -8,6 +8,7 @@ import { AnalyticsEvent } from '@backstage/core-plugin-api'; import { ApiHolder } from '@backstage/core-plugin-api'; import { ApiRef } from '@backstage/core-plugin-api'; import { AppComponents } from '@backstage/core-plugin-api'; +import { AppIcons } from '@backstage/core-app-api'; import { AuthorizeResult } from '@backstage/plugin-permission-common'; import { ComponentType } from 'react'; import { Config } from '@backstage/config'; @@ -21,6 +22,7 @@ import { EvaluatePermissionRequest } from '@backstage/plugin-permission-common'; import { EvaluatePermissionResponse } from '@backstage/plugin-permission-common'; import { ExternalRouteRef } from '@backstage/core-plugin-api'; import { FetchApi } from '@backstage/core-plugin-api'; +import { IconComponent } from '@backstage/core-plugin-api'; import { IdentityApi } from '@backstage/core-plugin-api'; import { JsonObject } from '@backstage/types'; import { JsonValue } from '@backstage/types'; @@ -245,6 +247,9 @@ export type TestAppOptions = { [path: string]: RouteRef | ExternalRouteRef; }; components?: Partial; + icons?: Partial & { + [key in string]: IconComponent; + }; }; // @public From f9011ac3d4c4d032511e6f52cd464facb22251c6 Mon Sep 17 00:00:00 2001 From: Rik Claessens Date: Sat, 13 Jul 2024 14:07:54 +0200 Subject: [PATCH 8/9] Wrap storybook components for SearchBar and SearchBarAutocomplete in wrapInTestApp Signed-off-by: Rik Claessens --- .../SearchAutocomplete.stories.tsx | 23 ++++++++-------- .../SearchBar/SearchBar.stories.tsx | 26 +++++++++++-------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/plugins/search-react/src/components/SearchAutocomplete/SearchAutocomplete.stories.tsx b/plugins/search-react/src/components/SearchAutocomplete/SearchAutocomplete.stories.tsx index eb113cb5fd..57f0c01f39 100644 --- a/plugins/search-react/src/components/SearchAutocomplete/SearchAutocomplete.stories.tsx +++ b/plugins/search-react/src/components/SearchAutocomplete/SearchAutocomplete.stories.tsx @@ -19,7 +19,7 @@ import React, { ComponentType, PropsWithChildren } from 'react'; import Grid from '@material-ui/core/Grid'; import LabelIcon from '@material-ui/icons/Label'; -import { TestApiProvider } from '@backstage/test-utils'; +import { TestApiProvider, wrapInTestApp } from '@backstage/test-utils'; import { searchApiRef, MockSearchApi } from '../../api'; import { SearchContextProvider } from '../../context'; @@ -31,17 +31,18 @@ export default { title: 'Plugins/Search/SearchAutocomplete', component: SearchAutocomplete, decorators: [ - (Story: ComponentType>) => ( - - - - - + (Story: ComponentType>) => + wrapInTestApp( + + + + + + - - - - ), + + , + ), ], }; diff --git a/plugins/search-react/src/components/SearchBar/SearchBar.stories.tsx b/plugins/search-react/src/components/SearchBar/SearchBar.stories.tsx index 852a3a1881..7bbd75d3f3 100644 --- a/plugins/search-react/src/components/SearchBar/SearchBar.stories.tsx +++ b/plugins/search-react/src/components/SearchBar/SearchBar.stories.tsx @@ -18,7 +18,7 @@ import React, { ComponentType, PropsWithChildren } from 'react'; import Grid from '@material-ui/core/Grid'; import { makeStyles } from '@material-ui/core/styles'; -import { TestApiProvider } from '@backstage/test-utils'; +import { TestApiProvider, wrapInTestApp } from '@backstage/test-utils'; import { searchApiRef, MockSearchApi } from '../../api'; import { SearchContextProvider } from '../../context'; @@ -28,18 +28,22 @@ import { SearchBar } from './SearchBar'; export default { title: 'Plugins/Search/SearchBar', component: SearchBar, + loaders: [ + async () => ({ component: (await import('./SearchBar')).SearchBar }), + ], decorators: [ - (Story: ComponentType>) => ( - - - - - + (Story: ComponentType>) => + wrapInTestApp( + + + + + + - - - - ), + + , + ), ], }; From c752364371eada8f5083adc2347a813c59f043f7 Mon Sep 17 00:00:00 2001 From: Rik Claessens Date: Wed, 7 Aug 2024 14:42:01 +0200 Subject: [PATCH 9/9] Surrounding some function names in quotes to make Vale happy Signed-off-by: Rik Claessens --- .changeset/silent-eyes-lie.md | 2 +- .changeset/sixty-rabbits-cheat.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/silent-eyes-lie.md b/.changeset/silent-eyes-lie.md index 6b96d8fe61..e9da3d2685 100644 --- a/.changeset/silent-eyes-lie.md +++ b/.changeset/silent-eyes-lie.md @@ -2,4 +2,4 @@ '@backstage/test-utils': minor --- -Added the icons option to the renderInTestApp function's TestAppOptions to be forwarded to the icons option of createApp. +Added the icons option to the renderInTestApp function's TestAppOptions to be forwarded to the icons option of `createApp`. diff --git a/.changeset/sixty-rabbits-cheat.md b/.changeset/sixty-rabbits-cheat.md index a713574c1e..0161e272ed 100644 --- a/.changeset/sixty-rabbits-cheat.md +++ b/.changeset/sixty-rabbits-cheat.md @@ -2,4 +2,4 @@ '@backstage/plugin-search-react': minor --- -Make use of the useApp hook to retrieve the specified search icon in the SearchBar +Make use of the `useApp` hook to retrieve the specified search icon in the SearchBar