@backstage/backend-test-utils 0.2.2-next.0 → 0.2.2

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 CHANGED
@@ -1,15 +1,26 @@
1
1
  # @backstage/backend-test-utils
2
2
 
3
- ## 0.2.2-next.0
3
+ ## 0.2.2
4
4
 
5
5
  ### Patch Changes
6
6
 
7
- - 9fb3b5373c45: Extended `mockService` to also include mocked variants, for example `mockServices.lifecycle.mock()`. The returned mocked implementation will have a `factory` property which is a service factory for itself. You can also pass a partial implementation of the service to the mock function to use a mock implementation of specific methods.
8
7
  - Updated dependencies
9
- - @backstage/plugin-auth-node@0.3.0-next.0
10
- - @backstage/backend-common@0.19.4-next.0
11
- - @backstage/backend-app-api@0.5.2-next.0
12
- - @backstage/backend-plugin-api@0.6.2-next.0
8
+ - @backstage/backend-common@0.19.4
9
+ - @backstage/backend-app-api@0.5.2
10
+ - @backstage/plugin-auth-node@0.2.19
11
+ - @backstage/backend-plugin-api@0.6.2
12
+ - @backstage/config@1.0.8
13
+ - @backstage/types@1.1.0
14
+
15
+ ## 0.2.1
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies
20
+ - @backstage/backend-common@0.19.3
21
+ - @backstage/backend-app-api@0.5.1
22
+ - @backstage/plugin-auth-node@0.2.18
23
+ - @backstage/backend-plugin-api@0.6.1
13
24
  - @backstage/config@1.0.8
14
25
  - @backstage/types@1.1.0
15
26
 
package/dist/index.cjs.js CHANGED
@@ -475,27 +475,6 @@ function simpleFactory(ref, factory) {
475
475
  }
476
476
  }));
477
477
  }
478
- function simpleMock(ref, mockFactory) {
479
- return (partialImpl) => {
480
- const mock = mockFactory();
481
- if (partialImpl) {
482
- for (const [key, impl] of Object.entries(partialImpl)) {
483
- if (typeof impl === "function") {
484
- mock[key].mockImplementation(impl);
485
- } else {
486
- mock[key] = impl;
487
- }
488
- }
489
- }
490
- return Object.assign(mock, {
491
- factory: backendPluginApi.createServiceFactory({
492
- service: ref,
493
- deps: {},
494
- factory: () => mock
495
- })()
496
- });
497
- };
498
- }
499
478
  exports.mockServices = void 0;
