diff --git a/packages/frontend-test-utils/report.api.md b/packages/frontend-test-utils/report.api.md index 3f5bf3930d..6b0b4d37b5 100644 --- a/packages/frontend-test-utils/report.api.md +++ b/packages/frontend-test-utils/report.api.md @@ -49,7 +49,6 @@ import { RouteRef } from '@backstage/frontend-plugin-api'; import { StorageApi } from '@backstage/core-plugin-api'; import { StorageApi as StorageApi_2 } from '@backstage/frontend-plugin-api'; import { StorageValueSnapshot } from '@backstage/core-plugin-api'; -import { testingLibraryDomTypesQueries } from '@testing-library/dom/types/queries'; import { TranslationApi } from '@backstage/core-plugin-api/alpha'; import { TranslationApi as TranslationApi_2 } from '@backstage/frontend-plugin-api'; import { TranslationRef } from '@backstage/core-plugin-api/alpha'; @@ -551,8 +550,8 @@ export function renderInTestApp( // @public export function renderTestApp( - options: RenderTestAppOptions, -): RenderResult; + options?: RenderTestAppOptions, +): RenderResult; // @public export type RenderTestAppOptions = { @@ -563,7 +562,9 @@ export type RenderTestAppOptions = { mountedRoutes?: { [path: string]: RouteRef; }; - apis?: readonly [...TestApiPairs]; + apis?: readonly [ + ...(TestApiProviderPropsApiPairs | MockWithApiFactory[]), + ]; }; // @public @@ -588,13 +589,8 @@ export type TestApiProviderProps = { }; // @public -export type TestApiProviderPropsApiPair = TApi extends readonly [ - infer _Ref, - infer _Impl, -] - ? TApi - : TApi extends infer TImpl - ? readonly [ApiRef, Partial] | MockWithApiFactory +export type TestApiProviderPropsApiPair = TApi extends infer TImpl + ? readonly [ApiRef, Partial] : never; // @public @@ -616,7 +612,9 @@ export type TestAppOptions = { config?: JsonObject; features?: FrontendFeature[]; initialRouteEntries?: string[]; - apis?: readonly [...TestApiPairs]; + apis?: readonly [ + ...(TestApiProviderPropsApiPairs | MockWithApiFactory[]), + ]; }; export { withLogCollector }; diff --git a/packages/frontend-test-utils/src/apis/FetchApi/MockFetchApi.test.ts b/packages/frontend-test-utils/src/apis/FetchApi/MockFetchApi.test.ts index 87598de2a3..ae4486d38f 100644 --- a/packages/frontend-test-utils/src/apis/FetchApi/MockFetchApi.test.ts +++ b/packages/frontend-test-utils/src/apis/FetchApi/MockFetchApi.test.ts @@ -14,9 +14,9 @@ * limitations under the License. */ -import { rest } from 'msw'; -import { setupServer } from 'msw'; -import { registerMswTestHooks } from '@backstage/test-utils'; +import { http, HttpResponse } from 'msw'; +import { setupServer } from 'msw/node'; +import { registerMswTestHooks } from '../../..'; import { MockFetchApi } from './MockFetchApi'; describe('MockFetchApi', () => { @@ -25,8 +25,8 @@ describe('MockFetchApi', () => { it('works with default constructor', async () => { worker.use( - rest.get('http://example.com/data.json', (_, res, ctx) => - res(ctx.status(200), ctx.json({ a: 'foo' })), + http.get('http://example.com/data.json', () => + HttpResponse.json({ a: 'foo' }, { status: 200 }), ), ); const m = new MockFetchApi(); diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx index 8293872e29..9ce1863186 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx @@ -173,11 +173,11 @@ describe('createExtensionTester', () => { }); const tester = createExtensionTester(extension, { - apis: [[analyticsApiRef, analyticsApiMock]], + apis: [[analyticsApiRef, analyticsApiMock] as const], }); renderInTestApp(tester.reactElement(), { - apis: [[analyticsApiRef, analyticsApiMock]], + apis: [[analyticsApiRef, analyticsApiMock] as const], }); expect(screen.getByText('Test')).toBeInTheDocument(); diff --git a/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx b/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx index 334722f38a..c9d90715f6 100644 --- a/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx +++ b/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx @@ -16,11 +16,8 @@ import { useCallback } from 'react'; import { screen, fireEvent } from '@testing-library/react'; -import { - MockAnalyticsApi, - TestApiProvider, -} from '@backstage/frontend-test-utils'; -import { analyticsApiRef, useAnalytics } from '@backstage/frontend-plugin-api'; +import { mockApis, TestApiProvider } from '@backstage/frontend-test-utils'; +import { useAnalytics } from '@backstage/frontend-plugin-api'; import { Routes, Route } from 'react-router-dom'; import { renderInTestApp } from './renderInTestApp'; @@ -47,10 +44,10 @@ describe('renderInTestApp', () => { ); }; - const analyticsApiMock = new MockAnalyticsApi(); + const analyticsApiMock = mockApis.analytics(); renderInTestApp( - + , ); @@ -94,10 +91,10 @@ describe('renderInTestApp', () => { ); }; - const analyticsApiMock = new MockAnalyticsApi(); + const analyticsApiMock = mockApis.analytics(); renderInTestApp(, { - apis: [[analyticsApiRef, analyticsApiMock]], + apis: [analyticsApiMock], }); fireEvent.click(screen.getByRole('button', { name: 'Click me' })); diff --git a/packages/frontend-test-utils/src/app/renderInTestApp.tsx b/packages/frontend-test-utils/src/app/renderInTestApp.tsx index bcc6e5948e..a84b7063d6 100644 --- a/packages/frontend-test-utils/src/app/renderInTestApp.tsx +++ b/packages/frontend-test-utils/src/app/renderInTestApp.tsx @@ -32,10 +32,12 @@ import { FrontendFeature, createFrontendModule, createApiFactory, + type ApiRef, } from '@backstage/frontend-plugin-api'; import { RouterBlueprint } from '@backstage/plugin-app-react'; import appPlugin from '@backstage/plugin-app'; -import { type TestApiPairs } from '../utils'; +import { type TestApiProviderPropsApiPairs } from '../utils'; +import { getMockApiFactory, type MockWithApiFactory } from '../apis/utils'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import type { CreateSpecializedAppInternalOptions } from '../../../frontend-app-api/src/wiring/createSpecializedApp'; @@ -88,15 +90,16 @@ export type TestAppOptions = { * * @example * ```ts - * import { identityApiRef } from '@backstage/frontend-plugin-api'; * import { mockApis } from '@backstage/frontend-test-utils'; * * renderInTestApp(, { - * apis: [[identityApiRef, mockApis.identity({ userEntityRef: 'user:default/guest' })]], + * apis: [mockApis.identity({ userEntityRef: 'user:default/guest' })], * }) * ``` */ - apis?: readonly [...TestApiPairs]; + apis?: readonly [ + ...(TestApiProviderPropsApiPairs | MockWithApiFactory[]), + ]; }; const NavItem = (props: { @@ -241,9 +244,14 @@ export function renderInTestApp( }, ]), __internal: options?.apis && { - apiFactoryOverrides: options.apis.map(([apiRef, implementation]) => - createApiFactory(apiRef, implementation), - ), + apiFactoryOverrides: options.apis.map(entry => { + const mockFactory = getMockApiFactory(entry); + if (mockFactory) { + return mockFactory; + } + const [apiRef, implementation] = entry as readonly [ApiRef, any]; + return createApiFactory(apiRef, implementation); + }), }, } as CreateSpecializedAppInternalOptions); diff --git a/packages/frontend-test-utils/src/app/renderTestApp.tsx b/packages/frontend-test-utils/src/app/renderTestApp.tsx index b83ae7832a..b7b2c2dd6e 100644 --- a/packages/frontend-test-utils/src/app/renderTestApp.tsx +++ b/packages/frontend-test-utils/src/app/renderTestApp.tsx @@ -25,14 +25,16 @@ import { ExtensionDefinition, FrontendFeature, RouteRef, + type ApiRef, } from '@backstage/frontend-plugin-api'; -import { render } from '@testing-library/react'; +import { render, type RenderResult } from '@testing-library/react'; import appPlugin from '@backstage/plugin-app'; import { JsonObject } from '@backstage/types'; import { ConfigReader } from '@backstage/config'; import { MemoryRouter } from 'react-router-dom'; import { RouterBlueprint } from '@backstage/plugin-app-react'; -import { type TestApiPairs } from '../utils'; +import { type TestApiProviderPropsApiPairs } from '../utils'; +import { getMockApiFactory, type MockWithApiFactory } from '../apis/utils'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import type { CreateSpecializedAppInternalOptions } from '../../../frontend-app-api/src/wiring/createSpecializedApp'; @@ -89,16 +91,17 @@ export type RenderTestAppOptions = { * * @example * ```ts - * import { identityApiRef } from '@backstage/frontend-plugin-api'; * import { mockApis } from '@backstage/frontend-test-utils'; * * renderTestApp({ - * apis: [[identityApiRef, mockApis.identity({ userEntityRef: 'user:default/guest' })]], + * apis: [mockApis.identity({ userEntityRef: 'user:default/guest' })], * extensions: [...], * }) * ``` */ - apis?: readonly [...TestApiPairs]; + apis?: readonly [ + ...(TestApiProviderPropsApiPairs | MockWithApiFactory[]), + ]; }; const appPluginOverride = appPlugin.withOverrides({ @@ -116,11 +119,11 @@ const appPluginOverride = appPlugin.withOverrides({ * @public */ export function renderTestApp( - options: RenderTestAppOptions, -) { - const extensions = [...(options.extensions ?? [])]; + options?: RenderTestAppOptions, +): RenderResult { + const extensions = [...(options?.extensions ?? [])]; - if (options.mountedRoutes) { + if (options?.mountedRoutes) { for (const [path, routeRef] of Object.entries(options.mountedRoutes)) { extensions.push( createExtension({ @@ -150,7 +153,7 @@ export function renderTestApp( params: { component: ({ children }) => ( ( appPluginOverride, ]; - if (options.features) { + if (options?.features) { features.push(...options.features); } @@ -183,9 +186,14 @@ export function renderTestApp( }, ]), __internal: options?.apis && { - apiFactoryOverrides: options.apis.map(([apiRef, implementation]) => - createApiFactory(apiRef, implementation), - ), + apiFactoryOverrides: options.apis.map(entry => { + const mockFactory = getMockApiFactory(entry); + if (mockFactory) { + return mockFactory; + } + const [apiRef, implementation] = entry as readonly [ApiRef, any]; + return createApiFactory(apiRef, implementation); + }), }, } as CreateSpecializedAppInternalOptions); diff --git a/packages/frontend-test-utils/src/utils/TestApiProvider.tsx b/packages/frontend-test-utils/src/utils/TestApiProvider.tsx index 3022f96f9c..4bd02a76c4 100644 --- a/packages/frontend-test-utils/src/utils/TestApiProvider.tsx +++ b/packages/frontend-test-utils/src/utils/TestApiProvider.tsx @@ -45,7 +45,7 @@ export type TestApiPairs = TestApiProviderPropsApiPairs; /** * Type for entries that can be passed to TestApiProvider/TestApiRegistry. * Can be either a traditional [apiRef, implementation] tuple or a mock API instance - * marked with the MockApiSymbol. + * marked with the mockApiFactorySymbol. * * @public */