frontend-test-utils: deprecate standalone mock API exports

Deprecate all standalone mock API exports in favor of the `mockApis`
namespace. This includes the mock classes, their option types, and
the `ErrorWithContext` type. Inline option types into the `mockApis`
function signatures to avoid dependence on the deprecated types.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
This commit is contained in:
Patrik Oldsberg
2026-03-05 12:14:02 +01:00
parent d0b53e39fd
commit b56f573815
12 changed files with 152 additions and 61 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/frontend-test-utils': patch
---
Deprecated standalone mock API exports in favor of the `mockApis` namespace. This includes the mock classes (`MockAlertApi`, `MockAnalyticsApi`, `MockConfigApi`, `MockErrorApi`, `MockFeatureFlagsApi`, `MockPermissionApi`, `MockStorageApi`, `MockTranslationApi`), their option types (`MockErrorApiOptions`, `MockFeatureFlagsApiOptions`), and the `ErrorWithContext` type. `MockFetchApi`, `MockFetchApiOptions` are kept as non-deprecated exports. Use the `mockApis` namespace instead, for example `mockApis.alert()` or `mockApis.alert.mock()`.
+73 -20
View File
@@ -86,7 +86,7 @@ export function createExtensionTester<
},
): ExtensionTester<NonNullable<T['output']>>;
// @public
// @public @deprecated
export type ErrorWithContext = {
error: ErrorApiError;
context?: ErrorApiErrorContext;
@@ -143,7 +143,7 @@ export class ExtensionTester<UOutput extends ExtensionDataRef> {
snapshot(): ExtensionSnapshotNode;
}
// @public
// @public @deprecated
export class MockAlertApi implements AlertApi {
// (undocumented)
alert$(): Observable<AlertMessage>;
@@ -157,7 +157,7 @@ export class MockAlertApi implements AlertApi {
): Promise<AlertMessage>;
}
// @public
// @public @deprecated
export class MockAnalyticsApi implements AnalyticsApi {
// (undocumented)
captureEvent(event: AnalyticsEvent): void;
@@ -200,18 +200,18 @@ export namespace mockApis {
partialImpl?: Partial<DiscoveryApi> | undefined,
) => ApiMock<DiscoveryApi>;
}
export function error(
options?: MockErrorApiOptions,
): MockErrorApi & MockWithApiFactory<ErrorApi_2>;
export function error(options?: {
collect?: boolean;
}): MockErrorApi & MockWithApiFactory<ErrorApi_2>;
export namespace error {
const // (undocumented)
mock: (
partialImpl?: Partial<ErrorApi_2> | undefined,
) => ApiMock<ErrorApi_2>;
}
export function featureFlags(
options?: MockFeatureFlagsApiOptions,
): MockWithApiFactory<MockFeatureFlagsApi>;
export function featureFlags(options?: {
initialStates?: Record<string, FeatureFlagState>;
}): MockWithApiFactory<MockFeatureFlagsApi>;
export namespace featureFlags {
const mock: (
partialImpl?: Partial<FeatureFlagsApi> | undefined,
@@ -272,7 +272,7 @@ export namespace mockApis {
}
}
// @public
// @public @deprecated
export class MockConfigApi implements ConfigApi {
constructor(input: { data: JsonObject });
get<T = JsonValue>(key?: string): T;
@@ -293,28 +293,37 @@ export class MockConfigApi implements ConfigApi {
keys(): string[];
}
// @public
// @public @deprecated
export class MockErrorApi implements ErrorApi {
constructor(options?: MockErrorApiOptions);
constructor(options?: { collect?: boolean });
// (undocumented)
error$(): Observable<{
error: ErrorApiError;
context?: ErrorApiErrorContext;
}>;
// (undocumented)
getErrors(): ErrorWithContext[];
getErrors(): {
error: ErrorApiError;
context?: ErrorApiErrorContext;
}[];
// (undocumented)
post(error: ErrorApiError, context?: ErrorApiErrorContext): void;
// (undocumented)
waitForError(pattern: RegExp, timeoutMs?: number): Promise<ErrorWithContext>;
waitForError(
pattern: RegExp,
timeoutMs?: number,
): Promise<{
error: ErrorApiError;
context?: ErrorApiErrorContext;
}>;
}
// @public
// @public @deprecated
export type MockErrorApiOptions = {
collect?: boolean;
};
// @public
// @public @deprecated
export class MockFeatureFlagsApi implements FeatureFlagsApi {
constructor(options?: MockFeatureFlagsApiOptions);
clearState(): void;
@@ -330,7 +339,7 @@ export class MockFeatureFlagsApi implements FeatureFlagsApi {
setState(states: Record<string, FeatureFlagState>): void;
}
// @public
// @public @deprecated
export interface MockFeatureFlagsApiOptions {
initialStates?: Record<string, FeatureFlagState>;
}
@@ -359,7 +368,7 @@ export interface MockFetchApiOptions {
};
}
// @public
// @public @deprecated
export class MockPermissionApi implements PermissionApi {
constructor(
requestHandler?: (
@@ -372,7 +381,7 @@ export class MockPermissionApi implements PermissionApi {
): Promise<EvaluatePermissionResponse>;
}
// @public
// @public @deprecated
export class MockStorageApi implements StorageApi {
// (undocumented)
static create(data?: JsonObject): MockStorageApi;
@@ -390,7 +399,7 @@ export class MockStorageApi implements StorageApi {
snapshot<T extends JsonValue>(key: string): StorageValueSnapshot<T>;
}
// @public
// @public @deprecated
export class MockTranslationApi implements TranslationApi {
// (undocumented)
static create(): MockTranslationApi;
@@ -473,4 +482,48 @@ export type TestAppOptions<TApiPairs extends any[] = any[]> = {
};
export { withLogCollector };
// Warnings were encountered during analysis:
//
// src/apis/AlertApi/MockAlertApi.d.ts:19:5 - (ae-undocumented) Missing documentation for "post".
// src/apis/AlertApi/MockAlertApi.d.ts:20:5 - (ae-undocumented) Missing documentation for "alert$".
// src/apis/AnalyticsApi/MockAnalyticsApi.d.ts:11:5 - (ae-undocumented) Missing documentation for "captureEvent".
// src/apis/AnalyticsApi/MockAnalyticsApi.d.ts:12:5 - (ae-undocumented) Missing documentation for "getEvents".
// src/apis/ErrorApi/MockErrorApi.d.ts:33:5 - (ae-undocumented) Missing documentation for "post".
// src/apis/ErrorApi/MockErrorApi.d.ts:34:5 - (ae-undocumented) Missing documentation for "error$".
// src/apis/ErrorApi/MockErrorApi.d.ts:38:5 - (ae-undocumented) Missing documentation for "getErrors".
// src/apis/ErrorApi/MockErrorApi.d.ts:42:5 - (ae-undocumented) Missing documentation for "waitForError".
// src/apis/FeatureFlagsApi/MockFeatureFlagsApi.d.ts:31:5 - (ae-undocumented) Missing documentation for "registerFlag".
// src/apis/FeatureFlagsApi/MockFeatureFlagsApi.d.ts:32:5 - (ae-undocumented) Missing documentation for "getRegisteredFlags".
// src/apis/FeatureFlagsApi/MockFeatureFlagsApi.d.ts:33:5 - (ae-undocumented) Missing documentation for "isActive".
// src/apis/FeatureFlagsApi/MockFeatureFlagsApi.d.ts:34:5 - (ae-undocumented) Missing documentation for "save".
// src/apis/PermissionApi/MockPermissionApi.d.ts:15:5 - (ae-undocumented) Missing documentation for "authorize".
// src/apis/StorageApi/MockStorageApi.d.ts:14:5 - (ae-undocumented) Missing documentation for "create".
// src/apis/StorageApi/MockStorageApi.d.ts:15:5 - (ae-undocumented) Missing documentation for "forBucket".
// src/apis/StorageApi/MockStorageApi.d.ts:16:5 - (ae-undocumented) Missing documentation for "snapshot".
// src/apis/StorageApi/MockStorageApi.d.ts:17:5 - (ae-undocumented) Missing documentation for "set".
// src/apis/StorageApi/MockStorageApi.d.ts:18:5 - (ae-undocumented) Missing documentation for "remove".
// src/apis/StorageApi/MockStorageApi.d.ts:19:5 - (ae-undocumented) Missing documentation for "observe$".
// src/apis/TranslationApi/MockTranslationApi.d.ts:11:5 - (ae-undocumented) Missing documentation for "create".
// src/apis/TranslationApi/MockTranslationApi.d.ts:13:5 - (ae-undocumented) Missing documentation for "getTranslation".
// src/apis/TranslationApi/MockTranslationApi.d.ts:16:5 - (ae-undocumented) Missing documentation for "translation$".
// src/apis/mockApis.d.ts:119:15 - (ae-undocumented) Missing documentation for "mock".
// src/apis/mockApis.d.ts:155:15 - (ae-undocumented) Missing documentation for "mock".
// src/apis/mockApis.d.ts:171:15 - (ae-undocumented) Missing documentation for "mock".
// src/apis/mockApis.d.ts:192:15 - (ae-undocumented) Missing documentation for "mock".
// src/apis/mockApis.d.ts:208:15 - (ae-undocumented) Missing documentation for "mock".
// src/apis/mockApis.d.ts:224:15 - (ae-undocumented) Missing documentation for "mock".
// src/apis/mockApis.d.ts:240:15 - (ae-undocumented) Missing documentation for "mock".
// src/apis/mockApis.d.ts:254:15 - (ae-undocumented) Missing documentation for "mock".
// src/app/createExtensionTester.d.ts:19:1 - (ae-undocumented) Missing documentation for "ExtensionQuery".
// src/app/createExtensionTester.d.ts:22:5 - (ae-undocumented) Missing documentation for "node".
// src/app/createExtensionTester.d.ts:23:5 - (ae-undocumented) Missing documentation for "instance".
// src/app/createExtensionTester.d.ts:24:5 - (ae-undocumented) Missing documentation for "get".
// src/app/createExtensionTester.d.ts:27:1 - (ae-undocumented) Missing documentation for "ExtensionTester".
// src/app/createExtensionTester.d.ts:30:5 - (ae-undocumented) Missing documentation for "add".
// src/app/createExtensionTester.d.ts:33:5 - (ae-undocumented) Missing documentation for "get".
// src/app/createExtensionTester.d.ts:34:5 - (ae-undocumented) Missing documentation for "query".
// src/app/createExtensionTester.d.ts:35:5 - (ae-undocumented) Missing documentation for "reactElement".
// src/app/createExtensionTester.d.ts:49:1 - (ae-undocumented) Missing documentation for "createExtensionTester".
// /Users/patriko/src/backstage/packages/version-bridge/src/lib/globalObject.ts:1:1 - (ae-wrong-input-file-type) Incorrect file type; API Extractor expects to analyze compiler outputs with the .d.ts file extension. Troubleshooting tips: https://api-extractor.com/link/dts-error
```
@@ -23,9 +23,10 @@ import ObservableImpl from 'zen-observable';
* Mock implementation of {@link @backstage/frontend-plugin-api#AlertApi} for testing alert behavior.
*
* @public
* @deprecated Use `mockApis.alert()` instead.
* @example
* ```ts
* const alertApi = new MockAlertApi();
* const alertApi = mockApis.alert();
* alertApi.post({ message: 'Test alert' });
* expect(alertApi.getAlerts()).toHaveLength(1);
* ```
@@ -21,6 +21,7 @@ import { AnalyticsApi, AnalyticsEvent } from '@backstage/frontend-plugin-api';
* Use getEvents in tests to verify captured events.
*
* @public
* @deprecated Use `mockApis.analytics()` instead.
*/
export class MockAnalyticsApi implements AnalyticsApi {
private events: AnalyticsEvent[] = [];
@@ -23,9 +23,10 @@ import { ConfigApi } from '@backstage/core-plugin-api';
* that can be used to mock configuration using a plain object.
*
* @public
* @deprecated Use `mockApis.config()` instead.
* @example
* ```tsx
* const mockConfig = new MockConfigApi({
* const mockConfig = mockApis.config({
* data: { app: { baseUrl: 'https://example.com' } },
* });
*
@@ -24,15 +24,16 @@ import { Observable } from '@backstage/types';
/**
* Constructor arguments for {@link MockErrorApi}
* @public
* @deprecated Use `mockApis.error()` instead.
*/
export type MockErrorApiOptions = {
// Need to be true if getErrors is used in testing.
collect?: boolean;
};
/**
* ErrorWithContext contains error and ErrorApiErrorContext
* @public
* @deprecated Use the return type of `MockErrorApi.getErrors` instead.
*/
export type ErrorWithContext = {
error: ErrorApiError;
@@ -41,7 +42,10 @@ export type ErrorWithContext = {
type Waiter = {
pattern: RegExp;
resolve: (err: ErrorWithContext) => void;
resolve: (err: {
error: ErrorApiError;
context?: ErrorApiErrorContext;
}) => void;
};
const nullObservable = {
@@ -56,12 +60,16 @@ const nullObservable = {
* Mock implementation of the {@link core-plugin-api#ErrorApi} to be used in tests.
* Includes withForError and getErrors methods for error testing.
* @public
* @deprecated Use `mockApis.error()` instead.
*/
export class MockErrorApi implements ErrorApi {
private readonly errors = new Array<ErrorWithContext>();
private readonly errors = new Array<{
error: ErrorApiError;
context?: ErrorApiErrorContext;
}>();
private readonly waiters = new Set<Waiter>();
constructor(private readonly options: MockErrorApiOptions = {}) {}
constructor(private readonly options: { collect?: boolean } = {}) {}
post(error: ErrorApiError, context?: ErrorApiErrorContext) {
if (this.options.collect) {
@@ -87,15 +95,18 @@ export class MockErrorApi implements ErrorApi {
return nullObservable;
}
getErrors(): ErrorWithContext[] {
getErrors(): { error: ErrorApiError; context?: ErrorApiErrorContext }[] {
return this.errors;
}
waitForError(
pattern: RegExp,
timeoutMs: number = 2000,
): Promise<ErrorWithContext> {
return new Promise<ErrorWithContext>((resolve, reject) => {
): Promise<{ error: ErrorApiError; context?: ErrorApiErrorContext }> {
return new Promise<{
error: ErrorApiError;
context?: ErrorApiErrorContext;
}>((resolve, reject) => {
setTimeout(() => {
reject(new Error('Timed out waiting for error'));
}, timeoutMs);
@@ -25,6 +25,7 @@ import {
* Options for configuring {@link MockFeatureFlagsApi}.
*
* @public
* @deprecated Use `mockApis.featureFlags()` instead.
*/
export interface MockFeatureFlagsApiOptions {
/**
@@ -37,10 +38,11 @@ export interface MockFeatureFlagsApiOptions {
* Mock implementation of {@link @backstage/frontend-plugin-api#FeatureFlagsApi} for testing feature flag behavior.
*
* @public
* @deprecated Use `mockApis.featureFlags()` instead.
* @example
* ```ts
* const api = new MockFeatureFlagsApi({
* initialStates: { 'my-feature': FeatureFlagState.Active }
* const api = mockApis.featureFlags({
* initialStates: { 'my-feature': FeatureFlagState.Active },
* });
* expect(api.isActive('my-feature')).toBe(true);
* ```
@@ -28,6 +28,7 @@ import {
* request.
*
* @public
* @deprecated Use `mockApis.permission()` instead.
*/
export class MockPermissionApi implements PermissionApi {
constructor(
@@ -19,9 +19,10 @@ import { JsonObject, JsonValue, Observable } from '@backstage/types';
import ObservableImpl from 'zen-observable';
/**
* Mock implementation of the {@link core-plugin-api#StorageApi} to be used in tests
* Mock implementation of the {@link core-plugin-api#StorageApi} to be used in tests.
*
* @public
* @deprecated Use `mockApis.storage()` instead.
*/
export class MockStorageApi implements StorageApi {
private readonly namespace: string;
@@ -35,6 +35,7 @@ const DEFAULT_LANGUAGE = 'en';
* Mock implementation of {@link @backstage/frontend-plugin-api#TranslationApi}.
*
* @public
* @deprecated Use `mockApis.translation()` instead.
*/
export class MockTranslationApi implements TranslationApi {
static create() {
+34 -15
View File
@@ -28,59 +28,78 @@ export {
type TestApiPairs,
} from './TestApiProvider';
/**
* Mock API classes are exported as types only to prevent direct instantiation.
* Always use the `mockApis` namespace to create mock instances (e.g., `mockApis.alert()`).
*/
/**
* @public
* @deprecated Use `mockApis.alert()` instead.
*/
export type { MockAlertApi } from './AlertApi';
/**
* @public
* @deprecated Use `mockApis.analytics()` instead.
*/
export type { MockAnalyticsApi } from './AnalyticsApi';
/**
* @public
* @deprecated Use `mockApis.config()` instead.
*/
export type { MockConfigApi } from './ConfigApi';
/**
* @public
* @deprecated Use `mockApis.error()` instead.
*/
export type {
MockErrorApi,
MockErrorApiOptions,
ErrorWithContext,
} from './ErrorApi';
export type { MockErrorApi } from './ErrorApi';
/**
* @public
* @deprecated Use `mockApis.error()` instead.
*/
export type { MockErrorApiOptions } from './ErrorApi/MockErrorApi';
/**
* @public
* @deprecated Use the return type of `MockErrorApi.getErrors` instead.
*/
export type { ErrorWithContext } from './ErrorApi/MockErrorApi';
/**
* @public
*/
export type { MockFetchApi, MockFetchApiOptions } from './FetchApi';
export type { MockFetchApi } from './FetchApi';
/**
* @public
*/
export type {
MockFeatureFlagsApi,
MockFeatureFlagsApiOptions,
} from './FeatureFlagsApi';
export type { MockFetchApiOptions } from './FetchApi/MockFetchApi';
/**
* @public
* @deprecated Use `mockApis.featureFlags()` instead.
*/
export type { MockFeatureFlagsApi } from './FeatureFlagsApi';
/**
* @public
* @deprecated Use `mockApis.featureFlags()` instead.
*/
export type { MockFeatureFlagsApiOptions } from './FeatureFlagsApi/MockFeatureFlagsApi';
/**
* @public
* @deprecated Use `mockApis.permission()` instead.
*/
export type { MockPermissionApi } from './PermissionApi';
/**
* @public
* @deprecated Use `mockApis.storage()` instead.
*/
export type { MockStorageApi } from './StorageApi';
/**
* @public
* @deprecated Use `mockApis.translation()` instead.
*/
export type { MockTranslationApi } from './TranslationApi';
@@ -30,6 +30,7 @@ import {
type DiscoveryApi,
type ErrorApi,
type FetchApi,
type FeatureFlagState,
type IdentityApi,
type StorageApi,
type TranslationApi,
@@ -44,13 +45,10 @@ import {
EvaluatePermissionRequest,
} from '@backstage/plugin-permission-common';
import { MockAlertApi } from './AlertApi';
import {
MockFeatureFlagsApi,
MockFeatureFlagsApiOptions,
} from './FeatureFlagsApi';
import { MockFeatureFlagsApi } from './FeatureFlagsApi';
import { MockAnalyticsApi } from './AnalyticsApi';
import { MockConfigApi } from './ConfigApi';
import { MockErrorApi, MockErrorApiOptions } from './ErrorApi';
import { MockErrorApi } from './ErrorApi';
import { MockFetchApi, MockFetchApiOptions } from './FetchApi';
import { MockStorageApi } from './StorageApi';
import { MockPermissionApi } from './PermissionApi';
@@ -114,7 +112,6 @@ export namespace mockApis {
/**
* Mock helpers for {@link @backstage/frontend-plugin-api#AlertApi}.
*
* @see {@link @backstage/frontend-plugin-api#mockApis.alert}
* @public
*/
export namespace alert {
@@ -145,9 +142,9 @@ export namespace mockApis {
* expect(featureFlagsApi.isActive('my-feature')).toBe(true);
* ```
*/
export function featureFlags(
options?: MockFeatureFlagsApiOptions,
): MockWithApiFactory<MockFeatureFlagsApi> {
export function featureFlags(options?: {
initialStates?: Record<string, FeatureFlagState>;
}): MockWithApiFactory<MockFeatureFlagsApi> {
const instance = new MockFeatureFlagsApi(options);
return mockWithApiFactory(
featureFlagsApiRef,
@@ -157,7 +154,6 @@ export namespace mockApis {
/**
* Mock helpers for {@link @backstage/frontend-plugin-api#FeatureFlagsApi}.
*
* @see {@link @backstage/frontend-plugin-api#mockApis.featureFlags}
* @public
*/
export namespace featureFlags {
@@ -218,7 +214,6 @@ export namespace mockApis {
/**
* Mock helpers for {@link @backstage/frontend-plugin-api#TranslationApi}.
*
* @see {@link @backstage/frontend-plugin-api#mockApis.translation}
* @public
*/
export namespace translation {
@@ -419,9 +414,9 @@ export namespace mockApis {
*
* @public
*/
export function error(
options?: MockErrorApiOptions,
): MockErrorApi & MockWithApiFactory<ErrorApi> {
export function error(options?: {
collect?: boolean;
}): MockErrorApi & MockWithApiFactory<ErrorApi> {
const instance = new MockErrorApi(options);
return mockWithApiFactory(errorApiRef, instance) as MockErrorApi &
MockWithApiFactory<ErrorApi>;