500
479
  ((mockServices2) => {
501
480
  function rootConfig(options) {
@@ -511,13 +490,6 @@ exports.mockServices = void 0;
511
490
  mockServices2.rootLogger = rootLogger;
512
491
  ((rootLogger2) => {
513
492
  rootLogger2.factory = simpleFactory(backendPluginApi.coreServices.rootLogger, rootLogger2);
514
- rootLogger2.mock = simpleMock(backendPluginApi.coreServices.rootLogger, () => ({
515
- child: jest.fn(),
516
- debug: jest.fn(),
517
- error: jest.fn(),
518
- info: jest.fn(),
519
- warn: jest.fn()
520
- }));
521
493
  })(rootLogger = mockServices2.rootLogger || (mockServices2.rootLogger = {}));
522
494
  function tokenManager() {
523
495
  return {
@@ -537,10 +509,6 @@ exports.mockServices = void 0;
537
509
  backendPluginApi.coreServices.tokenManager,
538
510
  tokenManager2
539
511
  );
540
- tokenManager2.mock = simpleMock(backendPluginApi.coreServices.tokenManager, () => ({
541
- authenticate: jest.fn(),
542
- getToken: jest.fn()
543
- }));
544
512
  })(tokenManager = mockServices2.tokenManager || (mockServices2.tokenManager = {}));
545
513
  function identity() {
546
514
  return new MockIdentityService();
@@ -548,78 +516,33 @@ exports.mockServices = void 0;
548
516
  mockServices2.identity = identity;
549
517
  ((identity2) => {
550
518
  identity2.factory = simpleFactory(backendPluginApi.coreServices.identity, identity2);
551
- identity2.mock = simpleMock(backendPluginApi.coreServices.identity, () => ({
552
- getIdentity: jest.fn()
553
- }));
554
519
  })(identity = mockServices2.identity || (mockServices2.identity = {}));
555
520
  ((cache2) => {
556
521
  cache2.factory = backendAppApi.cacheServiceFactory;
557
- cache2.mock = simpleMock(backendPluginApi.coreServices.cache, () => ({
558
- delete: jest.fn(),
559
- get: jest.fn(),
560
- set: jest.fn(),
561
- withOptions: jest.fn()
562
- }));
563
522
  })(mockServices2.cache || (mockServices2.cache = {}));
564
523
  ((database2) => {
565
524
  database2.factory = backendAppApi.databaseServiceFactory;
566
- database2.mock = simpleMock(backendPluginApi.coreServices.database, () => ({
567
- getClient: jest.fn()
568
- }));
569
525
  })(mockServices2.database || (mockServices2.database = {}));
570
526
  ((httpRouter2) => {
571
527
  httpRouter2.factory = backendAppApi.httpRouterServiceFactory;
572
- httpRouter2.mock = simpleMock(backendPluginApi.coreServices.httpRouter, () => ({
573
- use: jest.fn()
574
- }));
575
528
  })(mockServices2.httpRouter || (mockServices2.httpRouter = {}));
576
529
  ((lifecycle2) => {
577
530
  lifecycle2.factory = backendAppApi.lifecycleServiceFactory;
578
- lifecycle2.mock = simpleMock(backendPluginApi.coreServices.lifecycle, () => ({
579
- addShutdownHook: jest.fn(),
580
- addStartupHook: jest.fn()
581
- }));
582
531
  })(mockServices2.lifecycle || (mockServices2.lifecycle = {}));
583
532
  ((logger2) => {
584
533
  logger2.factory = backendAppApi.loggerServiceFactory;
585
- logger2.mock = simpleMock(backendPluginApi.coreServices.logger, () => ({
586
- child: jest.fn(),
587
- debug: jest.fn(),
588
- error: jest.fn(),
589
- info: jest.fn(),
590
- warn: jest.fn()
591
- }));
592
534
  })(mockServices2.logger || (mockServices2.logger = {}));
593
535
  ((permissions2) => {
594
536
  permissions2.factory = backendAppApi.permissionsServiceFactory;
595
- permissions2.mock = simpleMock(backendPluginApi.coreServices.permissions, () => ({
596
- authorize: jest.fn(),
597
- authorizeConditional: jest.fn()
598
- }));
599
537
  })(mockServices2.permissions || (mockServices2.permissions = {}));
600
538
  ((rootLifecycle2) => {
601
539
  rootLifecycle2.factory = backendAppApi.rootLifecycleServiceFactory;
602
- rootLifecycle2.mock = simpleMock(backendPluginApi.coreServices.rootLifecycle, () => ({
603
- addShutdownHook: jest.fn(),
604
- addStartupHook: jest.fn()
605
- }));
606
540
  })(mockServices2.rootLifecycle || (mockServices2.rootLifecycle = {}));
607
541
  ((scheduler2) => {
608
542
  scheduler2.factory = backendAppApi.schedulerServiceFactory;
609
- scheduler2.mock = simpleMock(backendPluginApi.coreServices.scheduler, () => ({
610
- createScheduledTaskRunner: jest.fn(),
611
- getScheduledTasks: jest.fn(),
612
- scheduleTask: jest.fn(),
613
- triggerTask: jest.fn()
614
- }));
615
543
  })(mockServices2.scheduler || (mockServices2.scheduler = {}));
616
544
  ((urlReader2) => {
617
545
  urlReader2.factory = backendAppApi.urlReaderServiceFactory;
618
- urlReader2.mock = simpleMock(backendPluginApi.coreServices.urlReader, () => ({
619
- readTree: jest.fn(),
620
- readUrl: jest.fn(),
621
- search: jest.fn()
622
- }));
623
546
  })(mockServices2.urlReader || (mockServices2.urlReader = {}));
624
547
  })(exports.mockServices || (exports.mockServices = {}));
625
548
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/util/isDockerDisabledForTests.ts","../src/database/startMysqlContainer.ts","../src/database/startPostgresContainer.ts","../src/util/getDockerImageForName.ts","../src/database/types.ts","../src/database/TestDatabases.ts","../src/msw/setupRequestMockHandlers.ts","../src/next/services/MockIdentityService.ts","../src/next/services/MockRootLoggerService.ts","../src/next/services/mockServices.ts","../src/next/wiring/TestBackend.ts"],"sourcesContent":["/*\n * Copyright 2021 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\n/** @public */\nexport function isDockerDisabledForTests() {\n // If we are not running in continuous integration, the default is to skip\n // the (relatively heavy, long running) docker based tests. If you want to\n // still run local tests for all databases, just pass either the CI=1 env\n // parameter to your test runner, or individual connection strings per\n // database.\n return (\n Boolean(process.env.BACKSTAGE_TEST_DISABLE_DOCKER) ||\n !Boolean(process.env.CI)\n );\n}\n","/*\n * Copyright 2021 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 createConnection, { Knex } from 'knex';\nimport { v4 as uuid } from 'uuid';\n\nasync function waitForMysqlReady(\n connection: Knex.MySqlConnectionConfig,\n): Promise<void> {\n const startTime = Date.now();\n const db = createConnection({ client: 'mysql2', connection });\n\n try {\n for (;;) {\n try {\n const result = await db.select(db.raw('version() AS version'));\n if (result[0]?.version) {\n return;\n }\n } catch (e) {\n if (Date.now() - startTime > 30_000) {\n throw new Error(\n `Timed out waiting for the database to be ready for connections, ${e}`,\n );\n }\n }\n\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n } finally {\n db.destroy();\n }\n}\n\nexport async function startMysqlContainer(image: string) {\n const user = 'root';\n const password = uuid();\n\n // Lazy-load to avoid side-effect of importing testcontainers\n const { GenericContainer } = await import('testcontainers');\n\n const container = await new GenericContainer(image)\n .withExposedPorts(3306)\n .withEnv('MYSQL_ROOT_PASSWORD', password)\n .withTmpFs({ '/var/lib/mysql': 'rw' })\n .start();\n\n const host = container.getHost();\n const port = container.getMappedPort(3306);\n const stop = async () => {\n await container.stop({ timeout: 10_000 });\n };\n\n await waitForMysqlReady({ host, port, user, password });\n\n return { host, port, user, password, stop };\n}\n","/*\n * Copyright 2021 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 createConnection, { Knex } from 'knex';\nimport { v4 as uuid } from 'uuid';\n\nasync function waitForPostgresReady(\n connection: Knex.PgConnectionConfig,\n): Promise<void> {\n const startTime = Date.now();\n const db = createConnection({ client: 'pg', connection });\n\n try {\n for (;;) {\n try {\n const result = await db.select(db.raw('version()'));\n if (Array.isArray(result) && result[0]?.version) {\n return;\n }\n } catch (e) {\n if (Date.now() - startTime > 30_000) {\n throw new Error(\n `Timed out waiting for the database to be ready for connections, ${e}`,\n );\n }\n }\n\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n } finally {\n db.destroy();\n }\n}\n\nexport async function startPostgresContainer(image: string) {\n const user = 'postgres';\n const password = uuid();\n\n // Lazy-load to avoid side-effect of importing testcontainers\n const { GenericContainer } = await import('testcontainers');\n\n const container = await new GenericContainer(image)\n .withExposedPorts(5432)\n .withEnv('POSTGRES_PASSWORD', password)\n .withTmpFs({ '/var/lib/postgresql/data': 'rw' })\n .start();\n\n const host = container.getHost();\n const port = container.getMappedPort(5432);\n const stop = async () => {\n await container.stop({ timeout: 10_000 });\n };\n\n await waitForPostgresReady({ host, port, user, password });\n\n return { host, port, user, password, stop };\n}\n","/*\n * Copyright 2021 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\nexport const getDockerImageForName = (name: string) => {\n return process.env.BACKSTAGE_TEST_DOCKER_REGISTRY\n ? `${process.env.BACKSTAGE_TEST_DOCKER_REGISTRY}/${name}`\n : name;\n};\n","/*\n * Copyright 2021 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 { DatabaseManager } from '@backstage/backend-common';\nimport { Knex } from 'knex';\nimport { getDockerImageForName } from '../util/getDockerImageForName';\n\n/**\n * The possible databases to test against.\n *\n * @public\n */\nexport type TestDatabaseId =\n | 'POSTGRES_14'\n | 'POSTGRES_13'\n | 'POSTGRES_12'\n | 'POSTGRES_11'\n | 'POSTGRES_9'\n | 'MYSQL_8'\n | 'SQLITE_3';\n\nexport type TestDatabaseProperties = {\n name: string;\n driver: string;\n dockerImageName?: string;\n connectionStringEnvironmentVariableName?: string;\n};\n\nexport type Instance = {\n stopContainer?: () => Promise<void>;\n databaseManager: DatabaseManager;\n connections: Array<Knex>;\n};\n\nexport const allDatabases: Record<TestDatabaseId, TestDatabaseProperties> =\n Object.freeze({\n POSTGRES_14: {\n name: 'Postgres 14.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:14'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES14_CONNECTION_STRING',\n },\n POSTGRES_13: {\n name: 'Postgres 13.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:13'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES13_CONNECTION_STRING',\n },\n POSTGRES_12: {\n name: 'Postgres 12.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:12'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES12_CONNECTION_STRING',\n },\n POSTGRES_11: {\n name: 'Postgres 11.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:11'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES11_CONNECTION_STRING',\n },\n POSTGRES_9: {\n name: 'Postgres 9.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:9'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES9_CONNECTION_STRING',\n },\n MYSQL_8: {\n name: 'MySQL 8.x',\n driver: 'mysql2',\n dockerImageName: getDockerImageForName('mysql:8'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_MYSQL8_CONNECTION_STRING',\n },\n SQLITE_3: {\n name: 'SQLite 3.x',\n driver: 'better-sqlite3',\n },\n });\n","/*\n * Copyright 2021 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 { DatabaseManager } from '@backstage/backend-common';\nimport { ConfigReader } from '@backstage/config';\nimport { randomBytes } from 'crypto';\nimport { Knex } from 'knex';\nimport { isDockerDisabledForTests } from '../util/isDockerDisabledForTests';\nimport { startMysqlContainer } from './startMysqlContainer';\nimport { startPostgresContainer } from './startPostgresContainer';\nimport {\n allDatabases,\n Instance,\n TestDatabaseId,\n TestDatabaseProperties,\n} from './types';\n\nconst LARGER_POOL_CONFIG = {\n pool: {\n min: 0,\n max: 50,\n },\n};\n\n/**\n * Encapsulates the creation of ephemeral test database instances for use\n * inside unit or integration tests.\n *\n * @public\n */\nexport class TestDatabases {\n private readonly instanceById: Map<string, Instance>;\n private readonly supportedIds: TestDatabaseId[];\n\n /**\n * Creates an empty `TestDatabases` instance, and sets up Jest to clean up\n * all of its acquired resources after all tests finish.\n *\n * You typically want to create just a single instance like this at the top\n * of your test file or `describe` block, and then call `init` many times on\n * that instance inside the individual tests. Spinning up a \"physical\"\n * database instance takes a considerable amount of time, slowing down tests.\n * But initializing a new logical database inside that instance using `init`\n * is very fast.\n */\n static create(options?: {\n ids?: TestDatabaseId[];\n disableDocker?: boolean;\n }): TestDatabases {\n const defaultOptions = {\n ids: Object.keys(allDatabases) as TestDatabaseId[],\n disableDocker: isDockerDisabledForTests(),\n };\n\n const { ids, disableDocker } = Object.assign(\n {},\n defaultOptions,\n options ?? {},\n );\n\n const supportedIds = ids.filter(id => {\n const properties = allDatabases[id];\n if (!properties) {\n return false;\n }\n // If the caller has set up the env with an explicit connection string,\n // we'll assume that this database will work\n if (\n properties.connectionStringEnvironmentVariableName &&\n process.env[properties.connectionStringEnvironmentVariableName]\n ) {\n return true;\n }\n // If the database doesn't require docker at all, there's nothing to worry\n // about\n if (!properties.dockerImageName) {\n return true;\n }\n // If the database requires docker, but docker is disabled, we will fail.\n if (disableDocker) {\n return false;\n }\n return true;\n });\n\n const databases = new TestDatabases(supportedIds);\n\n if (supportedIds.length > 0) {\n afterAll(async () => {\n await databases.shutdown();\n });\n }\n\n return databases;\n }\n\n private constructor(supportedIds: TestDatabaseId[]) {\n this.instanceById = new Map();\n this.supportedIds = supportedIds;\n }\n\n supports(id: TestDatabaseId): boolean {\n return this.supportedIds.includes(id);\n }\n\n eachSupportedId(): [TestDatabaseId][] {\n return this.supportedIds.map(id => [id]);\n }\n\n /**\n * Returns a fresh, unique, empty logical database on an instance of the\n * given database ID platform.\n *\n * @param id - The ID of the database platform to use, e.g. 'POSTGRES_13'\n * @returns A `Knex` connection object\n */\n async init(id: TestDatabaseId): Promise<Knex> {\n const properties = allDatabases[id];\n if (!properties) {\n const candidates = Object.keys(allDatabases).join(', ');\n throw new Error(\n `Unknown test database ${id}, possible values are ${candidates}`,\n );\n }\n if (!this.supportedIds.includes(id)) {\n const candidates = this.supportedIds.join(', ');\n throw new Error(\n `Unsupported test database ${id} for this environment, possible values are ${candidates}`,\n );\n }\n\n let instance: Instance | undefined = this.instanceById.get(id);\n\n // Ensure that a testcontainers instance is up for this ID\n if (!instance) {\n instance = await this.initAny(properties);\n this.instanceById.set(id, instance);\n }\n\n // Ensure that a unique logical database is created in the instance\n const connection = await instance.databaseManager\n .forPlugin(`db${randomBytes(16).toString('hex')}`)\n .getClient();\n\n instance.connections.push(connection);\n\n return connection;\n }\n\n private async initAny(properties: TestDatabaseProperties): Promise<Instance> {\n // Use the connection string if provided\n if (properties.driver === 'pg' || properties.driver === 'mysql2') {\n const envVarName = properties.connectionStringEnvironmentVariableName;\n if (envVarName) {\n const connectionString = process.env[envVarName];\n if (connectionString) {\n const databaseManager = DatabaseManager.fromConfig(\n new ConfigReader({\n backend: {\n database: {\n knexConfig: properties.driver.includes('sqlite')\n ? {}\n : LARGER_POOL_CONFIG,\n client: properties.driver,\n connection: connectionString,\n },\n },\n }),\n );\n return {\n databaseManager,\n connections: [],\n };\n }\n }\n }\n\n // Otherwise start a container for the purpose\n switch (properties.driver) {\n case 'pg':\n return this.initPostgres(properties);\n case 'mysql2':\n return this.initMysql(properties);\n case 'better-sqlite3':\n case 'sqlite3':\n return this.initSqlite(properties);\n default:\n throw new Error(`Unknown database driver ${properties.driver}`);\n }\n }\n\n private async initPostgres(\n properties: TestDatabaseProperties,\n ): Promise<Instance> {\n const { host, port, user, password, stop } = await startPostgresContainer(\n properties.dockerImageName!,\n );\n\n const databaseManager = DatabaseManager.fromConfig(\n new ConfigReader({\n backend: {\n database: {\n knexConfig: LARGER_POOL_CONFIG,\n client: 'pg',\n connection: { host, port, user, password },\n },\n },\n }),\n );\n\n return {\n stopContainer: stop,\n databaseManager,\n connections: [],\n };\n }\n\n private async initMysql(\n properties: TestDatabaseProperties,\n ): Promise<Instance> {\n const { host, port, user, password, stop } = await startMysqlContainer(\n properties.dockerImageName!,\n );\n\n const databaseManager = DatabaseManager.fromConfig(\n new ConfigReader({\n backend: {\n database: {\n knexConfig: LARGER_POOL_CONFIG,\n client: 'mysql2',\n connection: { host, port, user, password },\n },\n },\n }),\n );\n\n return {\n stopContainer: stop,\n databaseManager,\n connections: [],\n };\n }\n\n private async initSqlite(\n properties: TestDatabaseProperties,\n ): Promise<Instance> {\n const databaseManager = DatabaseManager.fromConfig(\n new ConfigReader({\n backend: {\n database: {\n client: properties.driver,\n connection: ':memory:',\n },\n },\n }),\n );\n\n return {\n databaseManager,\n connections: [],\n };\n }\n\n private async shutdown() {\n const instances = [...this.instanceById.values()];\n await Promise.all(\n instances.map(async ({ stopContainer, connections }) => {\n try {\n await Promise.all(connections.map(c => c.destroy()));\n } catch {\n // ignore\n }\n try {\n await stopContainer?.();\n } catch {\n // ignore\n }\n }),\n );\n }\n}\n","/*\n * Copyright 2020 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\n/**\n * Sets up handlers for request mocking\n * @public\n * @param worker - service worker\n */\nexport function setupRequestMockHandlers(worker: {\n listen: (t: any) => void;\n close: () => void;\n resetHandlers: () => void;\n}) {\n beforeAll(() => worker.listen({ onUnhandledRequest: 'error' }));\n afterAll(() => worker.close());\n afterEach(() => worker.resetHandlers());\n}\n","/*\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 */\nimport { IdentityService } from '@backstage/backend-plugin-api';\nimport {\n IdentityApiGetIdentityRequest,\n BackstageIdentityResponse,\n} from '@backstage/plugin-auth-node';\n\nexport class MockIdentityService implements IdentityService {\n getIdentity(\n _options: IdentityApiGetIdentityRequest,\n ): Promise<BackstageIdentityResponse | undefined> {\n return Promise.resolve({\n token: 'mock-token',\n identity: {\n type: 'user',\n userEntityRef: 'user:default/mock-user',\n ownershipEntityRefs: [],\n },\n });\n }\n}\n","/*\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","/*\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 RootConfigService,\n coreServices,\n createServiceFactory,\n IdentityService,\n LoggerService,\n ServiceFactory,\n ServiceRef,\n TokenManagerService,\n} from '@backstage/backend-plugin-api';\nimport {\n cacheServiceFactory,\n databaseServiceFactory,\n httpRouterServiceFactory,\n lifecycleServiceFactory,\n loggerServiceFactory,\n permissionsServiceFactory,\n rootLifecycleServiceFactory,\n schedulerServiceFactory,\n urlReaderServiceFactory,\n} from '@backstage/backend-app-api';\nimport { ConfigReader } from '@backstage/config';\nimport { JsonObject } from '@backstage/types';\nimport { MockIdentityService } from './MockIdentityService';\nimport { MockRootLoggerService } from './MockRootLoggerService';\n\n/** @internal */\nfunction simpleFactory<\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 return createServiceFactory((options: unknown) => ({\n service: ref as ServiceRef<TService, any>,\n deps: {},\n async factory() {\n return (factory as any)(options);\n },\n })) as (...options: TOptions) => ServiceFactory<TService, any>;\n}\n\n/** @public */\nexport type ServiceMock<TService> = {\n factory: ServiceFactory<TService>;\n} & {\n [Key in keyof TService]: TService[Key] extends (\n this: infer This,\n ...args: infer Args\n ) => infer Return\n ? TService[Key] & jest.MockInstance<Return, Args, This>\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 * @public\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 = simpleFactory(coreServices.rootConfig, rootConfig);\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 = simpleFactory(coreServices.rootLogger, rootLogger);\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 function tokenManager(): TokenManagerService {\n return {\n async getToken(): Promise<{ token: string }> {\n return { token: 'mock-token' };\n },\n async authenticate(token: string): Promise<void> {\n if (token !== 'mock-token') {\n throw new Error('Invalid token');\n }\n },\n };\n }\n export namespace tokenManager {\n export const factory = simpleFactory(\n coreServices.tokenManager,\n tokenManager,\n );\n export const mock = simpleMock(coreServices.tokenManager, () => ({\n authenticate: jest.fn(),\n getToken: jest.fn(),\n }));\n }\n\n export function identity(): IdentityService {\n return new MockIdentityService();\n }\n export namespace identity {\n export const factory = simpleFactory(coreServices.identity, identity);\n export const mock = simpleMock(coreServices.identity, () => ({\n getIdentity: 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 export namespace database {\n export const factory = databaseServiceFactory;\n export const mock = simpleMock(coreServices.database, () => ({\n getClient: jest.fn(),\n }));\n }\n export namespace httpRouter {\n export const factory = httpRouterServiceFactory;\n export const mock = simpleMock(coreServices.httpRouter, () => ({\n use: jest.fn(),\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 export namespace logger {\n export const factory = loggerServiceFactory;\n export const mock = simpleMock(coreServices.logger, () => ({\n child: jest.fn(),\n debug: jest.fn(),\n error: jest.fn(),\n info: jest.fn(),\n warn: jest.fn(),\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 export namespace rootLifecycle {\n export const factory = rootLifecycleServiceFactory;\n export const mock = simpleMock(coreServices.rootLifecycle, () => ({\n addShutdownHook: jest.fn(),\n addStartupHook: jest.fn(),\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 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 * 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 {\n Backend,\n createSpecializedBackend,\n MiddlewareFactory,\n createHttpServer,\n ExtendedHttpServer,\n DefaultRootHttpRouter,\n} from '@backstage/backend-app-api';\nimport { HostDiscovery } from '@backstage/backend-common';\nimport {\n createServiceFactory,\n BackendFeature,\n ExtensionPoint,\n coreServices,\n createBackendModule,\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-forbidden-package-imports\nimport { InternalBackendFeature } from '@backstage/backend-plugin-api/src/wiring/types';\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 | (() => 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\nconst defaultServiceFactories = [\n mockServices.cache.factory(),\n mockServices.rootConfig.factory(),\n mockServices.database.factory(),\n mockServices.httpRouter.factory(),\n mockServices.identity.factory(),\n mockServices.lifecycle.factory(),\n mockServices.logger.factory(),\n mockServices.permissions.factory(),\n mockServices.rootLifecycle.factory(),\n mockServices.rootLogger.factory(),\n mockServices.scheduler.factory(),\n mockServices.tokenManager.factory(),\n mockServices.urlReader.factory(),\n];\n\n/**\n * Given a set of extension points and plugins, find\n * @returns\n */\nfunction createExtensionPointTestModules(\n features: Array<BackendFeature | (() => 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(featureOrFunction => {\n const feature =\n typeof featureOrFunction === 'function'\n ? featureOrFunction()\n : featureOrFunction;\n\n if (feature.$$type !== '@backstage/BackendFeature') {\n throw new Error(\n `Failed to add feature, invalid type '${feature.$$type}'`,\n );\n }\n\n if (isInternalBackendFeature(feature)) {\n if (feature.version !== 'v1') {\n throw new Error(\n `Failed to add feature, invalid version '${feature.version}'`,\n );\n }\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: 'testExtensionPointRegistration',\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\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, features = [], ...otherOptions } = options;\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 },\n async factory({ config, lifecycle, rootLogger }) {\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\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\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 isInternalBackendFeature(\n feature: BackendFeature,\n): feature is InternalBackendFeature {\n return (\n typeof (feature as InternalBackendFeature).getRegistrations === 'function'\n );\n}\n"],"names":["createConnection","uuid","randomBytes","DatabaseManager","ConfigReader","createServiceFactory","mockServices","rootConfig","coreServices","rootLogger","tokenManager","identity","cache","cacheServiceFactory","database","databaseServiceFactory","httpRouter","httpRouterServiceFactory","lifecycle","lifecycleServiceFactory","logger","loggerServiceFactory","permissions","permissionsServiceFactory","rootLifecycle","rootLifecycleServiceFactory","scheduler","schedulerServiceFactory","urlReader","urlReaderServiceFactory","createBackendModule","DefaultRootHttpRouter","express","MiddlewareFactory","createHttpServer","HostDiscovery","createSpecializedBackend"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/util/isDockerDisabledForTests.ts","../src/database/startMysqlContainer.ts","../src/database/startPostgresContainer.ts","../src/util/getDockerImageForName.ts","../src/database/types.ts","../src/database/TestDatabases.ts","../src/msw/setupRequestMockHandlers.ts","../src/next/services/MockIdentityService.ts","../src/next/services/MockRootLoggerService.ts","../src/next/services/mockServices.ts","../src/next/wiring/TestBackend.ts"],"sourcesContent":["/*\n * Copyright 2021 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\n/** @public */\nexport function isDockerDisabledForTests() {\n // If we are not running in continuous integration, the default is to skip\n // the (relatively heavy, long running) docker based tests. If you want to\n // still run local tests for all databases, just pass either the CI=1 env\n // parameter to your test runner, or individual connection strings per\n // database.\n return (\n Boolean(process.env.BACKSTAGE_TEST_DISABLE_DOCKER) ||\n !Boolean(process.env.CI)\n );\n}\n","/*\n * Copyright 2021 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 createConnection, { Knex } from 'knex';\nimport { v4 as uuid } from 'uuid';\n\nasync function waitForMysqlReady(\n connection: Knex.MySqlConnectionConfig,\n): Promise<void> {\n const startTime = Date.now();\n const db = createConnection({ client: 'mysql2', connection });\n\n try {\n for (;;) {\n try {\n const result = await db.select(db.raw('version() AS version'));\n if (result[0]?.version) {\n return;\n }\n } catch (e) {\n if (Date.now() - startTime > 30_000) {\n throw new Error(\n `Timed out waiting for the database to be ready for connections, ${e}`,\n );\n }\n }\n\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n } finally {\n db.destroy();\n }\n}\n\nexport async function startMysqlContainer(image: string) {\n const user = 'root';\n const password = uuid();\n\n // Lazy-load to avoid side-effect of importing testcontainers\n const { GenericContainer } = await import('testcontainers');\n\n const container = await new GenericContainer(image)\n .withExposedPorts(3306)\n .withEnv('MYSQL_ROOT_PASSWORD', password)\n .withTmpFs({ '/var/lib/mysql': 'rw' })\n .start();\n\n const host = container.getHost();\n const port = container.getMappedPort(3306);\n const stop = async () => {\n await container.stop({ timeout: 10_000 });\n };\n\n await waitForMysqlReady({ host, port, user, password });\n\n return { host, port, user, password, stop };\n}\n","/*\n * Copyright 2021 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 createConnection, { Knex } from 'knex';\nimport { v4 as uuid } from 'uuid';\n\nasync function waitForPostgresReady(\n connection: Knex.PgConnectionConfig,\n): Promise<void> {\n const startTime = Date.now();\n const db = createConnection({ client: 'pg', connection });\n\n try {\n for (;;) {\n try {\n const result = await db.select(db.raw('version()'));\n if (Array.isArray(result) && result[0]?.version) {\n return;\n }\n } catch (e) {\n if (Date.now() - startTime > 30_000) {\n throw new Error(\n `Timed out waiting for the database to be ready for connections, ${e}`,\n );\n }\n }\n\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n } finally {\n db.destroy();\n }\n}\n\nexport async function startPostgresContainer(image: string) {\n const user = 'postgres';\n const password = uuid();\n\n // Lazy-load to avoid side-effect of importing testcontainers\n const { GenericContainer } = await import('testcontainers');\n\n const container = await new GenericContainer(image)\n .withExposedPorts(5432)\n .withEnv('POSTGRES_PASSWORD', password)\n .withTmpFs({ '/var/lib/postgresql/data': 'rw' })\n .start();\n\n const host = container.getHost();\n const port = container.getMappedPort(5432);\n const stop = async () => {\n await container.stop({ timeout: 10_000 });\n };\n\n await waitForPostgresReady({ host, port, user, password });\n\n return { host, port, user, password, stop };\n}\n","/*\n * Copyright 2021 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\nexport const getDockerImageForName = (name: string) => {\n return process.env.BACKSTAGE_TEST_DOCKER_REGISTRY\n ? `${process.env.BACKSTAGE_TEST_DOCKER_REGISTRY}/${name}`\n : name;\n};\n","/*\n * Copyright 2021 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 { DatabaseManager } from '@backstage/backend-common';\nimport { Knex } from 'knex';\nimport { getDockerImageForName } from '../util/getDockerImageForName';\n\n/**\n * The possible databases to test against.\n *\n * @public\n */\nexport type TestDatabaseId =\n | 'POSTGRES_14'\n | 'POSTGRES_13'\n | 'POSTGRES_12'\n | 'POSTGRES_11'\n | 'POSTGRES_9'\n | 'MYSQL_8'\n | 'SQLITE_3';\n\nexport type TestDatabaseProperties = {\n name: string;\n driver: string;\n dockerImageName?: string;\n connectionStringEnvironmentVariableName?: string;\n};\n\nexport type Instance = {\n stopContainer?: () => Promise<void>;\n databaseManager: DatabaseManager;\n connections: Array<Knex>;\n};\n\nexport const allDatabases: Record<TestDatabaseId, TestDatabaseProperties> =\n Object.freeze({\n POSTGRES_14: {\n name: 'Postgres 14.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:14'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES14_CONNECTION_STRING',\n },\n POSTGRES_13: {\n name: 'Postgres 13.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:13'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES13_CONNECTION_STRING',\n },\n POSTGRES_12: {\n name: 'Postgres 12.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:12'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES12_CONNECTION_STRING',\n },\n POSTGRES_11: {\n name: 'Postgres 11.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:11'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES11_CONNECTION_STRING',\n },\n POSTGRES_9: {\n name: 'Postgres 9.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:9'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES9_CONNECTION_STRING',\n },\n MYSQL_8: {\n name: 'MySQL 8.x',\n driver: 'mysql2',\n dockerImageName: getDockerImageForName('mysql:8'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_MYSQL8_CONNECTION_STRING',\n },\n SQLITE_3: {\n name: 'SQLite 3.x',\n driver: 'better-sqlite3',\n },\n });\n","/*\n * Copyright 2021 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 { DatabaseManager } from '@backstage/backend-common';\nimport { ConfigReader } from '@backstage/config';\nimport { randomBytes } from 'crypto';\nimport { Knex } from 'knex';\nimport { isDockerDisabledForTests } from '../util/isDockerDisabledForTests';\nimport { startMysqlContainer } from './startMysqlContainer';\nimport { startPostgresContainer } from './startPostgresContainer';\nimport {\n allDatabases,\n Instance,\n TestDatabaseId,\n TestDatabaseProperties,\n} from './types';\n\nconst LARGER_POOL_CONFIG = {\n pool: {\n min: 0,\n max: 50,\n },\n};\n\n/**\n * Encapsulates the creation of ephemeral test database instances for use\n * inside unit or integration tests.\n *\n * @public\n */\nexport class TestDatabases {\n private readonly instanceById: Map<string, Instance>;\n private readonly supportedIds: TestDatabaseId[];\n\n /**\n * Creates an empty `TestDatabases` instance, and sets up Jest to clean up\n * all of its acquired resources after all tests finish.\n *\n * You typically want to create just a single instance like this at the top\n * of your test file or `describe` block, and then call `init` many times on\n * that instance inside the individual tests. Spinning up a \"physical\"\n * database instance takes a considerable amount of time, slowing down tests.\n * But initializing a new logical database inside that instance using `init`\n * is very fast.\n */\n static create(options?: {\n ids?: TestDatabaseId[];\n disableDocker?: boolean;\n }): TestDatabases {\n const defaultOptions = {\n ids: Object.keys(allDatabases) as TestDatabaseId[],\n disableDocker: isDockerDisabledForTests(),\n };\n\n const { ids, disableDocker } = Object.assign(\n {},\n defaultOptions,\n options ?? {},\n );\n\n const supportedIds = ids.filter(id => {\n const properties = allDatabases[id];\n if (!properties) {\n return false;\n }\n // If the caller has set up the env with an explicit connection string,\n // we'll assume that this database will work\n if (\n properties.connectionStringEnvironmentVariableName &&\n process.env[properties.connectionStringEnvironmentVariableName]\n ) {\n return true;\n }\n // If the database doesn't require docker at all, there's nothing to worry\n // about\n if (!properties.dockerImageName) {\n return true;\n }\n // If the database requires docker, but docker is disabled, we will fail.\n if (disableDocker) {\n return false;\n }\n return true;\n });\n\n const databases = new TestDatabases(supportedIds);\n\n if (supportedIds.length > 0) {\n afterAll(async () => {\n await databases.shutdown();\n });\n }\n\n return databases;\n }\n\n private constructor(supportedIds: TestDatabaseId[]) {\n this.instanceById = new Map();\n this.supportedIds = supportedIds;\n }\n\n supports(id: TestDatabaseId): boolean {\n return this.supportedIds.includes(id);\n }\n\n eachSupportedId(): [TestDatabaseId][] {\n return this.supportedIds.map(id => [id]);\n }\n\n /**\n * Returns a fresh, unique, empty logical database on an instance of the\n * given database ID platform.\n *\n * @param id - The ID of the database platform to use, e.g. 'POSTGRES_13'\n * @returns A `Knex` connection object\n */\n async init(id: TestDatabaseId): Promise<Knex> {\n const properties = allDatabases[id];\n if (!properties) {\n const candidates = Object.keys(allDatabases).join(', ');\n throw new Error(\n `Unknown test database ${id}, possible values are ${candidates}`,\n );\n }\n if (!this.supportedIds.includes(id)) {\n const candidates = this.supportedIds.join(', ');\n throw new Error(\n `Unsupported test database ${id} for this environment, possible values are ${candidates}`,\n );\n }\n\n let instance: Instance | undefined = this.instanceById.get(id);\n\n // Ensure that a testcontainers instance is up for this ID\n if (!instance) {\n instance = await this.initAny(properties);\n this.instanceById.set(id, instance);\n }\n\n // Ensure that a unique logical database is created in the instance\n const connection = await instance.databaseManager\n .forPlugin(`db${randomBytes(16).toString('hex')}`)\n .getClient();\n\n instance.connections.push(connection);\n\n return connection;\n }\n\n private async initAny(properties: TestDatabaseProperties): Promise<Instance> {\n // Use the connection string if provided\n if (properties.driver === 'pg' || properties.driver === 'mysql2') {\n const envVarName = properties.connectionStringEnvironmentVariableName;\n if (envVarName) {\n const connectionString = process.env[envVarName];\n if (connectionString) {\n const databaseManager = DatabaseManager.fromConfig(\n new ConfigReader({\n backend: {\n database: {\n knexConfig: properties.driver.includes('sqlite')\n ? {}\n : LARGER_POOL_CONFIG,\n client: properties.driver,\n connection: connectionString,\n },\n },\n }),\n );\n return {\n databaseManager,\n connections: [],\n };\n }\n }\n }\n\n // Otherwise start a container for the purpose\n switch (properties.driver) {\n case 'pg':\n return this.initPostgres(properties);\n case 'mysql2':\n return this.initMysql(properties);\n case 'better-sqlite3':\n case 'sqlite3':\n return this.initSqlite(properties);\n default:\n throw new Error(`Unknown database driver ${properties.driver}`);\n }\n }\n\n private async initPostgres(\n properties: TestDatabaseProperties,\n ): Promise<Instance> {\n const { host, port, user, password, stop } = await startPostgresContainer(\n properties.dockerImageName!,\n );\n\n const databaseManager = DatabaseManager.fromConfig(\n new ConfigReader({\n backend: {\n database: {\n knexConfig: LARGER_POOL_CONFIG,\n client: 'pg',\n connection: { host, port, user, password },\n },\n },\n }),\n );\n\n return {\n stopContainer: stop,\n databaseManager,\n connections: [],\n };\n }\n\n private async initMysql(\n properties: TestDatabaseProperties,\n ): Promise<Instance> {\n const { host, port, user, password, stop } = await startMysqlContainer(\n properties.dockerImageName!,\n );\n\n const databaseManager = DatabaseManager.fromConfig(\n new ConfigReader({\n backend: {\n database: {\n knexConfig: LARGER_POOL_CONFIG,\n client: 'mysql2',\n connection: { host, port, user, password },\n },\n },\n }),\n );\n\n return {\n stopContainer: stop,\n databaseManager,\n connections: [],\n };\n }\n\n private async initSqlite(\n properties: TestDatabaseProperties,\n ): Promise<Instance> {\n const databaseManager = DatabaseManager.fromConfig(\n new ConfigReader({\n backend: {\n database: {\n client: properties.driver,\n connection: ':memory:',\n },\n },\n }),\n );\n\n return {\n databaseManager,\n connections: [],\n };\n }\n\n private async shutdown() {\n const instances = [...this.instanceById.values()];\n await Promise.all(\n instances.map(async ({ stopContainer, connections }) => {\n try {\n await Promise.all(connections.map(c => c.destroy()));\n } catch {\n // ignore\n }\n try {\n await stopContainer?.();\n } catch {\n // ignore\n }\n }),\n );\n }\n}\n","/*\n * Copyright 2020 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\n/**\n * Sets up handlers for request mocking\n * @public\n * @param worker - service worker\n */\nexport function setupRequestMockHandlers(worker: {\n listen: (t: any) => void;\n close: () => void;\n resetHandlers: () => void;\n}) {\n beforeAll(() => worker.listen({ onUnhandledRequest: 'error' }));\n afterAll(() => worker.close());\n afterEach(() => worker.resetHandlers());\n}\n","/*\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 */\nimport { IdentityService } from '@backstage/backend-plugin-api';\nimport {\n IdentityApiGetIdentityRequest,\n BackstageIdentityResponse,\n} from '@backstage/plugin-auth-node';\n\nexport class MockIdentityService implements IdentityService {\n getIdentity(\n _options: IdentityApiGetIdentityRequest,\n ): Promise<BackstageIdentityResponse | undefined> {\n return Promise.resolve({\n token: 'mock-token',\n identity: {\n type: 'user',\n userEntityRef: 'user:default/mock-user',\n ownershipEntityRefs: [],\n },\n });\n }\n}\n","/*\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","/*\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 RootConfigService,\n coreServices,\n createServiceFactory,\n IdentityService,\n LoggerService,\n ServiceFactory,\n ServiceRef,\n TokenManagerService,\n} from '@backstage/backend-plugin-api';\nimport {\n cacheServiceFactory,\n databaseServiceFactory,\n httpRouterServiceFactory,\n lifecycleServiceFactory,\n loggerServiceFactory,\n permissionsServiceFactory,\n rootLifecycleServiceFactory,\n schedulerServiceFactory,\n urlReaderServiceFactory,\n} from '@backstage/backend-app-api';\nimport { ConfigReader } from '@backstage/config';\nimport { JsonObject } from '@backstage/types';\nimport { MockIdentityService } from './MockIdentityService';\nimport { MockRootLoggerService } from './MockRootLoggerService';\n\nfunction simpleFactory<\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 return createServiceFactory((options: unknown) => ({\n service: ref as ServiceRef<TService, any>,\n deps: {},\n async factory() {\n return (factory as any)(options);\n },\n })) as (...options: TOptions) => ServiceFactory<TService, any>;\n}\n\n/**\n * @public\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 = simpleFactory(coreServices.rootConfig, rootConfig);\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 = simpleFactory(coreServices.rootLogger, rootLogger);\n }\n\n export function tokenManager(): TokenManagerService {\n return {\n async getToken(): Promise<{ token: string }> {\n return { token: 'mock-token' };\n },\n async authenticate(token: string): Promise<void> {\n if (token !== 'mock-token') {\n throw new Error('Invalid token');\n }\n },\n };\n }\n export namespace tokenManager {\n export const factory = simpleFactory(\n coreServices.tokenManager,\n tokenManager,\n );\n }\n\n export function identity(): IdentityService {\n return new MockIdentityService();\n }\n export namespace identity {\n export const factory = simpleFactory(coreServices.identity, identity);\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 }\n export namespace database {\n export const factory = databaseServiceFactory;\n }\n export namespace httpRouter {\n export const factory = httpRouterServiceFactory;\n }\n export namespace lifecycle {\n export const factory = lifecycleServiceFactory;\n }\n export namespace logger {\n export const factory = loggerServiceFactory;\n }\n export namespace permissions {\n export const factory = permissionsServiceFactory;\n }\n export namespace rootLifecycle {\n export const factory = rootLifecycleServiceFactory;\n }\n export namespace scheduler {\n export const factory = schedulerServiceFactory;\n }\n export namespace urlReader {\n export const factory = urlReaderServiceFactory;\n }\n}\n","/*\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 {\n Backend,\n createSpecializedBackend,\n MiddlewareFactory,\n createHttpServer,\n ExtendedHttpServer,\n DefaultRootHttpRouter,\n} from '@backstage/backend-app-api';\nimport { HostDiscovery } from '@backstage/backend-common';\nimport {\n createServiceFactory,\n BackendFeature,\n ExtensionPoint,\n coreServices,\n createBackendModule,\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-forbidden-package-imports\nimport { InternalBackendFeature } from '@backstage/backend-plugin-api/src/wiring/types';\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 | (() => 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\nconst defaultServiceFactories = [\n mockServices.cache.factory(),\n mockServices.rootConfig.factory(),\n mockServices.database.factory(),\n mockServices.httpRouter.factory(),\n mockServices.identity.factory(),\n mockServices.lifecycle.factory(),\n mockServices.logger.factory(),\n mockServices.permissions.factory(),\n mockServices.rootLifecycle.factory(),\n mockServices.rootLogger.factory(),\n mockServices.scheduler.factory(),\n mockServices.tokenManager.factory(),\n mockServices.urlReader.factory(),\n];\n\n/**\n * Given a set of extension points and plugins, find\n * @returns\n */\nfunction createExtensionPointTestModules(\n features: Array<BackendFeature | (() => 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(featureOrFunction => {\n const feature =\n typeof featureOrFunction === 'function'\n ? featureOrFunction()\n : featureOrFunction;\n\n if (feature.$$type !== '@backstage/BackendFeature') {\n throw new Error(\n `Failed to add feature, invalid type '${feature.$$type}'`,\n );\n }\n\n if (isInternalBackendFeature(feature)) {\n if (feature.version !== 'v1') {\n throw new Error(\n `Failed to add feature, invalid version '${feature.version}'`,\n );\n }\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: 'testExtensionPointRegistration',\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\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, features = [], ...otherOptions } = options;\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 },\n async factory({ config, lifecycle, rootLogger }) {\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\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\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 isInternalBackendFeature(\n feature: BackendFeature,\n): feature is InternalBackendFeature {\n return (\n typeof (feature as InternalBackendFeature).getRegistrations === 'function'\n );\n}\n"],"names":["createConnection","uuid","randomBytes","DatabaseManager","ConfigReader","createServiceFactory","mockServices","rootConfig","coreServices","rootLogger","tokenManager","identity","cache","cacheServiceFactory","database","databaseServiceFactory","httpRouter","httpRouterServiceFactory","lifecycle","lifecycleServiceFactory","logger","loggerServiceFactory","permissions","permissionsServiceFactory","rootLifecycle","rootLifecycleServiceFactory","scheduler","schedulerServiceFactory","urlReader","urlReaderServiceFactory","createBackendModule","DefaultRootHttpRouter","express","MiddlewareFactory","createHttpServer","HostDiscovery","createSpecializedBackend"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,9 +1,8 @@
1
- /// <reference types="jest" />
2
1
  import { Knex } from 'knex';
3
2
  import * as _backstage_backend_app_api from '@backstage/backend-app-api';
4
3
  import { Backend, ExtendedHttpServer } from '@backstage/backend-app-api';
5
4
  import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
6
- import { ExtensionPoint, BackendFeature, ServiceFactory, RootConfigService, LoggerService, TokenManagerService, IdentityService } from '@backstage/backend-plugin-api';
5
+ import { ExtensionPoint, BackendFeature, RootConfigService, ServiceFactory, LoggerService, TokenManagerService, IdentityService } from '@backstage/backend-plugin-api';
7
6
  import { JsonObject } from '@backstage/types';
8
7
 
9
8
  /** @public */
@@ -94,12 +93,6 @@ interface TestBackend extends Backend {
94
93
  /** @public */
95
94
  declare function startTestBackend<TExtensionPoints extends any[]>(options: TestBackendOptions<TExtensionPoints>): Promise<TestBackend>;
96
95
 
97
- /** @public */
98
- type ServiceMock<TService> = {
99
- factory: ServiceFactory<TService>;
100
- } & {
101
- [Key in keyof TService]: TService[Key] extends (this: infer This, ...args: infer Args) => infer Return ? TService[Key] & jest.MockInstance<Return, Args, This> : TService[Key];
102
- };
103
96
  /**
104
97
  * @public
105
98
  */
@@ -117,54 +110,42 @@ declare namespace mockServices {
117
110
  level?: 'none' | 'error' | 'warn' | 'info' | 'debug';
118
111
  };
119
112
  const factory: (options?: Options | undefined) => ServiceFactory<LoggerService, "root">;
120
- const mock: (partialImpl?: Partial<_backstage_backend_plugin_api.RootLoggerService> | undefined) => ServiceMock<_backstage_backend_plugin_api.RootLoggerService>;
121
113
  }
122
114
  function tokenManager(): TokenManagerService;
123
115
  namespace tokenManager {
124
116
  const factory: () => ServiceFactory<TokenManagerService, "plugin">;
125
- const mock: (partialImpl?: Partial<TokenManagerService> | undefined) => ServiceMock<TokenManagerService>;
126
117
  }
127
118
  function identity(): IdentityService;
128
119
  namespace identity {
129
120
  const factory: () => ServiceFactory<IdentityService, "plugin">;
130
- const mock: (partialImpl?: Partial<IdentityService> | undefined) => ServiceMock<IdentityService>;
131
121
  }
132
122
  namespace cache {
133
123
  const factory: () => ServiceFactory<_backstage_backend_plugin_api.CacheService, "plugin">;
134
- const mock: (partialImpl?: Partial<_backstage_backend_plugin_api.CacheService> | undefined) => ServiceMock<_backstage_backend_plugin_api.CacheService>;
135
124
  }
136
125
  namespace database {
137
126
  const factory: () => ServiceFactory<_backstage_backend_plugin_api.DatabaseService, "plugin">;
138
- const mock: (partialImpl?: Partial<_backstage_backend_plugin_api.DatabaseService> | undefined) => ServiceMock<_backstage_backend_plugin_api.DatabaseService>;
139
127
  }
140
128
  namespace httpRouter {
141
129
  const factory: (options?: _backstage_backend_app_api.HttpRouterFactoryOptions | undefined) => ServiceFactory<_backstage_backend_plugin_api.HttpRouterService, "plugin">;
142
- const mock: (partialImpl?: Partial<_backstage_backend_plugin_api.HttpRouterService> | undefined) => ServiceMock<_backstage_backend_plugin_api.HttpRouterService>;
143
130
  }
144
131
  namespace lifecycle {
145
132
  const factory: () => ServiceFactory<_backstage_backend_plugin_api.LifecycleService, "plugin">;
146
- const mock: (partialImpl?: Partial<_backstage_backend_plugin_api.LifecycleService> | undefined) => ServiceMock<_backstage_backend_plugin_api.LifecycleService>;
147
133
  }
148
134
  namespace logger {
149
135
  const factory: () => ServiceFactory<LoggerService, "plugin">;
150
- const mock: (partialImpl?: Partial<LoggerService> | undefined) => ServiceMock<LoggerService>;
151
136
  }
152
137
  namespace permissions {
153
138
  const factory: () => ServiceFactory<_backstage_backend_plugin_api.PermissionsService, "plugin">;
154
- const mock: (partialImpl?: Partial<_backstage_backend_plugin_api.PermissionsService> | undefined) => ServiceMock<_backstage_backend_plugin_api.PermissionsService>;
155
139
  }
156
140
  namespace rootLifecycle {
157
141
  const factory: () => ServiceFactory<_backstage_backend_plugin_api.RootLifecycleService, "root">;
158
- const mock: (partialImpl?: Partial<_backstage_backend_plugin_api.RootLifecycleService> | undefined) => ServiceMock<_backstage_backend_plugin_api.RootLifecycleService>;
159
142
  }
160
143
  namespace scheduler {
161
144
  const factory: () => ServiceFactory<_backstage_backend_plugin_api.SchedulerService, "plugin">;
162
- const mock: (partialImpl?: Partial<_backstage_backend_plugin_api.SchedulerService> | undefined) => ServiceMock<_backstage_backend_plugin_api.SchedulerService>;
163
145
  }
164
146
  namespace urlReader {
165
147
  const factory: () => ServiceFactory<_backstage_backend_plugin_api.UrlReaderService, "plugin">;
166
- const mock: (partialImpl?: Partial<_backstage_backend_plugin_api.UrlReaderService> | undefined) => ServiceMock<_backstage_backend_plugin_api.UrlReaderService>;
167
148
  }
168
149
  }
169
150
 
170
- export { ServiceMock, TestBackend, TestBackendOptions, TestDatabaseId, TestDatabases, isDockerDisabledForTests, mockServices, setupRequestMockHandlers, startTestBackend };
151
+ export { TestBackend, TestBackendOptions, TestDatabaseId, TestDatabases, isDockerDisabledForTests, mockServices, setupRequestMockHandlers, startTestBackend };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@backstage/backend-test-utils",
3
3
  "description": "Test helpers library for Backstage backends",
4
- "version": "0.2.2-next.0",
4
+ "version": "0.2.2",
5
5
  "main": "./dist/index.cjs.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "publishConfig": {
@@ -39,11 +39,11 @@
39
39
  "start": "backstage-cli package start"
40
40
  },
