@backstage/backend-test-utils 1.0.1-next.1 → 1.0.1-next.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/backend-app-api/src/lib/DependencyGraph.cjs.js +182 -0
  3. package/dist/backend-app-api/src/lib/DependencyGraph.cjs.js.map +1 -0
  4. package/dist/backend-app-api/src/wiring/ServiceRegistry.cjs.js +240 -0
  5. package/dist/backend-app-api/src/wiring/ServiceRegistry.cjs.js.map +1 -0
  6. package/dist/cache/TestCaches.cjs.js +159 -0
  7. package/dist/cache/TestCaches.cjs.js.map +1 -0
  8. package/dist/cache/memcache.cjs.js +62 -0
  9. package/dist/cache/memcache.cjs.js.map +1 -0
  10. package/dist/cache/redis.cjs.js +62 -0
  11. package/dist/cache/redis.cjs.js.map +1 -0
  12. package/dist/cache/types.cjs.js +25 -0
  13. package/dist/cache/types.cjs.js.map +1 -0
  14. package/dist/database/TestDatabases.cjs.js +128 -0
  15. package/dist/database/TestDatabases.cjs.js.map +1 -0
  16. package/dist/database/mysql.cjs.js +188 -0
  17. package/dist/database/mysql.cjs.js.map +1 -0
  18. package/dist/database/postgres.cjs.js +143 -0
  19. package/dist/database/postgres.cjs.js.map +1 -0
  20. package/dist/database/sqlite.cjs.js +40 -0
  21. package/dist/database/sqlite.cjs.js.map +1 -0
  22. package/dist/database/types.cjs.js +68 -0
  23. package/dist/database/types.cjs.js.map +1 -0
  24. package/dist/filesystem/MockDirectory.cjs.js +152 -0
  25. package/dist/filesystem/MockDirectory.cjs.js.map +1 -0
  26. package/dist/index.cjs.js +25 -2327
  27. package/dist/index.cjs.js.map +1 -1
  28. package/dist/msw/registerMswTestHooks.cjs.js +10 -0
  29. package/dist/msw/registerMswTestHooks.cjs.js.map +1 -0
  30. package/dist/next/services/MockAuthService.cjs.js +111 -0
  31. package/dist/next/services/MockAuthService.cjs.js.map +1 -0
  32. package/dist/next/services/MockHttpAuthService.cjs.js +87 -0
  33. package/dist/next/services/MockHttpAuthService.cjs.js.map +1 -0
  34. package/dist/next/services/MockRootLoggerService.cjs.js +49 -0
  35. package/dist/next/services/MockRootLoggerService.cjs.js.map +1 -0
  36. package/dist/next/services/MockUserInfoService.cjs.js +26 -0
  37. package/dist/next/services/MockUserInfoService.cjs.js.map +1 -0
  38. package/dist/next/services/mockCredentials.cjs.js +148 -0
  39. package/dist/next/services/mockCredentials.cjs.js.map +1 -0
  40. package/dist/next/services/mockServices.cjs.js +294 -0
  41. package/dist/next/services/mockServices.cjs.js.map +1 -0
  42. package/dist/next/wiring/ServiceFactoryTester.cjs.js +61 -0
  43. package/dist/next/wiring/ServiceFactoryTester.cjs.js.map +1 -0
  44. package/dist/next/wiring/TestBackend.cjs.js +258 -0
  45. package/dist/next/wiring/TestBackend.cjs.js.map +1 -0
  46. package/dist/util/errorHandler.cjs.js +18 -0
  47. package/dist/util/errorHandler.cjs.js.map +1 -0
  48. package/dist/util/getDockerImageForName.cjs.js +8 -0
  49. package/dist/util/getDockerImageForName.cjs.js.map +1 -0
  50. package/dist/util/isDockerDisabledForTests.cjs.js +8 -0
  51. package/dist/util/isDockerDisabledForTests.cjs.js.map +1 -0
  52. package/package.json +8 -8
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/util/isDockerDisabledForTests.ts","../src/cache/memcache.ts","../src/cache/redis.ts","../src/util/getDockerImageForName.ts","../src/cache/types.ts","../src/cache/TestCaches.ts","../src/database/types.ts","../src/database/mysql.ts","../src/database/postgres.ts","../src/database/sqlite.ts","../src/database/TestDatabases.ts","../src/msw/registerMswTestHooks.ts","../src/filesystem/MockDirectory.ts","../src/next/services/mockCredentials.ts","../src/next/services/MockAuthService.ts","../src/next/services/MockHttpAuthService.ts","../src/next/services/MockRootLoggerService.ts","../src/next/services/MockUserInfoService.ts","../src/next/services/mockServices.ts","../src/next/wiring/TestBackend.ts","../../backend-app-api/src/lib/DependencyGraph.ts","../../backend-app-api/src/wiring/ServiceRegistry.ts","../src/next/wiring/ServiceFactoryTester.ts","../src/util/errorHandler.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\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 or cache.\n return (\n Boolean(process.env.BACKSTAGE_TEST_DISABLE_DOCKER) ||\n !Boolean(process.env.CI)\n );\n}\n","/*\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 Keyv from 'keyv';\nimport KeyvMemcache from '@keyv/memcache';\nimport { v4 as uuid } from 'uuid';\nimport { Instance } from './types';\n\nasync function attemptMemcachedConnection(connection: string): Promise<Keyv> {\n const startTime = Date.now();\n\n for (;;) {\n try {\n const store = new KeyvMemcache(connection);\n const keyv = new Keyv({ store });\n const value = uuid();\n await keyv.set('test', value);\n if ((await keyv.get('test')) === value) {\n return keyv;\n }\n } catch (e) {\n if (Date.now() - startTime > 30_000) {\n throw new Error(\n `Timed out waiting for memcached to be ready for connections, ${e}`,\n );\n }\n }\n\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n}\n\nexport async function connectToExternalMemcache(\n connection: string,\n): Promise<Instance> {\n const keyv = await attemptMemcachedConnection(connection);\n return {\n store: 'memcache',\n connection,\n keyv,\n stop: async () => await keyv.disconnect(),\n };\n}\n\nexport async function startMemcachedContainer(\n image: string,\n): Promise<Instance> {\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(11211)\n .start();\n\n const host = container.getHost();\n const port = container.getMappedPort(11211);\n const connection = `${host}:${port}`;\n\n const keyv = await attemptMemcachedConnection(connection);\n\n return {\n store: 'memcache',\n connection,\n keyv,\n stop: async () => {\n await keyv.disconnect();\n await container.stop({ timeout: 10_000 });\n },\n };\n}\n","/*\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 Keyv from 'keyv';\nimport KeyvRedis from '@keyv/redis';\nimport { v4 as uuid } from 'uuid';\nimport { Instance } from './types';\n\nasync function attemptRedisConnection(connection: string): Promise<Keyv> {\n const startTime = Date.now();\n\n for (;;) {\n try {\n const store = new KeyvRedis(connection);\n const keyv = new Keyv({ store });\n const value = uuid();\n await keyv.set('test', value);\n if ((await keyv.get('test')) === value) {\n return keyv;\n }\n } catch (e) {\n if (Date.now() - startTime > 30_000) {\n throw new Error(\n `Timed out waiting for redis to be ready for connections, ${e}`,\n );\n }\n }\n\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n}\n\nexport async function connectToExternalRedis(\n connection: string,\n): Promise<Instance> {\n const keyv = await attemptRedisConnection(connection);\n return {\n store: 'redis',\n connection,\n keyv,\n stop: async () => await keyv.disconnect(),\n };\n}\n\nexport async function startRedisContainer(image: string): Promise<Instance> {\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(6379)\n .start();\n\n const host = container.getHost();\n const port = container.getMappedPort(6379);\n const connection = `redis://${host}:${port}`;\n\n const keyv = await attemptRedisConnection(connection);\n\n return {\n store: 'redis',\n connection,\n keyv,\n stop: async () => {\n await keyv.disconnect();\n await container.stop({ timeout: 10_000 });\n },\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\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 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 Keyv from 'keyv';\nimport { getDockerImageForName } from '../util/getDockerImageForName';\n\n/**\n * The possible caches to test against.\n *\n * @public\n */\nexport type TestCacheId = 'MEMORY' | 'REDIS_7' | 'MEMCACHED_1';\n\nexport type TestCacheProperties = {\n name: string;\n store: string;\n dockerImageName?: string;\n connectionStringEnvironmentVariableName?: string;\n};\n\nexport type Instance = {\n store: string;\n connection: string;\n keyv: Keyv;\n stop: () => Promise<void>;\n};\n\nexport const allCaches: Record<TestCacheId, TestCacheProperties> =\n Object.freeze({\n REDIS_7: {\n name: 'Redis 7.x',\n store: 'redis',\n dockerImageName: getDockerImageForName('redis:7'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_CACHE_REDIS7_CONNECTION_STRING',\n },\n MEMCACHED_1: {\n name: 'Memcached 1.x',\n store: 'memcache',\n dockerImageName: getDockerImageForName('memcached:1'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_CACHE_MEMCACHED1_CONNECTION_STRING',\n },\n MEMORY: {\n name: 'In-memory',\n store: 'memory',\n },\n });\n","/*\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 Keyv from 'keyv';\nimport { isDockerDisabledForTests } from '../util/isDockerDisabledForTests';\nimport { connectToExternalMemcache, startMemcachedContainer } from './memcache';\nimport { connectToExternalRedis, startRedisContainer } from './redis';\nimport { Instance, TestCacheId, TestCacheProperties, allCaches } from './types';\n\n/**\n * Encapsulates the creation of ephemeral test cache instances for use inside\n * unit or integration tests.\n *\n * @public\n */\nexport class TestCaches {\n private readonly instanceById: Map<string, Instance>;\n private readonly supportedIds: TestCacheId[];\n private static defaultIds?: TestCacheId[];\n\n /**\n * Creates an empty `TestCaches` instance, and sets up Jest to clean up all of\n * its acquired resources after all tests finish.\n *\n * You typically want to create just a single instance like this at the top of\n * your test file or `describe` block, and then call `init` many times on that\n * instance inside the individual tests. Spinning up a \"physical\" cache\n * instance takes a considerable amount of time, slowing down tests. But\n * wiping the contents of an instance using `init` is very fast.\n */\n static create(options?: {\n ids?: TestCacheId[];\n disableDocker?: boolean;\n }): TestCaches {\n const ids = options?.ids;\n const disableDocker = options?.disableDocker ?? isDockerDisabledForTests();\n\n let testCacheIds: TestCacheId[];\n if (ids) {\n testCacheIds = ids;\n } else if (TestCaches.defaultIds) {\n testCacheIds = TestCaches.defaultIds;\n } else {\n testCacheIds = Object.keys(allCaches) as TestCacheId[];\n }\n\n const supportedIds = testCacheIds.filter(id => {\n const properties = allCaches[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 target will work\n if (\n properties.connectionStringEnvironmentVariableName &&\n process.env[properties.connectionStringEnvironmentVariableName]\n ) {\n return true;\n }\n // If the cache doesn't require docker at all, there's nothing to worry\n // about\n if (!properties.dockerImageName) {\n return true;\n }\n // If the cache requires docker, but docker is disabled, we will fail.\n if (disableDocker) {\n return false;\n }\n return true;\n });\n\n const caches = new TestCaches(supportedIds);\n\n if (supportedIds.length > 0) {\n afterAll(async () => {\n await caches.shutdown();\n });\n }\n\n return caches;\n }\n\n static setDefaults(options: { ids?: TestCacheId[] }) {\n TestCaches.defaultIds = options.ids;\n }\n\n private constructor(supportedIds: TestCacheId[]) {\n this.instanceById = new Map();\n this.supportedIds = supportedIds;\n }\n\n supports(id: TestCacheId): boolean {\n return this.supportedIds.includes(id);\n }\n\n eachSupportedId(): [TestCacheId][] {\n return this.supportedIds.map(id => [id]);\n }\n\n /**\n * Returns a fresh, empty cache for the given driver.\n *\n * @param id - The ID of the cache to use, e.g. 'REDIS_7'\n * @returns Cache connection properties\n */\n async init(\n id: TestCacheId,\n ): Promise<{ store: string; connection: string; keyv: Keyv }> {\n const properties = allCaches[id];\n if (!properties) {\n const candidates = Object.keys(allCaches).join(', ');\n throw new Error(\n `Unknown test cache ${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 cache ${id} for this environment, possible values are ${candidates}`,\n );\n }\n\n // Ensure that a testcontainers instance is up for this ID\n let instance: Instance | undefined = this.instanceById.get(id);\n if (!instance) {\n instance = await this.initAny(properties);\n this.instanceById.set(id, instance);\n }\n\n // Ensure that it's cleared of data from previous tests\n await instance.keyv.clear();\n\n return {\n store: instance.store,\n connection: instance.connection,\n keyv: instance.keyv,\n };\n }\n\n private async initAny(properties: TestCacheProperties): Promise<Instance> {\n switch (properties.store) {\n case 'memcache':\n return this.initMemcached(properties);\n case 'redis':\n return this.initRedis(properties);\n case 'memory':\n return {\n store: 'memory',\n connection: 'memory',\n keyv: new Keyv(),\n stop: async () => {},\n };\n default:\n throw new Error(`Unknown cache store '${properties.store}'`);\n }\n }\n\n private async initMemcached(\n properties: TestCacheProperties,\n ): Promise<Instance> {\n // Use the connection string if provided\n const envVarName = properties.connectionStringEnvironmentVariableName;\n if (envVarName) {\n const connectionString = process.env[envVarName];\n if (connectionString) {\n return connectToExternalMemcache(connectionString);\n }\n }\n\n return await startMemcachedContainer(properties.dockerImageName!);\n }\n\n private async initRedis(properties: TestCacheProperties): Promise<Instance> {\n // Use the connection string if provided\n const envVarName = properties.connectionStringEnvironmentVariableName;\n if (envVarName) {\n const connectionString = process.env[envVarName];\n if (connectionString) {\n return connectToExternalRedis(connectionString);\n }\n }\n\n return await startRedisContainer(properties.dockerImageName!);\n }\n\n private async shutdown() {\n const instances = [...this.instanceById.values()];\n this.instanceById.clear();\n await Promise.all(\n instances.map(({ stop }) =>\n stop().catch(error => {\n console.warn(`TestCaches: Failed to stop container`, { error });\n }),\n ),\n );\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 { Knex } from 'knex';\nimport { getDockerImageForName } from '../util/getDockerImageForName';\n\nexport interface Engine {\n createDatabaseInstance(): Promise<Knex>;\n shutdown(): Promise<void>;\n}\n\n/**\n * The possible databases to test against.\n *\n * @public\n */\nexport type TestDatabaseId =\n | 'POSTGRES_16'\n | 'POSTGRES_15'\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 const allDatabases: Record<TestDatabaseId, TestDatabaseProperties> =\n Object.freeze({\n POSTGRES_16: {\n name: 'Postgres 16.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:16'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES16_CONNECTION_STRING',\n },\n POSTGRES_15: {\n name: 'Postgres 15.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:15'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES15_CONNECTION_STRING',\n },\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\nexport const LARGER_POOL_CONFIG = {\n pool: {\n min: 0,\n max: 50,\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 { stringifyError } from '@backstage/errors';\nimport { randomBytes } from 'crypto';\nimport knexFactory, { Knex } from 'knex';\nimport { v4 as uuid } from 'uuid';\nimport yn from 'yn';\nimport { Engine, LARGER_POOL_CONFIG, TestDatabaseProperties } from './types';\n\nasync function waitForMysqlReady(\n connection: Knex.MySqlConnectionConfig,\n): Promise<void> {\n const startTime = Date.now();\n\n let lastError: Error | undefined;\n let attempts = 0;\n for (;;) {\n attempts += 1;\n\n let knex: Knex | undefined;\n try {\n knex = knexFactory({\n client: 'mysql2',\n connection: {\n // make a copy because the driver mutates this\n ...connection,\n },\n });\n const result = await knex.select(knex.raw('version() AS version'));\n if (Array.isArray(result) && result[0]?.version) {\n return;\n }\n } catch (e) {\n lastError = e;\n } finally {\n await knex?.destroy();\n }\n\n if (Date.now() - startTime > 30_000) {\n throw new Error(\n `Timed out waiting for the database to be ready for connections, ${attempts} attempts, ${\n lastError\n ? `last error was ${stringifyError(lastError)}`\n : '(no errors thrown)'\n }`,\n );\n }\n\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n}\n\nexport async function startMysqlContainer(image: string): Promise<{\n connection: Knex.MySqlConnectionConfig;\n stopContainer: () => Promise<void>;\n}> {\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 .withEnvironment({ 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 connection = { host, port, user, password };\n const stopContainer = async () => {\n await container.stop({ timeout: 10_000 });\n };\n\n await waitForMysqlReady(connection);\n\n return { connection, stopContainer };\n}\n\nexport function parseMysqlConnectionString(\n connectionString: string,\n): Knex.MySqlConnectionConfig {\n try {\n const {\n protocol,\n username,\n password,\n port,\n hostname,\n pathname,\n searchParams,\n } = new URL(connectionString);\n\n if (protocol !== 'mysql:') {\n throw new Error(`Unknown protocol ${protocol}`);\n } else if (!username || !password) {\n throw new Error(`Missing username/password`);\n } else if (!pathname.match(/^\\/[^/]+$/)) {\n throw new Error(`Expected single path segment`);\n }\n\n const result: Knex.MySqlConnectionConfig = {\n user: username,\n password,\n host: hostname,\n port: Number(port || 3306),\n database: decodeURIComponent(pathname.substring(1)),\n };\n\n const ssl = searchParams.get('ssl');\n if (ssl) {\n result.ssl = ssl;\n }\n\n const debug = searchParams.get('debug');\n if (debug) {\n result.debug = yn(debug);\n }\n\n return result;\n } catch (e) {\n throw new Error(`Error while parsing MySQL connection string, ${e}`, e);\n }\n}\n\nexport class MysqlEngine implements Engine {\n static async create(\n properties: TestDatabaseProperties,\n ): Promise<MysqlEngine> {\n const { connectionStringEnvironmentVariableName, dockerImageName } =\n properties;\n\n if (connectionStringEnvironmentVariableName) {\n const connectionString =\n process.env[connectionStringEnvironmentVariableName];\n if (connectionString) {\n const connection = parseMysqlConnectionString(connectionString);\n return new MysqlEngine(\n properties,\n connection as Knex.MySqlConnectionConfig,\n );\n }\n }\n\n if (dockerImageName) {\n const { connection, stopContainer } = await startMysqlContainer(\n dockerImageName,\n );\n return new MysqlEngine(properties, connection, stopContainer);\n }\n\n throw new Error(`Test databasee for ${properties.name} not configured`);\n }\n\n readonly #properties: TestDatabaseProperties;\n readonly #connection: Knex.MySqlConnectionConfig;\n readonly #knexInstances: Knex[];\n readonly #databaseNames: string[];\n readonly #stopContainer?: () => Promise<void>;\n\n constructor(\n properties: TestDatabaseProperties,\n connection: Knex.MySqlConnectionConfig,\n stopContainer?: () => Promise<void>,\n ) {\n this.#properties = properties;\n this.#connection = connection;\n this.#knexInstances = [];\n this.#databaseNames = [];\n this.#stopContainer = stopContainer;\n }\n\n async createDatabaseInstance(): Promise<Knex> {\n const adminConnection = this.#connectAdmin();\n try {\n const databaseName = `db${randomBytes(16).toString('hex')}`;\n\n await adminConnection.raw('CREATE DATABASE ??', [databaseName]);\n this.#databaseNames.push(databaseName);\n\n const knexInstance = knexFactory({\n client: this.#properties.driver,\n connection: {\n ...this.#connection,\n database: databaseName,\n },\n ...LARGER_POOL_CONFIG,\n });\n this.#knexInstances.push(knexInstance);\n\n return knexInstance;\n } finally {\n await adminConnection.destroy();\n }\n }\n\n async shutdown(): Promise<void> {\n for (const instance of this.#knexInstances) {\n await instance.destroy();\n }\n\n const adminConnection = this.#connectAdmin();\n try {\n for (const databaseName of this.#databaseNames) {\n await adminConnection.raw('DROP DATABASE ??', [databaseName]);\n }\n } finally {\n await adminConnection.destroy();\n }\n\n await this.#stopContainer?.();\n }\n\n #connectAdmin(): Knex {\n const connection = {\n ...this.#connection,\n database: null as unknown as string,\n };\n return knexFactory({\n client: this.#properties.driver,\n connection,\n pool: {\n min: 0,\n max: 1,\n acquireTimeoutMillis: 20_000,\n createTimeoutMillis: 20_000,\n createRetryIntervalMillis: 1_000,\n },\n });\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 { stringifyError } from '@backstage/errors';\nimport { randomBytes } from 'crypto';\nimport knexFactory, { Knex } from 'knex';\nimport { parse as parsePgConnectionString } from 'pg-connection-string';\nimport { v4 as uuid } from 'uuid';\nimport { Engine, LARGER_POOL_CONFIG, TestDatabaseProperties } from './types';\n\nasync function waitForPostgresReady(\n connection: Knex.PgConnectionConfig,\n): Promise<void> {\n const startTime = Date.now();\n\n let lastError: Error | undefined;\n let attempts = 0;\n for (;;) {\n attempts += 1;\n\n let knex: Knex | undefined;\n try {\n knex = knexFactory({\n client: 'pg',\n connection: {\n // make a copy because the driver mutates this\n ...connection,\n },\n });\n const result = await knex.select(knex.raw('version()'));\n if (Array.isArray(result) && result[0]?.version) {\n return;\n }\n } catch (e) {\n lastError = e;\n } finally {\n await knex?.destroy();\n }\n\n if (Date.now() - startTime > 30_000) {\n throw new Error(\n `Timed out waiting for the database to be ready for connections, ${attempts} attempts, ${\n lastError\n ? `last error was ${stringifyError(lastError)}`\n : '(no errors thrown)'\n }`,\n );\n }\n\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n}\n\nexport async function startPostgresContainer(image: string): Promise<{\n connection: Knex.PgConnectionConfig;\n stopContainer: () => Promise<void>;\n}> {\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 .withEnvironment({ 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 connection = { host, port, user, password };\n const stopContainer = async () => {\n await container.stop({ timeout: 10_000 });\n };\n\n await waitForPostgresReady(connection);\n\n return { connection, stopContainer };\n}\n\nexport class PostgresEngine implements Engine {\n static async create(\n properties: TestDatabaseProperties,\n ): Promise<PostgresEngine> {\n const { connectionStringEnvironmentVariableName, dockerImageName } =\n properties;\n\n if (connectionStringEnvironmentVariableName) {\n const connectionString =\n process.env[connectionStringEnvironmentVariableName];\n if (connectionString) {\n const connection = parsePgConnectionString(connectionString);\n return new PostgresEngine(\n properties,\n connection as Knex.PgConnectionConfig,\n );\n }\n }\n\n if (dockerImageName) {\n const { connection, stopContainer } = await startPostgresContainer(\n dockerImageName,\n );\n return new PostgresEngine(properties, connection, stopContainer);\n }\n\n throw new Error(`Test databasee for ${properties.name} not configured`);\n }\n\n readonly #properties: TestDatabaseProperties;\n readonly #connection: Knex.PgConnectionConfig;\n readonly #knexInstances: Knex[];\n readonly #databaseNames: string[];\n readonly #stopContainer?: () => Promise<void>;\n\n constructor(\n properties: TestDatabaseProperties,\n connection: Knex.PgConnectionConfig,\n stopContainer?: () => Promise<void>,\n ) {\n this.#properties = properties;\n this.#connection = connection;\n this.#knexInstances = [];\n this.#databaseNames = [];\n this.#stopContainer = stopContainer;\n }\n\n async createDatabaseInstance(): Promise<Knex> {\n const adminConnection = this.#connectAdmin();\n try {\n const databaseName = `db${randomBytes(16).toString('hex')}`;\n\n await adminConnection.raw('CREATE DATABASE ??', [databaseName]);\n this.#databaseNames.push(databaseName);\n\n const knexInstance = knexFactory({\n client: this.#properties.driver,\n connection: {\n ...this.#connection,\n database: databaseName,\n },\n ...LARGER_POOL_CONFIG,\n });\n this.#knexInstances.push(knexInstance);\n\n return knexInstance;\n } finally {\n await adminConnection.destroy();\n }\n }\n\n async shutdown(): Promise<void> {\n for (const instance of this.#knexInstances) {\n await instance.destroy();\n }\n\n const adminConnection = this.#connectAdmin();\n try {\n for (const databaseName of this.#databaseNames) {\n await adminConnection.raw('DROP DATABASE ??', [databaseName]);\n }\n } finally {\n await adminConnection.destroy();\n }\n\n await this.#stopContainer?.();\n }\n\n #connectAdmin(): Knex {\n return knexFactory({\n client: this.#properties.driver,\n connection: {\n ...this.#connection,\n database: 'postgres',\n },\n pool: {\n acquireTimeoutMillis: 10000,\n },\n });\n }\n}\n","/*\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 knexFactory, { Knex } from 'knex';\nimport { Engine, TestDatabaseProperties } from './types';\n\nexport class SqliteEngine implements Engine {\n static async create(\n properties: TestDatabaseProperties,\n ): Promise<SqliteEngine> {\n return new SqliteEngine(properties);\n }\n\n readonly #properties: TestDatabaseProperties;\n readonly #instances: Knex[];\n\n constructor(properties: TestDatabaseProperties) {\n this.#properties = properties;\n this.#instances = [];\n }\n\n async createDatabaseInstance(): Promise<Knex> {\n const instance = knexFactory({\n client: this.#properties.driver,\n connection: ':memory:',\n useNullAsDefault: true,\n });\n\n instance.client.pool.on('createSuccess', (_eventId: any, resource: any) => {\n resource.run('PRAGMA foreign_keys = ON', () => {});\n });\n\n this.#instances.push(instance);\n return instance;\n }\n\n async shutdown(): Promise<void> {\n for (const instance of this.#instances) {\n await instance.destroy();\n }\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 { Knex } from 'knex';\nimport { isDockerDisabledForTests } from '../util/isDockerDisabledForTests';\nimport { MysqlEngine } from './mysql';\nimport { PostgresEngine } from './postgres';\nimport { SqliteEngine } from './sqlite';\nimport {\n Engine,\n TestDatabaseId,\n TestDatabaseProperties,\n allDatabases,\n} from './types';\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 engineFactoryByDriver: Record<\n string,\n (properties: TestDatabaseProperties) => Promise<Engine>\n > = {\n pg: PostgresEngine.create,\n mysql: MysqlEngine.create,\n mysql2: MysqlEngine.create,\n 'better-sqlite3': SqliteEngine.create,\n sqlite3: SqliteEngine.create,\n };\n private readonly engineByTestDatabaseId: Map<string, Engine>;\n private readonly supportedIds: TestDatabaseId[];\n private static defaultIds?: 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 ids = options?.ids;\n const disableDocker = options?.disableDocker ?? isDockerDisabledForTests();\n\n let testDatabaseIds: TestDatabaseId[];\n if (ids) {\n testDatabaseIds = ids;\n } else if (TestDatabases.defaultIds) {\n testDatabaseIds = TestDatabases.defaultIds;\n } else {\n testDatabaseIds = Object.keys(allDatabases) as TestDatabaseId[];\n }\n\n const supportedIds = testDatabaseIds.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 static setDefaults(options: { ids?: TestDatabaseId[] }) {\n TestDatabases.defaultIds = options.ids;\n }\n\n private constructor(supportedIds: TestDatabaseId[]) {\n this.engineByTestDatabaseId = 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 engine = this.engineByTestDatabaseId.get(id);\n if (!engine) {\n const factory = this.engineFactoryByDriver[properties.driver];\n if (!factory) {\n throw new Error(`Unknown database driver ${properties.driver}`);\n }\n engine = await factory(properties);\n this.engineByTestDatabaseId.set(id, engine);\n }\n\n return await engine.createDatabaseInstance();\n }\n\n private async shutdown() {\n const engines = [...this.engineByTestDatabaseId.values()];\n this.engineByTestDatabaseId.clear();\n\n for (const engine of engines) {\n try {\n await engine.shutdown();\n } catch (error) {\n console.warn(`TestDatabases: Failed to shutdown engine`, {\n engine,\n error,\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 registerMswTestHooks(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 */\n\nimport os from 'os';\nimport { isChildPath } from '@backstage/backend-plugin-api';\nimport fs from 'fs-extra';\nimport textextensions from 'textextensions';\nimport {\n dirname,\n extname,\n join as joinPath,\n resolve as resolvePath,\n relative as relativePath,\n win32,\n posix,\n} from 'path';\n\nconst tmpdirMarker = Symbol('os-tmpdir-mock');\n\n/**\n * A context that allows for more advanced file system operations when writing mock directory content.\n *\n * @public\n */\nexport interface MockDirectoryContentCallbackContext {\n /** Absolute path to the location of this piece of content on the filesystem */\n path: string;\n\n /** Creates a symbolic link at the current location */\n symlink(target: string): void;\n}\n\n/**\n * A callback that allows for more advanced file system operations when writing mock directory content.\n *\n * @public\n */\nexport type MockDirectoryContentCallback = (\n ctx: MockDirectoryContentCallbackContext,\n) => void;\n\n/**\n * The content of a mock directory represented by a nested object structure.\n *\n * @remarks\n *\n * When used as input, the keys may contain forward slashes to indicate nested directories.\n * Then returned as output, each directory will always be represented as a separate object.\n *\n * @example\n * ```ts\n * {\n * 'test.txt': 'content',\n * 'sub-dir': {\n * 'file.txt': 'content',\n * 'nested-dir/file.txt': 'content',\n * },\n * 'empty-dir': {},\n * 'binary-file': Buffer.from([0, 1, 2]),\n * }\n * ```\n *\n * @public\n */\nexport type MockDirectoryContent = {\n [name in string]:\n | MockDirectoryContent\n | string\n | Buffer\n | MockDirectoryContentCallback;\n};\n\n/**\n * Options for {@link MockDirectory.content}.\n *\n * @public\n */\nexport interface MockDirectoryContentOptions {\n /**\n * The path to read content from. Defaults to the root of the mock directory.\n *\n * An absolute path can also be provided, as long as it is a child path of the mock directory.\n */\n path?: string;\n\n /**\n * Whether or not to return files as text rather than buffers.\n *\n * Defaults to checking the file extension against a list of known text extensions.\n */\n shouldReadAsText?: boolean | ((path: string, buffer: Buffer) => boolean);\n}\n\n/**\n * A utility for creating a mock directory that is automatically cleaned up.\n *\n * @public\n */\nexport interface MockDirectory {\n /**\n * The path to the root of the mock directory\n */\n readonly path: string;\n\n /**\n * Resolves a path relative to the root of the mock directory.\n */\n resolve(...paths: string[]): string;\n\n /**\n * Sets the content of the mock directory. This will remove any existing content.\n *\n * @example\n * ```ts\n * mockDir.setContent({\n * 'test.txt': 'content',\n * 'sub-dir': {\n * 'file.txt': 'content',\n * 'nested-dir/file.txt': 'content',\n * },\n * 'empty-dir': {},\n * 'binary-file': Buffer.from([0, 1, 2]),\n * });\n * ```\n */\n setContent(root: MockDirectoryContent): void;\n\n /**\n * Adds content of the mock directory. This will overwrite existing files.\n *\n * @example\n * ```ts\n * mockDir.addContent({\n * 'test.txt': 'content',\n * 'sub-dir': {\n * 'file.txt': 'content',\n * 'nested-dir/file.txt': 'content',\n * },\n * 'empty-dir': {},\n * 'binary-file': Buffer.from([0, 1, 2]),\n * });\n * ```\n */\n addContent(root: MockDirectoryContent): void;\n\n /**\n * Reads the content of the mock directory.\n *\n * @remarks\n *\n * Text files will be returned as strings, while binary files will be returned as buffers.\n * By default the file extension is used to determine whether a file should be read as text.\n *\n * @example\n * ```ts\n * expect(mockDir.content()).toEqual({\n * 'test.txt': 'content',\n * 'sub-dir': {\n * 'file.txt': 'content',\n * 'nested-dir': {\n * 'file.txt': 'content',\n * },\n * },\n * 'empty-dir': {},\n * 'binary-file': Buffer.from([0, 1, 2]),\n * });\n * ```\n */\n content(\n options?: MockDirectoryContentOptions,\n ): MockDirectoryContent | undefined;\n\n /**\n * Clears the content of the mock directory, ensuring that the directory itself exists.\n */\n clear(): void;\n\n /**\n * Removes the mock directory and all its contents.\n */\n remove(): void;\n}\n\n/** @internal */\ntype MockEntry =\n | {\n type: 'file';\n path: string;\n content: Buffer;\n }\n | {\n type: 'dir';\n path: string;\n }\n | {\n type: 'callback';\n path: string;\n callback: MockDirectoryContentCallback;\n };\n\n/** @internal */\nclass MockDirectoryImpl {\n readonly #root: string;\n\n constructor(root: string) {\n this.#root = root;\n }\n\n get path(): string {\n return this.#root;\n }\n\n resolve(...paths: string[]): string {\n return resolvePath(this.#root, ...paths);\n }\n\n setContent(root: MockDirectoryContent): void {\n this.remove();\n\n return this.addContent(root);\n }\n\n addContent(root: MockDirectoryContent): void {\n const entries = this.#transformInput(root);\n\n for (const entry of entries) {\n const fullPath = resolvePath(this.#root, entry.path);\n if (!isChildPath(this.#root, fullPath)) {\n throw new Error(\n `Provided path must resolve to a child path of the mock directory, got '${fullPath}'`,\n );\n }\n\n if (entry.type === 'dir') {\n fs.ensureDirSync(fullPath);\n } else if (entry.type === 'file') {\n fs.ensureDirSync(dirname(fullPath));\n fs.writeFileSync(fullPath, entry.content);\n } else if (entry.type === 'callback') {\n fs.ensureDirSync(dirname(fullPath));\n entry.callback({\n path: fullPath,\n symlink(target: string) {\n fs.symlinkSync(target, fullPath);\n },\n });\n }\n }\n }\n\n content(\n options?: MockDirectoryContentOptions,\n ): MockDirectoryContent | undefined {\n const shouldReadAsText =\n (typeof options?.shouldReadAsText === 'boolean'\n ? () => options?.shouldReadAsText\n : options?.shouldReadAsText) ??\n ((path: string) => textextensions.includes(extname(path).slice(1)));\n\n const root = resolvePath(this.#root, options?.path ?? '');\n if (!isChildPath(this.#root, root)) {\n throw new Error(\n `Provided path must resolve to a child path of the mock directory, got '${root}'`,\n );\n }\n\n function read(path: string): MockDirectoryContent | undefined {\n if (!fs.pathExistsSync(path)) {\n return undefined;\n }\n\n const entries = fs.readdirSync(path, { withFileTypes: true });\n return Object.fromEntries(\n entries.map(entry => {\n const fullPath = resolvePath(path, entry.name);\n\n if (entry.isDirectory()) {\n return [entry.name, read(fullPath)];\n }\n const content = fs.readFileSync(fullPath);\n const relativePosixPath = relativePath(root, fullPath)\n .split(win32.sep)\n .join(posix.sep);\n\n if (shouldReadAsText(relativePosixPath, content)) {\n return [entry.name, content.toString('utf8')];\n }\n return [entry.name, content];\n }),\n );\n }\n\n return read(root);\n }\n\n clear = (): void => {\n this.setContent({});\n };\n\n remove = (): void => {\n fs.rmSync(this.#root, { recursive: true, force: true, maxRetries: 10 });\n };\n\n #transformInput(input: MockDirectoryContent[string]): MockEntry[] {\n const entries: MockEntry[] = [];\n\n function traverse(node: MockDirectoryContent[string], path: string) {\n if (typeof node === 'string') {\n entries.push({\n type: 'file',\n path,\n content: Buffer.from(node, 'utf8'),\n });\n } else if (node instanceof Buffer) {\n entries.push({ type: 'file', path, content: node });\n } else if (typeof node === 'function') {\n entries.push({ type: 'callback', path, callback: node });\n } else {\n entries.push({ type: 'dir', path });\n for (const [name, child] of Object.entries(node)) {\n traverse(child, path ? `${path}/${name}` : name);\n }\n }\n }\n\n traverse(input, '');\n\n return entries;\n }\n}\n\n/**\n * Options for {@link createMockDirectory}.\n *\n * @public\n */\nexport interface CreateMockDirectoryOptions {\n /**\n * In addition to creating a temporary directory, also mock `os.tmpdir()` to return the\n * mock directory path until the end of the test suite.\n *\n * @returns\n */\n mockOsTmpDir?: boolean;\n\n /**\n * Initializes the directory with the given content, see {@link MockDirectory.setContent}.\n */\n content?: MockDirectoryContent;\n}\n\n/**\n * Creates a new temporary mock directory that will be removed after the tests have completed.\n *\n * @public\n * @remarks\n *\n * This method is intended to be called outside of any test, either at top-level or\n * within a `describe` block. It will call `afterAll` to make sure that the mock directory\n * is removed after the tests have run.\n *\n * @example\n * ```ts\n * describe('MySubject', () => {\n * const mockDir = createMockDirectory();\n *\n * beforeEach(mockDir.clear);\n *\n * it('should work', () => {\n * // ... use mockDir\n * })\n * })\n * ```\n */\nexport function createMockDirectory(\n options?: CreateMockDirectoryOptions,\n): MockDirectory {\n const tmpDir = process.env.RUNNER_TEMP || os.tmpdir(); // GitHub Actions\n const root = fs.mkdtempSync(joinPath(tmpDir, 'backstage-tmp-test-dir-'));\n\n const mocker = new MockDirectoryImpl(root);\n\n const origTmpdir = options?.mockOsTmpDir ? os.tmpdir : undefined;\n if (origTmpdir) {\n if (Object.hasOwn(origTmpdir, tmpdirMarker)) {\n throw new Error(\n 'Cannot mock os.tmpdir() when it has already been mocked',\n );\n }\n const mock = Object.assign(() => mocker.path, { [tmpdirMarker]: true });\n os.tmpdir = mock;\n }\n\n // In CI we expect there to be no need to clean up temporary directories\n const needsCleanup = !process.env.CI;\n if (needsCleanup) {\n process.on('beforeExit', mocker.remove);\n }\n\n try {\n afterAll(() => {\n if (origTmpdir) {\n os.tmpdir = origTmpdir;\n }\n if (needsCleanup) {\n mocker.remove();\n }\n });\n } catch {\n /* ignore */\n }\n\n if (options?.content) {\n mocker.setContent(options.content);\n }\n\n return mocker;\n}\n","/*\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};\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 ): BackstageCredentials<BackstageUserPrincipal> {\n validateUserEntityRef(userEntityRef);\n return {\n $$type: '@backstage/BackstageCredentials',\n principal: { type: 'user', userEntityRef },\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(userEntityRef?: string): string {\n if (userEntityRef) {\n validateUserEntityRef(userEntityRef);\n return `${MOCK_USER_TOKEN_PREFIX}${JSON.stringify({\n sub: userEntityRef,\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","/*\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 }: UserTokenPayload = JSON.parse(\n token.slice(MOCK_USER_TOKEN_PREFIX.length),\n );\n\n return mockCredentials.user(userEntityRef);\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","/*\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","/*\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 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","/*\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 { cacheServiceFactory } from '@backstage/backend-defaults/cache';\nimport { databaseServiceFactory } from '@backstage/backend-defaults/database';\nimport {\n HostDiscovery,\n discoveryServiceFactory,\n} 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 { 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 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 {\n eventsServiceFactory,\n eventsServiceRef,\n} from '@backstage/plugin-events-node';\nimport { JsonObject } from '@backstage/types';\nimport { MockAuthService } from './MockAuthService';\nimport { MockHttpAuthService } from './MockHttpAuthService';\nimport { MockRootLoggerService } from './MockRootLoggerService';\nimport { MockUserInfoService } from './MockUserInfoService';\nimport { mockCredentials } from './mockCredentials';\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 * @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 = 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 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 = () => discoveryServiceFactory;\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 export namespace database {\n export const factory = () => databaseServiceFactory;\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 rootLifecycle {\n export const factory = () => rootLifecycleServiceFactory;\n export const mock = simpleMock(coreServices.rootLifecycle, () => ({\n addShutdownHook: 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 export namespace events {\n export const factory = () => eventsServiceFactory;\n export const mock = simpleMock(eventsServiceRef, () => ({\n publish: jest.fn(),\n subscribe: 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 { 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-forbidden-package-imports\nimport {\n InternalBackendFeature,\n InternalBackendRegistrations,\n} from '@backstage/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.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.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\nfunction unwrapFeature(\n feature: BackendFeature | (() => BackendFeature),\n): BackendFeature {\n return typeof feature === 'function' ? feature() : 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({ 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","/*\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\ninterface NodeInput<T> {\n value: T;\n consumes?: Iterable<string>;\n provides?: Iterable<string>;\n}\n\n/** @internal */\nclass Node<T> {\n static from<T>(input: NodeInput<T>) {\n return new Node<T>(\n input.value,\n input.consumes ? new Set(input.consumes) : new Set(),\n input.provides ? new Set(input.provides) : new Set(),\n );\n }\n\n private constructor(\n readonly value: T,\n readonly consumes: Set<string>,\n readonly provides: Set<string>,\n ) {}\n}\n\n/** @internal */\nclass CycleKeySet<T> {\n static from<T>(nodes: Array<Node<T>>) {\n return new CycleKeySet<T>(nodes);\n }\n\n #nodeIds: Map<T, number>;\n #cycleKeys: Set<string>;\n\n private constructor(nodes: Array<Node<T>>) {\n this.#nodeIds = new Map(nodes.map((n, i) => [n.value, i]));\n this.#cycleKeys = new Set<string>();\n }\n\n tryAdd(path: T[]): boolean {\n const cycleKey = this.#getCycleKey(path);\n if (this.#cycleKeys.has(cycleKey)) {\n return false;\n }\n this.#cycleKeys.add(cycleKey);\n return true;\n }\n\n #getCycleKey(path: T[]): string {\n return path\n .map(n => this.#nodeIds.get(n)!)\n .sort()\n .join(',');\n }\n}\n\n/**\n * Internal helper to help validate and traverse a dependency graph.\n * @internal\n */\nexport class DependencyGraph<T> {\n static fromMap(\n nodes: Record<string, Omit<NodeInput<unknown>, 'value'>>,\n ): DependencyGraph<string> {\n return this.fromIterable(\n Object.entries(nodes).map(([key, node]) => ({\n value: String(key),\n ...node,\n })),\n );\n }\n\n static fromIterable<T>(\n nodeInputs: Iterable<NodeInput<T>>,\n ): DependencyGraph<T> {\n const nodes = new Array<Node<T>>();\n for (const nodeInput of nodeInputs) {\n nodes.push(Node.from(nodeInput));\n }\n\n return new DependencyGraph(nodes);\n }\n\n #nodes: Array<Node<T>>;\n #allProvided: Set<string>;\n\n private constructor(nodes: Array<Node<T>>) {\n this.#nodes = nodes;\n this.#allProvided = new Set();\n\n for (const node of this.#nodes.values()) {\n for (const produced of node.provides) {\n this.#allProvided.add(produced);\n }\n }\n }\n\n /**\n * Find all nodes that consume dependencies that are not provided by any other node.\n */\n findUnsatisfiedDeps(): Array<{ value: T; unsatisfied: string[] }> {\n const unsatisfiedDependencies = [];\n for (const node of this.#nodes.values()) {\n const unsatisfied = Array.from(node.consumes).filter(\n id => !this.#allProvided.has(id),\n );\n if (unsatisfied.length > 0) {\n unsatisfiedDependencies.push({ value: node.value, unsatisfied });\n }\n }\n return unsatisfiedDependencies;\n }\n\n /**\n * Detect the first circular dependency within the graph, returning the path of nodes that\n * form a cycle, with the same node as the first and last element of the array.\n */\n detectCircularDependency(): T[] | undefined {\n return this.detectCircularDependencies().next().value;\n }\n\n /**\n * Detect circular dependencies within the graph, returning the path of nodes that\n * form a cycle, with the same node as the first and last element of the array.\n */\n *detectCircularDependencies(): Generator<T[], undefined> {\n const cycleKeys = CycleKeySet.from(this.#nodes);\n\n for (const startNode of this.#nodes) {\n const visited = new Set<Node<T>>();\n const stack = new Array<[node: Node<T>, path: T[]]>([\n startNode,\n [startNode.value],\n ]);\n\n while (stack.length > 0) {\n const [node, path] = stack.pop()!;\n if (visited.has(node)) {\n continue;\n }\n visited.add(node);\n for (const consumed of node.consumes) {\n const providerNodes = this.#nodes.filter(other =>\n other.provides.has(consumed),\n );\n for (const provider of providerNodes) {\n if (provider === startNode) {\n if (cycleKeys.tryAdd(path)) {\n yield [...path, startNode.value];\n }\n\n break;\n }\n if (!visited.has(provider)) {\n stack.push([provider, [...path, provider.value]]);\n }\n }\n }\n }\n }\n return undefined;\n }\n\n /**\n * Traverses the dependency graph in topological order, calling the provided\n * function for each node and waiting for it to resolve.\n *\n * The nodes are traversed in parallel, but in such a way that no node is\n * visited before all of its dependencies.\n *\n * Dependencies of nodes that are not produced by any other nodes will be ignored.\n */\n async parallelTopologicalTraversal<TResult>(\n fn: (value: T) => Promise<TResult>,\n ): Promise<TResult[]> {\n const allProvided = this.#allProvided;\n const producedSoFar = new Set<string>();\n const waiting = new Set(this.#nodes.values());\n const visited = new Set<Node<T>>();\n const results = new Array<TResult>();\n let inFlight = 0; // Keep track of how many callbacks are in flight, so that we know if we got stuck\n\n // Find all nodes that have no dependencies that have not already been produced by visited nodes\n async function processMoreNodes() {\n if (waiting.size === 0) {\n return;\n }\n const nodesToProcess = [];\n for (const node of waiting) {\n let ready = true;\n for (const consumed of node.consumes) {\n if (allProvided.has(consumed) && !producedSoFar.has(consumed)) {\n ready = false;\n continue;\n }\n }\n if (ready) {\n nodesToProcess.push(node);\n }\n }\n\n for (const node of nodesToProcess) {\n waiting.delete(node);\n }\n\n if (nodesToProcess.length === 0 && inFlight === 0) {\n // We expect the caller to check for circular dependencies before\n // traversal, so this error should never happen\n throw new Error('Circular dependency detected');\n }\n\n await Promise.all(nodesToProcess.map(processNode));\n }\n\n // Process an individual node, and then add its produced dependencies to the set of available products\n async function processNode(node: Node<T>) {\n visited.add(node);\n inFlight += 1;\n\n const result = await fn(node.value);\n results.push(result);\n\n node.provides.forEach(produced => producedSoFar.add(produced));\n inFlight -= 1;\n await processMoreNodes();\n }\n\n await processMoreNodes();\n\n return results;\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 ServiceFactory,\n ServiceRef,\n coreServices,\n createServiceFactory,\n} from '@backstage/backend-plugin-api';\nimport { ConflictError, stringifyError } from '@backstage/errors';\n// Direct internal import to avoid duplication\n// eslint-disable-next-line @backstage/no-forbidden-package-imports\nimport { InternalServiceFactory } from '@backstage/backend-plugin-api/src/services/system/types';\nimport { DependencyGraph } from '../lib/DependencyGraph';\n/**\n * Keep in sync with `@backstage/backend-plugin-api/src/services/system/types.ts`\n * @internal\n */\nexport type InternalServiceRef = ServiceRef<unknown> & {\n __defaultFactory?: (\n service: ServiceRef<unknown>,\n ) => Promise<ServiceFactory | (() => ServiceFactory)>;\n};\n\nfunction toInternalServiceFactory<TService, TScope extends 'plugin' | 'root'>(\n factory: ServiceFactory<TService, TScope>,\n): InternalServiceFactory<TService, TScope> {\n const f = factory as InternalServiceFactory<TService, TScope>;\n if (f.$$type !== '@backstage/BackendFeature') {\n throw new Error(`Invalid service factory, bad type '${f.$$type}'`);\n }\n if (f.version !== 'v1') {\n throw new Error(`Invalid service factory, bad version '${f.version}'`);\n }\n return f;\n}\n\nfunction createPluginMetadataServiceFactory(pluginId: string) {\n return createServiceFactory({\n service: coreServices.pluginMetadata,\n deps: {},\n factory: async () => ({ getId: () => pluginId }),\n });\n}\n\nexport class ServiceRegistry {\n static create(factories: Array<ServiceFactory>): ServiceRegistry {\n const factoryMap = new Map<string, InternalServiceFactory[]>();\n for (const factory of factories) {\n if (factory.service.multiton) {\n const existing = factoryMap.get(factory.service.id) ?? [];\n factoryMap.set(\n factory.service.id,\n existing.concat(toInternalServiceFactory(factory)),\n );\n } else {\n factoryMap.set(factory.service.id, [toInternalServiceFactory(factory)]);\n }\n }\n const registry = new ServiceRegistry(factoryMap);\n registry.checkForCircularDeps();\n return registry;\n }\n\n readonly #providedFactories: Map<string, InternalServiceFactory[]>;\n readonly #loadedDefaultFactories: Map<\n Function,\n Promise<InternalServiceFactory>\n >;\n readonly #implementations: Map<\n InternalServiceFactory,\n {\n context: Promise<unknown>;\n byPlugin: Map<string, Promise<unknown>>;\n }\n >;\n readonly #rootServiceImplementations = new Map<\n InternalServiceFactory,\n Promise<unknown>\n >();\n readonly #addedFactoryIds = new Set<string>();\n readonly #instantiatedFactories = new Set<string>();\n\n private constructor(factories: Map<string, InternalServiceFactory[]>) {\n this.#providedFactories = factories;\n this.#loadedDefaultFactories = new Map();\n this.#implementations = new Map();\n }\n\n #resolveFactory(\n ref: ServiceRef<unknown>,\n pluginId: string,\n ): Promise<InternalServiceFactory[]> | undefined {\n // Special case handling of the plugin metadata service, generating a custom factory for it each time\n if (ref.id === coreServices.pluginMetadata.id) {\n return Promise.resolve([\n toInternalServiceFactory(createPluginMetadataServiceFactory(pluginId)),\n ]);\n }\n\n let resolvedFactory:\n | Promise<InternalServiceFactory[]>\n | InternalServiceFactory[]\n | undefined = this.#providedFactories.get(ref.id);\n const { __defaultFactory: defaultFactory } = ref as InternalServiceRef;\n if (!resolvedFactory && !defaultFactory) {\n return undefined;\n }\n\n if (!resolvedFactory) {\n let loadedFactory = this.#loadedDefaultFactories.get(defaultFactory!);\n if (!loadedFactory) {\n loadedFactory = Promise.resolve()\n .then(() => defaultFactory!(ref))\n .then(f =>\n toInternalServiceFactory(typeof f === 'function' ? f() : f),\n );\n this.#loadedDefaultFactories.set(defaultFactory!, loadedFactory);\n }\n resolvedFactory = loadedFactory.then(\n factory => [factory],\n error => {\n throw new Error(\n `Failed to instantiate service '${\n ref.id\n }' because the default factory loader threw an error, ${stringifyError(\n error,\n )}`,\n );\n },\n );\n }\n\n return Promise.resolve(resolvedFactory);\n }\n\n #checkForMissingDeps(factory: InternalServiceFactory, pluginId: string) {\n const missingDeps = Object.values(factory.deps).filter(ref => {\n if (ref.id === coreServices.pluginMetadata.id) {\n return false;\n }\n if (this.#providedFactories.get(ref.id)) {\n return false;\n }\n if (ref.multiton) {\n return false;\n }\n\n return !(ref as InternalServiceRef).__defaultFactory;\n });\n\n if (missingDeps.length) {\n const missing = missingDeps.map(r => `'${r.id}'`).join(', ');\n throw new Error(\n `Failed to instantiate service '${factory.service.id}' for '${pluginId}' because the following dependent services are missing: ${missing}`,\n );\n }\n }\n\n checkForCircularDeps(): void {\n const graph = DependencyGraph.fromIterable(\n Array.from(this.#providedFactories).map(([serviceId, factories]) => ({\n value: serviceId,\n provides: [serviceId],\n consumes: factories.flatMap(factory =>\n Object.values(factory.deps).map(d => d.id),\n ),\n })),\n );\n const circularDependencies = Array.from(graph.detectCircularDependencies());\n\n if (circularDependencies.length) {\n const cycles = circularDependencies\n .map(c => c.map(id => `'${id}'`).join(' -> '))\n .join('\\n ');\n\n throw new ConflictError(`Circular dependencies detected:\\n ${cycles}`);\n }\n }\n\n add(factory: ServiceFactory) {\n const factoryId = factory.service.id;\n if (factoryId === coreServices.pluginMetadata.id) {\n throw new Error(\n `The ${coreServices.pluginMetadata.id} service cannot be overridden`,\n );\n }\n\n if (this.#instantiatedFactories.has(factoryId)) {\n throw new Error(\n `Unable to set service factory with id ${factoryId}, service has already been instantiated`,\n );\n }\n\n if (factory.service.multiton) {\n const newFactories = (\n this.#providedFactories.get(factoryId) ?? []\n ).concat(toInternalServiceFactory(factory));\n this.#providedFactories.set(factoryId, newFactories);\n } else {\n if (this.#addedFactoryIds.has(factoryId)) {\n throw new Error(\n `Duplicate service implementations provided for ${factoryId}`,\n );\n }\n\n this.#addedFactoryIds.add(factoryId);\n this.#providedFactories.set(factoryId, [\n toInternalServiceFactory(factory),\n ]);\n }\n }\n\n async initializeEagerServicesWithScope(\n scope: 'root' | 'plugin',\n pluginId: string = 'root',\n ) {\n for (const [factory] of this.#providedFactories.values()) {\n if (factory.service.scope === scope) {\n // Root-scoped services are eager by default, plugin-scoped are lazy by default\n if (scope === 'root' && factory.initialization !== 'lazy') {\n await this.get(factory.service, pluginId);\n } else if (scope === 'plugin' && factory.initialization === 'always') {\n await this.get(factory.service, pluginId);\n }\n }\n }\n }\n\n get<T, TInstances extends 'singleton' | 'multiton'>(\n ref: ServiceRef<T, 'plugin' | 'root', TInstances>,\n pluginId: string,\n ): Promise<TInstances extends 'multiton' ? T[] : T> | undefined {\n this.#instantiatedFactories.add(ref.id);\n\n const resolvedFactory = this.#resolveFactory(ref, pluginId);\n\n if (!resolvedFactory) {\n return ref.multiton\n ? (Promise.resolve([]) as\n | Promise<TInstances extends 'multiton' ? T[] : T>\n | undefined)\n : undefined;\n }\n\n return resolvedFactory\n .then(factories => {\n return Promise.all(\n factories.map(factory => {\n if (factory.service.scope === 'root') {\n let existing = this.#rootServiceImplementations.get(factory);\n if (!existing) {\n this.#checkForMissingDeps(factory, pluginId);\n const rootDeps = new Array<\n Promise<[name: string, impl: unknown]>\n >();\n\n for (const [name, serviceRef] of Object.entries(factory.deps)) {\n if (serviceRef.scope !== 'root') {\n throw new Error(\n `Failed to instantiate 'root' scoped service '${ref.id}' because it depends on '${serviceRef.scope}' scoped service '${serviceRef.id}'.`,\n );\n }\n const target = this.get(serviceRef, pluginId)!;\n rootDeps.push(target.then(impl => [name, impl]));\n }\n\n existing = Promise.all(rootDeps).then(entries =>\n factory.factory(Object.fromEntries(entries), undefined),\n );\n this.#rootServiceImplementations.set(factory, existing);\n }\n return existing as Promise<T>;\n }\n\n let implementation = this.#implementations.get(factory);\n if (!implementation) {\n this.#checkForMissingDeps(factory, pluginId);\n const rootDeps = new Array<\n Promise<[name: string, impl: unknown]>\n >();\n\n for (const [name, serviceRef] of Object.entries(factory.deps)) {\n if (serviceRef.scope === 'root') {\n const target = this.get(serviceRef, pluginId)!;\n rootDeps.push(target.then(impl => [name, impl]));\n }\n }\n\n implementation = {\n context: Promise.all(rootDeps)\n .then(entries =>\n factory.createRootContext?.(Object.fromEntries(entries)),\n )\n .catch(error => {\n const cause = stringifyError(error);\n throw new Error(\n `Failed to instantiate service '${ref.id}' because createRootContext threw an error, ${cause}`,\n );\n }),\n byPlugin: new Map(),\n };\n\n this.#implementations.set(factory, implementation);\n }\n\n let result = implementation.byPlugin.get(pluginId) as Promise<any>;\n if (!result) {\n const allDeps = new Array<\n Promise<[name: string, impl: unknown]>\n >();\n\n for (const [name, serviceRef] of Object.entries(factory.deps)) {\n const target = this.get(serviceRef, pluginId)!;\n allDeps.push(target.then(impl => [name, impl]));\n }\n\n result = implementation.context\n .then(context =>\n Promise.all(allDeps).then(entries =>\n factory.factory(Object.fromEntries(entries), context),\n ),\n )\n .catch(error => {\n const cause = stringifyError(error);\n throw new Error(\n `Failed to instantiate service '${ref.id}' for '${pluginId}' because the factory function threw an error, ${cause}`,\n );\n });\n implementation.byPlugin.set(pluginId, result);\n }\n return result;\n }),\n );\n })\n .then(results => (ref.multiton ? results : results[0]));\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 { 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","/*\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 '../next';\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":["KeyvMemcache","Keyv","uuid","KeyvRedis","knexFactory","stringifyError","yn","randomBytes","parsePgConnectionString","resolvePath","isChildPath","fs","dirname","path","textextensions","extname","relativePath","win32","posix","os","joinPath","mockCredentials","none","user","limitedUser","service","AuthenticationError","parseCookie","cookie","NotAllowedError","InputError","createServiceFactory","mockServices","ConfigReader","rootConfig","coreServices","rootLogger","auth","discovery","HostDiscovery","discoveryServiceFactory","httpAuth","userInfo","cache","cacheServiceFactory","database","databaseServiceFactory","rootHealth","rootHealthServiceFactory","httpRouter","httpRouterServiceFactory","rootHttpRouter","rootHttpRouterServiceFactory","lifecycle","lifecycleServiceFactory","logger","loggerServiceFactory","permissions","permissionsServiceFactory","rootLifecycle","rootLifecycleServiceFactory","scheduler","schedulerServiceFactory","urlReader","urlReaderServiceFactory","events","eventsServiceFactory","eventsServiceRef","createBackendPlugin","createBackendModule","DefaultRootHttpRouter","express","MiddlewareFactory","createHealthRouter","createHttpServer","createSpecializedBackend","ConflictError"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+
3
+ function registerMswTestHooks(worker) {
4
+ beforeAll(() => worker.listen({ onUnhandledRequest: "error" }));
5
+ afterAll(() => worker.close());
6
+ afterEach(() => worker.resetHandlers());
7
+ }
8
+
9
+ exports.registerMswTestHooks = registerMswTestHooks;
10
+ //# sourceMappingURL=registerMswTestHooks.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registerMswTestHooks.cjs.js","sources":["../../src/msw/registerMswTestHooks.ts"],"sourcesContent":["/*\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 registerMswTestHooks(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"],"names":[],"mappings":";;AAqBO,SAAS,qBAAqB,MAIlC,EAAA;AACD,EAAA,SAAA,CAAU,MAAM,MAAO,CAAA,MAAA,CAAO,EAAE,kBAAoB,EAAA,OAAA,EAAS,CAAC,CAAA,CAAA;AAC9D,EAAS,QAAA,CAAA,MAAM,MAAO,CAAA,KAAA,EAAO,CAAA,CAAA;AAC7B,EAAU,SAAA,CAAA,MAAM,MAAO,CAAA,aAAA,EAAe,CAAA,CAAA;AACxC;;;;"}