diff --git a/plugins/explore-common/src/index.ts b/plugins/explore-common/src/index.ts index 50a9b9f649..d829a62e63 100644 --- a/plugins/explore-common/src/index.ts +++ b/plugins/explore-common/src/index.ts @@ -20,5 +20,4 @@ * @packageDocumentation */ -export * from './api'; -export * from './types'; +export * from './tools'; diff --git a/plugins/explore-common/src/api.ts b/plugins/explore-common/src/tools/api.ts similarity index 100% rename from plugins/explore-common/src/api.ts rename to plugins/explore-common/src/tools/api.ts diff --git a/plugins/explore-common/src/tools/index.ts b/plugins/explore-common/src/tools/index.ts new file mode 100644 index 0000000000..50a9b9f649 --- /dev/null +++ b/plugins/explore-common/src/tools/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2022 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. + */ + +/** + * Common functionalities for the explore plugin. + * + * @packageDocumentation + */ + +export * from './api'; +export * from './types'; diff --git a/plugins/explore-common/src/types.ts b/plugins/explore-common/src/tools/types.ts similarity index 100% rename from plugins/explore-common/src/types.ts rename to plugins/explore-common/src/tools/types.ts diff --git a/plugins/explore/src/api/types.ts b/plugins/explore/src/api/ExploreApi.ts similarity index 100% rename from plugins/explore/src/api/types.ts rename to plugins/explore/src/api/ExploreApi.ts diff --git a/plugins/explore/src/api/ExploreClient.test.ts b/plugins/explore/src/api/ExploreClient.test.ts new file mode 100644 index 0000000000..bbec568a09 --- /dev/null +++ b/plugins/explore/src/api/ExploreClient.test.ts @@ -0,0 +1,114 @@ +/* + * Copyright 2022 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 { + ExploreTool, + GetExploreToolsResponse, +} from '@backstage/plugin-explore-common'; +import { MockFetchApi, setupRequestMockHandlers } from '@backstage/test-utils'; +import { rest } from 'msw'; +import { setupServer } from 'msw/node'; +import { ExploreClient } from './ExploreClient'; + +const server = setupServer(); + +describe('ExploreClient', () => { + setupRequestMockHandlers(server); + + const mockBaseUrl = 'http://backstage/api/explore'; + const discoveryApi = { getBaseUrl: async () => mockBaseUrl }; + const fetchApi = new MockFetchApi(); + + let client: ExploreClient; + beforeEach(() => { + client = new ExploreClient({ discoveryApi, fetchApi }); + }); + + describe('getTools', () => { + const mockTools: ExploreTool[] = [ + { + title: 'Tool 1', + image: 'https://example.com/image.png', + url: 'https://example.com', + }, + { + title: 'Tool 2', + image: 'https://example.com/image.png', + url: 'https://example.com', + }, + ]; + + it('should fetch data from the explore-backend', async () => { + const expectedResponse: GetExploreToolsResponse = { + tools: mockTools, + }; + + server.use( + rest.get(`${mockBaseUrl}/tools`, (_, res, ctx) => + res(ctx.json(expectedResponse)), + ), + ); + + const response = await client.getTools(); + expect(response).toEqual(expectedResponse); + }); + + it('should request explore tools with specific filters', async () => { + const expectedResponse: GetExploreToolsResponse = { + tools: mockTools, + }; + + server.use( + rest.get(`${mockBaseUrl}/tools`, (req, res, ctx) => { + expect(req.url.search).toBe('?tag=a&tag=b&lifecycle=alpha'); + return res(ctx.json(expectedResponse)); + }), + ); + + const response = await client.getTools({ + filter: { tags: ['a', 'b'], lifecycle: ['alpha'] }, + }); + expect(response).toEqual(expectedResponse); + }); + }); + + describe('when using exploreToolsConfig for backwards compatibility', () => { + const mockExploreToolsConfig = { + getTools: jest.fn(), + }; + + beforeEach(() => { + client = new ExploreClient({ + discoveryApi, + fetchApi, + exploreToolsConfig: mockExploreToolsConfig, + }); + }); + + it('should return data from the deprecated api', async () => { + mockExploreToolsConfig.getTools.mockResolvedValue([ + { + title: 'Some Tool', + image: 'https://example.com/image.png', + url: 'https://example.com', + }, + ]); + + await client.getTools(); + expect(mockExploreToolsConfig.getTools).toHaveBeenCalled(); + }); + }); +}); diff --git a/plugins/explore/src/api/client.ts b/plugins/explore/src/api/ExploreClient.ts similarity index 98% rename from plugins/explore/src/api/client.ts rename to plugins/explore/src/api/ExploreClient.ts index d51b554879..e913aeb041 100644 --- a/plugins/explore/src/api/client.ts +++ b/plugins/explore/src/api/ExploreClient.ts @@ -21,7 +21,7 @@ import { GetExploreToolsResponse, } from '@backstage/plugin-explore-common'; import { ExploreToolsConfig } from '@backstage/plugin-explore-react'; -import { ExploreApi } from './types'; +import { ExploreApi } from './ExploreApi'; /** * Default implementation of the ExploreApi. diff --git a/plugins/explore/src/api/index.ts b/plugins/explore/src/api/index.ts index a7ac3aa8c1..387393f231 100644 --- a/plugins/explore/src/api/index.ts +++ b/plugins/explore/src/api/index.ts @@ -14,6 +14,6 @@ * limitations under the License. */ -export { ExploreClient } from './client'; -export { exploreApiRef } from './types'; -export type { ExploreApi } from './types'; +export { ExploreClient } from './ExploreClient'; +export { exploreApiRef } from './ExploreApi'; +export type { ExploreApi } from './ExploreApi'; diff --git a/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.test.tsx b/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.test.tsx index da35c9fa39..f3cca5642f 100644 --- a/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.test.tsx +++ b/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.test.tsx @@ -14,25 +14,23 @@ * limitations under the License. */ -import { - ExploreTool, - exploreToolsConfigRef, -} from '@backstage/plugin-explore-react'; +import { ExploreTool } from '@backstage/plugin-explore-common'; import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; import { lightTheme } from '@backstage/theme'; import { ThemeProvider } from '@material-ui/core'; import { waitFor } from '@testing-library/react'; import React from 'react'; +import { exploreApiRef } from '../../api'; import { ToolExplorerContent } from './ToolExplorerContent'; describe('', () => { - const exploreToolsConfigApi: jest.Mocked = { + const exploreApi: jest.Mocked = { getTools: jest.fn(), }; const Wrapper = ({ children }: { children?: React.ReactNode }) => ( - + {children} @@ -63,7 +61,7 @@ describe('', () => { tags: ['standards', 'landscape'], }, ]; - exploreToolsConfigApi.getTools.mockResolvedValue(tools); + exploreApi.getTools.mockResolvedValue({ tools }); const { getByText } = await renderInTestApp( @@ -78,7 +76,7 @@ describe('', () => { }); it('renders a custom title', async () => { - exploreToolsConfigApi.getTools.mockResolvedValue([]); + exploreApi.getTools.mockResolvedValue({ tools: [] }); const { getByText } = await renderInTestApp( @@ -90,7 +88,7 @@ describe('', () => { }); it('renders empty state', async () => { - exploreToolsConfigApi.getTools.mockResolvedValue([]); + exploreApi.getTools.mockResolvedValue({ tools: [] }); const { getByText } = await renderInTestApp(