41
41
  "dependencies": {
42
- "@backstage/backend-app-api": "^0.5.2-next.0",
43
- "@backstage/backend-common": "^0.19.4-next.0",
44
- "@backstage/backend-plugin-api": "^0.6.2-next.0",
42
+ "@backstage/backend-app-api": "^0.5.2",
43
+ "@backstage/backend-common": "^0.19.4",
44
+ "@backstage/backend-plugin-api": "^0.6.2",
45
45
  "@backstage/config": "^1.0.8",
46
- "@backstage/plugin-auth-node": "^0.3.0-next.0",
46
+ "@backstage/plugin-auth-node": "^0.2.19",
47
47
  "@backstage/types": "^1.1.0",
48
48
  "better-sqlite3": "^8.0.0",
49
49
  "express": "^4.17.1",
@@ -54,11 +54,8 @@
54
54
  "testcontainers": "^8.1.2",
55
55
  "uuid": "^8.0.0"
56
56
  },
57
- "peerDependencies": {
58
- "@types/jest": "*"
59
- },
60
57
  "devDependencies": {
61
- "@backstage/cli": "^0.22.12-next.0",
58
+ "@backstage/cli": "^0.22.12",
62
59
  "@types/supertest": "^2.0.8",
63
60
  "supertest": "^6.1.3"
64
61
  },