From 09cba0bdaee0b077befe8e46790740298c6fae6a Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 11:41:59 +0200 Subject: [PATCH] deprecate search api ref, search api interface and search context in plugin-search Signed-off-by: Emma Indal --- plugins/search/src/apis.ts | 7 + .../SearchContext/SearchContext.test.tsx | 287 ------------------ .../SearchContext/SearchContext.tsx | 9 + .../SearchContextForStorybook.stories.tsx | 48 --- 4 files changed, 16 insertions(+), 335 deletions(-) delete mode 100644 plugins/search/src/components/SearchContext/SearchContext.test.tsx delete mode 100644 plugins/search/src/components/SearchContext/SearchContextForStorybook.stories.tsx diff --git a/plugins/search/src/apis.ts b/plugins/search/src/apis.ts index 908942d87d..62f65dbe4a 100644 --- a/plugins/search/src/apis.ts +++ b/plugins/search/src/apis.ts @@ -21,12 +21,19 @@ import { } from '@backstage/core-plugin-api'; import { ResponseError } from '@backstage/errors'; import { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common'; + import qs from 'qs'; +/** + * @deprecated import from "@backstage/plugin-search-react" instead + */ export const searchApiRef = createApiRef({ id: 'plugin.search.queryservice', }); +/** + * @deprecated import from "@backstage/plugin-search-react" instead + */ export interface SearchApi { query(query: SearchQuery): Promise; } diff --git a/plugins/search/src/components/SearchContext/SearchContext.test.tsx b/plugins/search/src/components/SearchContext/SearchContext.test.tsx deleted file mode 100644 index 6513dc21bb..0000000000 --- a/plugins/search/src/components/SearchContext/SearchContext.test.tsx +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { useApi } from '@backstage/core-plugin-api'; -import { render, screen, waitFor } from '@testing-library/react'; -import { act, renderHook } from '@testing-library/react-hooks'; -import React from 'react'; -import { SearchContextProvider, useSearch } from './SearchContext'; - -jest.mock('@backstage/core-plugin-api', () => ({ - ...jest.requireActual('@backstage/core-plugin-api'), - useApi: jest.fn(), -})); - -describe('SearchContext', () => { - const query = jest.fn(); - - const wrapper = ({ children, initialState }: any) => ( - - {children} - - ); - - const initialState = { - term: '', - filters: {}, - types: ['*'], - }; - - beforeEach(() => { - query.mockResolvedValue({}); - (useApi as jest.Mock).mockReturnValue({ query: query }); - }); - - afterAll(() => { - jest.resetAllMocks(); - }); - - it('Passes children', async () => { - const text = 'text'; - - render( - - {text} - , - ); - - await waitFor(() => { - expect(screen.getByText(text)).toBeInTheDocument(); - }); - }); - - it('Throws error when no context is set', () => { - const { result } = renderHook(() => useSearch()); - - expect(result.error).toEqual( - Error('useSearch must be used within a SearchContextProvider'), - ); - }); - - it('Uses initial state values', async () => { - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - expect(result.current).toEqual(expect.objectContaining(initialState)); - }); - - it('Resets cursor when term is set (and different from previous)', async () => { - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState: { - ...initialState, - pageCursor: 'SOMEPAGE', - }, - }, - }); - - await waitForNextUpdate(); - - expect(result.current.pageCursor).toEqual('SOMEPAGE'); - - act(() => { - result.current.setTerm('first term'); - }); - - act(() => { - result.current.setPageCursor('OTHERPAGE'); - }); - - await waitForNextUpdate(); - - expect(result.current.pageCursor).toEqual('OTHERPAGE'); - - act(() => { - result.current.setTerm('second term'); - }); - - await waitForNextUpdate(); - - expect(result.current.pageCursor).toEqual(undefined); - }); - - describe('Performs search (and sets results)', () => { - it('When term is set', async () => { - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - const term = 'term'; - - act(() => { - result.current.setTerm(term); - }); - - await waitForNextUpdate(); - - expect(query).toHaveBeenLastCalledWith({ - filters: {}, - types: ['*'], - term, - }); - }); - - it('When filters are set', async () => { - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - const filters = { filter: 'filter' }; - - act(() => { - result.current.setFilters(filters); - }); - - await waitForNextUpdate(); - - expect(query).toHaveBeenLastCalledWith({ - filters, - types: ['*'], - term: '', - }); - }); - - it('When page is set', async () => { - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - act(() => { - result.current.setPageCursor('SOMEPAGE'); - }); - - await waitForNextUpdate(); - - expect(query).toHaveBeenLastCalledWith({ - filters: {}, - types: ['*'], - pageCursor: 'SOMEPAGE', - term: '', - }); - }); - - it('When types is set', async () => { - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - const types = ['type']; - - act(() => { - result.current.setTypes(types); - }); - - await waitForNextUpdate(); - - expect(query).toHaveBeenLastCalledWith({ - types, - filters: {}, - term: '', - }); - }); - - it('provides function for fetch the next page', async () => { - query.mockResolvedValue({ - results: [], - nextPageCursor: 'NEXT', - }); - - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - expect(result.current.fetchNextPage).toBeDefined(); - expect(result.current.fetchPreviousPage).toBeUndefined(); - - act(() => { - result.current.fetchNextPage!(); - }); - - await waitForNextUpdate(); - - expect(query).toHaveBeenLastCalledWith({ - types: ['*'], - filters: {}, - term: '', - pageCursor: 'NEXT', - }); - }); - - it('provides function for fetch the previous page', async () => { - query.mockResolvedValue({ - results: [], - previousPageCursor: 'PREVIOUS', - }); - - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - expect(result.current.fetchNextPage).toBeUndefined(); - expect(result.current.fetchPreviousPage).toBeDefined(); - - act(() => { - result.current.fetchPreviousPage!(); - }); - - await waitForNextUpdate(); - - expect(query).toHaveBeenLastCalledWith({ - types: ['*'], - filters: {}, - term: '', - pageCursor: 'PREVIOUS', - }); - }); - }); -}); diff --git a/plugins/search/src/components/SearchContext/SearchContext.tsx b/plugins/search/src/components/SearchContext/SearchContext.tsx index 100d8a3ac3..d52e43af88 100644 --- a/plugins/search/src/components/SearchContext/SearchContext.tsx +++ b/plugins/search/src/components/SearchContext/SearchContext.tsx @@ -51,6 +51,9 @@ export type SearchContextState = { pageCursor?: string; }; +/** + * @deprecated import from "@backstage/plugin-search-react" instead + */ export const SearchContext = createContext( undefined, ); @@ -62,6 +65,9 @@ const searchInitialState: SearchContextState = { types: [], }; +/** + * @deprecated import from "@backstage/plugin-search-react" instead + */ export const SearchContextProvider = ({ initialState = searchInitialState, children, @@ -126,6 +132,9 @@ export const SearchContextProvider = ({ ); }; +/** + * @deprecated import from "@backstage/plugin-search-react" instead + */ export const useSearch = () => { const context = useContext(SearchContext); if (context === undefined) { diff --git a/plugins/search/src/components/SearchContext/SearchContextForStorybook.stories.tsx b/plugins/search/src/components/SearchContext/SearchContextForStorybook.stories.tsx deleted file mode 100644 index 7d6c35b00c..0000000000 --- a/plugins/search/src/components/SearchContext/SearchContextForStorybook.stories.tsx +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { ApiProvider } from '@backstage/core-app-api'; -import { SearchResultSet } from '@backstage/plugin-search-common'; -import { TestApiRegistry } from '@backstage/test-utils'; -import React, { ComponentProps, PropsWithChildren } from 'react'; -import { searchApiRef } from '../../apis'; -import { SearchContextProvider as RealSearchContextProvider } from './SearchContext'; - -type QueryResultProps = { - mockedResults?: SearchResultSet; -}; - -/** - * Utility context provider only for use in Storybook stories. You should use - * the real `` exported by `@backstage/plugin-search` in - * your app instead of this! In some cases (like the search page) it may - * already be provided on your behalf. - */ -export const SearchContextProvider = ( - props: ComponentProps & QueryResultProps, -) => { - return ( - - - - ); -}; - -export function SearchApiProvider(props: PropsWithChildren) { - const { mockedResults, children } = props; - const query: any = () => Promise.resolve(mockedResults || {}); - const apiRegistry = TestApiRegistry.from([searchApiRef, { query }]); - return ; -}