UNPKG

@backstage/backend-test-utils

Version:

Test helpers library for Backstage backends

171 lines (164 loc) • 6.8 kB
import { S as ServiceMock } from './types/createServiceMock.d-CeKvILsY.js'; import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api'; import { LoggerService, BackstageCredentials, ServiceFactory } from '@backstage/backend-plugin-api'; import * as _backstage_backend_plugin_api_alpha from '@backstage/backend-plugin-api/alpha'; import { ActionsRegistryService, ActionsService, ActionsRegistryActionOptions, ActionsServiceAction, MetricsService, TracingServiceContextAPI, TracingServicePropagationAPI, TracingServiceSpan, TracingServiceAttributeValue, TracingServiceSpanStatus, TracingService } from '@backstage/backend-plugin-api/alpha'; import { JsonObject, JsonValue } from '@backstage/types'; import { AnyZodObject } from 'zod/v3'; /** * A mock implementation of the ActionsRegistryService and ActionsService that can be used in tests. * * This is useful for testing actions that are registered with the ActionsRegistryService and ActionsService. * * The plugin ID is hardcoded to `testing` in the mock implementation. * * @example * ```ts * const actionsRegistry = mockServices.actionsRegistry(); * * actionsRegistry.register({ * name: 'test', * title: 'Test', * description: 'Test', * schema: { * input: z.object({ name: z.string() }), * output: z.object({ name: z.string() }), * }, * action: async ({ input }) => ({ output: { name: input.name } }), * }); * * * const result = await actionsRegistry.invoke({ * id: 'testing:test', * input: { name: 'test' }, * }); * * expect(result).toEqual({ output: { name: 'test' } }); * ``` * * @alpha */ declare class MockActionsRegistry implements ActionsRegistryService, ActionsService { private readonly logger; private constructor(); static create(opts: { logger: LoggerService; }): MockActionsRegistry; readonly actions: Map<string, ActionsRegistryActionOptions<any, any>>; list(): Promise<{ actions: ActionsServiceAction[]; }>; invoke(opts: { id: string; input?: JsonObject; credentials?: BackstageCredentials; }): Promise<{ output: JsonValue; }>; register<TInputSchema extends AnyZodObject, TOutputSchema extends AnyZodObject>(options: ActionsRegistryActionOptions<TInputSchema, TOutputSchema>): void; } /** * @alpha */ declare function actionsRegistryServiceMock(options?: { logger: LoggerService; }): MockActionsRegistry; /** * @alpha */ declare namespace actionsRegistryServiceMock { const factory: () => _backstage_backend_plugin_api.ServiceFactory<_backstage_backend_plugin_api_alpha.ActionsRegistryService, "plugin", "singleton">; const mock: (partialImpl?: Partial<_backstage_backend_plugin_api_alpha.ActionsRegistryService> | undefined) => ServiceMock<_backstage_backend_plugin_api_alpha.ActionsRegistryService>; } /** * @alpha */ declare namespace actionsServiceMock { const factory: () => _backstage_backend_plugin_api.ServiceFactory<_backstage_backend_plugin_api_alpha.ActionsService, "plugin", "singleton">; const mock: (partialImpl?: Partial<_backstage_backend_plugin_api_alpha.ActionsService> | undefined) => ServiceMock<_backstage_backend_plugin_api_alpha.ActionsService>; } /** * @alpha */ declare namespace metricsServiceMock { const factory: () => _backstage_backend_plugin_api.ServiceFactory<MetricsService, "plugin", "singleton">; const mock: (partialImpl?: Partial<MetricsService> | undefined) => ServiceMock<MetricsService>; } /** * A jest-mocked span captured by {@link TracingServiceMock}. * * @alpha */ interface MockedTracingServiceSpan extends TracingServiceSpan { setAttribute: jest.Mock<void, [string, TracingServiceAttributeValue]>; setStatus: jest.Mock<void, [TracingServiceSpanStatus]>; } /** * Jest-mocked counterpart of the `context` member on the * `TracingService`. * * @alpha */ interface MockedTracingServiceContextAPI extends TracingServiceContextAPI { active: jest.MockedFunction<TracingServiceContextAPI['active']>; with: jest.MockedFunction<TracingServiceContextAPI['with']>; } /** * Jest-mocked counterpart of the `propagation` member on the * `TracingService`. * * @alpha */ interface MockedTracingServicePropagationAPI extends TracingServicePropagationAPI { extract: jest.MockedFunction<TracingServicePropagationAPI['extract']>; getBaggage: jest.MockedFunction<TracingServicePropagationAPI['getBaggage']>; getActiveBaggage: jest.MockedFunction<TracingServicePropagationAPI['getActiveBaggage']>; } /** * Mock for the `TracingService`. Captures every span created via * `startActiveSpan` so tests can assert on the options passed in and the * methods called on the span inside the callback. * * By default, `propagation.extract` parses the `baggage` header (W3C * Baggage syntax) out of the supplied carrier and stashes the entries * on the returned context handle. `context.with` activates that handle * for the duration of the wrapped callback so * `propagation.getActiveBaggage` (and `propagation.getBaggage` on the * supplied handle) returns those entries. Other propagation fields * (e.g. `traceparent`) are ignored. Tests that need fully custom * baggage can still override `propagation.getActiveBaggage` via * `mockReturnValue` / `mockImplementation`, which takes precedence over * the default behaviour. * * Unlike the real `DefaultTracingService`, the mock's `startActiveSpan` * does **not** resolve `options.credentials` from `options.request` via * `httpAuth`. Tests that need principal-derived span attributes should * supply `options.credentials` directly on the span options, or assert * on the raw `options` captured by `startActiveSpan.mock.calls`. * * @alpha */ interface TracingServiceMock extends TracingService { startActiveSpan: jest.MockedFunction<TracingService['startActiveSpan']>; context: MockedTracingServiceContextAPI; propagation: MockedTracingServicePropagationAPI; /** Spans created by `startActiveSpan` calls, in order. */ spans: MockedTracingServiceSpan[]; factory: ServiceFactory<TracingService>; } /** * @alpha */ declare namespace tracingServiceMock { /** * Returns the real `tracingServiceFactory` from `@backstage/backend-defaults`, * for tests that want the full default implementation. */ const factory: () => ServiceFactory<TracingService, "plugin", "singleton">; /** * Builds a mock `TracingService` backed by jest mocks. */ const mock: () => TracingServiceMock; } export { MockActionsRegistry, ServiceMock, actionsRegistryServiceMock, actionsServiceMock, metricsServiceMock, tracingServiceMock }; export type { MockedTracingServiceContextAPI, MockedTracingServicePropagationAPI, MockedTracingServiceSpan, TracingServiceMock };