@backstage/backend-test-utils 1.6.0-next.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -0
- package/dist/alpha/services/ActionsRegistryServiceMock.cjs.js +26 -0
- package/dist/alpha/services/ActionsRegistryServiceMock.cjs.js.map +1 -0
- package/dist/alpha/services/ActionsServiceMock.cjs.js +15 -0
- package/dist/alpha/services/ActionsServiceMock.cjs.js.map +1 -0
- package/dist/alpha/services/MockActionsRegistry.cjs.js +83 -0
- package/dist/alpha/services/MockActionsRegistry.cjs.js.map +1 -0
- package/dist/alpha/services/simpleMock.cjs.js +28 -0
- package/dist/alpha/services/simpleMock.cjs.js.map +1 -0
- package/dist/alpha.cjs.js +18 -0
- package/dist/alpha.cjs.js.map +1 -0
- package/dist/alpha.d.ts +89 -0
- package/dist/backend-app-api/src/lib/DependencyGraph.cjs.js +19 -3
- package/dist/backend-app-api/src/lib/DependencyGraph.cjs.js.map +1 -1
- package/dist/index.cjs.js +6 -6
- package/dist/index.d.ts +106 -92
- package/dist/services/MockAuthService.cjs.js.map +1 -0
- package/dist/services/MockEventsService.cjs.js.map +1 -0
- package/dist/services/MockHttpAuthService.cjs.js.map +1 -0
- package/dist/services/MockPermissionsService.cjs.js +25 -0
- package/dist/services/MockPermissionsService.cjs.js.map +1 -0
- package/dist/services/MockRootLoggerService.cjs.js.map +1 -0
- package/dist/services/MockUserInfoService.cjs.js.map +1 -0
- package/dist/{next/services → services}/mockCredentials.cjs.js +16 -8
- package/dist/services/mockCredentials.cjs.js.map +1 -0
- package/dist/{next/services → services}/mockServices.cjs.js +32 -58
- package/dist/services/mockServices.cjs.js.map +1 -0
- package/dist/services/simpleMock.cjs.js +28 -0
- package/dist/services/simpleMock.cjs.js.map +1 -0
- package/dist/util/errorHandler.cjs.js +2 -5
- package/dist/util/errorHandler.cjs.js.map +1 -1
- package/dist/{next/wiring → wiring}/ServiceFactoryTester.cjs.js +1 -1
- package/dist/wiring/ServiceFactoryTester.cjs.js.map +1 -0
- package/dist/{next/wiring → wiring}/TestBackend.cjs.js +9 -1
- package/dist/wiring/TestBackend.cjs.js.map +1 -0
- package/package.json +23 -12
- package/dist/next/services/MockAuthService.cjs.js.map +0 -1
- package/dist/next/services/MockEventsService.cjs.js.map +0 -1
- package/dist/next/services/MockHttpAuthService.cjs.js.map +0 -1
- package/dist/next/services/MockRootLoggerService.cjs.js.map +0 -1
- package/dist/next/services/MockUserInfoService.cjs.js.map +0 -1
- package/dist/next/services/mockCredentials.cjs.js.map +0 -1
- package/dist/next/services/mockServices.cjs.js.map +0 -1
- package/dist/next/wiring/ServiceFactoryTester.cjs.js.map +0 -1
- package/dist/next/wiring/TestBackend.cjs.js.map +0 -1
- /package/dist/{next/services → services}/MockAuthService.cjs.js +0 -0
- /package/dist/{next/services → services}/MockEventsService.cjs.js +0 -0
- /package/dist/{next/services → services}/MockHttpAuthService.cjs.js +0 -0
- /package/dist/{next/services → services}/MockRootLoggerService.cjs.js +0 -0
- /package/dist/{next/services → services}/MockUserInfoService.cjs.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mockServices.cjs.js","sources":["../../src/services/mockServices.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { auditorServiceFactory } from '@backstage/backend-defaults/auditor';\nimport { cacheServiceFactory } from '@backstage/backend-defaults/cache';\nimport { databaseServiceFactory } from '@backstage/backend-defaults/database';\nimport { HostDiscovery } from '@backstage/backend-defaults/discovery';\nimport { httpRouterServiceFactory } from '@backstage/backend-defaults/httpRouter';\nimport { lifecycleServiceFactory } from '@backstage/backend-defaults/lifecycle';\nimport { loggerServiceFactory } from '@backstage/backend-defaults/logger';\nimport { permissionsServiceFactory } from '@backstage/backend-defaults/permissions';\nimport { permissionsRegistryServiceFactory } from '@backstage/backend-defaults/permissionsRegistry';\nimport { rootHealthServiceFactory } from '@backstage/backend-defaults/rootHealth';\nimport { rootHttpRouterServiceFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport { rootLifecycleServiceFactory } from '@backstage/backend-defaults/rootLifecycle';\nimport { schedulerServiceFactory } from '@backstage/backend-defaults/scheduler';\nimport { urlReaderServiceFactory } from '@backstage/backend-defaults/urlReader';\nimport {\n AuthService,\n BackstageCredentials,\n BackstageUserInfo,\n DatabaseService,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n PermissionsService,\n RootConfigService,\n ServiceFactory,\n ServiceRef,\n UserInfoService,\n coreServices,\n createServiceFactory,\n} from '@backstage/backend-plugin-api';\nimport { ConfigReader } from '@backstage/config';\nimport { EventsService, eventsServiceRef } from '@backstage/plugin-events-node';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\nimport { JsonObject } from '@backstage/types';\nimport { Knex } from 'knex';\nimport { MockAuthService } from './MockAuthService';\nimport { MockHttpAuthService } from './MockHttpAuthService';\nimport { MockRootLoggerService } from './MockRootLoggerService';\nimport { MockUserInfoService } from './MockUserInfoService';\nimport { mockCredentials } from './mockCredentials';\nimport { MockEventsService } from './MockEventsService';\nimport { MockPermissionsService } from './MockPermissionsService';\nimport { simpleMock } from './simpleMock';\n\n/** @internal */\nfunction createLoggerMock() {\n return {\n child: jest.fn().mockImplementation(createLoggerMock),\n debug: jest.fn(),\n error: jest.fn(),\n info: jest.fn(),\n warn: jest.fn(),\n };\n}\n\n/** @internal */\nfunction simpleFactoryWithOptions<\n TService,\n TScope extends 'root' | 'plugin',\n TOptions extends [options?: object] = [],\n>(\n ref: ServiceRef<TService, TScope>,\n factory: (...options: TOptions) => TService,\n): (...options: TOptions) => ServiceFactory<TService, TScope> {\n const factoryWithOptions = (...options: TOptions) =>\n createServiceFactory({\n service: ref as ServiceRef<TService, any>,\n deps: {},\n async factory() {\n return factory(...options);\n },\n });\n return Object.assign(\n factoryWithOptions,\n factoryWithOptions(...([undefined] as unknown as TOptions)),\n ) as ServiceFactory<TService, TScope> &\n ((...options: TOptions) => ServiceFactory<TService, TScope>);\n}\n\n/**\n * Mock implementations of the core services, to be used in tests.\n *\n * @public\n * @remarks\n *\n * There are some variations among the services depending on what needs tests\n * might have, but overall there are three main usage patterns:\n *\n * 1. Creating an actual fake service instance, often with a simplified version\n * of functionality, by calling the mock service itself as a function.\n *\n * ```ts\n * // The function often accepts parameters that control its behavior\n * const foo = mockServices.foo();\n * ```\n *\n * 2. Creating a mock service, where all methods are replaced with jest mocks, by\n * calling the service's `mock` function.\n *\n * ```ts\n * // You can optionally supply a subset of its methods to implement\n * const foo = mockServices.foo.mock({\n * someMethod: () => 'mocked result',\n * });\n * // After exercising your test, you can make assertions on the mock:\n * expect(foo.someMethod).toHaveBeenCalledTimes(2);\n * expect(foo.otherMethod).toHaveBeenCalledWith(testData);\n * ```\n *\n * 3. Creating a service factory that behaves similarly to the mock as per above.\n *\n * ```ts\n * await startTestBackend({\n * features: [\n * mockServices.foo.factory({\n * someMethod: () => 'mocked result',\n * })\n * ],\n * });\n * ```\n */\nexport namespace mockServices {\n export function rootConfig(options?: rootConfig.Options): RootConfigService {\n return new ConfigReader(options?.data, 'mock-config');\n }\n export namespace rootConfig {\n export type Options = { data?: JsonObject };\n\n export const factory = simpleFactoryWithOptions(\n coreServices.rootConfig,\n rootConfig,\n );\n export const mock = simpleMock(coreServices.rootConfig, () => ({\n get: jest.fn(),\n getBoolean: jest.fn(),\n getConfig: jest.fn(),\n getConfigArray: jest.fn(),\n getNumber: jest.fn(),\n getOptional: jest.fn(),\n getOptionalBoolean: jest.fn(),\n getOptionalConfig: jest.fn(),\n getOptionalConfigArray: jest.fn(),\n getOptionalNumber: jest.fn(),\n getOptionalString: jest.fn(),\n getOptionalStringArray: jest.fn(),\n getString: jest.fn(),\n getStringArray: jest.fn(),\n has: jest.fn(),\n keys: jest.fn(),\n }));\n }\n\n export function rootLogger(options?: rootLogger.Options): LoggerService {\n return MockRootLoggerService.create(options);\n }\n export namespace rootLogger {\n export type Options = {\n level?: 'none' | 'error' | 'warn' | 'info' | 'debug';\n };\n\n export const factory = simpleFactoryWithOptions(\n coreServices.rootLogger,\n rootLogger,\n );\n export const mock = simpleMock(coreServices.rootLogger, () => ({\n child: jest.fn(),\n debug: jest.fn(),\n error: jest.fn(),\n info: jest.fn(),\n warn: jest.fn(),\n }));\n }\n\n export namespace auditor {\n export const factory = () => auditorServiceFactory;\n\n export const mock = simpleMock(coreServices.auditor, () => ({\n createEvent: jest.fn(async _ => {\n return {\n success: jest.fn(),\n fail: jest.fn(),\n };\n }),\n }));\n }\n\n export function auth(options?: {\n pluginId?: string;\n disableDefaultAuthPolicy?: boolean;\n }): AuthService {\n return new MockAuthService({\n pluginId: options?.pluginId ?? 'test',\n disableDefaultAuthPolicy: Boolean(options?.disableDefaultAuthPolicy),\n });\n }\n export namespace auth {\n export const factory = () =>\n createServiceFactory({\n service: coreServices.auth,\n deps: {\n plugin: coreServices.pluginMetadata,\n config: coreServices.rootConfig,\n },\n factory({ plugin, config }) {\n const disableDefaultAuthPolicy = Boolean(\n config.getOptionalBoolean(\n 'backend.auth.dangerouslyDisableDefaultAuthPolicy',\n ),\n );\n return new MockAuthService({\n pluginId: plugin.getId(),\n disableDefaultAuthPolicy,\n });\n },\n });\n export const mock = simpleMock(coreServices.auth, () => ({\n authenticate: jest.fn(),\n getNoneCredentials: jest.fn(),\n getOwnServiceCredentials: jest.fn(),\n isPrincipal: jest.fn() as any,\n getPluginRequestToken: jest.fn(),\n getLimitedUserToken: jest.fn(),\n listPublicServiceKeys: jest.fn(),\n }));\n }\n\n export function discovery(): DiscoveryService {\n return HostDiscovery.fromConfig(\n new ConfigReader({\n backend: {\n // Invalid port to make sure that requests are always mocked\n baseUrl: 'http://localhost:0',\n listen: { port: 0 },\n },\n }),\n );\n }\n export namespace discovery {\n export const factory = () =>\n createServiceFactory({\n service: coreServices.discovery,\n deps: {},\n factory: () => discovery(),\n });\n export const mock = simpleMock(coreServices.discovery, () => ({\n getBaseUrl: jest.fn(),\n getExternalBaseUrl: jest.fn(),\n }));\n }\n\n /**\n * Creates a mock implementation of the `HttpAuthService`.\n *\n * By default all requests without credentials are treated as requests from\n * the default mock user principal. This behavior can be configured with the\n * `defaultCredentials` option.\n */\n export function httpAuth(options?: {\n pluginId?: string;\n /**\n * The default credentials to use if there are no credentials present in the\n * incoming request.\n *\n * By default all requests without credentials are treated as authenticated\n * as the default mock user as returned from `mockCredentials.user()`.\n */\n defaultCredentials?: BackstageCredentials;\n }): HttpAuthService {\n return new MockHttpAuthService(\n options?.pluginId ?? 'test',\n options?.defaultCredentials ?? mockCredentials.user(),\n );\n }\n export namespace httpAuth {\n /**\n * Creates a mock service factory for the `HttpAuthService`.\n *\n * By default all requests without credentials are treated as requests from\n * the default mock user principal. This behavior can be configured with the\n * `defaultCredentials` option.\n */\n export const factory = (options?: {\n defaultCredentials?: BackstageCredentials;\n }) =>\n createServiceFactory({\n service: coreServices.httpAuth,\n deps: { plugin: coreServices.pluginMetadata },\n factory: ({ plugin }) =>\n new MockHttpAuthService(\n plugin.getId(),\n options?.defaultCredentials ?? mockCredentials.user(),\n ),\n });\n export const mock = simpleMock(coreServices.httpAuth, () => ({\n credentials: jest.fn(),\n issueUserCookie: jest.fn(),\n }));\n }\n\n /**\n * Creates a mock implementation of the `UserInfoService`.\n *\n * By default it extracts the user's entity ref from a user principal and\n * returns that as the only ownership entity ref, but this can be overridden\n * by passing in a custom set of user info.\n */\n export function userInfo(\n customInfo?: Partial<BackstageUserInfo>,\n ): UserInfoService {\n return new MockUserInfoService(customInfo);\n }\n export namespace userInfo {\n /**\n * Creates a mock service factory for the `UserInfoService`.\n *\n * By default it extracts the user's entity ref from a user principal and\n * returns that as the only ownership entity ref.\n */\n export const factory = () =>\n createServiceFactory({\n service: coreServices.userInfo,\n deps: {},\n factory() {\n return new MockUserInfoService();\n },\n });\n export const mock = simpleMock(coreServices.userInfo, () => ({\n getUserInfo: jest.fn(),\n }));\n }\n\n // TODO(Rugvip): Not all core services have implementations available here yet.\n // some may need a bit more refactoring for it to be simpler to\n // re-implement functioning mock versions here.\n export namespace cache {\n export const factory = () => cacheServiceFactory;\n export const mock = simpleMock(coreServices.cache, () => ({\n delete: jest.fn(),\n get: jest.fn(),\n set: jest.fn(),\n withOptions: jest.fn(),\n }));\n }\n\n /**\n * Creates a mock implementation of the\n * {@link @backstage/backend-plugin-api#coreServices.database}. Just returns\n * the given `knex` instance, which is useful in combination with the\n * {@link TestDatabases} facility.\n */\n export function database(options: {\n knex: Knex;\n migrations?: { skip?: boolean };\n }): DatabaseService {\n return {\n getClient: async () => options.knex,\n migrations: options.migrations,\n };\n }\n export namespace database {\n /**\n * Creates a mock factory for the\n * {@link @backstage/backend-plugin-api#coreServices.database}. Just returns\n * the given `knex` instance if you supply one, which is useful in\n * combination with the {@link TestDatabases} facility. Otherwise, it\n * returns the regular default database factory which reads config settings.\n */\n export const factory = (options?: {\n knex: Knex;\n migrations?: { skip?: boolean };\n }) =>\n options\n ? createServiceFactory({\n service: coreServices.database,\n deps: {},\n factory: () => database(options),\n })\n : databaseServiceFactory;\n /**\n * Creates a mock of the\n * {@link @backstage/backend-plugin-api#coreServices.database}, optionally\n * with some given method implementations.\n */\n export const mock = simpleMock(coreServices.database, () => ({\n getClient: jest.fn(),\n }));\n }\n\n export namespace rootHealth {\n export const factory = () => rootHealthServiceFactory;\n export const mock = simpleMock(coreServices.rootHealth, () => ({\n getLiveness: jest.fn(),\n getReadiness: jest.fn(),\n }));\n }\n\n export namespace httpRouter {\n export const factory = () => httpRouterServiceFactory;\n export const mock = simpleMock(coreServices.httpRouter, () => ({\n use: jest.fn(),\n addAuthPolicy: jest.fn(),\n }));\n }\n\n export namespace rootHttpRouter {\n export const factory = () => rootHttpRouterServiceFactory();\n export const mock = simpleMock(coreServices.rootHttpRouter, () => ({\n use: jest.fn(),\n }));\n }\n\n export namespace lifecycle {\n export const factory = () => lifecycleServiceFactory;\n export const mock = simpleMock(coreServices.lifecycle, () => ({\n addShutdownHook: jest.fn(),\n addStartupHook: jest.fn(),\n }));\n }\n\n export namespace logger {\n export const factory = () => loggerServiceFactory;\n export const mock = simpleMock(coreServices.logger, () =>\n createLoggerMock(),\n );\n }\n\n /**\n * Creates a functional mock implementation of the\n * {@link @backstage/backend-plugin-api#PermissionsService}.\n */\n export function permissions(options?: {\n result: AuthorizeResult.ALLOW | AuthorizeResult.DENY;\n }): PermissionsService {\n return new MockPermissionsService(options);\n }\n export namespace permissions {\n /**\n * Creates a mock factory for the\n * {@link @backstage/backend-plugin-api#coreServices.permissions}. Just\n * returns the given `result` if you supply one. Otherwise, it returns the\n * regular default permissions factory.\n */\n export const factory = (options?: {\n result: AuthorizeResult.ALLOW | AuthorizeResult.DENY;\n }) =>\n options?.result\n ? createServiceFactory({\n service: coreServices.permissions,\n deps: {},\n factory: () => new MockPermissionsService(options),\n })\n : permissionsServiceFactory;\n /**\n * Creates a mock of the\n * {@link @backstage/backend-plugin-api#coreServices.permissions},\n * optionally with some given method implementations.\n */\n export const mock = simpleMock(coreServices.permissions, () => ({\n authorize: jest.fn(),\n authorizeConditional: jest.fn(),\n }));\n }\n\n export namespace permissionsRegistry {\n export const factory = () => permissionsRegistryServiceFactory;\n export const mock = simpleMock(coreServices.permissionsRegistry, () => ({\n addPermissionRules: jest.fn(),\n addPermissions: jest.fn(),\n addResourceType: jest.fn(),\n getPermissionRuleset: jest.fn(),\n }));\n }\n\n export namespace rootLifecycle {\n export const factory = () => rootLifecycleServiceFactory;\n export const mock = simpleMock(coreServices.rootLifecycle, () => ({\n addShutdownHook: jest.fn(),\n addBeforeShutdownHook: jest.fn(),\n addStartupHook: jest.fn(),\n }));\n }\n\n export namespace scheduler {\n export const factory = () => schedulerServiceFactory;\n export const mock = simpleMock(coreServices.scheduler, () => ({\n createScheduledTaskRunner: jest.fn(),\n getScheduledTasks: jest.fn(),\n scheduleTask: jest.fn(),\n triggerTask: jest.fn(),\n }));\n }\n\n export namespace urlReader {\n export const factory = () => urlReaderServiceFactory;\n export const mock = simpleMock(coreServices.urlReader, () => ({\n readTree: jest.fn(),\n readUrl: jest.fn(),\n search: jest.fn(),\n }));\n }\n\n /**\n * Creates a functional mock implementation of the\n * {@link @backstage/backend-events-node#eventsServiceRef}.\n */\n export function events(): EventsService {\n return new MockEventsService();\n }\n export namespace events {\n /**\n * Creates a functional mock factory for the\n * {@link @backstage/backend-events-node#eventsServiceRef}.\n */\n export const factory = simpleFactoryWithOptions(eventsServiceRef, events);\n /**\n * Creates a mock of the\n * {@link @backstage/backend-events-node#eventsServiceRef}, optionally\n * with some given method implementations.\n */\n export const mock = simpleMock(eventsServiceRef, () => ({\n publish: jest.fn(),\n subscribe: jest.fn(),\n }));\n }\n}\n"],"names":["createServiceFactory","mockServices","ConfigReader","rootConfig","coreServices","simpleMock","MockRootLoggerService","rootLogger","auditor","auditorServiceFactory","MockAuthService","auth","discovery","HostDiscovery","MockHttpAuthService","mockCredentials","httpAuth","MockUserInfoService","userInfo","cache","cacheServiceFactory","database","databaseServiceFactory","rootHealth","rootHealthServiceFactory","httpRouter","httpRouterServiceFactory","rootHttpRouter","rootHttpRouterServiceFactory","lifecycle","lifecycleServiceFactory","logger","loggerServiceFactory","permissions","MockPermissionsService","permissionsServiceFactory","permissionsRegistry","permissionsRegistryServiceFactory","rootLifecycle","rootLifecycleServiceFactory","scheduler","schedulerServiceFactory","urlReader","urlReaderServiceFactory","MockEventsService","events","eventsServiceRef"],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
4
|
+
|
|
5
|
+
function simpleMock(ref, mockFactory) {
|
|
6
|
+
return (partialImpl) => {
|
|
7
|
+
const mock = mockFactory();
|
|
8
|
+
if (partialImpl) {
|
|
9
|
+
for (const [key, impl] of Object.entries(partialImpl)) {
|
|
10
|
+
if (typeof impl === "function") {
|
|
11
|
+
mock[key].mockImplementation(impl);
|
|
12
|
+
} else {
|
|
13
|
+
mock[key] = impl;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return Object.assign(mock, {
|
|
18
|
+
factory: backendPluginApi.createServiceFactory({
|
|
19
|
+
service: ref,
|
|
20
|
+
deps: {},
|
|
21
|
+
factory: () => mock
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
exports.simpleMock = simpleMock;
|
|
28
|
+
//# sourceMappingURL=simpleMock.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simpleMock.cjs.js","sources":["../../src/services/simpleMock.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n createServiceFactory,\n ServiceFactory,\n ServiceRef,\n} from '@backstage/backend-plugin-api';\n\n/** @public */\nexport type ServiceMock<TService> = {\n factory: ServiceFactory<TService>;\n} & {\n [Key in keyof TService]: TService[Key] extends (\n ...args: infer Args\n ) => infer Return\n ? TService[Key] & jest.MockInstance<Return, Args>\n : TService[Key];\n};\n\n/** @internal */\nexport function simpleMock<TService>(\n ref: ServiceRef<TService, any>,\n mockFactory: () => jest.Mocked<TService>,\n): (partialImpl?: Partial<TService>) => ServiceMock<TService> {\n return partialImpl => {\n const mock = mockFactory();\n if (partialImpl) {\n for (const [key, impl] of Object.entries(partialImpl)) {\n if (typeof impl === 'function') {\n (mock as any)[key].mockImplementation(impl);\n } else {\n (mock as any)[key] = impl;\n }\n }\n }\n return Object.assign(mock, {\n factory: createServiceFactory({\n service: ref,\n deps: {},\n factory: () => mock,\n }),\n }) as ServiceMock<TService>;\n };\n}\n"],"names":["createServiceFactory"],"mappings":";;;;AAiCgB,SAAA,UAAA,CACd,KACA,WAC4D,EAAA;AAC5D,EAAA,OAAO,CAAe,WAAA,KAAA;AACpB,IAAA,MAAM,OAAO,WAAY,EAAA;AACzB,IAAA,IAAI,WAAa,EAAA;AACf,MAAA,KAAA,MAAW,CAAC,GAAK,EAAA,IAAI,KAAK,MAAO,CAAA,OAAA,CAAQ,WAAW,CAAG,EAAA;AACrD,QAAI,IAAA,OAAO,SAAS,UAAY,EAAA;AAC9B,UAAC,IAAa,CAAA,GAAG,CAAE,CAAA,kBAAA,CAAmB,IAAI,CAAA;AAAA,SACrC,MAAA;AACL,UAAC,IAAA,CAAa,GAAG,CAAI,GAAA,IAAA;AAAA;AACvB;AACF;AAEF,IAAO,OAAA,MAAA,CAAO,OAAO,IAAM,EAAA;AAAA,MACzB,SAASA,qCAAqB,CAAA;AAAA,QAC5B,OAAS,EAAA,GAAA;AAAA,QACT,MAAM,EAAC;AAAA,QACP,SAAS,MAAM;AAAA,OAChB;AAAA,KACF,CAAA;AAAA,GACH;AACF;;;;"}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var rootHttpRouter = require('@backstage/backend-defaults/rootHttpRouter');
|
|
4
|
-
require('../
|
|
5
|
-
require('
|
|
6
|
-
require('@backstage/errors');
|
|
7
|
-
var mockServices = require('../next/services/mockServices.cjs.js');
|
|
8
|
-
require('../next/services/mockCredentials.cjs.js');
|
|
4
|
+
var mockServices = require('../services/mockServices.cjs.js');
|
|
5
|
+
require('../services/mockCredentials.cjs.js');
|
|
9
6
|
|
|
10
7
|
function mockErrorHandler() {
|
|
11
8
|
return rootHttpRouter.MiddlewareFactory.create({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorHandler.cjs.js","sources":["../../src/util/errorHandler.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport { mockServices } from '../
|
|
1
|
+
{"version":3,"file":"errorHandler.cjs.js","sources":["../../src/util/errorHandler.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport { mockServices } from '../services';\n\n/**\n * A mock for error handler middleware that can be used in router tests.\n * @public\n */\nexport function mockErrorHandler() {\n return MiddlewareFactory.create({\n config: mockServices.rootConfig(),\n logger: mockServices.rootLogger(),\n }).error();\n}\n"],"names":["MiddlewareFactory","mockServices"],"mappings":";;;;;;AAuBO,SAAS,gBAAmB,GAAA;AACjC,EAAA,OAAOA,iCAAkB,MAAO,CAAA;AAAA,IAC9B,MAAA,EAAQC,0BAAa,UAAW,EAAA;AAAA,IAChC,MAAA,EAAQA,0BAAa,UAAW;AAAA,GACjC,EAAE,KAAM,EAAA;AACX;;;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var TestBackend = require('./TestBackend.cjs.js');
|
|
4
|
-
var ServiceRegistry = require('
|
|
4
|
+
var ServiceRegistry = require('../backend-app-api/src/wiring/ServiceRegistry.cjs.js');
|
|
5
5
|
|
|
6
6
|
class ServiceFactoryTester {
|
|
7
7
|
#subject;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ServiceFactoryTester.cjs.js","sources":["../../src/wiring/ServiceFactoryTester.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ServiceFactory, ServiceRef } from '@backstage/backend-plugin-api';\nimport { defaultServiceFactories } from './TestBackend';\n// Direct internal import to avoid duplication.\n// This is a relative import in order to make sure that the implementation is duplicated\n// rather than leading to an import from @backstage/backend-app-api.\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { ServiceRegistry } from '../../../backend-app-api/src/wiring/ServiceRegistry';\n\n/**\n * Options for {@link ServiceFactoryTester}.\n * @public\n */\nexport interface ServiceFactoryTesterOptions {\n /**\n * Additional service factories to make available as dependencies.\n *\n * @remarks\n *\n * If a service factory is provided for a service that already has a default\n * implementation, the provided factory will override the default.\n */\n dependencies?: Array<ServiceFactory>;\n}\n\n/**\n * A utility to help test service factories in isolation.\n *\n * @public\n */\nexport class ServiceFactoryTester<\n TService,\n TScope extends 'root' | 'plugin',\n TInstances extends 'singleton' | 'multiton' = 'singleton',\n> {\n readonly #subject: ServiceRef<TService, TScope, TInstances>;\n readonly #registry: ServiceRegistry;\n\n /**\n * Creates a new {@link ServiceFactoryTester} used to test the provided subject.\n *\n * @param subject - The service factory to test.\n * @param options - Additional options\n * @returns A new tester instance for the provided subject.\n */\n static from<\n TService,\n TScope extends 'root' | 'plugin',\n TInstances extends 'singleton' | 'multiton' = 'singleton',\n >(\n subject: ServiceFactory<TService, TScope, TInstances>,\n options?: ServiceFactoryTesterOptions,\n ): ServiceFactoryTester<TService, TScope, TInstances> {\n const registry = ServiceRegistry.create([\n ...defaultServiceFactories,\n ...(options?.dependencies ?? []),\n subject,\n ]);\n return new ServiceFactoryTester(subject.service, registry);\n }\n\n private constructor(\n subject: ServiceRef<TService, TScope, TInstances>,\n registry: ServiceRegistry,\n ) {\n this.#subject = subject;\n this.#registry = registry;\n }\n\n /**\n * Returns the service instance for the subject.\n *\n * @remarks\n *\n * If the subject is a plugin scoped service factory a plugin ID\n * can be provided to instantiate the service for a specific plugin.\n *\n * By default the plugin ID 'test' is used.\n */\n async getSubject(\n ...args: 'root' extends TScope ? [] : [pluginId?: string]\n ): Promise<TInstances extends 'multiton' ? TService[] : TService> {\n const [pluginId] = args;\n const instance = this.#registry.get(this.#subject, pluginId ?? 'test')!;\n return instance;\n }\n\n /**\n * Return the service instance for any of the provided dependencies or built-in services.\n *\n * @remarks\n *\n * A plugin ID can optionally be provided for plugin scoped services, otherwise the plugin ID 'test' is used.\n */\n async getService<\n TGetService,\n TGetScope extends 'root' | 'plugin',\n TGetInstances extends 'singleton' | 'multiton' = 'singleton',\n >(\n service: ServiceRef<TGetService, TGetScope, TGetInstances>,\n ...args: 'root' extends TGetScope ? [] : [pluginId?: string]\n ): Promise<TGetInstances extends 'multiton' ? TGetService[] : TGetService> {\n const [pluginId] = args;\n const instance = await this.#registry.get(service, pluginId ?? 'test');\n if (instance === undefined) {\n throw new Error(`Service '${service.id}' not found`);\n }\n return instance;\n }\n}\n"],"names":["ServiceRegistry","defaultServiceFactories"],"mappings":";;;;;AA6CO,MAAM,oBAIX,CAAA;AAAA,EACS,QAAA;AAAA,EACA,SAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAST,OAAO,IAKL,CAAA,OAAA,EACA,OACoD,EAAA;AACpD,IAAM,MAAA,QAAA,GAAWA,gCAAgB,MAAO,CAAA;AAAA,MACtC,GAAGC,mCAAA;AAAA,MACH,GAAI,OAAS,EAAA,YAAA,IAAgB,EAAC;AAAA,MAC9B;AAAA,KACD,CAAA;AACD,IAAA,OAAO,IAAI,oBAAA,CAAqB,OAAQ,CAAA,OAAA,EAAS,QAAQ,CAAA;AAAA;AAC3D,EAEQ,WAAA,CACN,SACA,QACA,EAAA;AACA,IAAA,IAAA,CAAK,QAAW,GAAA,OAAA;AAChB,IAAA,IAAA,CAAK,SAAY,GAAA,QAAA;AAAA;AACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,cACD,IAC6D,EAAA;AAChE,IAAM,MAAA,CAAC,QAAQ,CAAI,GAAA,IAAA;AACnB,IAAA,MAAM,WAAW,IAAK,CAAA,SAAA,CAAU,IAAI,IAAK,CAAA,QAAA,EAAU,YAAY,MAAM,CAAA;AACrE,IAAO,OAAA,QAAA;AAAA;AACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,UAKJ,CAAA,OAAA,EAAA,GACG,IACsE,EAAA;AACzE,IAAM,MAAA,CAAC,QAAQ,CAAI,GAAA,IAAA;AACnB,IAAA,MAAM,WAAW,MAAM,IAAA,CAAK,UAAU,GAAI,CAAA,OAAA,EAAS,YAAY,MAAM,CAAA;AACrE,IAAA,IAAI,aAAa,KAAW,CAAA,EAAA;AAC1B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAY,SAAA,EAAA,OAAA,CAAQ,EAAE,CAAa,WAAA,CAAA,CAAA;AAAA;AAErD,IAAO,OAAA,QAAA;AAAA;AAEX;;;;"}
|
|
@@ -8,6 +8,11 @@ var config = require('@backstage/config');
|
|
|
8
8
|
var express = require('express');
|
|
9
9
|
var rootHttpRouter = require('@backstage/backend-defaults/rootHttpRouter');
|
|
10
10
|
var discovery = require('@backstage/backend-defaults/discovery');
|
|
11
|
+
var ActionsRegistryServiceMock = require('../alpha/services/ActionsRegistryServiceMock.cjs.js');
|
|
12
|
+
require('@backstage/errors');
|
|
13
|
+
require('zod');
|
|
14
|
+
require('zod-to-json-schema');
|
|
15
|
+
var ActionsServiceMock = require('../alpha/services/ActionsServiceMock.cjs.js');
|
|
11
16
|
|
|
12
17
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
13
18
|
|
|
@@ -31,7 +36,10 @@ const defaultServiceFactories = [
|
|
|
31
36
|
mockServices.mockServices.scheduler.factory(),
|
|
32
37
|
mockServices.mockServices.userInfo.factory(),
|
|
33
38
|
mockServices.mockServices.urlReader.factory(),
|
|
34
|
-
mockServices.mockServices.events.factory()
|
|
39
|
+
mockServices.mockServices.events.factory(),
|
|
40
|
+
// Alpha services
|
|
41
|
+
ActionsRegistryServiceMock.actionsRegistryServiceMock.factory(),
|
|
42
|
+
ActionsServiceMock.actionsServiceMock.factory()
|
|
35
43
|
];
|
|
36
44
|
function createPluginsForOrphanModules(features) {
|
|
37
45
|
const pluginIds = /* @__PURE__ */ new Set();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TestBackend.cjs.js","sources":["../../src/wiring/TestBackend.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Backend, createSpecializedBackend } from '@backstage/backend-app-api';\nimport {\n createServiceFactory,\n BackendFeature,\n ExtensionPoint,\n coreServices,\n createBackendModule,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { mockServices } from '../services';\nimport { ConfigReader } from '@backstage/config';\nimport express from 'express';\n// Direct internal import to avoid duplication\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport {\n InternalBackendFeature,\n InternalBackendRegistrations,\n} from '../../../backend-plugin-api/src/wiring/types';\nimport {\n DefaultRootHttpRouter,\n ExtendedHttpServer,\n MiddlewareFactory,\n createHealthRouter,\n createHttpServer,\n} from '@backstage/backend-defaults/rootHttpRouter';\nimport { HostDiscovery } from '@backstage/backend-defaults/discovery';\nimport {\n actionsRegistryServiceMock,\n actionsServiceMock,\n} from '../alpha/services';\n\n/** @public */\nexport interface TestBackendOptions<TExtensionPoints extends any[]> {\n extensionPoints?: readonly [\n ...{\n [index in keyof TExtensionPoints]: [\n ExtensionPoint<TExtensionPoints[index]>,\n Partial<TExtensionPoints[index]>,\n ];\n },\n ];\n features?: Array<BackendFeature | Promise<{ default: BackendFeature }>>;\n}\n\n/** @public */\nexport interface TestBackend extends Backend {\n /**\n * Provides access to the underling HTTP server for use with utilities\n * such as `supertest`.\n *\n * If the root http router service has been replaced, this will throw an error.\n */\n readonly server: ExtendedHttpServer;\n}\n\nexport const defaultServiceFactories = [\n mockServices.auth.factory(),\n mockServices.auditor.factory(),\n mockServices.cache.factory(),\n mockServices.rootConfig.factory(),\n mockServices.database.factory(),\n mockServices.httpAuth.factory(),\n mockServices.httpRouter.factory(),\n mockServices.lifecycle.factory(),\n mockServices.logger.factory(),\n mockServices.permissions.factory(),\n mockServices.permissionsRegistry.factory(),\n mockServices.rootHealth.factory(),\n mockServices.rootLifecycle.factory(),\n mockServices.rootLogger.factory(),\n mockServices.scheduler.factory(),\n mockServices.userInfo.factory(),\n mockServices.urlReader.factory(),\n mockServices.events.factory(),\n\n // Alpha services\n actionsRegistryServiceMock.factory(),\n actionsServiceMock.factory(),\n];\n\n/**\n * Given a set of features, return an array of plugins that ensures that each\n * module in the provided set of features has a corresponding plugin.\n * @internal\n */\nfunction createPluginsForOrphanModules(features: Array<BackendFeature>) {\n const pluginIds = new Set<string>();\n const modulePluginIds = new Set<string>();\n\n for (const feature of features) {\n if (isInternalBackendRegistrations(feature)) {\n const registrations = feature.getRegistrations();\n for (const registration of registrations) {\n if (registration.type === 'plugin') {\n pluginIds.add(registration.pluginId);\n } else if (registration.type === 'module') {\n modulePluginIds.add(registration.pluginId);\n }\n }\n }\n }\n\n for (const pluginId of pluginIds) {\n modulePluginIds.delete(pluginId);\n }\n\n return Array.from(modulePluginIds).map(pluginId =>\n createBackendPlugin({\n pluginId,\n register(reg) {\n reg.registerInit({ deps: {}, async init() {} });\n },\n }),\n );\n}\n\n/**\n * Given a set of extension points and features, find the extension\n * points that we mock and tie them to the correct plugin ID.\n * @returns\n */\nfunction createExtensionPointTestModules(\n features: Array<BackendFeature>,\n extensionPointTuples?: readonly [\n ref: ExtensionPoint<unknown>,\n impl: unknown,\n ][],\n): Array<BackendFeature> {\n if (!extensionPointTuples) {\n return [];\n }\n\n const registrations = features.flatMap(feature => {\n if (isInternalBackendRegistrations(feature)) {\n return feature.getRegistrations();\n }\n return [];\n });\n\n const extensionPointMap = new Map(\n extensionPointTuples.map(ep => [ep[0].id, ep]),\n );\n const extensionPointsToSort = new Set(extensionPointMap.keys());\n const extensionPointsByPlugin = new Map<string, string[]>();\n\n for (const registration of registrations) {\n if (registration.type === 'module') {\n const testDep = Object.values(registration.init.deps).filter(dep =>\n extensionPointsToSort.has(dep.id),\n );\n if (testDep.length > 0) {\n let points = extensionPointsByPlugin.get(registration.pluginId);\n if (!points) {\n points = [];\n extensionPointsByPlugin.set(registration.pluginId, points);\n }\n for (const { id } of testDep) {\n points.push(id);\n extensionPointsToSort.delete(id);\n }\n }\n }\n }\n\n if (extensionPointsToSort.size > 0) {\n const list = Array.from(extensionPointsToSort)\n .map(id => `'${id}'`)\n .join(', ');\n throw new Error(\n `Unable to determine the plugin ID of extension point(s) ${list}. ` +\n 'Tested extension points must be depended on by one or more tested modules.',\n );\n }\n\n const modules = [];\n\n for (const [pluginId, pluginExtensionPointIds] of extensionPointsByPlugin) {\n modules.push(\n createBackendModule({\n pluginId,\n moduleId: 'test-extension-point-registration',\n register(reg) {\n for (const id of pluginExtensionPointIds) {\n const tuple = extensionPointMap.get(id)!;\n reg.registerExtensionPoint(...tuple);\n }\n\n reg.registerInit({ deps: {}, async init() {} });\n },\n }),\n );\n }\n\n return modules;\n}\n\nfunction isPromise<T>(value: unknown | Promise<T>): value is Promise<T> {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'then' in value &&\n typeof value.then === 'function'\n );\n}\n\n// Same as in the backend-app-api, handles double defaults from dynamic imports\nfunction unwrapFeature(\n feature: BackendFeature | { default: BackendFeature },\n): BackendFeature {\n if ('$$type' in feature) {\n return feature;\n }\n\n if ('default' in feature) {\n return feature.default;\n }\n\n return feature;\n}\n\nconst backendInstancesToCleanUp = new Array<Backend>();\n\n/** @public */\nexport async function startTestBackend<TExtensionPoints extends any[]>(\n options: TestBackendOptions<TExtensionPoints>,\n): Promise<TestBackend> {\n const { extensionPoints, ...otherOptions } = options;\n\n // Unpack input into awaited plain BackendFeatures\n const features: BackendFeature[] = await Promise.all(\n options.features?.map(async val => {\n if (isPromise(val)) {\n const { default: feature } = await val;\n return unwrapFeature(feature);\n }\n return unwrapFeature(val);\n }) ?? [],\n );\n\n let server: ExtendedHttpServer;\n\n const rootHttpRouterFactory = createServiceFactory({\n service: coreServices.rootHttpRouter,\n deps: {\n config: coreServices.rootConfig,\n lifecycle: coreServices.rootLifecycle,\n rootLogger: coreServices.rootLogger,\n health: coreServices.rootHealth,\n },\n async factory({ config, lifecycle, rootLogger, health }) {\n const router = DefaultRootHttpRouter.create();\n const logger = rootLogger.child({ service: 'rootHttpRouter' });\n\n const app = express();\n\n const middleware = MiddlewareFactory.create({ config, logger });\n const healthRouter = createHealthRouter({ config, health });\n\n app.use(healthRouter);\n app.use(router.handler());\n app.use(middleware.notFound());\n app.use(middleware.error());\n\n server = await createHttpServer(\n app,\n { listen: { host: '', port: 0 } },\n { logger },\n );\n\n lifecycle.addShutdownHook(() => server.stop(), { logger });\n\n await server.start();\n\n return router;\n },\n });\n\n const discoveryFactory = createServiceFactory({\n service: coreServices.discovery,\n deps: {\n rootHttpRouter: coreServices.rootHttpRouter,\n },\n async factory() {\n if (!server) {\n throw new Error('Test server not started yet');\n }\n const port = server.port();\n const discovery = HostDiscovery.fromConfig(\n new ConfigReader({\n backend: { baseUrl: `http://localhost:${port}`, listen: { port } },\n }),\n );\n return discovery;\n },\n });\n\n const backend = createSpecializedBackend({\n ...otherOptions,\n defaultServiceFactories: [\n ...defaultServiceFactories,\n rootHttpRouterFactory,\n discoveryFactory,\n ],\n });\n\n backendInstancesToCleanUp.push(backend);\n\n for (const m of createExtensionPointTestModules(features, extensionPoints)) {\n backend.add(m);\n }\n for (const p of createPluginsForOrphanModules(features)) {\n backend.add(p);\n }\n for (const feature of features) {\n backend.add(feature);\n }\n\n await backend.start();\n\n return Object.assign(backend, {\n get server() {\n if (!server) {\n throw new Error('TestBackend server is not available');\n }\n return server;\n },\n });\n}\n\nlet registered = false;\nfunction registerTestHooks() {\n if (typeof afterAll !== 'function') {\n return;\n }\n if (registered) {\n return;\n }\n registered = true;\n\n afterAll(async () => {\n await Promise.all(\n backendInstancesToCleanUp.map(async backend => {\n try {\n await backend.stop();\n } catch (error) {\n console.error(`Failed to stop backend after tests, ${error}`);\n }\n }),\n );\n backendInstancesToCleanUp.length = 0;\n });\n}\n\nregisterTestHooks();\n\nfunction toInternalBackendFeature(\n feature: BackendFeature,\n): InternalBackendFeature {\n if (feature.$$type !== '@backstage/BackendFeature') {\n throw new Error(`Invalid BackendFeature, bad type '${feature.$$type}'`);\n }\n const internal = feature as InternalBackendFeature;\n if (internal.version !== 'v1') {\n throw new Error(\n `Invalid BackendFeature, bad version '${internal.version}'`,\n );\n }\n return internal;\n}\n\nfunction isInternalBackendRegistrations(\n feature: BackendFeature,\n): feature is InternalBackendRegistrations {\n const internal = toInternalBackendFeature(feature);\n if (internal.featureType === 'registrations') {\n return true;\n }\n // Backwards compatibility for v1 registrations that use duck typing\n return 'getRegistrations' in internal;\n}\n"],"names":["mockServices","actionsRegistryServiceMock","actionsServiceMock","createBackendPlugin","createBackendModule","createServiceFactory","coreServices","DefaultRootHttpRouter","express","MiddlewareFactory","createHealthRouter","createHttpServer","discovery","HostDiscovery","ConfigReader","createSpecializedBackend"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/backend-test-utils",
|
|
3
|
-
"version": "1.6.0
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Test helpers library for Backstage backends",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "node-library"
|
|
@@ -25,12 +25,20 @@
|
|
|
25
25
|
"types": "./dist/index.d.ts",
|
|
26
26
|
"default": "./dist/index.cjs.js"
|
|
27
27
|
},
|
|
28
|
-
"./package.json": "./package.json"
|
|
28
|
+
"./package.json": "./package.json",
|
|
29
|
+
"./alpha": {
|
|
30
|
+
"require": "./dist/alpha.cjs.js",
|
|
31
|
+
"types": "./dist/alpha.d.ts",
|
|
32
|
+
"default": "./dist/alpha.cjs.js"
|
|
33
|
+
}
|
|
29
34
|
},
|
|
30
35
|
"main": "./dist/index.cjs.js",
|
|
31
36
|
"types": "./dist/index.d.ts",
|
|
32
37
|
"typesVersions": {
|
|
33
38
|
"*": {
|
|
39
|
+
"alpha": [
|
|
40
|
+
"dist/alpha.d.ts"
|
|
41
|
+
],
|
|
34
42
|
"package.json": [
|
|
35
43
|
"package.json"
|
|
36
44
|
]
|
|
@@ -49,14 +57,15 @@
|
|
|
49
57
|
"test": "backstage-cli package test"
|
|
50
58
|
},
|
|
51
59
|
"dependencies": {
|
|
52
|
-
"@backstage/backend-app-api": "1.2.4
|
|
53
|
-
"@backstage/backend-defaults": "0.
|
|
54
|
-
"@backstage/backend-plugin-api": "1.4.0
|
|
55
|
-
"@backstage/config": "1.3.2",
|
|
56
|
-
"@backstage/errors": "1.2.7",
|
|
57
|
-
"@backstage/plugin-auth-node": "0.6.4
|
|
58
|
-
"@backstage/plugin-events-node": "0.4.12
|
|
59
|
-
"@backstage/
|
|
60
|
+
"@backstage/backend-app-api": "^1.2.4",
|
|
61
|
+
"@backstage/backend-defaults": "^0.11.0",
|
|
62
|
+
"@backstage/backend-plugin-api": "^1.4.0",
|
|
63
|
+
"@backstage/config": "^1.3.2",
|
|
64
|
+
"@backstage/errors": "^1.2.7",
|
|
65
|
+
"@backstage/plugin-auth-node": "^0.6.4",
|
|
66
|
+
"@backstage/plugin-events-node": "^0.4.12",
|
|
67
|
+
"@backstage/plugin-permission-common": "^0.9.0",
|
|
68
|
+
"@backstage/types": "^1.2.1",
|
|
60
69
|
"@keyv/memcache": "^2.0.1",
|
|
61
70
|
"@keyv/redis": "^4.0.1",
|
|
62
71
|
"@keyv/valkey": "^1.0.1",
|
|
@@ -76,10 +85,12 @@
|
|
|
76
85
|
"testcontainers": "^10.0.0",
|
|
77
86
|
"textextensions": "^5.16.0",
|
|
78
87
|
"uuid": "^11.0.0",
|
|
79
|
-
"yn": "^4.0.0"
|
|
88
|
+
"yn": "^4.0.0",
|
|
89
|
+
"zod": "^3.22.4",
|
|
90
|
+
"zod-to-json-schema": "^3.20.4"
|
|
80
91
|
},
|
|
81
92
|
"devDependencies": {
|
|
82
|
-
"@backstage/cli": "0.
|
|
93
|
+
"@backstage/cli": "^0.33.0",
|
|
83
94
|
"@types/jest": "*",
|
|
84
95
|
"@types/supertest": "^2.0.8",
|
|
85
96
|
"supertest": "^7.0.0"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MockAuthService.cjs.js","sources":["../../../src/next/services/MockAuthService.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n BackstageCredentials,\n BackstageServicePrincipal,\n BackstagePrincipalTypes,\n BackstageUserPrincipal,\n BackstageNonePrincipal,\n AuthService,\n} from '@backstage/backend-plugin-api';\nimport { AuthenticationError } from '@backstage/errors';\nimport {\n mockCredentials,\n MOCK_USER_TOKEN,\n MOCK_USER_TOKEN_PREFIX,\n MOCK_INVALID_USER_TOKEN,\n MOCK_USER_LIMITED_TOKEN_PREFIX,\n MOCK_INVALID_USER_LIMITED_TOKEN,\n MOCK_SERVICE_TOKEN,\n MOCK_SERVICE_TOKEN_PREFIX,\n MOCK_INVALID_SERVICE_TOKEN,\n UserTokenPayload,\n ServiceTokenPayload,\n} from './mockCredentials';\nimport { JsonObject } from '@backstage/types';\n\n/** @internal */\nexport class MockAuthService implements AuthService {\n readonly pluginId: string;\n readonly disableDefaultAuthPolicy: boolean;\n\n constructor(options: {\n pluginId: string;\n disableDefaultAuthPolicy: boolean;\n }) {\n this.pluginId = options.pluginId;\n this.disableDefaultAuthPolicy = options.disableDefaultAuthPolicy;\n }\n\n async authenticate(\n token: string,\n options?: { allowLimitedAccess?: boolean },\n ): Promise<BackstageCredentials> {\n switch (token) {\n case MOCK_USER_TOKEN:\n return mockCredentials.user();\n case MOCK_SERVICE_TOKEN:\n return mockCredentials.service();\n case MOCK_INVALID_USER_TOKEN:\n throw new AuthenticationError('User token is invalid');\n case MOCK_INVALID_USER_LIMITED_TOKEN:\n throw new AuthenticationError('Limited user token is invalid');\n case MOCK_INVALID_SERVICE_TOKEN:\n throw new AuthenticationError('Service token is invalid');\n case '':\n throw new AuthenticationError('Token is empty');\n default:\n break;\n }\n\n if (token.startsWith(MOCK_USER_TOKEN_PREFIX)) {\n const { sub: userEntityRef, actor }: UserTokenPayload = JSON.parse(\n token.slice(MOCK_USER_TOKEN_PREFIX.length),\n );\n\n return mockCredentials.user(userEntityRef, { actor });\n }\n\n if (token.startsWith(MOCK_USER_LIMITED_TOKEN_PREFIX)) {\n if (!options?.allowLimitedAccess) {\n throw new AuthenticationError('Limited user token is not allowed');\n }\n\n const { sub: userEntityRef }: UserTokenPayload = JSON.parse(\n token.slice(MOCK_USER_LIMITED_TOKEN_PREFIX.length),\n );\n\n return mockCredentials.user(userEntityRef);\n }\n\n if (token.startsWith(MOCK_SERVICE_TOKEN_PREFIX)) {\n const { sub, target, obo }: ServiceTokenPayload = JSON.parse(\n token.slice(MOCK_SERVICE_TOKEN_PREFIX.length),\n );\n\n if (target && target !== this.pluginId) {\n throw new AuthenticationError(\n `Invalid mock token target plugin ID, got '${target}' but expected '${this.pluginId}'`,\n );\n }\n if (obo) {\n return mockCredentials.user(obo);\n }\n\n return mockCredentials.service(sub);\n }\n\n throw new AuthenticationError(`Unknown mock token '${token}'`);\n }\n\n async getNoneCredentials() {\n return mockCredentials.none();\n }\n\n async getOwnServiceCredentials(): Promise<\n BackstageCredentials<BackstageServicePrincipal>\n > {\n return mockCredentials.service(`plugin:${this.pluginId}`);\n }\n\n isPrincipal<TType extends keyof BackstagePrincipalTypes>(\n credentials: BackstageCredentials,\n type: TType,\n ): credentials is BackstageCredentials<BackstagePrincipalTypes[TType]> {\n const principal = credentials.principal as\n | BackstageUserPrincipal\n | BackstageServicePrincipal\n | BackstageNonePrincipal;\n\n if (type === 'unknown') {\n return true;\n }\n\n if (principal.type !== type) {\n return false;\n }\n\n return true;\n }\n\n async getPluginRequestToken(options: {\n onBehalfOf: BackstageCredentials;\n targetPluginId: string;\n }): Promise<{ token: string }> {\n const principal = options.onBehalfOf.principal as\n | BackstageUserPrincipal\n | BackstageServicePrincipal\n | BackstageNonePrincipal;\n\n if (principal.type === 'none' && this.disableDefaultAuthPolicy) {\n return { token: '' };\n }\n\n if (principal.type !== 'user' && principal.type !== 'service') {\n throw new AuthenticationError(\n `Refused to issue service token for credential type '${principal.type}'`,\n );\n }\n\n return {\n token: mockCredentials.service.token({\n onBehalfOf: options.onBehalfOf,\n targetPluginId: options.targetPluginId,\n }),\n };\n }\n\n async getLimitedUserToken(\n credentials: BackstageCredentials<BackstageUserPrincipal>,\n ): Promise<{ token: string; expiresAt: Date }> {\n if (credentials.principal.type !== 'user') {\n throw new AuthenticationError(\n `Refused to issue limited user token for credential type '${credentials.principal.type}'`,\n );\n }\n\n return {\n token: mockCredentials.limitedUser.token(\n credentials.principal.userEntityRef,\n ),\n expiresAt: new Date(Date.now() + 3600_000),\n };\n }\n\n listPublicServiceKeys(): Promise<{ keys: JsonObject[] }> {\n throw new Error('Not implemented');\n }\n}\n"],"names":["MOCK_USER_TOKEN","mockCredentials","MOCK_SERVICE_TOKEN","MOCK_INVALID_USER_TOKEN","AuthenticationError","MOCK_INVALID_USER_LIMITED_TOKEN","MOCK_INVALID_SERVICE_TOKEN","MOCK_USER_TOKEN_PREFIX","MOCK_USER_LIMITED_TOKEN_PREFIX","MOCK_SERVICE_TOKEN_PREFIX"],"mappings":";;;;;AAyCO,MAAM,eAAuC,CAAA;AAAA,EACzC,QAAA;AAAA,EACA,wBAAA;AAAA,EAET,YAAY,OAGT,EAAA;AACD,IAAA,IAAA,CAAK,WAAW,OAAQ,CAAA,QAAA;AACxB,IAAA,IAAA,CAAK,2BAA2B,OAAQ,CAAA,wBAAA;AAAA;AAC1C,EAEA,MAAM,YACJ,CAAA,KAAA,EACA,OAC+B,EAAA;AAC/B,IAAA,QAAQ,KAAO;AAAA,MACb,KAAKA,+BAAA;AACH,QAAA,OAAOC,gCAAgB,IAAK,EAAA;AAAA,MAC9B,KAAKC,kCAAA;AACH,QAAA,OAAOD,gCAAgB,OAAQ,EAAA;AAAA,MACjC,KAAKE,uCAAA;AACH,QAAM,MAAA,IAAIC,2BAAoB,uBAAuB,CAAA;AAAA,MACvD,KAAKC,+CAAA;AACH,QAAM,MAAA,IAAID,2BAAoB,+BAA+B,CAAA;AAAA,MAC/D,KAAKE,0CAAA;AACH,QAAM,MAAA,IAAIF,2BAAoB,0BAA0B,CAAA;AAAA,MAC1D,KAAK,EAAA;AACH,QAAM,MAAA,IAAIA,2BAAoB,gBAAgB,CAAA;AAE9C;AAGJ,IAAI,IAAA,KAAA,CAAM,UAAW,CAAAG,sCAAsB,CAAG,EAAA;AAC5C,MAAA,MAAM,EAAE,GAAA,EAAK,aAAe,EAAA,KAAA,KAA4B,IAAK,CAAA,KAAA;AAAA,QAC3D,KAAA,CAAM,KAAM,CAAAA,sCAAA,CAAuB,MAAM;AAAA,OAC3C;AAEA,MAAA,OAAON,+BAAgB,CAAA,IAAA,CAAK,aAAe,EAAA,EAAE,OAAO,CAAA;AAAA;AAGtD,IAAI,IAAA,KAAA,CAAM,UAAW,CAAAO,8CAA8B,CAAG,EAAA;AACpD,MAAI,IAAA,CAAC,SAAS,kBAAoB,EAAA;AAChC,QAAM,MAAA,IAAIJ,2BAAoB,mCAAmC,CAAA;AAAA;AAGnE,MAAA,MAAM,EAAE,GAAA,EAAK,aAAc,EAAA,GAAsB,IAAK,CAAA,KAAA;AAAA,QACpD,KAAA,CAAM,KAAM,CAAAI,8CAAA,CAA+B,MAAM;AAAA,OACnD;AAEA,MAAO,OAAAP,+BAAA,CAAgB,KAAK,aAAa,CAAA;AAAA;AAG3C,IAAI,IAAA,KAAA,CAAM,UAAW,CAAAQ,yCAAyB,CAAG,EAAA;AAC/C,MAAA,MAAM,EAAE,GAAA,EAAK,MAAQ,EAAA,GAAA,KAA6B,IAAK,CAAA,KAAA;AAAA,QACrD,KAAA,CAAM,KAAM,CAAAA,yCAAA,CAA0B,MAAM;AAAA,OAC9C;AAEA,MAAI,IAAA,MAAA,IAAU,MAAW,KAAA,IAAA,CAAK,QAAU,EAAA;AACtC,QAAA,MAAM,IAAIL,0BAAA;AAAA,UACR,CAA6C,0CAAA,EAAA,MAAM,CAAmB,gBAAA,EAAA,IAAA,CAAK,QAAQ,CAAA,CAAA;AAAA,SACrF;AAAA;AAEF,MAAA,IAAI,GAAK,EAAA;AACP,QAAO,OAAAH,+BAAA,CAAgB,KAAK,GAAG,CAAA;AAAA;AAGjC,MAAO,OAAAA,+BAAA,CAAgB,QAAQ,GAAG,CAAA;AAAA;AAGpC,IAAA,MAAM,IAAIG,0BAAA,CAAoB,CAAuB,oBAAA,EAAA,KAAK,CAAG,CAAA,CAAA,CAAA;AAAA;AAC/D,EAEA,MAAM,kBAAqB,GAAA;AACzB,IAAA,OAAOH,gCAAgB,IAAK,EAAA;AAAA;AAC9B,EAEA,MAAM,wBAEJ,GAAA;AACA,IAAA,OAAOA,+BAAgB,CAAA,OAAA,CAAQ,CAAU,OAAA,EAAA,IAAA,CAAK,QAAQ,CAAE,CAAA,CAAA;AAAA;AAC1D,EAEA,WAAA,CACE,aACA,IACqE,EAAA;AACrE,IAAA,MAAM,YAAY,WAAY,CAAA,SAAA;AAK9B,IAAA,IAAI,SAAS,SAAW,EAAA;AACtB,MAAO,OAAA,IAAA;AAAA;AAGT,IAAI,IAAA,SAAA,CAAU,SAAS,IAAM,EAAA;AAC3B,MAAO,OAAA,KAAA;AAAA;AAGT,IAAO,OAAA,IAAA;AAAA;AACT,EAEA,MAAM,sBAAsB,OAGG,EAAA;AAC7B,IAAM,MAAA,SAAA,GAAY,QAAQ,UAAW,CAAA,SAAA;AAKrC,IAAA,IAAI,SAAU,CAAA,IAAA,KAAS,MAAU,IAAA,IAAA,CAAK,wBAA0B,EAAA;AAC9D,MAAO,OAAA,EAAE,OAAO,EAAG,EAAA;AAAA;AAGrB,IAAA,IAAI,SAAU,CAAA,IAAA,KAAS,MAAU,IAAA,SAAA,CAAU,SAAS,SAAW,EAAA;AAC7D,MAAA,MAAM,IAAIG,0BAAA;AAAA,QACR,CAAA,oDAAA,EAAuD,UAAU,IAAI,CAAA,CAAA;AAAA,OACvE;AAAA;AAGF,IAAO,OAAA;AAAA,MACL,KAAA,EAAOH,+BAAgB,CAAA,OAAA,CAAQ,KAAM,CAAA;AAAA,QACnC,YAAY,OAAQ,CAAA,UAAA;AAAA,QACpB,gBAAgB,OAAQ,CAAA;AAAA,OACzB;AAAA,KACH;AAAA;AACF,EAEA,MAAM,oBACJ,WAC6C,EAAA;AAC7C,IAAI,IAAA,WAAA,CAAY,SAAU,CAAA,IAAA,KAAS,MAAQ,EAAA;AACzC,MAAA,MAAM,IAAIG,0BAAA;AAAA,QACR,CAAA,yDAAA,EAA4D,WAAY,CAAA,SAAA,CAAU,IAAI,CAAA,CAAA;AAAA,OACxF;AAAA;AAGF,IAAO,OAAA;AAAA,MACL,KAAA,EAAOH,gCAAgB,WAAY,CAAA,KAAA;AAAA,QACjC,YAAY,SAAU,CAAA;AAAA,OACxB;AAAA,MACA,WAAW,IAAI,IAAA,CAAK,IAAK,CAAA,GAAA,KAAQ,IAAQ;AAAA,KAC3C;AAAA;AACF,EAEA,qBAAyD,GAAA;AACvD,IAAM,MAAA,IAAI,MAAM,iBAAiB,CAAA;AAAA;AAErC;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MockEventsService.cjs.js","sources":["../../../src/next/services/MockEventsService.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n EventParams,\n EventsService,\n EventsServiceSubscribeOptions,\n} from '@backstage/plugin-events-node';\n\nexport class MockEventsService implements EventsService {\n #subscribers: EventsServiceSubscribeOptions[];\n\n constructor() {\n this.#subscribers = [];\n }\n\n async publish(params: EventParams): Promise<void> {\n for (const subscriber of this.#subscribers) {\n if (subscriber.topics.includes(params.topic)) {\n await subscriber.onEvent(params);\n }\n }\n }\n\n async subscribe(options: EventsServiceSubscribeOptions): Promise<void> {\n this.#subscribers.push(options);\n }\n}\n"],"names":[],"mappings":";;AAsBO,MAAM,iBAA2C,CAAA;AAAA,EACtD,YAAA;AAAA,EAEA,WAAc,GAAA;AACZ,IAAA,IAAA,CAAK,eAAe,EAAC;AAAA;AACvB,EAEA,MAAM,QAAQ,MAAoC,EAAA;AAChD,IAAW,KAAA,MAAA,UAAA,IAAc,KAAK,YAAc,EAAA;AAC1C,MAAA,IAAI,UAAW,CAAA,MAAA,CAAO,QAAS,CAAA,MAAA,CAAO,KAAK,CAAG,EAAA;AAC5C,QAAM,MAAA,UAAA,CAAW,QAAQ,MAAM,CAAA;AAAA;AACjC;AACF;AACF,EAEA,MAAM,UAAU,OAAuD,EAAA;AACrE,IAAK,IAAA,CAAA,YAAA,CAAa,KAAK,OAAO,CAAA;AAAA;AAElC;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MockHttpAuthService.cjs.js","sources":["../../../src/next/services/MockHttpAuthService.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AuthService,\n BackstageCredentials,\n BackstagePrincipalTypes,\n BackstageUserPrincipal,\n HttpAuthService,\n} from '@backstage/backend-plugin-api';\nimport { Request, Response } from 'express';\nimport { parse as parseCookie } from 'cookie';\nimport { MockAuthService } from './MockAuthService';\nimport { AuthenticationError, NotAllowedError } from '@backstage/errors';\nimport {\n MOCK_NONE_TOKEN,\n MOCK_AUTH_COOKIE,\n mockCredentials,\n} from './mockCredentials';\n\n// TODO: support mock cookie auth?\nexport class MockHttpAuthService implements HttpAuthService {\n #auth: AuthService;\n #defaultCredentials: BackstageCredentials;\n\n constructor(pluginId: string, defaultCredentials: BackstageCredentials) {\n this.#auth = new MockAuthService({\n pluginId,\n disableDefaultAuthPolicy: false,\n });\n this.#defaultCredentials = defaultCredentials;\n }\n\n async #getCredentials(req: Request, allowLimitedAccess: boolean) {\n const header = req.headers.authorization;\n const token =\n typeof header === 'string'\n ? header.match(/^Bearer[ ]+(\\S+)$/i)?.[1]\n : undefined;\n\n if (token) {\n if (token === MOCK_NONE_TOKEN) {\n return this.#auth.getNoneCredentials();\n }\n\n return await this.#auth.authenticate(token, {\n allowLimitedAccess,\n });\n }\n\n if (allowLimitedAccess) {\n const cookieHeader = req.headers.cookie;\n\n if (cookieHeader) {\n const cookies = parseCookie(cookieHeader);\n const cookie = cookies[MOCK_AUTH_COOKIE];\n\n if (cookie) {\n return await this.#auth.authenticate(cookie, {\n allowLimitedAccess: true,\n });\n }\n }\n }\n\n return this.#defaultCredentials;\n }\n\n async credentials<TAllowed extends keyof BackstagePrincipalTypes = 'unknown'>(\n req: Request,\n options?: {\n allow?: Array<TAllowed>;\n allowLimitedAccess?: boolean;\n },\n ): Promise<BackstageCredentials<BackstagePrincipalTypes[TAllowed]>> {\n const credentials = await this.#getCredentials(\n req,\n options?.allowLimitedAccess ?? false,\n );\n\n const allowedPrincipalTypes = options?.allow;\n if (!allowedPrincipalTypes) {\n return credentials as any;\n }\n\n if (this.#auth.isPrincipal(credentials, 'none')) {\n if (allowedPrincipalTypes.includes('none' as TAllowed)) {\n return credentials as any;\n }\n\n throw new AuthenticationError('Missing credentials');\n } else if (this.#auth.isPrincipal(credentials, 'user')) {\n if (allowedPrincipalTypes.includes('user' as TAllowed)) {\n return credentials as any;\n }\n\n throw new NotAllowedError(\n `This endpoint does not allow 'user' credentials`,\n );\n } else if (this.#auth.isPrincipal(credentials, 'service')) {\n if (allowedPrincipalTypes.includes('service' as TAllowed)) {\n return credentials as any;\n }\n\n throw new NotAllowedError(\n `This endpoint does not allow 'service' credentials`,\n );\n }\n\n throw new NotAllowedError(\n 'Unknown principal type, this should never happen',\n );\n }\n\n async issueUserCookie(\n res: Response,\n options?: { credentials?: BackstageCredentials<BackstageUserPrincipal> },\n ): Promise<{ expiresAt: Date }> {\n const credentials =\n options?.credentials ??\n (await this.credentials(res.req, { allow: ['user'] }));\n\n res.setHeader(\n 'Set-Cookie',\n mockCredentials.limitedUser.cookie(credentials.principal.userEntityRef),\n );\n\n return { expiresAt: new Date(Date.now() + 3600_000) };\n }\n}\n"],"names":["MockAuthService","MOCK_NONE_TOKEN","parseCookie","cookie","MOCK_AUTH_COOKIE","AuthenticationError","NotAllowedError","mockCredentials"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MockRootLoggerService.cjs.js","sources":["../../../src/next/services/MockRootLoggerService.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n LoggerService,\n RootLoggerService,\n} from '@backstage/backend-plugin-api';\nimport { JsonObject } from '@backstage/types';\nimport type { mockServices } from './mockServices';\n\nconst levels = {\n none: 0,\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n};\n\nexport class MockRootLoggerService implements RootLoggerService {\n #level: number;\n #meta: JsonObject;\n\n static create(\n options?: mockServices.rootLogger.Options,\n ): MockRootLoggerService {\n const level = options?.level ?? 'none';\n if (!(level in levels)) {\n throw new Error(`Invalid log level '${level}'`);\n }\n return new MockRootLoggerService(levels[level], {});\n }\n\n error(message: string, meta?: JsonObject | Error | undefined): void {\n this.#log('error', message, meta);\n }\n\n warn(message: string, meta?: JsonObject | Error | undefined): void {\n this.#log('warn', message, meta);\n }\n\n info(message: string, meta?: JsonObject | Error | undefined): void {\n this.#log('info', message, meta);\n }\n\n debug(message: string, meta?: JsonObject | Error | undefined): void {\n this.#log('debug', message, meta);\n }\n\n child(meta: JsonObject): LoggerService {\n return new MockRootLoggerService(this.#level, { ...this.#meta, ...meta });\n }\n\n private constructor(level: number, meta: JsonObject) {\n this.#level = level;\n this.#meta = meta;\n }\n\n #log(\n level: 'error' | 'warn' | 'info' | 'debug',\n message: string,\n meta?: JsonObject | Error | undefined,\n ) {\n const levelValue = levels[level] ?? 0;\n if (levelValue <= this.#level) {\n const labels = Object.entries(this.#meta)\n .map(([key, value]) => `${key}=${value}`)\n .join(',');\n console[level](`${labels} ${message}`, meta);\n }\n }\n}\n"],"names":[],"mappings":";;AAuBA,MAAM,MAAS,GAAA;AAAA,EACb,IAAM,EAAA,CAAA;AAAA,EACN,KAAO,EAAA,CAAA;AAAA,EACP,IAAM,EAAA,CAAA;AAAA,EACN,IAAM,EAAA,CAAA;AAAA,EACN,KAAO,EAAA;AACT,CAAA;AAEO,MAAM,qBAAmD,CAAA;AAAA,EAC9D,MAAA;AAAA,EACA,KAAA;AAAA,EAEA,OAAO,OACL,OACuB,EAAA;AACvB,IAAM,MAAA,KAAA,GAAQ,SAAS,KAAS,IAAA,MAAA;AAChC,IAAI,IAAA,EAAE,SAAS,MAAS,CAAA,EAAA;AACtB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAsB,mBAAA,EAAA,KAAK,CAAG,CAAA,CAAA,CAAA;AAAA;AAEhD,IAAA,OAAO,IAAI,qBAAsB,CAAA,MAAA,CAAO,KAAK,CAAA,EAAG,EAAE,CAAA;AAAA;AACpD,EAEA,KAAA,CAAM,SAAiB,IAA6C,EAAA;AAClE,IAAK,IAAA,CAAA,IAAA,CAAK,OAAS,EAAA,OAAA,EAAS,IAAI,CAAA;AAAA;AAClC,EAEA,IAAA,CAAK,SAAiB,IAA6C,EAAA;AACjE,IAAK,IAAA,CAAA,IAAA,CAAK,MAAQ,EAAA,OAAA,EAAS,IAAI,CAAA;AAAA;AACjC,EAEA,IAAA,CAAK,SAAiB,IAA6C,EAAA;AACjE,IAAK,IAAA,CAAA,IAAA,CAAK,MAAQ,EAAA,OAAA,EAAS,IAAI,CAAA;AAAA;AACjC,EAEA,KAAA,CAAM,SAAiB,IAA6C,EAAA;AAClE,IAAK,IAAA,CAAA,IAAA,CAAK,OAAS,EAAA,OAAA,EAAS,IAAI,CAAA;AAAA;AAClC,EAEA,MAAM,IAAiC,EAAA;AACrC,IAAO,OAAA,IAAI,qBAAsB,CAAA,IAAA,CAAK,MAAQ,EAAA,EAAE,GAAG,IAAK,CAAA,KAAA,EAAO,GAAG,IAAA,EAAM,CAAA;AAAA;AAC1E,EAEQ,WAAA,CAAY,OAAe,IAAkB,EAAA;AACnD,IAAA,IAAA,CAAK,MAAS,GAAA,KAAA;AACd,IAAA,IAAA,CAAK,KAAQ,GAAA,IAAA;AAAA;AACf,EAEA,IAAA,CACE,KACA,EAAA,OAAA,EACA,IACA,EAAA;AACA,IAAM,MAAA,UAAA,GAAa,MAAO,CAAA,KAAK,CAAK,IAAA,CAAA;AACpC,IAAI,IAAA,UAAA,IAAc,KAAK,MAAQ,EAAA;AAC7B,MAAA,MAAM,SAAS,MAAO,CAAA,OAAA,CAAQ,KAAK,KAAK,CAAA,CACrC,IAAI,CAAC,CAAC,KAAK,KAAK,CAAA,KAAM,GAAG,GAAG,CAAA,CAAA,EAAI,KAAK,CAAE,CAAA,CAAA,CACvC,KAAK,GAAG,CAAA;AACX,MAAA,OAAA,CAAQ,KAAK,CAAE,CAAA,CAAA,EAAG,MAAM,CAAI,CAAA,EAAA,OAAO,IAAI,IAAI,CAAA;AAAA;AAC7C;AAEJ;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MockUserInfoService.cjs.js","sources":["../../../src/next/services/MockUserInfoService.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n BackstageCredentials,\n BackstageNonePrincipal,\n BackstageServicePrincipal,\n BackstageUserInfo,\n BackstageUserPrincipal,\n UserInfoService,\n} from '@backstage/backend-plugin-api';\nimport { InputError } from '@backstage/errors';\n\n/** @internal */\nexport class MockUserInfoService implements UserInfoService {\n private readonly customInfo: Partial<BackstageUserInfo>;\n\n constructor(customInfo?: Partial<BackstageUserInfo>) {\n this.customInfo = customInfo ?? {};\n }\n\n async getUserInfo(\n credentials: BackstageCredentials,\n ): Promise<BackstageUserInfo> {\n const principal = credentials.principal as\n | BackstageUserPrincipal\n | BackstageServicePrincipal\n | BackstageNonePrincipal;\n\n if (principal.type !== 'user') {\n throw new InputError(\n `User info not available for principal type '${principal.type}'`,\n );\n }\n\n return {\n userEntityRef: principal.userEntityRef,\n ownershipEntityRefs: [principal.userEntityRef],\n ...this.customInfo,\n };\n }\n}\n"],"names":["InputError"],"mappings":";;;;AA2BO,MAAM,mBAA+C,CAAA;AAAA,EACzC,UAAA;AAAA,EAEjB,YAAY,UAAyC,EAAA;AACnD,IAAK,IAAA,CAAA,UAAA,GAAa,cAAc,EAAC;AAAA;AACnC,EAEA,MAAM,YACJ,WAC4B,EAAA;AAC5B,IAAA,MAAM,YAAY,WAAY,CAAA,SAAA;AAK9B,IAAI,IAAA,SAAA,CAAU,SAAS,MAAQ,EAAA;AAC7B,MAAA,MAAM,IAAIA,iBAAA;AAAA,QACR,CAAA,4CAAA,EAA+C,UAAU,IAAI,CAAA,CAAA;AAAA,OAC/D;AAAA;AAGF,IAAO,OAAA;AAAA,MACL,eAAe,SAAU,CAAA,aAAA;AAAA,MACzB,mBAAA,EAAqB,CAAC,SAAA,CAAU,aAAa,CAAA;AAAA,MAC7C,GAAG,IAAK,CAAA;AAAA,KACV;AAAA;AAEJ;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mockCredentials.cjs.js","sources":["../../../src/next/services/mockCredentials.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n BackstageCredentials,\n BackstageNonePrincipal,\n BackstagePrincipalAccessRestrictions,\n BackstageServicePrincipal,\n BackstageUserPrincipal,\n} from '@backstage/backend-plugin-api';\n\nexport const DEFAULT_MOCK_USER_ENTITY_REF = 'user:default/mock';\nexport const DEFAULT_MOCK_SERVICE_SUBJECT = 'external:test-service';\n\nexport const MOCK_AUTH_COOKIE = 'backstage-auth';\n\nexport const MOCK_NONE_TOKEN = 'mock-none-token';\n\nexport const MOCK_USER_TOKEN = 'mock-user-token';\nexport const MOCK_USER_TOKEN_PREFIX = 'mock-user-token:';\nexport const MOCK_INVALID_USER_TOKEN = 'mock-invalid-user-token';\n\nexport const MOCK_USER_LIMITED_TOKEN_PREFIX = 'mock-limited-user-token:';\nexport const MOCK_INVALID_USER_LIMITED_TOKEN =\n 'mock-invalid-limited-user-token';\n\nexport const MOCK_SERVICE_TOKEN = 'mock-service-token';\nexport const MOCK_SERVICE_TOKEN_PREFIX = 'mock-service-token:';\nexport const MOCK_INVALID_SERVICE_TOKEN = 'mock-invalid-service-token';\n\nfunction validateUserEntityRef(ref: string) {\n if (!ref.match(/^.+:.+\\/.+$/)) {\n throw new TypeError(\n `Invalid user entity reference '${ref}', expected <kind>:<namespace>/<name>`,\n );\n }\n}\n\n/**\n * The payload that can be encoded into a mock user token.\n * @internal\n */\nexport type UserTokenPayload = {\n sub?: string;\n actor?: { subject: string };\n};\n\n/**\n * The payload that can be encoded into a mock service token.\n * @internal\n */\nexport type ServiceTokenPayload = {\n sub?: string; // service subject\n obo?: string; // user entity reference\n target?: string; // target plugin id\n};\n\n/**\n * @public\n */\nexport namespace mockCredentials {\n /**\n * Creates a mocked credentials object for a unauthenticated principal.\n */\n export function none(): BackstageCredentials<BackstageNonePrincipal> {\n return {\n $$type: '@backstage/BackstageCredentials',\n principal: { type: 'none' },\n };\n }\n\n /**\n * Utilities related to none credentials.\n */\n export namespace none {\n /**\n * Returns an authorization header that translates to unauthenticated\n * credentials.\n *\n * This is useful when one wants to explicitly test unauthenticated requests\n * while still using the default behavior of the mock HttpAuthService where\n * it defaults to user credentials.\n */\n export function header(): string {\n // NOTE: there is no .token() version of this because only the\n // HttpAuthService should know about and consume this token\n return `Bearer ${MOCK_NONE_TOKEN}`;\n }\n }\n\n /**\n * Creates a mocked credentials object for a user principal.\n *\n * The default user entity reference is 'user:default/mock'.\n */\n export function user(\n userEntityRef: string = DEFAULT_MOCK_USER_ENTITY_REF,\n options?: { actor?: { subject: string } },\n ): BackstageCredentials<BackstageUserPrincipal> {\n validateUserEntityRef(userEntityRef);\n return {\n $$type: '@backstage/BackstageCredentials',\n principal: {\n type: 'user',\n userEntityRef,\n ...(options?.actor && {\n actor: { type: 'service', subject: options.actor.subject },\n }),\n },\n };\n }\n\n /**\n * Utilities related to user credentials.\n */\n export namespace user {\n /**\n * Creates a mocked user token. If a payload is provided it will be encoded\n * into the token and forwarded to the credentials object when authenticated\n * by the mock auth service.\n */\n export function token(\n userEntityRef?: string,\n options?: { actor?: { subject: string } },\n ): string {\n if (userEntityRef) {\n validateUserEntityRef(userEntityRef);\n return `${MOCK_USER_TOKEN_PREFIX}${JSON.stringify({\n sub: userEntityRef,\n ...(options?.actor && {\n actor: { subject: options.actor.subject },\n }),\n } satisfies UserTokenPayload)}`;\n }\n return MOCK_USER_TOKEN;\n }\n\n /**\n * Returns an authorization header with a mocked user token. If a payload is\n * provided it will be encoded into the token and forwarded to the\n * credentials object when authenticated by the mock auth service.\n */\n export function header(userEntityRef?: string): string {\n return `Bearer ${token(userEntityRef)}`;\n }\n\n export function invalidToken(): string {\n return MOCK_INVALID_USER_TOKEN;\n }\n\n export function invalidHeader(): string {\n return `Bearer ${invalidToken()}`;\n }\n }\n\n /**\n * Creates a mocked credentials object for a user principal with limited\n * access.\n *\n * The default user entity reference is 'user:default/mock'.\n */\n export function limitedUser(\n userEntityRef: string = DEFAULT_MOCK_USER_ENTITY_REF,\n ): BackstageCredentials<BackstageUserPrincipal> {\n return user(userEntityRef);\n }\n\n /**\n * Utilities related to limited user credentials.\n */\n export namespace limitedUser {\n /**\n * Creates a mocked limited user token. If a payload is provided it will be\n * encoded into the token and forwarded to the credentials object when\n * authenticated by the mock auth service.\n */\n export function token(\n userEntityRef: string = DEFAULT_MOCK_USER_ENTITY_REF,\n ): string {\n validateUserEntityRef(userEntityRef);\n return `${MOCK_USER_LIMITED_TOKEN_PREFIX}${JSON.stringify({\n sub: userEntityRef,\n } satisfies UserTokenPayload)}`;\n }\n\n /**\n * Returns an authorization header with a mocked limited user token. If a\n * payload is provided it will be encoded into the token and forwarded to\n * the credentials object when authenticated by the mock auth service.\n */\n export function cookie(userEntityRef?: string): string {\n return `${MOCK_AUTH_COOKIE}=${token(userEntityRef)}`;\n }\n\n export function invalidToken(): string {\n return MOCK_INVALID_USER_LIMITED_TOKEN;\n }\n\n export function invalidCookie(): string {\n return `${MOCK_AUTH_COOKIE}=${invalidToken()}`;\n }\n }\n\n /**\n * Creates a mocked credentials object for a service principal.\n *\n * The default subject is 'external:test-service', and no access restrictions.\n */\n export function service(\n subject: string = DEFAULT_MOCK_SERVICE_SUBJECT,\n accessRestrictions?: BackstagePrincipalAccessRestrictions,\n ): BackstageCredentials<BackstageServicePrincipal> {\n return {\n $$type: '@backstage/BackstageCredentials',\n principal: {\n type: 'service',\n subject,\n ...(accessRestrictions ? { accessRestrictions } : {}),\n },\n };\n }\n\n /**\n * Utilities related to service credentials.\n */\n export namespace service {\n /**\n * Options for the creation of mock service tokens.\n */\n export type TokenOptions = {\n onBehalfOf: BackstageCredentials;\n targetPluginId: string;\n };\n\n /**\n * Creates a mocked service token. The provided options will be encoded into\n * the token and forwarded to the credentials object when authenticated by\n * the mock auth service.\n */\n export function token(options?: TokenOptions): string {\n if (options) {\n const { targetPluginId, onBehalfOf } = options; // for fixed ordering\n\n const oboPrincipal = onBehalfOf?.principal as\n | BackstageServicePrincipal\n | BackstageUserPrincipal\n | BackstageNonePrincipal;\n const obo =\n oboPrincipal.type === 'user' ? oboPrincipal.userEntityRef : undefined;\n const subject =\n oboPrincipal.type === 'service' ? oboPrincipal.subject : undefined;\n\n return `${MOCK_SERVICE_TOKEN_PREFIX}${JSON.stringify({\n sub: subject,\n obo,\n target: targetPluginId,\n } satisfies ServiceTokenPayload)}`;\n }\n return MOCK_SERVICE_TOKEN;\n }\n\n /**\n * Returns an authorization header with a mocked service token. The provided\n * options will be encoded into the token and forwarded to the credentials\n * object when authenticated by the mock auth service.\n */\n export function header(options?: TokenOptions): string {\n return `Bearer ${token(options)}`;\n }\n\n export function invalidToken(): string {\n return MOCK_INVALID_SERVICE_TOKEN;\n }\n\n export function invalidHeader(): string {\n return `Bearer ${invalidToken()}`;\n }\n }\n}\n"],"names":["mockCredentials","none","user","limitedUser","service"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mockServices.cjs.js","sources":["../../../src/next/services/mockServices.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { auditorServiceFactory } from '@backstage/backend-defaults/auditor';\nimport { cacheServiceFactory } from '@backstage/backend-defaults/cache';\nimport { databaseServiceFactory } from '@backstage/backend-defaults/database';\nimport { HostDiscovery } from '@backstage/backend-defaults/discovery';\nimport { httpRouterServiceFactory } from '@backstage/backend-defaults/httpRouter';\nimport { lifecycleServiceFactory } from '@backstage/backend-defaults/lifecycle';\nimport { loggerServiceFactory } from '@backstage/backend-defaults/logger';\nimport { permissionsServiceFactory } from '@backstage/backend-defaults/permissions';\nimport { permissionsRegistryServiceFactory } from '@backstage/backend-defaults/permissionsRegistry';\nimport { rootHealthServiceFactory } from '@backstage/backend-defaults/rootHealth';\nimport { rootHttpRouterServiceFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport { rootLifecycleServiceFactory } from '@backstage/backend-defaults/rootLifecycle';\nimport { schedulerServiceFactory } from '@backstage/backend-defaults/scheduler';\nimport { urlReaderServiceFactory } from '@backstage/backend-defaults/urlReader';\nimport {\n AuthService,\n BackstageCredentials,\n BackstageUserInfo,\n DatabaseService,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n RootConfigService,\n ServiceFactory,\n ServiceRef,\n UserInfoService,\n coreServices,\n createServiceFactory,\n} from '@backstage/backend-plugin-api';\nimport { ConfigReader } from '@backstage/config';\nimport { EventsService, eventsServiceRef } from '@backstage/plugin-events-node';\nimport { JsonObject } from '@backstage/types';\nimport { Knex } from 'knex';\nimport { MockAuthService } from './MockAuthService';\nimport { MockHttpAuthService } from './MockHttpAuthService';\nimport { MockRootLoggerService } from './MockRootLoggerService';\nimport { MockUserInfoService } from './MockUserInfoService';\nimport { mockCredentials } from './mockCredentials';\nimport { MockEventsService } from './MockEventsService';\nimport { actionsServiceFactory } from '@backstage/backend-defaults/actions';\nimport { actionsRegistryServiceFactory } from '@backstage/backend-defaults/actionsRegistry';\n\n/** @internal */\nfunction createLoggerMock() {\n return {\n child: jest.fn().mockImplementation(createLoggerMock),\n debug: jest.fn(),\n error: jest.fn(),\n info: jest.fn(),\n warn: jest.fn(),\n };\n}\n\n/** @internal */\nfunction simpleFactoryWithOptions<\n TService,\n TScope extends 'root' | 'plugin',\n TOptions extends [options?: object] = [],\n>(\n ref: ServiceRef<TService, TScope>,\n factory: (...options: TOptions) => TService,\n): (...options: TOptions) => ServiceFactory<TService, TScope> {\n const factoryWithOptions = (...options: TOptions) =>\n createServiceFactory({\n service: ref as ServiceRef<TService, any>,\n deps: {},\n async factory() {\n return factory(...options);\n },\n });\n return Object.assign(\n factoryWithOptions,\n factoryWithOptions(...([undefined] as unknown as TOptions)),\n ) as ServiceFactory<TService, TScope> &\n ((...options: TOptions) => ServiceFactory<TService, TScope>);\n}\n\n/** @public */\nexport type ServiceMock<TService> = {\n factory: ServiceFactory<TService>;\n} & {\n [Key in keyof TService]: TService[Key] extends (\n ...args: infer Args\n ) => infer Return\n ? TService[Key] & jest.MockInstance<Return, Args>\n : TService[Key];\n};\n\n/** @internal */\nfunction simpleMock<TService>(\n ref: ServiceRef<TService, any>,\n mockFactory: () => jest.Mocked<TService>,\n): (partialImpl?: Partial<TService>) => ServiceMock<TService> {\n return partialImpl => {\n const mock = mockFactory();\n if (partialImpl) {\n for (const [key, impl] of Object.entries(partialImpl)) {\n if (typeof impl === 'function') {\n (mock as any)[key].mockImplementation(impl);\n } else {\n (mock as any)[key] = impl;\n }\n }\n }\n return Object.assign(mock, {\n factory: createServiceFactory({\n service: ref,\n deps: {},\n factory: () => mock,\n }),\n }) as ServiceMock<TService>;\n };\n}\n\n/**\n * Mock implementations of the core services, to be used in tests.\n *\n * @public\n * @remarks\n *\n * There are some variations among the services depending on what needs tests\n * might have, but overall there are three main usage patterns:\n *\n * 1. Creating an actual fake service instance, often with a simplified version\n * of functionality, by calling the mock service itself as a function.\n *\n * ```ts\n * // The function often accepts parameters that control its behavior\n * const foo = mockServices.foo();\n * ```\n *\n * 2. Creating a mock service, where all methods are replaced with jest mocks, by\n * calling the service's `mock` function.\n *\n * ```ts\n * // You can optionally supply a subset of its methods to implement\n * const foo = mockServices.foo.mock({\n * someMethod: () => 'mocked result',\n * });\n * // After exercising your test, you can make assertions on the mock:\n * expect(foo.someMethod).toHaveBeenCalledTimes(2);\n * expect(foo.otherMethod).toHaveBeenCalledWith(testData);\n * ```\n *\n * 3. Creating a service factory that behaves similarly to the mock as per above.\n *\n * ```ts\n * await startTestBackend({\n * features: [\n * mockServices.foo.factory({\n * someMethod: () => 'mocked result',\n * })\n * ],\n * });\n * ```\n */\nexport namespace mockServices {\n export function rootConfig(options?: rootConfig.Options): RootConfigService {\n return new ConfigReader(options?.data, 'mock-config');\n }\n export namespace rootConfig {\n export type Options = { data?: JsonObject };\n\n export const factory = simpleFactoryWithOptions(\n coreServices.rootConfig,\n rootConfig,\n );\n export const mock = simpleMock(coreServices.rootConfig, () => ({\n get: jest.fn(),\n getBoolean: jest.fn(),\n getConfig: jest.fn(),\n getConfigArray: jest.fn(),\n getNumber: jest.fn(),\n getOptional: jest.fn(),\n getOptionalBoolean: jest.fn(),\n getOptionalConfig: jest.fn(),\n getOptionalConfigArray: jest.fn(),\n getOptionalNumber: jest.fn(),\n getOptionalString: jest.fn(),\n getOptionalStringArray: jest.fn(),\n getString: jest.fn(),\n getStringArray: jest.fn(),\n has: jest.fn(),\n keys: jest.fn(),\n }));\n }\n\n export function rootLogger(options?: rootLogger.Options): LoggerService {\n return MockRootLoggerService.create(options);\n }\n export namespace rootLogger {\n export type Options = {\n level?: 'none' | 'error' | 'warn' | 'info' | 'debug';\n };\n\n export const factory = simpleFactoryWithOptions(\n coreServices.rootLogger,\n rootLogger,\n );\n export const mock = simpleMock(coreServices.rootLogger, () => ({\n child: jest.fn(),\n debug: jest.fn(),\n error: jest.fn(),\n info: jest.fn(),\n warn: jest.fn(),\n }));\n }\n\n export namespace auditor {\n export const factory = () => auditorServiceFactory;\n\n export const mock = simpleMock(coreServices.auditor, () => ({\n createEvent: jest.fn(async _ => {\n return {\n success: jest.fn(),\n fail: jest.fn(),\n };\n }),\n }));\n }\n\n export function auth(options?: {\n pluginId?: string;\n disableDefaultAuthPolicy?: boolean;\n }): AuthService {\n return new MockAuthService({\n pluginId: options?.pluginId ?? 'test',\n disableDefaultAuthPolicy: Boolean(options?.disableDefaultAuthPolicy),\n });\n }\n export namespace auth {\n export const factory = () =>\n createServiceFactory({\n service: coreServices.auth,\n deps: {\n plugin: coreServices.pluginMetadata,\n config: coreServices.rootConfig,\n },\n factory({ plugin, config }) {\n const disableDefaultAuthPolicy = Boolean(\n config.getOptionalBoolean(\n 'backend.auth.dangerouslyDisableDefaultAuthPolicy',\n ),\n );\n return new MockAuthService({\n pluginId: plugin.getId(),\n disableDefaultAuthPolicy,\n });\n },\n });\n export const mock = simpleMock(coreServices.auth, () => ({\n authenticate: jest.fn(),\n getNoneCredentials: jest.fn(),\n getOwnServiceCredentials: jest.fn(),\n isPrincipal: jest.fn() as any,\n getPluginRequestToken: jest.fn(),\n getLimitedUserToken: jest.fn(),\n listPublicServiceKeys: jest.fn(),\n }));\n }\n\n export function discovery(): DiscoveryService {\n return HostDiscovery.fromConfig(\n new ConfigReader({\n backend: {\n // Invalid port to make sure that requests are always mocked\n baseUrl: 'http://localhost:0',\n listen: { port: 0 },\n },\n }),\n );\n }\n export namespace discovery {\n export const factory = () =>\n createServiceFactory({\n service: coreServices.discovery,\n deps: {},\n factory: () => discovery(),\n });\n export const mock = simpleMock(coreServices.discovery, () => ({\n getBaseUrl: jest.fn(),\n getExternalBaseUrl: jest.fn(),\n }));\n }\n\n /**\n * Creates a mock implementation of the `HttpAuthService`.\n *\n * By default all requests without credentials are treated as requests from\n * the default mock user principal. This behavior can be configured with the\n * `defaultCredentials` option.\n */\n export function httpAuth(options?: {\n pluginId?: string;\n /**\n * The default credentials to use if there are no credentials present in the\n * incoming request.\n *\n * By default all requests without credentials are treated as authenticated\n * as the default mock user as returned from `mockCredentials.user()`.\n */\n defaultCredentials?: BackstageCredentials;\n }): HttpAuthService {\n return new MockHttpAuthService(\n options?.pluginId ?? 'test',\n options?.defaultCredentials ?? mockCredentials.user(),\n );\n }\n export namespace httpAuth {\n /**\n * Creates a mock service factory for the `HttpAuthService`.\n *\n * By default all requests without credentials are treated as requests from\n * the default mock user principal. This behavior can be configured with the\n * `defaultCredentials` option.\n */\n export const factory = (options?: {\n defaultCredentials?: BackstageCredentials;\n }) =>\n createServiceFactory({\n service: coreServices.httpAuth,\n deps: { plugin: coreServices.pluginMetadata },\n factory: ({ plugin }) =>\n new MockHttpAuthService(\n plugin.getId(),\n options?.defaultCredentials ?? mockCredentials.user(),\n ),\n });\n export const mock = simpleMock(coreServices.httpAuth, () => ({\n credentials: jest.fn(),\n issueUserCookie: jest.fn(),\n }));\n }\n\n /**\n * Creates a mock implementation of the `UserInfoService`.\n *\n * By default it extracts the user's entity ref from a user principal and\n * returns that as the only ownership entity ref, but this can be overridden\n * by passing in a custom set of user info.\n */\n export function userInfo(\n customInfo?: Partial<BackstageUserInfo>,\n ): UserInfoService {\n return new MockUserInfoService(customInfo);\n }\n export namespace userInfo {\n /**\n * Creates a mock service factory for the `UserInfoService`.\n *\n * By default it extracts the user's entity ref from a user principal and\n * returns that as the only ownership entity ref.\n */\n export const factory = () =>\n createServiceFactory({\n service: coreServices.userInfo,\n deps: {},\n factory() {\n return new MockUserInfoService();\n },\n });\n export const mock = simpleMock(coreServices.userInfo, () => ({\n getUserInfo: jest.fn(),\n }));\n }\n\n // TODO(Rugvip): Not all core services have implementations available here yet.\n // some may need a bit more refactoring for it to be simpler to\n // re-implement functioning mock versions here.\n export namespace cache {\n export const factory = () => cacheServiceFactory;\n export const mock = simpleMock(coreServices.cache, () => ({\n delete: jest.fn(),\n get: jest.fn(),\n set: jest.fn(),\n withOptions: jest.fn(),\n }));\n }\n\n /**\n * Creates a mock implementation of the\n * {@link @backstage/backend-plugin-api#coreServices.database}. Just returns\n * the given `knex` instance, which is useful in combination with the\n * {@link TestDatabases} facility.\n */\n export function database(options: {\n knex: Knex;\n migrations?: { skip?: boolean };\n }): DatabaseService {\n return {\n getClient: async () => options.knex,\n migrations: options.migrations,\n };\n }\n export namespace database {\n /**\n * Creates a mock factory for the\n * {@link @backstage/backend-plugin-api#coreServices.database}. Just returns\n * the given `knex` instance if you supply one, which is useful in\n * combination with the {@link TestDatabases} facility. Otherwise, it\n * returns the regular default database factory which reads config settings.\n */\n export const factory = (options?: {\n knex: Knex;\n migrations?: { skip?: boolean };\n }) =>\n options\n ? createServiceFactory({\n service: coreServices.database,\n deps: {},\n factory: () => database(options),\n })\n : databaseServiceFactory;\n /**\n * Creates a mock of the\n * {@link @backstage/backend-plugin-api#coreServices.database}, optionally\n * with some given method implementations.\n */\n export const mock = simpleMock(coreServices.database, () => ({\n getClient: jest.fn(),\n }));\n }\n\n export namespace rootHealth {\n export const factory = () => rootHealthServiceFactory;\n export const mock = simpleMock(coreServices.rootHealth, () => ({\n getLiveness: jest.fn(),\n getReadiness: jest.fn(),\n }));\n }\n\n export namespace httpRouter {\n export const factory = () => httpRouterServiceFactory;\n export const mock = simpleMock(coreServices.httpRouter, () => ({\n use: jest.fn(),\n addAuthPolicy: jest.fn(),\n }));\n }\n\n export namespace rootHttpRouter {\n export const factory = () => rootHttpRouterServiceFactory();\n export const mock = simpleMock(coreServices.rootHttpRouter, () => ({\n use: jest.fn(),\n }));\n }\n\n export namespace lifecycle {\n export const factory = () => lifecycleServiceFactory;\n export const mock = simpleMock(coreServices.lifecycle, () => ({\n addShutdownHook: jest.fn(),\n addStartupHook: jest.fn(),\n }));\n }\n\n export namespace logger {\n export const factory = () => loggerServiceFactory;\n export const mock = simpleMock(coreServices.logger, () =>\n createLoggerMock(),\n );\n }\n\n export namespace permissions {\n export const factory = () => permissionsServiceFactory;\n export const mock = simpleMock(coreServices.permissions, () => ({\n authorize: jest.fn(),\n authorizeConditional: jest.fn(),\n }));\n }\n\n export namespace permissionsRegistry {\n export const factory = () => permissionsRegistryServiceFactory;\n export const mock = simpleMock(coreServices.permissionsRegistry, () => ({\n addPermissionRules: jest.fn(),\n addPermissions: jest.fn(),\n addResourceType: jest.fn(),\n getPermissionRuleset: jest.fn(),\n }));\n }\n\n export namespace rootLifecycle {\n export const factory = () => rootLifecycleServiceFactory;\n export const mock = simpleMock(coreServices.rootLifecycle, () => ({\n addShutdownHook: jest.fn(),\n addBeforeShutdownHook: jest.fn(),\n addStartupHook: jest.fn(),\n }));\n }\n\n export namespace scheduler {\n export const factory = () => schedulerServiceFactory;\n export const mock = simpleMock(coreServices.scheduler, () => ({\n createScheduledTaskRunner: jest.fn(),\n getScheduledTasks: jest.fn(),\n scheduleTask: jest.fn(),\n triggerTask: jest.fn(),\n }));\n }\n\n export namespace urlReader {\n export const factory = () => urlReaderServiceFactory;\n export const mock = simpleMock(coreServices.urlReader, () => ({\n readTree: jest.fn(),\n readUrl: jest.fn(),\n search: jest.fn(),\n }));\n }\n export namespace actions {\n export const factory = () => actionsServiceFactory;\n export const mock = simpleMock(coreServices.actions, () => ({\n list: jest.fn(),\n invoke: jest.fn(),\n }));\n }\n\n export namespace actionsRegistry {\n export const factory = () => actionsRegistryServiceFactory;\n export const mock = simpleMock(coreServices.actionsRegistry, () => ({\n register: jest.fn(),\n }));\n }\n\n /**\n * Creates a functional mock implementation of the\n * {@link @backstage/backend-events-node#eventsServiceRef}.\n */\n export function events(): EventsService {\n return new MockEventsService();\n }\n export namespace events {\n /**\n * Creates a functional mock factory for the\n * {@link @backstage/backend-events-node#eventsServiceRef}.\n */\n export const factory = simpleFactoryWithOptions(eventsServiceRef, events);\n /**\n * Creates a mock of the\n * {@link @backstage/backend-events-node#eventsServiceRef}, optionally\n * with some given method implementations.\n */\n export const mock = simpleMock(eventsServiceRef, () => ({\n publish: jest.fn(),\n subscribe: jest.fn(),\n }));\n }\n}\n"],"names":["createServiceFactory","mockServices","ConfigReader","rootConfig","coreServices","MockRootLoggerService","rootLogger","auditor","auditorServiceFactory","MockAuthService","auth","discovery","HostDiscovery","MockHttpAuthService","mockCredentials","httpAuth","MockUserInfoService","userInfo","cache","cacheServiceFactory","database","databaseServiceFactory","rootHealth","rootHealthServiceFactory","httpRouter","httpRouterServiceFactory","rootHttpRouter","rootHttpRouterServiceFactory","lifecycle","lifecycleServiceFactory","logger","loggerServiceFactory","permissions","permissionsServiceFactory","permissionsRegistry","permissionsRegistryServiceFactory","rootLifecycle","rootLifecycleServiceFactory","scheduler","schedulerServiceFactory","urlReader","urlReaderServiceFactory","actions","actionsServiceFactory","actionsRegistry","actionsRegistryServiceFactory","MockEventsService","events","eventsServiceRef"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2DA,SAAS,gBAAmB,GAAA;AAC1B,EAAO,OAAA;AAAA,IACL,KAAO,EAAA,IAAA,CAAK,EAAG,EAAA,CAAE,mBAAmB,gBAAgB,CAAA;AAAA,IACpD,KAAA,EAAO,KAAK,EAAG,EAAA;AAAA,IACf,KAAA,EAAO,KAAK,EAAG,EAAA;AAAA,IACf,IAAA,EAAM,KAAK,EAAG,EAAA;AAAA,IACd,IAAA,EAAM,KAAK,EAAG;AAAA,GAChB;AACF;AAGA,SAAS,wBAAA,CAKP,KACA,OAC4D,EAAA;AAC5D,EAAM,MAAA,kBAAA,GAAqB,CAAI,GAAA,OAAA,KAC7BA,qCAAqB,CAAA;AAAA,IACnB,OAAS,EAAA,GAAA;AAAA,IACT,MAAM,EAAC;AAAA,IACP,MAAM,OAAU,GAAA;AACd,MAAO,OAAA,OAAA,CAAQ,GAAG,OAAO,CAAA;AAAA;AAC3B,GACD,CAAA;AACH,EAAA,OAAO,MAAO,CAAA,MAAA;AAAA,IACZ,kBAAA;AAAA,IACA,kBAAmB,CAAA,GAAI,CAAC,KAAA,CAAS,CAAyB;AAAA,GAC5D;AAEF;AAcA,SAAS,UAAA,CACP,KACA,WAC4D,EAAA;AAC5D,EAAA,OAAO,CAAe,WAAA,KAAA;AACpB,IAAA,MAAM,OAAO,WAAY,EAAA;AACzB,IAAA,IAAI,WAAa,EAAA;AACf,MAAA,KAAA,MAAW,CAAC,GAAK,EAAA,IAAI,KAAK,MAAO,CAAA,OAAA,CAAQ,WAAW,CAAG,EAAA;AACrD,QAAI,IAAA,OAAO,SAAS,UAAY,EAAA;AAC9B,UAAC,IAAa,CAAA,GAAG,CAAE,CAAA,kBAAA,CAAmB,IAAI,CAAA;AAAA,SACrC,MAAA;AACL,UAAC,IAAA,CAAa,GAAG,CAAI,GAAA,IAAA;AAAA;AACvB;AACF;AAEF,IAAO,OAAA,MAAA,CAAO,OAAO,IAAM,EAAA;AAAA,MACzB,SAASA,qCAAqB,CAAA;AAAA,QAC5B,OAAS,EAAA,GAAA;AAAA,QACT,MAAM,EAAC;AAAA,QACP,SAAS,MAAM;AAAA,OAChB;AAAA,KACF,CAAA;AAAA,GACH;AACF;AA4CiBC;AAAA,CAAV,CAAUA,aAAV,KAAA;AACE,EAAA,SAAS,WAAW,OAAiD,EAAA;AAC1E,IAAA,OAAO,IAAIC,mBAAA,CAAa,OAAS,EAAA,IAAA,EAAM,aAAa,CAAA;AAAA;AAD/C,EAAAD,aAAS,CAAA,UAAA,GAAA,UAAA;AAGT,EAAA,CAAA,CAAUE,WAAV,KAAA;AAGE,IAAMA,YAAA,OAAU,GAAA,wBAAA;AAAA,MACrBC,6BAAa,CAAA,UAAA;AAAA,MACbD;AAAA,KACF;AACO,IAAMA,WAAA,CAAA,IAAA,GAAO,UAAW,CAAAC,6BAAA,CAAa,YAAY,OAAO;AAAA,MAC7D,GAAA,EAAK,KAAK,EAAG,EAAA;AAAA,MACb,UAAA,EAAY,KAAK,EAAG,EAAA;AAAA,MACpB,SAAA,EAAW,KAAK,EAAG,EAAA;AAAA,MACnB,cAAA,EAAgB,KAAK,EAAG,EAAA;AAAA,MACxB,SAAA,EAAW,KAAK,EAAG,EAAA;AAAA,MACnB,WAAA,EAAa,KAAK,EAAG,EAAA;AAAA,MACrB,kBAAA,EAAoB,KAAK,EAAG,EAAA;AAAA,MAC5B,iBAAA,EAAmB,KAAK,EAAG,EAAA;AAAA,MAC3B,sBAAA,EAAwB,KAAK,EAAG,EAAA;AAAA,MAChC,iBAAA,EAAmB,KAAK,EAAG,EAAA;AAAA,MAC3B,iBAAA,EAAmB,KAAK,EAAG,EAAA;AAAA,MAC3B,sBAAA,EAAwB,KAAK,EAAG,EAAA;AAAA,MAChC,SAAA,EAAW,KAAK,EAAG,EAAA;AAAA,MACnB,cAAA,EAAgB,KAAK,EAAG,EAAA;AAAA,MACxB,GAAA,EAAK,KAAK,EAAG,EAAA;AAAA,MACb,IAAA,EAAM,KAAK,EAAG;AAAA,KACd,CAAA,CAAA;AAAA,GAxBa,EAAA,UAAA,GAAAH,aAAA,CAAA,UAAA,KAAAA,aAAA,CAAA,UAAA,GAAA,EAAA,CAAA,CAAA;AA2BV,EAAA,SAAS,WAAW,OAA6C,EAAA;AACtE,IAAO,OAAAI,2CAAA,CAAsB,OAAO,OAAO,CAAA;AAAA;AADtC,EAAAJ,aAAS,CAAA,UAAA,GAAA,UAAA;AAGT,EAAA,CAAA,CAAUK,WAAV,KAAA;AAKE,IAAMA,YAAA,OAAU,GAAA,wBAAA;AAAA,MACrBF,6BAAa,CAAA,UAAA;AAAA,MACbE;AAAA,KACF;AACO,IAAMA,WAAA,CAAA,IAAA,GAAO,UAAW,CAAAF,6BAAA,CAAa,YAAY,OAAO;AAAA,MAC7D,KAAA,EAAO,KAAK,EAAG,EAAA;AAAA,MACf,KAAA,EAAO,KAAK,EAAG,EAAA;AAAA,MACf,KAAA,EAAO,KAAK,EAAG,EAAA;AAAA,MACf,IAAA,EAAM,KAAK,EAAG,EAAA;AAAA,MACd,IAAA,EAAM,KAAK,EAAG;AAAA,KACd,CAAA,CAAA;AAAA,GAfa,EAAA,UAAA,GAAAH,aAAA,CAAA,UAAA,KAAAA,aAAA,CAAA,UAAA,GAAA,EAAA,CAAA,CAAA;AAkBV,EAAA,CAAA,CAAUM,QAAV,KAAA;AACE,IAAMA,QAAAA,CAAA,UAAU,MAAMC,6BAAA;AAEtB,IAAMD,QAAA,CAAA,IAAA,GAAO,UAAW,CAAAH,6BAAA,CAAa,SAAS,OAAO;AAAA,MAC1D,WAAa,EAAA,IAAA,CAAK,EAAG,CAAA,OAAM,CAAK,KAAA;AAC9B,QAAO,OAAA;AAAA,UACL,OAAA,EAAS,KAAK,EAAG,EAAA;AAAA,UACjB,IAAA,EAAM,KAAK,EAAG;AAAA,SAChB;AAAA,OACD;AAAA,KACD,CAAA,CAAA;AAAA,GAVa,EAAAH,aAAA,CAAA,OAAA,KAAAA,aAAA,CAAA,OAAA,GAAA,EAAA,CAAA,CAAA;AAaV,EAAA,SAAS,KAAK,OAGL,EAAA;AACd,IAAA,OAAO,IAAIQ,+BAAgB,CAAA;AAAA,MACzB,QAAA,EAAU,SAAS,QAAY,IAAA,MAAA;AAAA,MAC/B,wBAAA,EAA0B,OAAQ,CAAA,OAAA,EAAS,wBAAwB;AAAA,KACpE,CAAA;AAAA;AAPI,EAAAR,aAAS,CAAA,IAAA,GAAA,IAAA;AAST,EAAA,CAAA,CAAUS,KAAV,KAAA;AACE,IAAMA,KAAAA,CAAA,OAAU,GAAA,MACrBV,qCAAqB,CAAA;AAAA,MACnB,SAASI,6BAAa,CAAA,IAAA;AAAA,MACtB,IAAM,EAAA;AAAA,QACJ,QAAQA,6BAAa,CAAA,cAAA;AAAA,QACrB,QAAQA,6BAAa,CAAA;AAAA,OACvB;AAAA,MACA,OAAQ,CAAA,EAAE,MAAQ,EAAA,MAAA,EAAU,EAAA;AAC1B,QAAA,MAAM,wBAA2B,GAAA,OAAA;AAAA,UAC/B,MAAO,CAAA,kBAAA;AAAA,YACL;AAAA;AACF,SACF;AACA,QAAA,OAAO,IAAIK,+BAAgB,CAAA;AAAA,UACzB,QAAA,EAAU,OAAO,KAAM,EAAA;AAAA,UACvB;AAAA,SACD,CAAA;AAAA;AACH,KACD,CAAA;AACI,IAAMC,KAAA,CAAA,IAAA,GAAO,UAAW,CAAAN,6BAAA,CAAa,MAAM,OAAO;AAAA,MACvD,YAAA,EAAc,KAAK,EAAG,EAAA;AAAA,MACtB,kBAAA,EAAoB,KAAK,EAAG,EAAA;AAAA,MAC5B,wBAAA,EAA0B,KAAK,EAAG,EAAA;AAAA,MAClC,WAAA,EAAa,KAAK,EAAG,EAAA;AAAA,MACrB,qBAAA,EAAuB,KAAK,EAAG,EAAA;AAAA,MAC/B,mBAAA,EAAqB,KAAK,EAAG,EAAA;AAAA,MAC7B,qBAAA,EAAuB,KAAK,EAAG;AAAA,KAC/B,CAAA,CAAA;AAAA,GA5Ba,EAAA,IAAA,GAAAH,aAAA,CAAA,IAAA,KAAAA,aAAA,CAAA,IAAA,GAAA,EAAA,CAAA,CAAA;AA+BV,EAAA,SAASU,WAA8B,GAAA;AAC5C,IAAA,OAAOC,uBAAc,CAAA,UAAA;AAAA,MACnB,IAAIV,mBAAa,CAAA;AAAA,QACf,OAAS,EAAA;AAAA;AAAA,UAEP,OAAS,EAAA,oBAAA;AAAA,UACT,MAAA,EAAQ,EAAE,IAAA,EAAM,CAAE;AAAA;AACpB,OACD;AAAA,KACH;AAAA;AATK,EAAAD,aAAS,CAAA,SAAA,GAAAU,WAAA;AAWT,EAAA,CAAA,CAAUA,UAAV,KAAA;AACE,IAAMA,UAAAA,CAAA,OAAU,GAAA,MACrBX,qCAAqB,CAAA;AAAA,MACnB,SAASI,6BAAa,CAAA,SAAA;AAAA,MACtB,MAAM,EAAC;AAAA,MACP,OAAA,EAAS,MAAMO,UAAU;AAAA,KAC1B,CAAA;AACI,IAAMA,UAAA,CAAA,IAAA,GAAO,UAAW,CAAAP,6BAAA,CAAa,WAAW,OAAO;AAAA,MAC5D,UAAA,EAAY,KAAK,EAAG,EAAA;AAAA,MACpB,kBAAA,EAAoB,KAAK,EAAG;AAAA,KAC5B,CAAA,CAAA;AAAA,GAVa,EAAAO,WAAA,GAAAV,aAAA,CAAA,SAAA,KAAAA,aAAA,CAAA,SAAA,GAAA,EAAA,CAAA,CAAA;AAoBV,EAAA,SAAS,SAAS,OAUL,EAAA;AAClB,IAAA,OAAO,IAAIY,uCAAA;AAAA,MACT,SAAS,QAAY,IAAA,MAAA;AAAA,MACrB,OAAA,EAAS,kBAAsB,IAAAC,+BAAA,CAAgB,IAAK;AAAA,KACtD;AAAA;AAdK,EAAAb,aAAS,CAAA,QAAA,GAAA,QAAA;AAgBT,EAAA,CAAA,CAAUc,SAAV,KAAA;AAQE,IAAMA,SAAA,CAAA,OAAA,GAAU,CAAC,OAAA,KAGtBf,qCAAqB,CAAA;AAAA,MACnB,SAASI,6BAAa,CAAA,QAAA;AAAA,MACtB,IAAM,EAAA,EAAE,MAAQ,EAAAA,6BAAA,CAAa,cAAe,EAAA;AAAA,MAC5C,OAAS,EAAA,CAAC,EAAE,MAAA,OACV,IAAIS,uCAAA;AAAA,QACF,OAAO,KAAM,EAAA;AAAA,QACb,OAAA,EAAS,kBAAsB,IAAAC,+BAAA,CAAgB,IAAK;AAAA;AACtD,KACH,CAAA;AACI,IAAMC,SAAA,CAAA,IAAA,GAAO,UAAW,CAAAX,6BAAA,CAAa,UAAU,OAAO;AAAA,MAC3D,WAAA,EAAa,KAAK,EAAG,EAAA;AAAA,MACrB,eAAA,EAAiB,KAAK,EAAG;AAAA,KACzB,CAAA,CAAA;AAAA,GAvBa,EAAA,QAAA,GAAAH,aAAA,CAAA,QAAA,KAAAA,aAAA,CAAA,QAAA,GAAA,EAAA,CAAA,CAAA;AAiCV,EAAA,SAAS,SACd,UACiB,EAAA;AACjB,IAAO,OAAA,IAAIe,wCAAoB,UAAU,CAAA;AAAA;AAHpC,EAAAf,aAAS,CAAA,QAAA,GAAA,QAAA;AAKT,EAAA,CAAA,CAAUgB,SAAV,KAAA;AAOE,IAAMA,SAAAA,CAAA,OAAU,GAAA,MACrBjB,qCAAqB,CAAA;AAAA,MACnB,SAASI,6BAAa,CAAA,QAAA;AAAA,MACtB,MAAM,EAAC;AAAA,MACP,OAAU,GAAA;AACR,QAAA,OAAO,IAAIY,uCAAoB,EAAA;AAAA;AACjC,KACD,CAAA;AACI,IAAMC,SAAA,CAAA,IAAA,GAAO,UAAW,CAAAb,6BAAA,CAAa,UAAU,OAAO;AAAA,MAC3D,WAAA,EAAa,KAAK,EAAG;AAAA,KACrB,CAAA,CAAA;AAAA,GAjBa,EAAA,QAAA,GAAAH,aAAA,CAAA,QAAA,KAAAA,aAAA,CAAA,QAAA,GAAA,EAAA,CAAA,CAAA;AAuBV,EAAA,CAAA,CAAUiB,MAAV,KAAA;AACE,IAAMA,MAAAA,CAAA,UAAU,MAAMC,yBAAA;AACtB,IAAMD,MAAA,CAAA,IAAA,GAAO,UAAW,CAAAd,6BAAA,CAAa,OAAO,OAAO;AAAA,MACxD,MAAA,EAAQ,KAAK,EAAG,EAAA;AAAA,MAChB,GAAA,EAAK,KAAK,EAAG,EAAA;AAAA,MACb,GAAA,EAAK,KAAK,EAAG,EAAA;AAAA,MACb,WAAA,EAAa,KAAK,EAAG;AAAA,KACrB,CAAA,CAAA;AAAA,GAPa,EAAAH,aAAA,CAAA,KAAA,KAAAA,aAAA,CAAA,KAAA,GAAA,EAAA,CAAA,CAAA;AAgBV,EAAA,SAASmB,WAAS,OAGL,EAAA;AAClB,IAAO,OAAA;AAAA,MACL,SAAA,EAAW,YAAY,OAAQ,CAAA,IAAA;AAAA,MAC/B,YAAY,OAAQ,CAAA;AAAA,KACtB;AAAA;AAPK,EAAAnB,aAAS,CAAA,QAAA,GAAAmB,UAAA;AAST,EAAA,CAAA,CAAUA,SAAV,KAAA;AAQE,IAAMA,SAAA,CAAA,OAAA,GAAU,CAAC,OAAA,KAItB,UACIpB,qCAAqB,CAAA;AAAA,MACnB,SAASI,6BAAa,CAAA,QAAA;AAAA,MACtB,MAAM,EAAC;AAAA,MACP,OAAA,EAAS,MAAMgB,SAAAA,CAAS,OAAO;AAAA,KAChC,CACD,GAAAC,+BAAA;AAMC,IAAMD,SAAA,CAAA,IAAA,GAAO,UAAW,CAAAhB,6BAAA,CAAa,UAAU,OAAO;AAAA,MAC3D,SAAA,EAAW,KAAK,EAAG;AAAA,KACnB,CAAA,CAAA;AAAA,GA1Ba,EAAAgB,UAAA,GAAAnB,aAAA,CAAA,QAAA,KAAAA,aAAA,CAAA,QAAA,GAAA,EAAA,CAAA,CAAA;AA6BV,EAAA,CAAA,CAAUqB,WAAV,KAAA;AACE,IAAMA,WAAAA,CAAA,UAAU,MAAMC,mCAAA;AACtB,IAAMD,WAAA,CAAA,IAAA,GAAO,UAAW,CAAAlB,6BAAA,CAAa,YAAY,OAAO;AAAA,MAC7D,WAAA,EAAa,KAAK,EAAG,EAAA;AAAA,MACrB,YAAA,EAAc,KAAK,EAAG;AAAA,KACtB,CAAA,CAAA;AAAA,GALa,EAAAH,aAAA,CAAA,UAAA,KAAAA,aAAA,CAAA,UAAA,GAAA,EAAA,CAAA,CAAA;AAQV,EAAA,CAAA,CAAUuB,WAAV,KAAA;AACE,IAAMA,WAAAA,CAAA,UAAU,MAAMC,mCAAA;AACtB,IAAMD,WAAA,CAAA,IAAA,GAAO,UAAW,CAAApB,6BAAA,CAAa,YAAY,OAAO;AAAA,MAC7D,GAAA,EAAK,KAAK,EAAG,EAAA;AAAA,MACb,aAAA,EAAe,KAAK,EAAG;AAAA,KACvB,CAAA,CAAA;AAAA,GALa,EAAAH,aAAA,CAAA,UAAA,KAAAA,aAAA,CAAA,UAAA,GAAA,EAAA,CAAA,CAAA;AAQV,EAAA,CAAA,CAAUyB,eAAV,KAAA;AACE,IAAMA,eAAAA,CAAA,OAAU,GAAA,MAAMC,2CAA6B,EAAA;AACnD,IAAMD,eAAA,CAAA,IAAA,GAAO,UAAW,CAAAtB,6BAAA,CAAa,gBAAgB,OAAO;AAAA,MACjE,GAAA,EAAK,KAAK,EAAG;AAAA,KACb,CAAA,CAAA;AAAA,GAJa,EAAAH,aAAA,CAAA,cAAA,KAAAA,aAAA,CAAA,cAAA,GAAA,EAAA,CAAA,CAAA;AAOV,EAAA,CAAA,CAAU2B,UAAV,KAAA;AACE,IAAMA,UAAAA,CAAA,UAAU,MAAMC,iCAAA;AACtB,IAAMD,UAAA,CAAA,IAAA,GAAO,UAAW,CAAAxB,6BAAA,CAAa,WAAW,OAAO;AAAA,MAC5D,eAAA,EAAiB,KAAK,EAAG,EAAA;AAAA,MACzB,cAAA,EAAgB,KAAK,EAAG;AAAA,KACxB,CAAA,CAAA;AAAA,GALa,EAAAH,aAAA,CAAA,SAAA,KAAAA,aAAA,CAAA,SAAA,GAAA,EAAA,CAAA,CAAA;AAQV,EAAA,CAAA,CAAU6B,OAAV,KAAA;AACE,IAAMA,OAAAA,CAAA,UAAU,MAAMC,2BAAA;AACtB,IAAMD,QAAA,IAAO,GAAA,UAAA;AAAA,MAAW1B,6BAAa,CAAA,MAAA;AAAA,MAAQ,MAClD,gBAAiB;AAAA,KACnB;AAAA,GAJe,EAAAH,aAAA,CAAA,MAAA,KAAAA,aAAA,CAAA,MAAA,GAAA,EAAA,CAAA,CAAA;AAOV,EAAA,CAAA,CAAU+B,YAAV,KAAA;AACE,IAAMA,YAAAA,CAAA,UAAU,MAAMC,qCAAA;AACtB,IAAMD,YAAA,CAAA,IAAA,GAAO,UAAW,CAAA5B,6BAAA,CAAa,aAAa,OAAO;AAAA,MAC9D,SAAA,EAAW,KAAK,EAAG,EAAA;AAAA,MACnB,oBAAA,EAAsB,KAAK,EAAG;AAAA,KAC9B,CAAA,CAAA;AAAA,GALa,EAAAH,aAAA,CAAA,WAAA,KAAAA,aAAA,CAAA,WAAA,GAAA,EAAA,CAAA,CAAA;AAQV,EAAA,CAAA,CAAUiC,oBAAV,KAAA;AACE,IAAMA,oBAAAA,CAAA,UAAU,MAAMC,qDAAA;AACtB,IAAMD,oBAAA,CAAA,IAAA,GAAO,UAAW,CAAA9B,6BAAA,CAAa,qBAAqB,OAAO;AAAA,MACtE,kBAAA,EAAoB,KAAK,EAAG,EAAA;AAAA,MAC5B,cAAA,EAAgB,KAAK,EAAG,EAAA;AAAA,MACxB,eAAA,EAAiB,KAAK,EAAG,EAAA;AAAA,MACzB,oBAAA,EAAsB,KAAK,EAAG;AAAA,KAC9B,CAAA,CAAA;AAAA,GAPa,EAAAH,aAAA,CAAA,mBAAA,KAAAA,aAAA,CAAA,mBAAA,GAAA,EAAA,CAAA,CAAA;AAUV,EAAA,CAAA,CAAUmC,cAAV,KAAA;AACE,IAAMA,cAAAA,CAAA,UAAU,MAAMC,yCAAA;AACtB,IAAMD,cAAA,CAAA,IAAA,GAAO,UAAW,CAAAhC,6BAAA,CAAa,eAAe,OAAO;AAAA,MAChE,eAAA,EAAiB,KAAK,EAAG,EAAA;AAAA,MACzB,qBAAA,EAAuB,KAAK,EAAG,EAAA;AAAA,MAC/B,cAAA,EAAgB,KAAK,EAAG;AAAA,KACxB,CAAA,CAAA;AAAA,GANa,EAAAH,aAAA,CAAA,aAAA,KAAAA,aAAA,CAAA,aAAA,GAAA,EAAA,CAAA,CAAA;AASV,EAAA,CAAA,CAAUqC,UAAV,KAAA;AACE,IAAMA,UAAAA,CAAA,UAAU,MAAMC,iCAAA;AACtB,IAAMD,UAAA,CAAA,IAAA,GAAO,UAAW,CAAAlC,6BAAA,CAAa,WAAW,OAAO;AAAA,MAC5D,yBAAA,EAA2B,KAAK,EAAG,EAAA;AAAA,MACnC,iBAAA,EAAmB,KAAK,EAAG,EAAA;AAAA,MAC3B,YAAA,EAAc,KAAK,EAAG,EAAA;AAAA,MACtB,WAAA,EAAa,KAAK,EAAG;AAAA,KACrB,CAAA,CAAA;AAAA,GAPa,EAAAH,aAAA,CAAA,SAAA,KAAAA,aAAA,CAAA,SAAA,GAAA,EAAA,CAAA,CAAA;AAUV,EAAA,CAAA,CAAUuC,UAAV,KAAA;AACE,IAAMA,UAAAA,CAAA,UAAU,MAAMC,iCAAA;AACtB,IAAMD,UAAA,CAAA,IAAA,GAAO,UAAW,CAAApC,6BAAA,CAAa,WAAW,OAAO;AAAA,MAC5D,QAAA,EAAU,KAAK,EAAG,EAAA;AAAA,MAClB,OAAA,EAAS,KAAK,EAAG,EAAA;AAAA,MACjB,MAAA,EAAQ,KAAK,EAAG;AAAA,KAChB,CAAA,CAAA;AAAA,GANa,EAAAH,aAAA,CAAA,SAAA,KAAAA,aAAA,CAAA,SAAA,GAAA,EAAA,CAAA,CAAA;AAQV,EAAA,CAAA,CAAUyC,QAAV,KAAA;AACE,IAAMA,QAAAA,CAAA,UAAU,MAAMC,6BAAA;AACtB,IAAMD,QAAA,CAAA,IAAA,GAAO,UAAW,CAAAtC,6BAAA,CAAa,SAAS,OAAO;AAAA,MAC1D,IAAA,EAAM,KAAK,EAAG,EAAA;AAAA,MACd,MAAA,EAAQ,KAAK,EAAG;AAAA,KAChB,CAAA,CAAA;AAAA,GALa,EAAAH,aAAA,CAAA,OAAA,KAAAA,aAAA,CAAA,OAAA,GAAA,EAAA,CAAA,CAAA;AAQV,EAAA,CAAA,CAAU2C,gBAAV,KAAA;AACE,IAAMA,gBAAAA,CAAA,UAAU,MAAMC,6CAAA;AACtB,IAAMD,gBAAA,CAAA,IAAA,GAAO,UAAW,CAAAxC,6BAAA,CAAa,iBAAiB,OAAO;AAAA,MAClE,QAAA,EAAU,KAAK,EAAG;AAAA,KAClB,CAAA,CAAA;AAAA,GAJa,EAAAH,aAAA,CAAA,eAAA,KAAAA,aAAA,CAAA,eAAA,GAAA,EAAA,CAAA,CAAA;AAWV,EAAA,SAAS,MAAwB,GAAA;AACtC,IAAA,OAAO,IAAI6C,mCAAkB,EAAA;AAAA;AADxB,EAAA7C,aAAS,CAAA,MAAA,GAAA,MAAA;AAGT,EAAA,CAAA,CAAU8C,OAAV,KAAA;AAKE,IAAMA,OAAA,CAAA,OAAA,GAAU,wBAAyB,CAAAC,iCAAA,EAAkBD,OAAM,CAAA;AAMjE,IAAMA,OAAA,CAAA,IAAA,GAAO,UAAW,CAAAC,iCAAA,EAAkB,OAAO;AAAA,MACtD,OAAA,EAAS,KAAK,EAAG,EAAA;AAAA,MACjB,SAAA,EAAW,KAAK,EAAG;AAAA,KACnB,CAAA,CAAA;AAAA,GAda,EAAA,MAAA,GAAA/C,aAAA,CAAA,MAAA,KAAAA,aAAA,CAAA,MAAA,GAAA,EAAA,CAAA,CAAA;AAAA,CApXF,EAAAA,oBAAA,KAAAA,oBAAA,GAAA,EAAA,CAAA,CAAA;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ServiceFactoryTester.cjs.js","sources":["../../../src/next/wiring/ServiceFactoryTester.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ServiceFactory, ServiceRef } from '@backstage/backend-plugin-api';\nimport { defaultServiceFactories } from './TestBackend';\n// Direct internal import to avoid duplication.\n// This is a relative import in order to make sure that the implementation is duplicated\n// rather than leading to an import from @backstage/backend-app-api.\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { ServiceRegistry } from '../../../../backend-app-api/src/wiring/ServiceRegistry';\n\n/**\n * Options for {@link ServiceFactoryTester}.\n * @public\n */\nexport interface ServiceFactoryTesterOptions {\n /**\n * Additional service factories to make available as dependencies.\n *\n * @remarks\n *\n * If a service factory is provided for a service that already has a default\n * implementation, the provided factory will override the default.\n */\n dependencies?: Array<ServiceFactory>;\n}\n\n/**\n * A utility to help test service factories in isolation.\n *\n * @public\n */\nexport class ServiceFactoryTester<\n TService,\n TScope extends 'root' | 'plugin',\n TInstances extends 'singleton' | 'multiton' = 'singleton',\n> {\n readonly #subject: ServiceRef<TService, TScope, TInstances>;\n readonly #registry: ServiceRegistry;\n\n /**\n * Creates a new {@link ServiceFactoryTester} used to test the provided subject.\n *\n * @param subject - The service factory to test.\n * @param options - Additional options\n * @returns A new tester instance for the provided subject.\n */\n static from<\n TService,\n TScope extends 'root' | 'plugin',\n TInstances extends 'singleton' | 'multiton' = 'singleton',\n >(\n subject: ServiceFactory<TService, TScope, TInstances>,\n options?: ServiceFactoryTesterOptions,\n ): ServiceFactoryTester<TService, TScope, TInstances> {\n const registry = ServiceRegistry.create([\n ...defaultServiceFactories,\n ...(options?.dependencies ?? []),\n subject,\n ]);\n return new ServiceFactoryTester(subject.service, registry);\n }\n\n private constructor(\n subject: ServiceRef<TService, TScope, TInstances>,\n registry: ServiceRegistry,\n ) {\n this.#subject = subject;\n this.#registry = registry;\n }\n\n /**\n * Returns the service instance for the subject.\n *\n * @remarks\n *\n * If the subject is a plugin scoped service factory a plugin ID\n * can be provided to instantiate the service for a specific plugin.\n *\n * By default the plugin ID 'test' is used.\n */\n async getSubject(\n ...args: 'root' extends TScope ? [] : [pluginId?: string]\n ): Promise<TInstances extends 'multiton' ? TService[] : TService> {\n const [pluginId] = args;\n const instance = this.#registry.get(this.#subject, pluginId ?? 'test')!;\n return instance;\n }\n\n /**\n * Return the service instance for any of the provided dependencies or built-in services.\n *\n * @remarks\n *\n * A plugin ID can optionally be provided for plugin scoped services, otherwise the plugin ID 'test' is used.\n */\n async getService<\n TGetService,\n TGetScope extends 'root' | 'plugin',\n TGetInstances extends 'singleton' | 'multiton' = 'singleton',\n >(\n service: ServiceRef<TGetService, TGetScope, TGetInstances>,\n ...args: 'root' extends TGetScope ? [] : [pluginId?: string]\n ): Promise<TGetInstances extends 'multiton' ? TGetService[] : TGetService> {\n const [pluginId] = args;\n const instance = await this.#registry.get(service, pluginId ?? 'test');\n if (instance === undefined) {\n throw new Error(`Service '${service.id}' not found`);\n }\n return instance;\n }\n}\n"],"names":["ServiceRegistry","defaultServiceFactories"],"mappings":";;;;;AA6CO,MAAM,oBAIX,CAAA;AAAA,EACS,QAAA;AAAA,EACA,SAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAST,OAAO,IAKL,CAAA,OAAA,EACA,OACoD,EAAA;AACpD,IAAM,MAAA,QAAA,GAAWA,gCAAgB,MAAO,CAAA;AAAA,MACtC,GAAGC,mCAAA;AAAA,MACH,GAAI,OAAS,EAAA,YAAA,IAAgB,EAAC;AAAA,MAC9B;AAAA,KACD,CAAA;AACD,IAAA,OAAO,IAAI,oBAAA,CAAqB,OAAQ,CAAA,OAAA,EAAS,QAAQ,CAAA;AAAA;AAC3D,EAEQ,WAAA,CACN,SACA,QACA,EAAA;AACA,IAAA,IAAA,CAAK,QAAW,GAAA,OAAA;AAChB,IAAA,IAAA,CAAK,SAAY,GAAA,QAAA;AAAA;AACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,cACD,IAC6D,EAAA;AAChE,IAAM,MAAA,CAAC,QAAQ,CAAI,GAAA,IAAA;AACnB,IAAA,MAAM,WAAW,IAAK,CAAA,SAAA,CAAU,IAAI,IAAK,CAAA,QAAA,EAAU,YAAY,MAAM,CAAA;AACrE,IAAO,OAAA,QAAA;AAAA;AACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,UAKJ,CAAA,OAAA,EAAA,GACG,IACsE,EAAA;AACzE,IAAM,MAAA,CAAC,QAAQ,CAAI,GAAA,IAAA;AACnB,IAAA,MAAM,WAAW,MAAM,IAAA,CAAK,UAAU,GAAI,CAAA,OAAA,EAAS,YAAY,MAAM,CAAA;AACrE,IAAA,IAAI,aAAa,KAAW,CAAA,EAAA;AAC1B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAY,SAAA,EAAA,OAAA,CAAQ,EAAE,CAAa,WAAA,CAAA,CAAA;AAAA;AAErD,IAAO,OAAA,QAAA;AAAA;AAEX;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TestBackend.cjs.js","sources":["../../../src/next/wiring/TestBackend.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Backend, createSpecializedBackend } from '@backstage/backend-app-api';\nimport {\n createServiceFactory,\n BackendFeature,\n ExtensionPoint,\n coreServices,\n createBackendModule,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { mockServices } from '../services';\nimport { ConfigReader } from '@backstage/config';\nimport express from 'express';\n// Direct internal import to avoid duplication\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport {\n InternalBackendFeature,\n InternalBackendRegistrations,\n} from '../../../../backend-plugin-api/src/wiring/types';\nimport {\n DefaultRootHttpRouter,\n ExtendedHttpServer,\n MiddlewareFactory,\n createHealthRouter,\n createHttpServer,\n} from '@backstage/backend-defaults/rootHttpRouter';\nimport { HostDiscovery } from '@backstage/backend-defaults/discovery';\n\n/** @public */\nexport interface TestBackendOptions<TExtensionPoints extends any[]> {\n extensionPoints?: readonly [\n ...{\n [index in keyof TExtensionPoints]: [\n ExtensionPoint<TExtensionPoints[index]>,\n Partial<TExtensionPoints[index]>,\n ];\n },\n ];\n features?: Array<BackendFeature | Promise<{ default: BackendFeature }>>;\n}\n\n/** @public */\nexport interface TestBackend extends Backend {\n /**\n * Provides access to the underling HTTP server for use with utilities\n * such as `supertest`.\n *\n * If the root http router service has been replaced, this will throw an error.\n */\n readonly server: ExtendedHttpServer;\n}\n\nexport const defaultServiceFactories = [\n mockServices.auth.factory(),\n mockServices.auditor.factory(),\n mockServices.cache.factory(),\n mockServices.rootConfig.factory(),\n mockServices.database.factory(),\n mockServices.httpAuth.factory(),\n mockServices.httpRouter.factory(),\n mockServices.lifecycle.factory(),\n mockServices.logger.factory(),\n mockServices.permissions.factory(),\n mockServices.permissionsRegistry.factory(),\n mockServices.rootHealth.factory(),\n mockServices.rootLifecycle.factory(),\n mockServices.rootLogger.factory(),\n mockServices.scheduler.factory(),\n mockServices.userInfo.factory(),\n mockServices.urlReader.factory(),\n mockServices.events.factory(),\n];\n\n/**\n * Given a set of features, return an array of plugins that ensures that each\n * module in the provided set of features has a corresponding plugin.\n * @internal\n */\nfunction createPluginsForOrphanModules(features: Array<BackendFeature>) {\n const pluginIds = new Set<string>();\n const modulePluginIds = new Set<string>();\n\n for (const feature of features) {\n if (isInternalBackendRegistrations(feature)) {\n const registrations = feature.getRegistrations();\n for (const registration of registrations) {\n if (registration.type === 'plugin') {\n pluginIds.add(registration.pluginId);\n } else if (registration.type === 'module') {\n modulePluginIds.add(registration.pluginId);\n }\n }\n }\n }\n\n for (const pluginId of pluginIds) {\n modulePluginIds.delete(pluginId);\n }\n\n return Array.from(modulePluginIds).map(pluginId =>\n createBackendPlugin({\n pluginId,\n register(reg) {\n reg.registerInit({ deps: {}, async init() {} });\n },\n }),\n );\n}\n\n/**\n * Given a set of extension points and features, find the extension\n * points that we mock and tie them to the correct plugin ID.\n * @returns\n */\nfunction createExtensionPointTestModules(\n features: Array<BackendFeature>,\n extensionPointTuples?: readonly [\n ref: ExtensionPoint<unknown>,\n impl: unknown,\n ][],\n): Array<BackendFeature> {\n if (!extensionPointTuples) {\n return [];\n }\n\n const registrations = features.flatMap(feature => {\n if (isInternalBackendRegistrations(feature)) {\n return feature.getRegistrations();\n }\n return [];\n });\n\n const extensionPointMap = new Map(\n extensionPointTuples.map(ep => [ep[0].id, ep]),\n );\n const extensionPointsToSort = new Set(extensionPointMap.keys());\n const extensionPointsByPlugin = new Map<string, string[]>();\n\n for (const registration of registrations) {\n if (registration.type === 'module') {\n const testDep = Object.values(registration.init.deps).filter(dep =>\n extensionPointsToSort.has(dep.id),\n );\n if (testDep.length > 0) {\n let points = extensionPointsByPlugin.get(registration.pluginId);\n if (!points) {\n points = [];\n extensionPointsByPlugin.set(registration.pluginId, points);\n }\n for (const { id } of testDep) {\n points.push(id);\n extensionPointsToSort.delete(id);\n }\n }\n }\n }\n\n if (extensionPointsToSort.size > 0) {\n const list = Array.from(extensionPointsToSort)\n .map(id => `'${id}'`)\n .join(', ');\n throw new Error(\n `Unable to determine the plugin ID of extension point(s) ${list}. ` +\n 'Tested extension points must be depended on by one or more tested modules.',\n );\n }\n\n const modules = [];\n\n for (const [pluginId, pluginExtensionPointIds] of extensionPointsByPlugin) {\n modules.push(\n createBackendModule({\n pluginId,\n moduleId: 'test-extension-point-registration',\n register(reg) {\n for (const id of pluginExtensionPointIds) {\n const tuple = extensionPointMap.get(id)!;\n reg.registerExtensionPoint(...tuple);\n }\n\n reg.registerInit({ deps: {}, async init() {} });\n },\n }),\n );\n }\n\n return modules;\n}\n\nfunction isPromise<T>(value: unknown | Promise<T>): value is Promise<T> {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'then' in value &&\n typeof value.then === 'function'\n );\n}\n\n// Same as in the backend-app-api, handles double defaults from dynamic imports\nfunction unwrapFeature(\n feature: BackendFeature | { default: BackendFeature },\n): BackendFeature {\n if ('$$type' in feature) {\n return feature;\n }\n\n if ('default' in feature) {\n return feature.default;\n }\n\n return feature;\n}\n\nconst backendInstancesToCleanUp = new Array<Backend>();\n\n/** @public */\nexport async function startTestBackend<TExtensionPoints extends any[]>(\n options: TestBackendOptions<TExtensionPoints>,\n): Promise<TestBackend> {\n const { extensionPoints, ...otherOptions } = options;\n\n // Unpack input into awaited plain BackendFeatures\n const features: BackendFeature[] = await Promise.all(\n options.features?.map(async val => {\n if (isPromise(val)) {\n const { default: feature } = await val;\n return unwrapFeature(feature);\n }\n return unwrapFeature(val);\n }) ?? [],\n );\n\n let server: ExtendedHttpServer;\n\n const rootHttpRouterFactory = createServiceFactory({\n service: coreServices.rootHttpRouter,\n deps: {\n config: coreServices.rootConfig,\n lifecycle: coreServices.rootLifecycle,\n rootLogger: coreServices.rootLogger,\n health: coreServices.rootHealth,\n },\n async factory({ config, lifecycle, rootLogger, health }) {\n const router = DefaultRootHttpRouter.create();\n const logger = rootLogger.child({ service: 'rootHttpRouter' });\n\n const app = express();\n\n const middleware = MiddlewareFactory.create({ config, logger });\n const healthRouter = createHealthRouter({ config, health });\n\n app.use(healthRouter);\n app.use(router.handler());\n app.use(middleware.notFound());\n app.use(middleware.error());\n\n server = await createHttpServer(\n app,\n { listen: { host: '', port: 0 } },\n { logger },\n );\n\n lifecycle.addShutdownHook(() => server.stop(), { logger });\n\n await server.start();\n\n return router;\n },\n });\n\n const discoveryFactory = createServiceFactory({\n service: coreServices.discovery,\n deps: {\n rootHttpRouter: coreServices.rootHttpRouter,\n },\n async factory() {\n if (!server) {\n throw new Error('Test server not started yet');\n }\n const port = server.port();\n const discovery = HostDiscovery.fromConfig(\n new ConfigReader({\n backend: { baseUrl: `http://localhost:${port}`, listen: { port } },\n }),\n );\n return discovery;\n },\n });\n\n const backend = createSpecializedBackend({\n ...otherOptions,\n defaultServiceFactories: [\n ...defaultServiceFactories,\n rootHttpRouterFactory,\n discoveryFactory,\n ],\n });\n\n backendInstancesToCleanUp.push(backend);\n\n for (const m of createExtensionPointTestModules(features, extensionPoints)) {\n backend.add(m);\n }\n for (const p of createPluginsForOrphanModules(features)) {\n backend.add(p);\n }\n for (const feature of features) {\n backend.add(feature);\n }\n\n await backend.start();\n\n return Object.assign(backend, {\n get server() {\n if (!server) {\n throw new Error('TestBackend server is not available');\n }\n return server;\n },\n });\n}\n\nlet registered = false;\nfunction registerTestHooks() {\n if (typeof afterAll !== 'function') {\n return;\n }\n if (registered) {\n return;\n }\n registered = true;\n\n afterAll(async () => {\n await Promise.all(\n backendInstancesToCleanUp.map(async backend => {\n try {\n await backend.stop();\n } catch (error) {\n console.error(`Failed to stop backend after tests, ${error}`);\n }\n }),\n );\n backendInstancesToCleanUp.length = 0;\n });\n}\n\nregisterTestHooks();\n\nfunction toInternalBackendFeature(\n feature: BackendFeature,\n): InternalBackendFeature {\n if (feature.$$type !== '@backstage/BackendFeature') {\n throw new Error(`Invalid BackendFeature, bad type '${feature.$$type}'`);\n }\n const internal = feature as InternalBackendFeature;\n if (internal.version !== 'v1') {\n throw new Error(\n `Invalid BackendFeature, bad version '${internal.version}'`,\n );\n }\n return internal;\n}\n\nfunction isInternalBackendRegistrations(\n feature: BackendFeature,\n): feature is InternalBackendRegistrations {\n const internal = toInternalBackendFeature(feature);\n if (internal.featureType === 'registrations') {\n return true;\n }\n // Backwards compatibility for v1 registrations that use duck typing\n return 'getRegistrations' in internal;\n}\n"],"names":["mockServices","createBackendPlugin","createBackendModule","createServiceFactory","coreServices","DefaultRootHttpRouter","express","MiddlewareFactory","createHealthRouter","createHttpServer","discovery","HostDiscovery","ConfigReader","createSpecializedBackend"],"mappings":"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"}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|