diff --git a/.changeset/deprecate-mock-api-classes.md b/.changeset/deprecate-mock-api-classes.md new file mode 100644 index 0000000000..0b27b3dfd3 --- /dev/null +++ b/.changeset/deprecate-mock-api-classes.md @@ -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()`. diff --git a/packages/frontend-test-utils/report.api.md b/packages/frontend-test-utils/report.api.md index a17c2ed483..2a0c24a80b 100644 --- a/packages/frontend-test-utils/report.api.md +++ b/packages/frontend-test-utils/report.api.md @@ -86,7 +86,7 @@ export function createExtensionTester< }, ): ExtensionTester>; -// @public +// @public @deprecated export type ErrorWithContext = { error: ErrorApiError; context?: ErrorApiErrorContext; @@ -143,7 +143,7 @@ export class ExtensionTester { snapshot(): ExtensionSnapshotNode; } -// @public +// @public @deprecated export class MockAlertApi implements AlertApi { // (undocumented) alert$(): Observable; @@ -157,7 +157,7 @@ export class MockAlertApi implements AlertApi { ): Promise; } -// @public +// @public @deprecated export class MockAnalyticsApi implements AnalyticsApi { // (undocumented) captureEvent(event: AnalyticsEvent): void; @@ -200,18 +200,18 @@ export namespace mockApis { partialImpl?: Partial | undefined, ) => ApiMock; } - export function error( - options?: MockErrorApiOptions, - ): MockErrorApi & MockWithApiFactory; + export function error(options?: { + collect?: boolean; + }): MockErrorApi & MockWithApiFactory; export namespace error { const // (undocumented) mock: ( partialImpl?: Partial | undefined, ) => ApiMock; } - export function featureFlags( - options?: MockFeatureFlagsApiOptions, - ): MockWithApiFactory; + export function featureFlags(options?: { + initialStates?: Record; + }): MockWithApiFactory; export namespace featureFlags { const mock: ( partialImpl?: Partial | undefined, @@ -272,7 +272,7 @@ export namespace mockApis { } } -// @public +// @public @deprecated export class MockConfigApi implements ConfigApi { constructor(input: { data: JsonObject }); get(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; + 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): void; } -// @public +// @public @deprecated export interface MockFeatureFlagsApiOptions { initialStates?: Record; } @@ -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; } -// @public +// @public @deprecated export class MockStorageApi implements StorageApi { // (undocumented) static create(data?: JsonObject): MockStorageApi; @@ -390,7 +399,7 @@ export class MockStorageApi implements StorageApi { snapshot(key: string): StorageValueSnapshot; } -// @public +// @public @deprecated export class MockTranslationApi implements TranslationApi { // (undocumented) static create(): MockTranslationApi; @@ -473,4 +482,48 @@ export type TestAppOptions = { }; 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 ``` diff --git a/packages/frontend-test-utils/src/apis/AlertApi/MockAlertApi.ts b/packages/frontend-test-utils/src/apis/AlertApi/MockAlertApi.ts index 305a527b87..dcd39fdb78 100644 --- a/packages/frontend-test-utils/src/apis/AlertApi/MockAlertApi.ts +++ b/packages/frontend-test-utils/src/apis/AlertApi/MockAlertApi.ts @@ -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); * ``` diff --git a/packages/frontend-test-utils/src/apis/AnalyticsApi/MockAnalyticsApi.ts b/packages/frontend-test-utils/src/apis/AnalyticsApi/MockAnalyticsApi.ts index f6ccf4e9d1..24117d980f 100644 --- a/packages/frontend-test-utils/src/apis/AnalyticsApi/MockAnalyticsApi.ts +++ b/packages/frontend-test-utils/src/apis/AnalyticsApi/MockAnalyticsApi.ts @@ -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[] = []; diff --git a/packages/frontend-test-utils/src/apis/ConfigApi/MockConfigApi.ts b/packages/frontend-test-utils/src/apis/ConfigApi/MockConfigApi.ts index 349eee0d3a..ea445fac19 100644 --- a/packages/frontend-test-utils/src/apis/ConfigApi/MockConfigApi.ts +++ b/packages/frontend-test-utils/src/apis/ConfigApi/MockConfigApi.ts @@ -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' } }, * }); * diff --git a/packages/frontend-test-utils/src/apis/ErrorApi/MockErrorApi.ts b/packages/frontend-test-utils/src/apis/ErrorApi/MockErrorApi.ts index c7c8556355..0b627d59e4 100644 --- a/packages/frontend-test-utils/src/apis/ErrorApi/MockErrorApi.ts +++ b/packages/frontend-test-utils/src/apis/ErrorApi/MockErrorApi.ts @@ -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(); + private readonly errors = new Array<{ + error: ErrorApiError; + context?: ErrorApiErrorContext; + }>(); private readonly waiters = new Set(); - 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 { - return new Promise((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); diff --git a/packages/frontend-test-utils/src/apis/FeatureFlagsApi/MockFeatureFlagsApi.ts b/packages/frontend-test-utils/src/apis/FeatureFlagsApi/MockFeatureFlagsApi.ts index 5421687c65..591f6a2e95 100644 --- a/packages/frontend-test-utils/src/apis/FeatureFlagsApi/MockFeatureFlagsApi.ts +++ b/packages/frontend-test-utils/src/apis/FeatureFlagsApi/MockFeatureFlagsApi.ts @@ -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); * ``` diff --git a/packages/frontend-test-utils/src/apis/PermissionApi/MockPermissionApi.ts b/packages/frontend-test-utils/src/apis/PermissionApi/MockPermissionApi.ts index c54a3993d3..52f8fa4bb6 100644 --- a/packages/frontend-test-utils/src/apis/PermissionApi/MockPermissionApi.ts +++ b/packages/frontend-test-utils/src/apis/PermissionApi/MockPermissionApi.ts @@ -28,6 +28,7 @@ import { * request. * * @public + * @deprecated Use `mockApis.permission()` instead. */ export class MockPermissionApi implements PermissionApi { constructor( diff --git a/packages/frontend-test-utils/src/apis/StorageApi/MockStorageApi.ts b/packages/frontend-test-utils/src/apis/StorageApi/MockStorageApi.ts index b4cf762599..f7ad0fe39a 100644 --- a/packages/frontend-test-utils/src/apis/StorageApi/MockStorageApi.ts +++ b/packages/frontend-test-utils/src/apis/StorageApi/MockStorageApi.ts @@ -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; diff --git a/packages/frontend-test-utils/src/apis/TranslationApi/MockTranslationApi.ts b/packages/frontend-test-utils/src/apis/TranslationApi/MockTranslationApi.ts index f5112ca175..91708b0528 100644 --- a/packages/frontend-test-utils/src/apis/TranslationApi/MockTranslationApi.ts +++ b/packages/frontend-test-utils/src/apis/TranslationApi/MockTranslationApi.ts @@ -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() { diff --git a/packages/frontend-test-utils/src/apis/index.ts b/packages/frontend-test-utils/src/apis/index.ts index 6e09833298..41cd3a3bbf 100644 --- a/packages/frontend-test-utils/src/apis/index.ts +++ b/packages/frontend-test-utils/src/apis/index.ts @@ -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'; diff --git a/packages/frontend-test-utils/src/apis/mockApis.ts b/packages/frontend-test-utils/src/apis/mockApis.ts index 78d5c2bf19..96932318bb 100644 --- a/packages/frontend-test-utils/src/apis/mockApis.ts +++ b/packages/frontend-test-utils/src/apis/mockApis.ts @@ -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 { + export function featureFlags(options?: { + initialStates?: Record; + }): MockWithApiFactory { 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 { + export function error(options?: { + collect?: boolean; + }): MockErrorApi & MockWithApiFactory { const instance = new MockErrorApi(options); return mockWithApiFactory(errorApiRef, instance) as MockErrorApi & MockWithApiFactory;