import { AnalyticsApi, AnalyticsEvent, ConfigApi, ErrorApi, ErrorApiError, ErrorApiErrorContext, FetchApi, DiscoveryApi, IdentityApi, StorageApi, StorageValueSnapshot, ApiFactory, RouteRef, ExternalRouteRef, AppComponents, IconComponent, ApiRef, ApiHolder } from '@backstage/core-plugin-api'; import * as _backstage_config from '@backstage/config'; import { Config } from '@backstage/config'; import { JsonObject, JsonValue, Observable } from '@backstage/types'; import crossFetch from 'cross-fetch'; import { PermissionApi } from '@backstage/plugin-permission-react'; import { EvaluatePermissionRequest, AuthorizeResult, EvaluatePermissionResponse } from '@backstage/plugin-permission-common'; import { TranslationApi } from '@backstage/core-plugin-api/alpha'; import { ReactElement, ComponentType, ReactNode, PropsWithChildren } from 'react'; import { AppIcons } from '@backstage/core-app-api'; import { RenderOptions, RenderResult, MatcherFunction } from '@testing-library/react'; import * as react_jsx_runtime from 'react/jsx-runtime'; /** * @public * @deprecated Use `registerMswTestHooks` from `@backstage/test-utils` instead. */ declare function setupRequestMockHandlers(worker: { listen: (t: any) => void; close: () => void; resetHandlers: () => void; }): void; /** * Mock implementation of {@link core-plugin-api#AnalyticsApi} with helpers to ensure that events are sent correctly. * Use getEvents in tests to verify captured events. * * @public * @deprecated Use {@link @backstage/test-utils#mockApis.(analytics:namespace)} instead */ declare class MockAnalyticsApi implements AnalyticsApi { private events; captureEvent(event: AnalyticsEvent): void; getEvents(): AnalyticsEvent[]; } /** * MockConfigApi is a thin wrapper around {@link @backstage/config#ConfigReader} * that can be used to mock configuration using a plain object. * * @public * @deprecated Use {@link mockApis.(config:namespace)} instead * @example * ```tsx * const mockConfig = new MockConfigApi({ * app: { baseUrl: 'https://example.com' }, * }); * * const rendered = await renderInTestApp( * * * , * ); * ``` */ declare class MockConfigApi implements ConfigApi { private readonly config; constructor(data: JsonObject); /** {@inheritdoc @backstage/config#Config.has} */ has(key: string): boolean; /** {@inheritdoc @backstage/config#Config.keys} */ keys(): string[]; /** {@inheritdoc @backstage/config#Config.get} */ get(key?: string): T; /** {@inheritdoc @backstage/config#Config.getOptional} */ getOptional(key?: string): T | undefined; /** {@inheritdoc @backstage/config#Config.getConfig} */ getConfig(key: string): Config; /** {@inheritdoc @backstage/config#Config.getOptionalConfig} */ getOptionalConfig(key: string): Config | undefined; /** {@inheritdoc @backstage/config#Config.getConfigArray} */ getConfigArray(key: string): Config[]; /** {@inheritdoc @backstage/config#Config.getOptionalConfigArray} */ getOptionalConfigArray(key: string): Config[] | undefined; /** {@inheritdoc @backstage/config#Config.getNumber} */ getNumber(key: string): number; /** {@inheritdoc @backstage/config#Config.getOptionalNumber} */ getOptionalNumber(key: string): number | undefined; /** {@inheritdoc @backstage/config#Config.getBoolean} */ getBoolean(key: string): boolean; /** {@inheritdoc @backstage/config#Config.getOptionalBoolean} */ getOptionalBoolean(key: string): boolean | undefined; /** {@inheritdoc @backstage/config#Config.getString} */ getString(key: string): string; /** {@inheritdoc @backstage/config#Config.getOptionalString} */ getOptionalString(key: string): string | undefined; /** {@inheritdoc @backstage/config#Config.getStringArray} */ getStringArray(key: string): string[]; /** {@inheritdoc @backstage/config#Config.getOptionalStringArray} */ getOptionalStringArray(key: string): string[] | undefined; } /** * Constructor arguments for {@link MockErrorApi} * @public */ type MockErrorApiOptions = { collect?: boolean; }; /** * ErrorWithContext contains error and ErrorApiErrorContext * @public */ type ErrorWithContext = { error: ErrorApiError; context?: ErrorApiErrorContext; }; /** * Mock implementation of the {@link core-plugin-api#ErrorApi} to be used in tests. * Includes withForError and getErrors methods for error testing. * @public */ declare class MockErrorApi implements ErrorApi { private readonly options; private readonly errors; private readonly waiters; constructor(options?: MockErrorApiOptions); post(error: ErrorApiError, context?: ErrorApiErrorContext): void; error$(): Observable<{ error: ErrorApiError; context?: ErrorApiErrorContext; }>; getErrors(): ErrorWithContext[]; waitForError(pattern: RegExp, timeoutMs?: number): Promise; } /** * The options given when constructing a {@link MockFetchApi}. * * @public */ interface MockFetchApiOptions { /** * Define the underlying base `fetch` implementation. * * @defaultValue undefined * @remarks * * Leaving out this parameter or passing `undefined`, makes the API use the * global `fetch` implementation to make real network requests. * * `'none'` swallows all calls and makes no requests at all. * * You can also pass in any `fetch` compatible callback, such as a * `jest.fn()`, if you want to use a custom implementation or to just track * and assert on calls. */ baseImplementation?: undefined | 'none' | typeof crossFetch; /** * Add translation from `plugin://` URLs to concrete http(s) URLs, basically * simulating what * {@link @backstage/core-app-api#FetchMiddlewares.resolvePluginProtocol} * does. * * @defaultValue undefined * @remarks * * Leaving out this parameter or passing `undefined`, disables plugin protocol * translation. * * To enable the feature, pass in a discovery API which is then used to * resolve the URLs. */ resolvePluginProtocol?: undefined | { discoveryApi: Pick; }; /** * Add token based Authorization headers to requests, basically simulating * what {@link @backstage/core-app-api#FetchMiddlewares.injectIdentityAuth} * does. * * @defaultValue undefined * @remarks * * Leaving out this parameter or passing `undefined`, disables auth injection. * * To enable the feature, pass in either a static token or an identity API * which is queried on each request for a token. */ injectIdentityAuth?: undefined | { token: string; } | { identityApi: Pick; }; } /** * A test helper implementation of {@link @backstage/core-plugin-api#FetchApi}. * * @public */ declare class MockFetchApi implements FetchApi { private readonly implementation; /** * Creates a mock {@link @backstage/core-plugin-api#FetchApi}. */ constructor(options?: MockFetchApiOptions); /** {@inheritdoc @backstage/core-plugin-api#FetchApi.fetch} */ get fetch(): typeof crossFetch; } /** * Mock implementation of * {@link @backstage/plugin-permission-react#PermissionApi}. Supply a * requestHandler function to override the mock result returned for a given * request. * @deprecated Use {@link @backstage/test-utils#mockApis.(permission:namespace)} instead * @public */ declare class MockPermissionApi implements PermissionApi { private readonly requestHandler; constructor(requestHandler?: (request: EvaluatePermissionRequest) => AuthorizeResult.ALLOW | AuthorizeResult.DENY); authorize(request: EvaluatePermissionRequest): Promise; } /** * Type for map holding data in {@link MockStorageApi} * @deprecated Use {@link @backstage/test-utils#mockApis.(storage:namespace)} instead * @public */ type MockStorageBucket = { [key: string]: any; }; /** * Mock implementation of the {@link core-plugin-api#StorageApi} to be used in tests * @deprecated Use {@link @backstage/test-utils#mockApis.(storage:namespace)} instead * @public */ declare class MockStorageApi implements StorageApi { private readonly namespace; private readonly data; private readonly bucketStorageApis; private constructor(); static create(data?: MockStorageBucket): MockStorageApi; forBucket(name: string): StorageApi; snapshot(key: string): StorageValueSnapshot; set(key: string, data: T): Promise; remove(key: string): Promise; observe$(key: string): Observable>; private getKeyName; private notifyChanges; private subscribers; private readonly observable; } /** * Represents a mocked version of an API, where you automatically have access to * the mocked versions of all of its methods along with a factory that returns * that same mock. * * @public */ type ApiMock = { factory: ApiFactory; } & { [Key in keyof TApi]: TApi[Key] extends (...args: infer Args) => infer Return ? TApi[Key] & jest.MockInstance : TApi[Key]; }; /** * Mock implementations of the core utility APIs, to be used in tests. * * @public * @remarks * * There are some variations among the APIs depending on what needs tests * might have, but overall there are three main usage patterns: * * 1: Creating an actual fake API instance, often with a simplified version * of functionality, by calling the mock API itself as a function. * * ```ts * // The function often accepts parameters that control its behavior * const foo = mockApis.foo(); * ``` * * 2: Creating a mock API, where all methods are replaced with jest mocks, by * calling the API's `mock` function. * * ```ts * // You can optionally supply a subset of its methods to implement * const foo = mockApis.foo.mock({ * someMethod: () => 'mocked result', * }); * // After exercising your test, you can make assertions on the mock: * expect(foo.someMethod).toHaveBeenCalledTimes(2); * expect(foo.otherMethod).toHaveBeenCalledWith(testData); * ``` * * 3: Creating an API factory that behaves similarly to the mock as per above. * * ```ts * const factory = mockApis.foo.factory({ * someMethod: () => 'mocked result', * }); * ``` */ declare namespace mockApis { /** * Mock implementation of {@link @backstage/core-plugin-api#AnalyticsApi}. * * @public */ function analytics(): AnalyticsApi; /** * Mock implementations of {@link @backstage/core-plugin-api#AnalyticsApi}. * * @public */ namespace analytics { const factory: () => ApiFactory; const mock: (partialImpl?: Partial | undefined) => ApiMock; } /** * Fake implementation of {@link @backstage/core-plugin-api#ConfigApi} * with optional data supplied. * * @public * @example * * ```tsx * const config = mockApis.config({ * data: { app: { baseUrl: 'https://example.com' } }, * }); * * await renderInTestApp( * * * , * ); * ``` */ function config(options?: { data?: JsonObject; }): ConfigApi; /** * Mock helpers for {@link @backstage/core-plugin-api#ConfigApi}. * * @see {@link @backstage/core-plugin-api#mockApis.config} * @public */ namespace config { /** * Creates a factory for a fake implementation of * {@link @backstage/core-plugin-api#ConfigApi} with optional * configuration data supplied. * * @public */ const factory: (options?: { data?: JsonObject; } | undefined) => ApiFactory<_backstage_config.Config, _backstage_config.Config, {}>; /** * Creates a mock implementation of * {@link @backstage/core-plugin-api#ConfigApi}. All methods are * replaced with jest mock functions, and you can optionally pass in a * subset of methods with an explicit implementation. * * @public */ const mock: (partialImpl?: Partial<_backstage_config.Config> | undefined) => ApiMock<_backstage_config.Config>; } /** * Fake implementation of {@link @backstage/core-plugin-api#DiscoveryApi}. By * default returns URLs on the form `http://example.com/api/`. * * @public */ function discovery(options?: { baseUrl?: string; }): DiscoveryApi; /** * Mock implementations of {@link @backstage/core-plugin-api#DiscoveryApi}. * * @public */ namespace discovery { const factory: (options?: { baseUrl?: string; } | undefined) => ApiFactory; const mock: (partialImpl?: Partial | undefined) => ApiMock; } /** * Fake implementation of {@link @backstage/core-plugin-api#IdentityApi}. By * default returns no token or profile info, and the user `user:default/test`. * * @public */ function identity(options?: { userEntityRef?: string; ownershipEntityRefs?: string[]; token?: string; email?: string; displayName?: string; picture?: string; }): IdentityApi; /** * Mock implementations of {@link @backstage/core-plugin-api#IdentityApi}. * * @public */ namespace identity { const factory: (options?: { userEntityRef?: string; ownershipEntityRefs?: string[]; token?: string; email?: string; displayName?: string; picture?: string; } | undefined) => ApiFactory; const mock: (partialImpl?: Partial | undefined) => ApiMock; } /** * Fake implementation of * {@link @backstage/plugin-permission-react#PermissionApi}. By default allows * all actions. * * @public */ function permission(options?: { authorize?: AuthorizeResult.ALLOW | AuthorizeResult.DENY | ((request: EvaluatePermissionRequest) => AuthorizeResult.ALLOW | AuthorizeResult.DENY); }): PermissionApi; /** * Mock implementation of * {@link @backstage/plugin-permission-react#PermissionApi}. * * @public */ namespace permission { const factory: (options?: { authorize?: AuthorizeResult.ALLOW | AuthorizeResult.DENY | ((request: EvaluatePermissionRequest) => AuthorizeResult.ALLOW | AuthorizeResult.DENY); } | undefined) => ApiFactory; const mock: (partialImpl?: Partial | undefined) => ApiMock; } /** * Fake implementation of {@link @backstage/core-plugin-api#StorageApi}. * Stores data temporarily in memory. * * @public */ function storage(options?: { data?: JsonObject; }): StorageApi; /** * Mock implementations of {@link @backstage/core-plugin-api#StorageApi}. * * @public */ namespace storage { const factory: (options?: { data?: JsonObject; } | undefined) => ApiFactory; const mock: (partialImpl?: Partial | undefined) => ApiMock; } /** * Fake implementation of {@link @backstage/core-plugin-api/alpha#TranslationApi}. * By default returns the default translation. * * @public */ function translation(): TranslationApi; /** * Mock implementations of {@link @backstage/core-plugin-api/alpha#TranslationApi}. * * @public */ namespace translation { const factory: () => ApiFactory; const mock: (partialImpl?: Partial | undefined) => ApiMock; } } /** * This is a mocking method suggested in the Jest docs, as it is not implemented in JSDOM yet. * It can be used to mock values for the Material UI `useMediaQuery` hook if it is used in a tested component. * * For issues checkout the documentation: * https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom * * If there are any updates from Material UI React on testing `useMediaQuery` this mock should be replaced * https://mui.com/material-ui/react-use-media-query/#testing * * @public * @deprecated Import from `@backstage/core-components/testUtils` instead. */ declare function mockBreakpoint(options: { matches: boolean; }): void; /** * @public * Set legacy mode when using React 18/RTL 13+. * Mock this option while we're working against React 17 or lower. */ type LegacyRootOption = { legacyRoot?: boolean; }; /** * @public * Simplifies rendering of async components in by taking care of the wrapping inside act * * @remarks * * Components using useEffect to perform an asynchronous action (such as fetch) must be rendered within an async * act call to properly get the final state, even with mocked responses. This utility method makes the signature a bit * cleaner, since act doesn't return the result of the evaluated function. * https://github.com/testing-library/react-testing-library/issues/281 * https://github.com/facebook/react/pull/14853 */ declare function renderWithEffects(nodes: ReactElement, options?: Pick & LegacyRootOption): Promise; /** * Options to customize the behavior of the test app wrapper. * @public */ type TestAppOptions = { /** * Initial route entries to pass along as `initialEntries` to the router. */ routeEntries?: string[]; /** * An object of paths to mount route ref on, with the key being the path and the value * being the RouteRef that the path will be bound to. This allows the route refs to be * used by `useRouteRef` in the rendered elements. * * @example * wrapInTestApp(, \{ * mountedRoutes: \{ * '/my-path': myRouteRef, * \} * \}) * // ... * const link = useRouteRef(myRouteRef) */ mountedRoutes?: { [path: string]: RouteRef | ExternalRouteRef; }; /** * 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; }; }; /** * Creates a Wrapper component that wraps a component inside a Backstage test app, * providing a mocked theme and app context, along with mocked APIs. * * @param options - Additional options for the rendering. * @public */ declare function createTestAppWrapper(options?: TestAppOptions): (props: { children: ReactNode; }) => JSX.Element; /** * Wraps a component inside a Backstage test app, providing a mocked theme * and app context, along with mocked APIs. * * @param Component - A component or react node to render inside the test app. * @param options - Additional options for the rendering. * @public */ declare function wrapInTestApp(Component: ComponentType | ReactNode, options?: TestAppOptions): ReactElement; /** * Renders a component inside a Backstage test app, providing a mocked theme * and app context, along with mocked APIs. * * The render executes async effects similar to `renderWithEffects`. To avoid this * behavior, use a regular `render()` + `wrapInTestApp()` instead. * * @param Component - A component or react node to render inside the test app. * @param options - Additional options for the rendering. * @public */ declare function renderInTestApp(Component: ComponentType> | ReactNode, options?: TestAppOptions & LegacyRootOption): Promise; /** * Returns a `@testing-library/react` valid MatcherFunction for supplied text * * @param string - text Text to match by element's textContent * * @public */ declare const textContentMatcher: (text: string) => MatcherFunction; /** * Sets up handlers for request mocking * @public * @param worker - service worker */ declare function registerMswTestHooks(worker: { listen: (t: any) => void; close: () => void; resetHandlers: () => void; }): void; /** * Severity levels of {@link CollectedLogs} * @public */ type LogFuncs = 'log' | 'warn' | 'error'; /** * AsyncLogCollector type used in {@link (withLogCollector:1)} callback function. * @public */ type AsyncLogCollector = () => Promise; /** * SyncLogCollector type used in {@link (withLogCollector:2)} callback function. * @public */ type SyncLogCollector = () => void; /** * Union type used in {@link (withLogCollector:3)} callback function. * @public */ type LogCollector = AsyncLogCollector | SyncLogCollector; /** * Map of severity level and corresponding log lines. * @public */ type CollectedLogs = { [key in T]: string[]; }; /** * Asynchronous log collector with that collects all categories * @public */ declare function withLogCollector(callback: AsyncLogCollector): Promise>; /** * Synchronous log collector with that collects all categories * @public */ declare function withLogCollector(callback: SyncLogCollector): CollectedLogs; /** * Asynchronous log collector with that only collects selected categories * @public */ declare function withLogCollector(logsToCollect: T[], callback: AsyncLogCollector): Promise>; /** * Synchronous log collector with that only collects selected categories * @public */ declare function withLogCollector(logsToCollect: T[], callback: SyncLogCollector): CollectedLogs; /** @ignore */ type TestApiProviderPropsApiPair = TApi extends infer TImpl ? readonly [ApiRef, Partial] : never; /** @ignore */ type TestApiProviderPropsApiPairs = { [TIndex in keyof TApiPairs]: TestApiProviderPropsApiPair; }; /** * Properties for the {@link TestApiProvider} component. * * @public */ type TestApiProviderProps = { apis: readonly [...TestApiProviderPropsApiPairs]; children: ReactNode; }; /** * The `TestApiRegistry` is an {@link @backstage/core-plugin-api#ApiHolder} implementation * that is particularly well suited for development and test environments such as * unit tests, storybooks, and isolated plugin development setups. * * @public */ declare class TestApiRegistry implements ApiHolder { private readonly apis; /** * Creates a new {@link TestApiRegistry} with a list of API implementation pairs. * * Similar to the {@link TestApiProvider}, there is no need to provide a full * implementation of each API, it's enough to implement the methods that are tested. * * @example * ```ts * const apis = TestApiRegistry.from( * [configApiRef, new ConfigReader({})], * [identityApiRef, { getUserId: () => 'tester' }], * ); * ``` * * @public * @param apis - A list of pairs mapping an ApiRef to its respective implementation. */ static from(...apis: readonly [...TestApiProviderPropsApiPairs]): TestApiRegistry; private constructor(); /** * Returns an implementation of the API. * * @public */ get(api: ApiRef): T | undefined; } /** * The `TestApiProvider` is a Utility API context provider that is particularly * well suited for development and test environments such as unit tests, storybooks, * and isolated plugin development setups. * * It lets you provide any number of API implementations, without necessarily * having to fully implement each of the APIs. * * @remarks * todo: remove this remark tag and ship in the api-reference. There's some odd formatting going on when this is made into a markdown doc, that there's no line break between * the emitted

for To the following

so what happens is that when parsing in docusaurus, it thinks that the code block is mdx rather than a code * snippet. Just omitting this from the report for now until we can work out how to fix later. * A migration from `ApiRegistry` and `ApiProvider` might look like this, from: * * ```tsx * renderInTestApp( * * ... * * ) * ``` * * To the following: * * ```tsx * renderInTestApp( * * ... * * ) * ``` * * Note that the cast to `IdentityApi` is no longer needed as long as the mock API * implements a subset of the `IdentityApi`. * * @public */ declare const TestApiProvider: (props: TestApiProviderProps) => react_jsx_runtime.JSX.Element; export { MockAnalyticsApi, MockConfigApi, MockErrorApi, MockFetchApi, MockPermissionApi, MockStorageApi, TestApiProvider, TestApiRegistry, createTestAppWrapper, mockApis, mockBreakpoint, registerMswTestHooks, renderInTestApp, renderWithEffects, setupRequestMockHandlers, textContentMatcher, withLogCollector, wrapInTestApp }; export type { ApiMock, AsyncLogCollector, CollectedLogs, ErrorWithContext, LegacyRootOption, LogCollector, LogFuncs, MockErrorApiOptions, MockFetchApiOptions, MockStorageBucket, SyncLogCollector, TestApiProviderProps, TestAppOptions };