@backstage/backend-test-utils 1.2.1-next.1 → 1.3.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/dist/cache/memcache.cjs.js +1 -1
- package/dist/cache/memcache.cjs.js.map +1 -1
- package/dist/cache/redis.cjs.js +1 -1
- package/dist/cache/redis.cjs.js.map +1 -1
- package/dist/database/mysql.cjs.js +1 -1
- package/dist/database/mysql.cjs.js.map +1 -1
- package/dist/database/postgres.cjs.js +1 -1
- package/dist/database/postgres.cjs.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/next/services/mockServices.cjs.js +21 -0
- package/dist/next/services/mockServices.cjs.js.map +1 -1
- package/dist/next/wiring/TestBackend.cjs.js +9 -1
- package/dist/next/wiring/TestBackend.cjs.js.map +1 -1
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# @backstage/backend-test-utils
|
|
2
2
|
|
|
3
|
+
## 1.3.0-next.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- dd05a97: Added mocks for the new `PermissionsRegistryService`.
|
|
8
|
+
- a4aa244: This change introduces mocks for the `auditor` service.
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- f866b86: Internal refactor to use explicit `require` for lazy-loading dependency.
|
|
13
|
+
- fb051f2: Sync feature installation compatibility logic with `@backstage/backend-app-api`.
|
|
14
|
+
- Updated dependencies
|
|
15
|
+
- @backstage/backend-defaults@0.8.0-next.0
|
|
16
|
+
- @backstage/backend-plugin-api@1.2.0-next.0
|
|
17
|
+
- @backstage/backend-app-api@1.1.2-next.0
|
|
18
|
+
- @backstage/config@1.3.2
|
|
19
|
+
- @backstage/errors@1.2.7
|
|
20
|
+
- @backstage/types@1.2.1
|
|
21
|
+
- @backstage/plugin-auth-node@0.5.7-next.0
|
|
22
|
+
- @backstage/plugin-events-node@0.4.8-next.0
|
|
23
|
+
|
|
24
|
+
## 1.2.1
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- Updated dependencies
|
|
29
|
+
- @backstage/backend-defaults@0.7.0
|
|
30
|
+
- @backstage/backend-app-api@1.1.1
|
|
31
|
+
- @backstage/types@1.2.1
|
|
32
|
+
- @backstage/plugin-auth-node@0.5.6
|
|
33
|
+
- @backstage/backend-plugin-api@1.1.1
|
|
34
|
+
- @backstage/config@1.3.2
|
|
35
|
+
- @backstage/errors@1.2.7
|
|
36
|
+
- @backstage/plugin-events-node@0.4.7
|
|
37
|
+
|
|
3
38
|
## 1.2.1-next.1
|
|
4
39
|
|
|
5
40
|
### Patch Changes
|
|
@@ -40,7 +40,7 @@ async function connectToExternalMemcache(connection) {
|
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
async function startMemcachedContainer(image) {
|
|
43
|
-
const { GenericContainer } =
|
|
43
|
+
const { GenericContainer } = require("testcontainers");
|
|
44
44
|
const container = await new GenericContainer(image).withExposedPorts(11211).start();
|
|
45
45
|
const host = container.getHost();
|
|
46
46
|
const port = container.getMappedPort(11211);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memcache.cjs.js","sources":["../../src/cache/memcache.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport 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 }
|
|
1
|
+
{"version":3,"file":"memcache.cjs.js","sources":["../../src/cache/memcache.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport 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 } =\n require('testcontainers') as typeof 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"],"names":["KeyvMemcache","Keyv","uuid"],"mappings":";;;;;;;;;;;AAqBA,eAAe,2BAA2B,UAAmC,EAAA;AAC3E,EAAM,MAAA,SAAA,GAAY,KAAK,GAAI,EAAA;AAE3B,EAAS,WAAA;AACP,IAAI,IAAA;AACF,MAAM,MAAA,KAAA,GAAQ,IAAIA,6BAAA,CAAa,UAAU,CAAA;AACzC,MAAA,MAAM,IAAO,GAAA,IAAIC,qBAAK,CAAA,EAAE,OAAO,CAAA;AAC/B,MAAA,MAAM,QAAQC,OAAK,EAAA;AACnB,MAAM,MAAA,IAAA,CAAK,GAAI,CAAA,MAAA,EAAQ,KAAK,CAAA;AAC5B,MAAA,IAAK,MAAM,IAAA,CAAK,GAAI,CAAA,MAAM,MAAO,KAAO,EAAA;AACtC,QAAO,OAAA,IAAA;AAAA;AACT,aACO,CAAG,EAAA;AACV,MAAA,IAAI,IAAK,CAAA,GAAA,EAAQ,GAAA,SAAA,GAAY,GAAQ,EAAA;AACnC,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,gEAAgE,CAAC,CAAA;AAAA,SACnE;AAAA;AACF;AAGF,IAAA,MAAM,IAAI,OAAQ,CAAA,CAAA,OAAA,KAAW,UAAW,CAAA,OAAA,EAAS,GAAG,CAAC,CAAA;AAAA;AAEzD;AAEA,eAAsB,0BACpB,UACmB,EAAA;AACnB,EAAM,MAAA,IAAA,GAAO,MAAM,0BAAA,CAA2B,UAAU,CAAA;AACxD,EAAO,OAAA;AAAA,IACL,KAAO,EAAA,UAAA;AAAA,IACP,UAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAM,EAAA,YAAY,MAAM,IAAA,CAAK,UAAW;AAAA,GAC1C;AACF;AAEA,eAAsB,wBACpB,KACmB,EAAA;AAEnB,EAAA,MAAM,EAAE,gBAAA,EACN,GAAA,OAAA,CAAQ,gBAAgB,CAAA;AAE1B,EAAM,MAAA,SAAA,GAAY,MAAM,IAAI,gBAAA,CAAiB,KAAK,CAC/C,CAAA,gBAAA,CAAiB,KAAK,CAAA,CACtB,KAAM,EAAA;AAET,EAAM,MAAA,IAAA,GAAO,UAAU,OAAQ,EAAA;AAC/B,EAAM,MAAA,IAAA,GAAO,SAAU,CAAA,aAAA,CAAc,KAAK,CAAA;AAC1C,EAAA,MAAM,UAAa,GAAA,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AAElC,EAAM,MAAA,IAAA,GAAO,MAAM,0BAAA,CAA2B,UAAU,CAAA;AAExD,EAAO,OAAA;AAAA,IACL,KAAO,EAAA,UAAA;AAAA,IACP,UAAA;AAAA,IACA,IAAA;AAAA,IACA,MAAM,YAAY;AAChB,MAAA,MAAM,KAAK,UAAW,EAAA;AACtB,MAAA,MAAM,SAAU,CAAA,IAAA,CAAK,EAAE,OAAA,EAAS,KAAQ,CAAA;AAAA;AAC1C,GACF;AACF;;;;;"}
|
package/dist/cache/redis.cjs.js
CHANGED
|
@@ -40,7 +40,7 @@ async function connectToExternalRedis(connection) {
|
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
async function startRedisContainer(image) {
|
|
43
|
-
const { GenericContainer } =
|
|
43
|
+
const { GenericContainer } = require("testcontainers");
|
|
44
44
|
const container = await new GenericContainer(image).withExposedPorts(6379).start();
|
|
45
45
|
const host = container.getHost();
|
|
46
46
|
const port = container.getMappedPort(6379);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis.cjs.js","sources":["../../src/cache/redis.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport 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 }
|
|
1
|
+
{"version":3,"file":"redis.cjs.js","sources":["../../src/cache/redis.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport 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 } =\n require('testcontainers') as typeof 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"],"names":["KeyvRedis","Keyv","uuid"],"mappings":";;;;;;;;;;;AAqBA,eAAe,uBAAuB,UAAmC,EAAA;AACvE,EAAM,MAAA,SAAA,GAAY,KAAK,GAAI,EAAA;AAE3B,EAAS,WAAA;AACP,IAAI,IAAA;AACF,MAAM,MAAA,KAAA,GAAQ,IAAIA,0BAAA,CAAU,UAAU,CAAA;AACtC,MAAA,MAAM,IAAO,GAAA,IAAIC,qBAAK,CAAA,EAAE,OAAO,CAAA;AAC/B,MAAA,MAAM,QAAQC,OAAK,EAAA;AACnB,MAAM,MAAA,IAAA,CAAK,GAAI,CAAA,MAAA,EAAQ,KAAK,CAAA;AAC5B,MAAA,IAAK,MAAM,IAAA,CAAK,GAAI,CAAA,MAAM,MAAO,KAAO,EAAA;AACtC,QAAO,OAAA,IAAA;AAAA;AACT,aACO,CAAG,EAAA;AACV,MAAA,IAAI,IAAK,CAAA,GAAA,EAAQ,GAAA,SAAA,GAAY,GAAQ,EAAA;AACnC,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,4DAA4D,CAAC,CAAA;AAAA,SAC/D;AAAA;AACF;AAGF,IAAA,MAAM,IAAI,OAAQ,CAAA,CAAA,OAAA,KAAW,UAAW,CAAA,OAAA,EAAS,GAAG,CAAC,CAAA;AAAA;AAEzD;AAEA,eAAsB,uBACpB,UACmB,EAAA;AACnB,EAAM,MAAA,IAAA,GAAO,MAAM,sBAAA,CAAuB,UAAU,CAAA;AACpD,EAAO,OAAA;AAAA,IACL,KAAO,EAAA,OAAA;AAAA,IACP,UAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAM,EAAA,YAAY,MAAM,IAAA,CAAK,UAAW;AAAA,GAC1C;AACF;AAEA,eAAsB,oBAAoB,KAAkC,EAAA;AAE1E,EAAA,MAAM,EAAE,gBAAA,EACN,GAAA,OAAA,CAAQ,gBAAgB,CAAA;AAE1B,EAAM,MAAA,SAAA,GAAY,MAAM,IAAI,gBAAA,CAAiB,KAAK,CAC/C,CAAA,gBAAA,CAAiB,IAAI,CAAA,CACrB,KAAM,EAAA;AAET,EAAM,MAAA,IAAA,GAAO,UAAU,OAAQ,EAAA;AAC/B,EAAM,MAAA,IAAA,GAAO,SAAU,CAAA,aAAA,CAAc,IAAI,CAAA;AACzC,EAAA,MAAM,UAAa,GAAA,CAAA,QAAA,EAAW,IAAI,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AAE1C,EAAM,MAAA,IAAA,GAAO,MAAM,sBAAA,CAAuB,UAAU,CAAA;AAEpD,EAAO,OAAA;AAAA,IACL,KAAO,EAAA,OAAA;AAAA,IACP,UAAA;AAAA,IACA,IAAA;AAAA,IACA,MAAM,YAAY;AAChB,MAAA,MAAM,KAAK,UAAW,EAAA;AACtB,MAAA,MAAM,SAAU,CAAA,IAAA,CAAK,EAAE,OAAA,EAAS,KAAQ,CAAA;AAAA;AAC1C,GACF;AACF;;;;;"}
|
|
@@ -47,7 +47,7 @@ async function waitForMysqlReady(connection) {
|
|
|
47
47
|
async function startMysqlContainer(image) {
|
|
48
48
|
const user = "root";
|
|
49
49
|
const password = uuid.v4();
|
|
50
|
-
const { GenericContainer } =
|
|
50
|
+
const { GenericContainer } = require("testcontainers");
|
|
51
51
|
const container = await new GenericContainer(image).withExposedPorts(3306).withEnvironment({ MYSQL_ROOT_PASSWORD: password }).withTmpFs({ "/var/lib/mysql": "rw" }).start();
|
|
52
52
|
const host = container.getHost();
|
|
53
53
|
const port = container.getMappedPort(3306);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mysql.cjs.js","sources":["../../src/database/mysql.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\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"],"names":["knexFactory","stringifyError","uuid","yn","randomBytes","LARGER_POOL_CONFIG"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mysql.cjs.js","sources":["../../src/database/mysql.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\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 } =\n require('testcontainers') as typeof 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"],"names":["knexFactory","stringifyError","uuid","yn","randomBytes","LARGER_POOL_CONFIG"],"mappings":"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"}
|
|
@@ -46,7 +46,7 @@ async function waitForPostgresReady(connection) {
|
|
|
46
46
|
async function startPostgresContainer(image) {
|
|
47
47
|
const user = "postgres";
|
|
48
48
|
const password = uuid.v4();
|
|
49
|
-
const { GenericContainer } =
|
|
49
|
+
const { GenericContainer } = require("testcontainers");
|
|
50
50
|
const container = await new GenericContainer(image).withExposedPorts(5432).withEnvironment({ POSTGRES_PASSWORD: password }).withTmpFs({ "/var/lib/postgresql/data": "rw" }).start();
|
|
51
51
|
const host = container.getHost();
|
|
52
52
|
const port = container.getMappedPort(5432);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.cjs.js","sources":["../../src/database/postgres.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\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 }
|
|
1
|
+
{"version":3,"file":"postgres.cjs.js","sources":["../../src/database/postgres.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\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 } =\n require('testcontainers') as typeof 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"],"names":["knexFactory","stringifyError","uuid","parsePgConnectionString","randomBytes","LARGER_POOL_CONFIG"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -462,6 +462,10 @@ declare namespace mockServices {
|
|
|
462
462
|
const factory: (options?: Options | undefined) => ServiceFactory<LoggerService, "root", "singleton" | "multiton">;
|
|
463
463
|
const mock: (partialImpl?: Partial<_backstage_backend_plugin_api.RootLoggerService> | undefined) => ServiceMock<_backstage_backend_plugin_api.RootLoggerService>;
|
|
464
464
|
}
|
|
465
|
+
namespace auditor {
|
|
466
|
+
const factory: () => ServiceFactory<_backstage_backend_plugin_api.AuditorService, "plugin", "singleton">;
|
|
467
|
+
const mock: (partialImpl?: Partial<_backstage_backend_plugin_api.AuditorService> | undefined) => ServiceMock<_backstage_backend_plugin_api.AuditorService>;
|
|
468
|
+
}
|
|
465
469
|
function auth(options?: {
|
|
466
470
|
pluginId?: string;
|
|
467
471
|
disableDefaultAuthPolicy?: boolean;
|
|
@@ -585,6 +589,10 @@ declare namespace mockServices {
|
|
|
585
589
|
const factory: () => ServiceFactory<_backstage_backend_plugin_api.PermissionsService, "plugin", "singleton">;
|
|
586
590
|
const mock: (partialImpl?: Partial<_backstage_backend_plugin_api.PermissionsService> | undefined) => ServiceMock<_backstage_backend_plugin_api.PermissionsService>;
|
|
587
591
|
}
|
|
592
|
+
namespace permissionsRegistry {
|
|
593
|
+
const factory: () => ServiceFactory<_backstage_backend_plugin_api.PermissionsRegistryService, "plugin", "singleton">;
|
|
594
|
+
const mock: (partialImpl?: Partial<_backstage_backend_plugin_api.PermissionsRegistryService> | undefined) => ServiceMock<_backstage_backend_plugin_api.PermissionsRegistryService>;
|
|
595
|
+
}
|
|
588
596
|
namespace rootLifecycle {
|
|
589
597
|
const factory: () => ServiceFactory<_backstage_backend_plugin_api.RootLifecycleService, "root", "singleton">;
|
|
590
598
|
const mock: (partialImpl?: Partial<_backstage_backend_plugin_api.RootLifecycleService> | undefined) => ServiceMock<_backstage_backend_plugin_api.RootLifecycleService>;
|
|
@@ -7,6 +7,7 @@ var httpRouter = require('@backstage/backend-defaults/httpRouter');
|
|
|
7
7
|
var lifecycle = require('@backstage/backend-defaults/lifecycle');
|
|
8
8
|
var logger = require('@backstage/backend-defaults/logger');
|
|
9
9
|
var permissions = require('@backstage/backend-defaults/permissions');
|
|
10
|
+
var permissionsRegistry = require('@backstage/backend-defaults/permissionsRegistry');
|
|
10
11
|
var rootHealth = require('@backstage/backend-defaults/rootHealth');
|
|
11
12
|
var rootHttpRouter = require('@backstage/backend-defaults/rootHttpRouter');
|
|
12
13
|
var rootLifecycle = require('@backstage/backend-defaults/rootLifecycle');
|
|
@@ -20,6 +21,7 @@ var MockHttpAuthService = require('./MockHttpAuthService.cjs.js');
|
|
|
20
21
|
var MockRootLoggerService = require('./MockRootLoggerService.cjs.js');
|
|
21
22
|
var MockUserInfoService = require('./MockUserInfoService.cjs.js');
|
|
22
23
|
var mockCredentials = require('./mockCredentials.cjs.js');
|
|
24
|
+
var auditor = require('@backstage/backend-defaults/auditor');
|
|
23
25
|
|
|
24
26
|
function createLoggerMock() {
|
|
25
27
|
return {
|
|
@@ -111,6 +113,17 @@ exports.mockServices = void 0;
|
|
|
111
113
|
warn: jest.fn()
|
|
112
114
|
}));
|
|
113
115
|
})(rootLogger = mockServices2.rootLogger || (mockServices2.rootLogger = {}));
|
|
116
|
+
((auditor2) => {
|
|
117
|
+
auditor2.factory = () => auditor.auditorServiceFactory;
|
|
118
|
+
auditor2.mock = simpleMock(backendPluginApi.coreServices.auditor, () => ({
|
|
119
|
+
createEvent: jest.fn(async (_) => {
|
|
120
|
+
return {
|
|
121
|
+
success: jest.fn(),
|
|
122
|
+
fail: jest.fn()
|
|
123
|
+
};
|
|
124
|
+
})
|
|
125
|
+
}));
|
|
126
|
+
})(mockServices2.auditor || (mockServices2.auditor = {}));
|
|
114
127
|
function auth(options) {
|
|
115
128
|
return new MockAuthService.MockAuthService({
|
|
116
129
|
pluginId: options?.pluginId ?? "test",
|
|
@@ -274,6 +287,14 @@ exports.mockServices = void 0;
|
|
|
274
287
|
authorizeConditional: jest.fn()
|
|
275
288
|
}));
|
|
276
289
|
})(mockServices2.permissions || (mockServices2.permissions = {}));
|
|
290
|
+
((permissionsRegistry2) => {
|
|
291
|
+
permissionsRegistry2.factory = () => permissionsRegistry.permissionsRegistryServiceFactory;
|
|
292
|
+
permissionsRegistry2.mock = simpleMock(backendPluginApi.coreServices.permissionsRegistry, () => ({
|
|
293
|
+
addPermissionRules: jest.fn(),
|
|
294
|
+
addPermissions: jest.fn(),
|
|
295
|
+
addResourceType: jest.fn()
|
|
296
|
+
}));
|
|
297
|
+
})(mockServices2.permissionsRegistry || (mockServices2.permissionsRegistry = {}));
|
|
277
298
|
((rootLifecycle2) => {
|
|
278
299
|
rootLifecycle2.factory = () => rootLifecycle.rootLifecycleServiceFactory;
|
|
279
300
|
rootLifecycle2.mock = simpleMock(backendPluginApi.coreServices.rootLifecycle, () => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockServices.cjs.js","sources":["../../../src/next/services/mockServices.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cacheServiceFactory } from '@backstage/backend-defaults/cache';\nimport { databaseServiceFactory } from '@backstage/backend-defaults/database';\nimport { HostDiscovery } from '@backstage/backend-defaults/discovery';\nimport { httpRouterServiceFactory } from '@backstage/backend-defaults/httpRouter';\nimport { lifecycleServiceFactory } from '@backstage/backend-defaults/lifecycle';\nimport { loggerServiceFactory } from '@backstage/backend-defaults/logger';\nimport { permissionsServiceFactory } from '@backstage/backend-defaults/permissions';\nimport { rootHealthServiceFactory } from '@backstage/backend-defaults/rootHealth';\nimport { rootHttpRouterServiceFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport { rootLifecycleServiceFactory } from '@backstage/backend-defaults/rootLifecycle';\nimport { schedulerServiceFactory } from '@backstage/backend-defaults/scheduler';\nimport { urlReaderServiceFactory } from '@backstage/backend-defaults/urlReader';\nimport {\n AuthService,\n BackstageCredentials,\n BackstageUserInfo,\n DatabaseService,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n RootConfigService,\n ServiceFactory,\n ServiceRef,\n UserInfoService,\n coreServices,\n createServiceFactory,\n} from '@backstage/backend-plugin-api';\nimport { ConfigReader } from '@backstage/config';\nimport {\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';\nimport { Knex } from 'knex';\n\n/** @internal */\nfunction createLoggerMock() {\n return {\n child: jest.fn().mockImplementation(createLoggerMock),\n debug: jest.fn(),\n error: jest.fn(),\n info: jest.fn(),\n warn: jest.fn(),\n };\n}\n\n/** @internal */\nfunction simpleFactoryWithOptions<\n TService,\n TScope extends 'root' | 'plugin',\n TOptions extends [options?: object] = [],\n>(\n ref: ServiceRef<TService, TScope>,\n factory: (...options: TOptions) => TService,\n): (...options: TOptions) => ServiceFactory<TService, TScope> {\n const factoryWithOptions = (...options: TOptions) =>\n createServiceFactory({\n service: ref as ServiceRef<TService, any>,\n deps: {},\n async factory() {\n return factory(...options);\n },\n });\n return Object.assign(\n factoryWithOptions,\n factoryWithOptions(...([undefined] as unknown as TOptions)),\n ) as ServiceFactory<TService, TScope> &\n ((...options: TOptions) => ServiceFactory<TService, TScope>);\n}\n\n/** @public */\nexport type ServiceMock<TService> = {\n factory: ServiceFactory<TService>;\n} & {\n [Key in keyof TService]: TService[Key] extends (\n ...args: infer Args\n ) => infer Return\n ? TService[Key] & jest.MockInstance<Return, Args>\n : TService[Key];\n};\n\n/** @internal */\nfunction simpleMock<TService>(\n ref: ServiceRef<TService, any>,\n mockFactory: () => jest.Mocked<TService>,\n): (partialImpl?: Partial<TService>) => ServiceMock<TService> {\n return partialImpl => {\n const mock = mockFactory();\n if (partialImpl) {\n for (const [key, impl] of Object.entries(partialImpl)) {\n if (typeof impl === 'function') {\n (mock as any)[key].mockImplementation(impl);\n } else {\n (mock as any)[key] = impl;\n }\n }\n }\n return Object.assign(mock, {\n factory: createServiceFactory({\n service: ref,\n deps: {},\n factory: () => mock,\n }),\n }) as ServiceMock<TService>;\n };\n}\n\n/**\n * Mock implementations of the core services, to be used in tests.\n *\n * @public\n * @remarks\n *\n * There are some variations among the services depending on what needs tests\n * might have, but overall there are three main usage patterns:\n *\n * 1. Creating an actual fake service instance, often with a simplified version\n * of functionality, by calling the mock service itself as a function.\n *\n * ```ts\n * // The function often accepts parameters that control its behavior\n * const foo = mockServices.foo();\n * ```\n *\n * 2. Creating a mock service, where all methods are replaced with jest mocks, by\n * calling the service's `mock` function.\n *\n * ```ts\n * // You can optionally supply a subset of its methods to implement\n * const foo = mockServices.foo.mock({\n * someMethod: () => 'mocked result',\n * });\n * // After exercising your test, you can make assertions on the mock:\n * expect(foo.someMethod).toHaveBeenCalledTimes(2);\n * expect(foo.otherMethod).toHaveBeenCalledWith(testData);\n * ```\n *\n * 3. Creating a service factory that behaves similarly to the mock as per above.\n *\n * ```ts\n * await startTestBackend({\n * features: [\n * mockServices.foo.factory({\n * someMethod: () => 'mocked result',\n * })\n * ],\n * });\n * ```\n */\nexport namespace mockServices {\n export function rootConfig(options?: rootConfig.Options): RootConfigService {\n return new ConfigReader(options?.data, 'mock-config');\n }\n export namespace rootConfig {\n export type Options = { data?: JsonObject };\n\n export const factory = simpleFactoryWithOptions(\n coreServices.rootConfig,\n rootConfig,\n );\n export const mock = simpleMock(coreServices.rootConfig, () => ({\n get: jest.fn(),\n getBoolean: jest.fn(),\n getConfig: jest.fn(),\n getConfigArray: jest.fn(),\n getNumber: jest.fn(),\n getOptional: jest.fn(),\n getOptionalBoolean: jest.fn(),\n getOptionalConfig: jest.fn(),\n getOptionalConfigArray: jest.fn(),\n getOptionalNumber: jest.fn(),\n getOptionalString: jest.fn(),\n getOptionalStringArray: jest.fn(),\n getString: jest.fn(),\n getStringArray: jest.fn(),\n has: jest.fn(),\n keys: jest.fn(),\n }));\n }\n\n export function rootLogger(options?: rootLogger.Options): LoggerService {\n return MockRootLoggerService.create(options);\n }\n export namespace rootLogger {\n export type Options = {\n level?: 'none' | 'error' | 'warn' | 'info' | 'debug';\n };\n\n export const factory = simpleFactoryWithOptions(\n coreServices.rootLogger,\n rootLogger,\n );\n export const mock = simpleMock(coreServices.rootLogger, () => ({\n child: jest.fn(),\n debug: jest.fn(),\n error: jest.fn(),\n info: jest.fn(),\n warn: jest.fn(),\n }));\n }\n\n export function auth(options?: {\n pluginId?: string;\n disableDefaultAuthPolicy?: boolean;\n }): AuthService {\n return new MockAuthService({\n pluginId: options?.pluginId ?? 'test',\n disableDefaultAuthPolicy: Boolean(options?.disableDefaultAuthPolicy),\n });\n }\n export namespace auth {\n export const factory = () =>\n createServiceFactory({\n service: coreServices.auth,\n deps: {\n plugin: coreServices.pluginMetadata,\n config: coreServices.rootConfig,\n },\n factory({ plugin, config }) {\n const disableDefaultAuthPolicy = Boolean(\n config.getOptionalBoolean(\n 'backend.auth.dangerouslyDisableDefaultAuthPolicy',\n ),\n );\n return new MockAuthService({\n pluginId: plugin.getId(),\n disableDefaultAuthPolicy,\n });\n },\n });\n export const mock = simpleMock(coreServices.auth, () => ({\n authenticate: jest.fn(),\n getNoneCredentials: jest.fn(),\n getOwnServiceCredentials: jest.fn(),\n isPrincipal: jest.fn() as any,\n getPluginRequestToken: jest.fn(),\n getLimitedUserToken: jest.fn(),\n listPublicServiceKeys: jest.fn(),\n }));\n }\n\n export function discovery(): DiscoveryService {\n return HostDiscovery.fromConfig(\n new ConfigReader({\n backend: {\n // Invalid port to make sure that requests are always mocked\n baseUrl: 'http://localhost:0',\n listen: { port: 0 },\n },\n }),\n );\n }\n export namespace discovery {\n export const factory = () =>\n createServiceFactory({\n service: coreServices.discovery,\n deps: {},\n factory: () => discovery(),\n });\n export const mock = simpleMock(coreServices.discovery, () => ({\n getBaseUrl: jest.fn(),\n getExternalBaseUrl: jest.fn(),\n }));\n }\n\n /**\n * Creates a mock implementation of the `HttpAuthService`.\n *\n * By default all requests without credentials are treated as requests from\n * the default mock user principal. This behavior can be configured with the\n * `defaultCredentials` option.\n */\n export function httpAuth(options?: {\n pluginId?: string;\n /**\n * The default credentials to use if there are no credentials present in the\n * incoming request.\n *\n * By default all requests without credentials are treated as authenticated\n * as the default mock user as returned from `mockCredentials.user()`.\n */\n defaultCredentials?: BackstageCredentials;\n }): HttpAuthService {\n return new MockHttpAuthService(\n options?.pluginId ?? 'test',\n options?.defaultCredentials ?? mockCredentials.user(),\n );\n }\n export namespace httpAuth {\n /**\n * Creates a mock service factory for the `HttpAuthService`.\n *\n * By default all requests without credentials are treated as requests from\n * the default mock user principal. This behavior can be configured with the\n * `defaultCredentials` option.\n */\n export const factory = (options?: {\n defaultCredentials?: BackstageCredentials;\n }) =>\n createServiceFactory({\n service: coreServices.httpAuth,\n deps: { plugin: coreServices.pluginMetadata },\n factory: ({ plugin }) =>\n new MockHttpAuthService(\n plugin.getId(),\n options?.defaultCredentials ?? mockCredentials.user(),\n ),\n });\n export const mock = simpleMock(coreServices.httpAuth, () => ({\n credentials: jest.fn(),\n issueUserCookie: jest.fn(),\n }));\n }\n\n /**\n * Creates a mock implementation of the `UserInfoService`.\n *\n * By default it extracts the user's entity ref from a user principal and\n * returns that as the only ownership entity ref, but this can be overridden\n * by passing in a custom set of user info.\n */\n export function userInfo(\n customInfo?: Partial<BackstageUserInfo>,\n ): UserInfoService {\n return new MockUserInfoService(customInfo);\n }\n export namespace userInfo {\n /**\n * Creates a mock service factory for the `UserInfoService`.\n *\n * By default it extracts the user's entity ref from a user principal and\n * returns that as the only ownership entity ref.\n */\n export const factory = () =>\n createServiceFactory({\n service: coreServices.userInfo,\n deps: {},\n factory() {\n return new MockUserInfoService();\n },\n });\n export const mock = simpleMock(coreServices.userInfo, () => ({\n getUserInfo: jest.fn(),\n }));\n }\n\n // TODO(Rugvip): Not all core services have implementations available here yet.\n // some may need a bit more refactoring for it to be simpler to\n // re-implement functioning mock versions here.\n export namespace cache {\n export const factory = () => cacheServiceFactory;\n export const mock = simpleMock(coreServices.cache, () => ({\n delete: jest.fn(),\n get: jest.fn(),\n set: jest.fn(),\n withOptions: jest.fn(),\n }));\n }\n\n /**\n * Creates a mock implementation of the\n * {@link @backstage/backend-plugin-api#coreServices.database}. Just returns\n * the given `knex` instance, which is useful in combination with the\n * {@link TestDatabases} facility.\n */\n export function database(options: {\n knex: Knex;\n migrations?: { skip?: boolean };\n }): DatabaseService {\n return {\n getClient: async () => options.knex,\n migrations: options.migrations,\n };\n }\n export namespace database {\n /**\n * Creates a mock factory for the\n * {@link @backstage/backend-plugin-api#coreServices.database}. Just returns\n * the given `knex` instance if you supply one, which is useful in\n * combination with the {@link TestDatabases} facility. Otherwise, it\n * returns the regular default database factory which reads config settings.\n */\n export const factory = (options?: {\n knex: Knex;\n migrations?: { skip?: boolean };\n }) =>\n options\n ? createServiceFactory({\n service: coreServices.database,\n deps: {},\n factory: () => database(options),\n })\n : databaseServiceFactory;\n /**\n * Creates a mock of the\n * {@link @backstage/backend-plugin-api#coreServices.database}, optionally\n * with some given method implementations.\n */\n export const mock = simpleMock(coreServices.database, () => ({\n getClient: jest.fn(),\n }));\n }\n\n export namespace rootHealth {\n export const factory = () => rootHealthServiceFactory;\n export const mock = simpleMock(coreServices.rootHealth, () => ({\n getLiveness: jest.fn(),\n getReadiness: jest.fn(),\n }));\n }\n\n export namespace httpRouter {\n export const factory = () => httpRouterServiceFactory;\n export const mock = simpleMock(coreServices.httpRouter, () => ({\n use: jest.fn(),\n addAuthPolicy: jest.fn(),\n }));\n }\n\n export namespace rootHttpRouter {\n export const factory = () => rootHttpRouterServiceFactory();\n export const mock = simpleMock(coreServices.rootHttpRouter, () => ({\n use: jest.fn(),\n }));\n }\n\n export namespace lifecycle {\n export const factory = () => lifecycleServiceFactory;\n export const mock = simpleMock(coreServices.lifecycle, () => ({\n addShutdownHook: jest.fn(),\n addStartupHook: jest.fn(),\n }));\n }\n\n export namespace logger {\n export const factory = () => loggerServiceFactory;\n export const mock = simpleMock(coreServices.logger, () =>\n createLoggerMock(),\n );\n }\n\n export namespace permissions {\n export const factory = () => permissionsServiceFactory;\n export const mock = simpleMock(coreServices.permissions, () => ({\n authorize: jest.fn(),\n authorizeConditional: jest.fn(),\n }));\n }\n\n export namespace rootLifecycle {\n export const factory = () => rootLifecycleServiceFactory;\n export const mock = simpleMock(coreServices.rootLifecycle, () => ({\n addShutdownHook: jest.fn(),\n addBeforeShutdownHook: jest.fn(),\n addStartupHook: jest.fn(),\n }));\n }\n\n export namespace scheduler {\n export const factory = () => schedulerServiceFactory;\n export const mock = simpleMock(coreServices.scheduler, () => ({\n createScheduledTaskRunner: jest.fn(),\n getScheduledTasks: jest.fn(),\n scheduleTask: jest.fn(),\n triggerTask: jest.fn(),\n }));\n }\n\n export namespace urlReader {\n export const factory = () => urlReaderServiceFactory;\n export const mock = simpleMock(coreServices.urlReader, () => ({\n readTree: jest.fn(),\n readUrl: jest.fn(),\n search: jest.fn(),\n }));\n }\n\n 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"],"names":["createServiceFactory","mockServices","ConfigReader","rootConfig","coreServices","MockRootLoggerService","rootLogger","MockAuthService","auth","discovery","HostDiscovery","MockHttpAuthService","mockCredentials","httpAuth","MockUserInfoService","userInfo","cache","cacheServiceFactory","database","databaseServiceFactory","rootHealth","rootHealthServiceFactory","httpRouter","httpRouterServiceFactory","rootHttpRouter","rootHttpRouterServiceFactory","lifecycle","lifecycleServiceFactory","logger","loggerServiceFactory","permissions","permissionsServiceFactory","rootLifecycle","rootLifecycleServiceFactory","scheduler","schedulerServiceFactory","urlReader","urlReaderServiceFactory","events","eventsServiceFactory","eventsServiceRef"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mockServices.cjs.js","sources":["../../../src/next/services/mockServices.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cacheServiceFactory } from '@backstage/backend-defaults/cache';\nimport { databaseServiceFactory } from '@backstage/backend-defaults/database';\nimport { HostDiscovery } from '@backstage/backend-defaults/discovery';\nimport { httpRouterServiceFactory } from '@backstage/backend-defaults/httpRouter';\nimport { lifecycleServiceFactory } from '@backstage/backend-defaults/lifecycle';\nimport { loggerServiceFactory } from '@backstage/backend-defaults/logger';\nimport { permissionsServiceFactory } from '@backstage/backend-defaults/permissions';\nimport { permissionsRegistryServiceFactory } from '@backstage/backend-defaults/permissionsRegistry';\nimport { rootHealthServiceFactory } from '@backstage/backend-defaults/rootHealth';\nimport { rootHttpRouterServiceFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport { rootLifecycleServiceFactory } from '@backstage/backend-defaults/rootLifecycle';\nimport { schedulerServiceFactory } from '@backstage/backend-defaults/scheduler';\nimport { urlReaderServiceFactory } from '@backstage/backend-defaults/urlReader';\nimport {\n AuthService,\n BackstageCredentials,\n BackstageUserInfo,\n DatabaseService,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n RootConfigService,\n ServiceFactory,\n ServiceRef,\n UserInfoService,\n coreServices,\n createServiceFactory,\n} from '@backstage/backend-plugin-api';\nimport { ConfigReader } from '@backstage/config';\nimport {\n eventsServiceFactory,\n eventsServiceRef,\n} from '@backstage/plugin-events-node';\nimport { JsonObject } from '@backstage/types';\nimport { Knex } from 'knex';\nimport { MockAuthService } from './MockAuthService';\nimport { MockHttpAuthService } from './MockHttpAuthService';\nimport { MockRootLoggerService } from './MockRootLoggerService';\nimport { MockUserInfoService } from './MockUserInfoService';\nimport { mockCredentials } from './mockCredentials';\nimport { auditorServiceFactory } from '@backstage/backend-defaults/auditor';\n\n/** @internal */\nfunction createLoggerMock() {\n return {\n child: jest.fn().mockImplementation(createLoggerMock),\n debug: jest.fn(),\n error: jest.fn(),\n info: jest.fn(),\n warn: jest.fn(),\n };\n}\n\n/** @internal */\nfunction simpleFactoryWithOptions<\n TService,\n TScope extends 'root' | 'plugin',\n TOptions extends [options?: object] = [],\n>(\n ref: ServiceRef<TService, TScope>,\n factory: (...options: TOptions) => TService,\n): (...options: TOptions) => ServiceFactory<TService, TScope> {\n const factoryWithOptions = (...options: TOptions) =>\n createServiceFactory({\n service: ref as ServiceRef<TService, any>,\n deps: {},\n async factory() {\n return factory(...options);\n },\n });\n return Object.assign(\n factoryWithOptions,\n factoryWithOptions(...([undefined] as unknown as TOptions)),\n ) as ServiceFactory<TService, TScope> &\n ((...options: TOptions) => ServiceFactory<TService, TScope>);\n}\n\n/** @public */\nexport type ServiceMock<TService> = {\n factory: ServiceFactory<TService>;\n} & {\n [Key in keyof TService]: TService[Key] extends (\n ...args: infer Args\n ) => infer Return\n ? TService[Key] & jest.MockInstance<Return, Args>\n : TService[Key];\n};\n\n/** @internal */\nfunction simpleMock<TService>(\n ref: ServiceRef<TService, any>,\n mockFactory: () => jest.Mocked<TService>,\n): (partialImpl?: Partial<TService>) => ServiceMock<TService> {\n return partialImpl => {\n const mock = mockFactory();\n if (partialImpl) {\n for (const [key, impl] of Object.entries(partialImpl)) {\n if (typeof impl === 'function') {\n (mock as any)[key].mockImplementation(impl);\n } else {\n (mock as any)[key] = impl;\n }\n }\n }\n return Object.assign(mock, {\n factory: createServiceFactory({\n service: ref,\n deps: {},\n factory: () => mock,\n }),\n }) as ServiceMock<TService>;\n };\n}\n\n/**\n * Mock implementations of the core services, to be used in tests.\n *\n * @public\n * @remarks\n *\n * There are some variations among the services depending on what needs tests\n * might have, but overall there are three main usage patterns:\n *\n * 1. Creating an actual fake service instance, often with a simplified version\n * of functionality, by calling the mock service itself as a function.\n *\n * ```ts\n * // The function often accepts parameters that control its behavior\n * const foo = mockServices.foo();\n * ```\n *\n * 2. Creating a mock service, where all methods are replaced with jest mocks, by\n * calling the service's `mock` function.\n *\n * ```ts\n * // You can optionally supply a subset of its methods to implement\n * const foo = mockServices.foo.mock({\n * someMethod: () => 'mocked result',\n * });\n * // After exercising your test, you can make assertions on the mock:\n * expect(foo.someMethod).toHaveBeenCalledTimes(2);\n * expect(foo.otherMethod).toHaveBeenCalledWith(testData);\n * ```\n *\n * 3. Creating a service factory that behaves similarly to the mock as per above.\n *\n * ```ts\n * await startTestBackend({\n * features: [\n * mockServices.foo.factory({\n * someMethod: () => 'mocked result',\n * })\n * ],\n * });\n * ```\n */\nexport namespace mockServices {\n export function rootConfig(options?: rootConfig.Options): RootConfigService {\n return new ConfigReader(options?.data, 'mock-config');\n }\n export namespace rootConfig {\n export type Options = { data?: JsonObject };\n\n export const factory = simpleFactoryWithOptions(\n coreServices.rootConfig,\n rootConfig,\n );\n export const mock = simpleMock(coreServices.rootConfig, () => ({\n get: jest.fn(),\n getBoolean: jest.fn(),\n getConfig: jest.fn(),\n getConfigArray: jest.fn(),\n getNumber: jest.fn(),\n getOptional: jest.fn(),\n getOptionalBoolean: jest.fn(),\n getOptionalConfig: jest.fn(),\n getOptionalConfigArray: jest.fn(),\n getOptionalNumber: jest.fn(),\n getOptionalString: jest.fn(),\n getOptionalStringArray: jest.fn(),\n getString: jest.fn(),\n getStringArray: jest.fn(),\n has: jest.fn(),\n keys: jest.fn(),\n }));\n }\n\n export function rootLogger(options?: rootLogger.Options): LoggerService {\n return MockRootLoggerService.create(options);\n }\n export namespace rootLogger {\n export type Options = {\n level?: 'none' | 'error' | 'warn' | 'info' | 'debug';\n };\n\n export const factory = simpleFactoryWithOptions(\n coreServices.rootLogger,\n rootLogger,\n );\n export const mock = simpleMock(coreServices.rootLogger, () => ({\n child: jest.fn(),\n debug: jest.fn(),\n error: jest.fn(),\n info: jest.fn(),\n warn: jest.fn(),\n }));\n }\n\n export namespace auditor {\n export const factory = () => auditorServiceFactory;\n\n export const mock = simpleMock(coreServices.auditor, () => ({\n createEvent: jest.fn(async _ => {\n return {\n success: jest.fn(),\n fail: jest.fn(),\n };\n }),\n }));\n }\n\n export function auth(options?: {\n pluginId?: string;\n disableDefaultAuthPolicy?: boolean;\n }): AuthService {\n return new MockAuthService({\n pluginId: options?.pluginId ?? 'test',\n disableDefaultAuthPolicy: Boolean(options?.disableDefaultAuthPolicy),\n });\n }\n export namespace auth {\n export const factory = () =>\n createServiceFactory({\n service: coreServices.auth,\n deps: {\n plugin: coreServices.pluginMetadata,\n config: coreServices.rootConfig,\n },\n factory({ plugin, config }) {\n const disableDefaultAuthPolicy = Boolean(\n config.getOptionalBoolean(\n 'backend.auth.dangerouslyDisableDefaultAuthPolicy',\n ),\n );\n return new MockAuthService({\n pluginId: plugin.getId(),\n disableDefaultAuthPolicy,\n });\n },\n });\n export const mock = simpleMock(coreServices.auth, () => ({\n authenticate: jest.fn(),\n getNoneCredentials: jest.fn(),\n getOwnServiceCredentials: jest.fn(),\n isPrincipal: jest.fn() as any,\n getPluginRequestToken: jest.fn(),\n getLimitedUserToken: jest.fn(),\n listPublicServiceKeys: jest.fn(),\n }));\n }\n\n export function discovery(): DiscoveryService {\n return HostDiscovery.fromConfig(\n new ConfigReader({\n backend: {\n // Invalid port to make sure that requests are always mocked\n baseUrl: 'http://localhost:0',\n listen: { port: 0 },\n },\n }),\n );\n }\n export namespace discovery {\n export const factory = () =>\n createServiceFactory({\n service: coreServices.discovery,\n deps: {},\n factory: () => discovery(),\n });\n export const mock = simpleMock(coreServices.discovery, () => ({\n getBaseUrl: jest.fn(),\n getExternalBaseUrl: jest.fn(),\n }));\n }\n\n /**\n * Creates a mock implementation of the `HttpAuthService`.\n *\n * By default all requests without credentials are treated as requests from\n * the default mock user principal. This behavior can be configured with the\n * `defaultCredentials` option.\n */\n export function httpAuth(options?: {\n pluginId?: string;\n /**\n * The default credentials to use if there are no credentials present in the\n * incoming request.\n *\n * By default all requests without credentials are treated as authenticated\n * as the default mock user as returned from `mockCredentials.user()`.\n */\n defaultCredentials?: BackstageCredentials;\n }): HttpAuthService {\n return new MockHttpAuthService(\n options?.pluginId ?? 'test',\n options?.defaultCredentials ?? mockCredentials.user(),\n );\n }\n export namespace httpAuth {\n /**\n * Creates a mock service factory for the `HttpAuthService`.\n *\n * By default all requests without credentials are treated as requests from\n * the default mock user principal. This behavior can be configured with the\n * `defaultCredentials` option.\n */\n export const factory = (options?: {\n defaultCredentials?: BackstageCredentials;\n }) =>\n createServiceFactory({\n service: coreServices.httpAuth,\n deps: { plugin: coreServices.pluginMetadata },\n factory: ({ plugin }) =>\n new MockHttpAuthService(\n plugin.getId(),\n options?.defaultCredentials ?? mockCredentials.user(),\n ),\n });\n export const mock = simpleMock(coreServices.httpAuth, () => ({\n credentials: jest.fn(),\n issueUserCookie: jest.fn(),\n }));\n }\n\n /**\n * Creates a mock implementation of the `UserInfoService`.\n *\n * By default it extracts the user's entity ref from a user principal and\n * returns that as the only ownership entity ref, but this can be overridden\n * by passing in a custom set of user info.\n */\n export function userInfo(\n customInfo?: Partial<BackstageUserInfo>,\n ): UserInfoService {\n return new MockUserInfoService(customInfo);\n }\n export namespace userInfo {\n /**\n * Creates a mock service factory for the `UserInfoService`.\n *\n * By default it extracts the user's entity ref from a user principal and\n * returns that as the only ownership entity ref.\n */\n export const factory = () =>\n createServiceFactory({\n service: coreServices.userInfo,\n deps: {},\n factory() {\n return new MockUserInfoService();\n },\n });\n export const mock = simpleMock(coreServices.userInfo, () => ({\n getUserInfo: jest.fn(),\n }));\n }\n\n // TODO(Rugvip): Not all core services have implementations available here yet.\n // some may need a bit more refactoring for it to be simpler to\n // re-implement functioning mock versions here.\n export namespace cache {\n export const factory = () => cacheServiceFactory;\n export const mock = simpleMock(coreServices.cache, () => ({\n delete: jest.fn(),\n get: jest.fn(),\n set: jest.fn(),\n withOptions: jest.fn(),\n }));\n }\n\n /**\n * Creates a mock implementation of the\n * {@link @backstage/backend-plugin-api#coreServices.database}. Just returns\n * the given `knex` instance, which is useful in combination with the\n * {@link TestDatabases} facility.\n */\n export function database(options: {\n knex: Knex;\n migrations?: { skip?: boolean };\n }): DatabaseService {\n return {\n getClient: async () => options.knex,\n migrations: options.migrations,\n };\n }\n export namespace database {\n /**\n * Creates a mock factory for the\n * {@link @backstage/backend-plugin-api#coreServices.database}. Just returns\n * the given `knex` instance if you supply one, which is useful in\n * combination with the {@link TestDatabases} facility. Otherwise, it\n * returns the regular default database factory which reads config settings.\n */\n export const factory = (options?: {\n knex: Knex;\n migrations?: { skip?: boolean };\n }) =>\n options\n ? createServiceFactory({\n service: coreServices.database,\n deps: {},\n factory: () => database(options),\n })\n : databaseServiceFactory;\n /**\n * Creates a mock of the\n * {@link @backstage/backend-plugin-api#coreServices.database}, optionally\n * with some given method implementations.\n */\n export const mock = simpleMock(coreServices.database, () => ({\n getClient: jest.fn(),\n }));\n }\n\n export namespace rootHealth {\n export const factory = () => rootHealthServiceFactory;\n export const mock = simpleMock(coreServices.rootHealth, () => ({\n getLiveness: jest.fn(),\n getReadiness: jest.fn(),\n }));\n }\n\n export namespace httpRouter {\n export const factory = () => httpRouterServiceFactory;\n export const mock = simpleMock(coreServices.httpRouter, () => ({\n use: jest.fn(),\n addAuthPolicy: jest.fn(),\n }));\n }\n\n export namespace rootHttpRouter {\n export const factory = () => rootHttpRouterServiceFactory();\n export const mock = simpleMock(coreServices.rootHttpRouter, () => ({\n use: jest.fn(),\n }));\n }\n\n export namespace lifecycle {\n export const factory = () => lifecycleServiceFactory;\n export const mock = simpleMock(coreServices.lifecycle, () => ({\n addShutdownHook: jest.fn(),\n addStartupHook: jest.fn(),\n }));\n }\n\n export namespace logger {\n export const factory = () => loggerServiceFactory;\n export const mock = simpleMock(coreServices.logger, () =>\n createLoggerMock(),\n );\n }\n\n export namespace permissions {\n export const factory = () => permissionsServiceFactory;\n export const mock = simpleMock(coreServices.permissions, () => ({\n authorize: jest.fn(),\n authorizeConditional: jest.fn(),\n }));\n }\n\n export namespace permissionsRegistry {\n export const factory = () => permissionsRegistryServiceFactory;\n export const mock = simpleMock(coreServices.permissionsRegistry, () => ({\n addPermissionRules: jest.fn(),\n addPermissions: jest.fn(),\n addResourceType: jest.fn(),\n }));\n }\n\n export namespace rootLifecycle {\n export const factory = () => rootLifecycleServiceFactory;\n export const mock = simpleMock(coreServices.rootLifecycle, () => ({\n addShutdownHook: jest.fn(),\n addBeforeShutdownHook: jest.fn(),\n addStartupHook: jest.fn(),\n }));\n }\n\n export namespace scheduler {\n export const factory = () => schedulerServiceFactory;\n export const mock = simpleMock(coreServices.scheduler, () => ({\n createScheduledTaskRunner: jest.fn(),\n getScheduledTasks: jest.fn(),\n scheduleTask: jest.fn(),\n triggerTask: jest.fn(),\n }));\n }\n\n export namespace urlReader {\n export const factory = () => urlReaderServiceFactory;\n export const mock = simpleMock(coreServices.urlReader, () => ({\n readTree: jest.fn(),\n readUrl: jest.fn(),\n search: jest.fn(),\n }));\n }\n\n 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"],"names":["createServiceFactory","mockServices","ConfigReader","rootConfig","coreServices","MockRootLoggerService","rootLogger","auditor","auditorServiceFactory","MockAuthService","auth","discovery","HostDiscovery","MockHttpAuthService","mockCredentials","httpAuth","MockUserInfoService","userInfo","cache","cacheServiceFactory","database","databaseServiceFactory","rootHealth","rootHealthServiceFactory","httpRouter","httpRouterServiceFactory","rootHttpRouter","rootHttpRouterServiceFactory","lifecycle","lifecycleServiceFactory","logger","loggerServiceFactory","permissions","permissionsServiceFactory","permissionsRegistry","permissionsRegistryServiceFactory","rootLifecycle","rootLifecycleServiceFactory","scheduler","schedulerServiceFactory","urlReader","urlReaderServiceFactory","events","eventsServiceFactory","eventsServiceRef"],"mappings":"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"}
|
|
@@ -15,6 +15,7 @@ var express__default = /*#__PURE__*/_interopDefaultCompat(express);
|
|
|
15
15
|
|
|
16
16
|
const defaultServiceFactories = [
|
|
17
17
|
mockServices.mockServices.auth.factory(),
|
|
18
|
+
mockServices.mockServices.auditor.factory(),
|
|
18
19
|
mockServices.mockServices.cache.factory(),
|
|
19
20
|
mockServices.mockServices.rootConfig.factory(),
|
|
20
21
|
mockServices.mockServices.database.factory(),
|
|
@@ -23,6 +24,7 @@ const defaultServiceFactories = [
|
|
|
23
24
|
mockServices.mockServices.lifecycle.factory(),
|
|
24
25
|
mockServices.mockServices.logger.factory(),
|
|
25
26
|
mockServices.mockServices.permissions.factory(),
|
|
27
|
+
mockServices.mockServices.permissionsRegistry.factory(),
|
|
26
28
|
mockServices.mockServices.rootHealth.factory(),
|
|
27
29
|
mockServices.mockServices.rootLifecycle.factory(),
|
|
28
30
|
mockServices.mockServices.rootLogger.factory(),
|
|
@@ -121,7 +123,13 @@ function isPromise(value) {
|
|
|
121
123
|
return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
|
|
122
124
|
}
|
|
123
125
|
function unwrapFeature(feature) {
|
|
124
|
-
|
|
126
|
+
if ("$$type" in feature) {
|
|
127
|
+
return feature;
|
|
128
|
+
}
|
|
129
|
+
if ("default" in feature) {
|
|
130
|
+
return feature.default;
|
|
131
|
+
}
|
|
132
|
+
return feature;
|
|
125
133
|
}
|
|
126
134
|
const backendInstancesToCleanUp = new Array();
|
|
127
135
|
async function startTestBackend(options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestBackend.cjs.js","sources":["../../../src/next/wiring/TestBackend.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Backend, createSpecializedBackend } from '@backstage/backend-app-api';\nimport {\n createServiceFactory,\n BackendFeature,\n ExtensionPoint,\n coreServices,\n createBackendModule,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { mockServices } from '../services';\nimport { ConfigReader } from '@backstage/config';\nimport express from 'express';\n// Direct internal import to avoid duplication\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport {\n InternalBackendFeature,\n InternalBackendRegistrations,\n} from '../../../../backend-plugin-api/src/wiring/types';\nimport {\n DefaultRootHttpRouter,\n ExtendedHttpServer,\n MiddlewareFactory,\n createHealthRouter,\n createHttpServer,\n} from '@backstage/backend-defaults/rootHttpRouter';\nimport { HostDiscovery } from '@backstage/backend-defaults/discovery';\n\n/** @public */\nexport interface TestBackendOptions<TExtensionPoints extends any[]> {\n extensionPoints?: readonly [\n ...{\n [index in keyof TExtensionPoints]: [\n ExtensionPoint<TExtensionPoints[index]>,\n Partial<TExtensionPoints[index]>,\n ];\n },\n ];\n features?: Array<BackendFeature | Promise<{ default: BackendFeature }>>;\n}\n\n/** @public */\nexport interface TestBackend extends Backend {\n /**\n * Provides access to the underling HTTP server for use with utilities\n * such as `supertest`.\n *\n * If the root http router service has been replaced, this will throw an error.\n */\n readonly server: ExtendedHttpServer;\n}\n\nexport const defaultServiceFactories = [\n mockServices.auth.factory(),\n mockServices.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({ config, health });\n\n app.use(healthRouter);\n app.use(router.handler());\n app.use(middleware.notFound());\n app.use(middleware.error());\n\n server = await createHttpServer(\n app,\n { listen: { host: '', port: 0 } },\n { logger },\n );\n\n lifecycle.addShutdownHook(() => server.stop(), { logger });\n\n await server.start();\n\n return router;\n },\n });\n\n const discoveryFactory = createServiceFactory({\n service: coreServices.discovery,\n deps: {\n rootHttpRouter: coreServices.rootHttpRouter,\n },\n async factory() {\n if (!server) {\n throw new Error('Test server not started yet');\n }\n const port = server.port();\n const discovery = HostDiscovery.fromConfig(\n new ConfigReader({\n backend: { baseUrl: `http://localhost:${port}`, listen: { port } },\n }),\n );\n return discovery;\n },\n });\n\n const backend = createSpecializedBackend({\n ...otherOptions,\n defaultServiceFactories: [\n ...defaultServiceFactories,\n rootHttpRouterFactory,\n discoveryFactory,\n ],\n });\n\n backendInstancesToCleanUp.push(backend);\n\n for (const m of createExtensionPointTestModules(features, extensionPoints)) {\n backend.add(m);\n }\n for (const p of createPluginsForOrphanModules(features)) {\n backend.add(p);\n }\n for (const feature of features) {\n backend.add(feature);\n }\n\n await backend.start();\n\n return Object.assign(backend, {\n get server() {\n if (!server) {\n throw new Error('TestBackend server is not available');\n }\n return server;\n },\n });\n}\n\nlet registered = false;\nfunction registerTestHooks() {\n if (typeof afterAll !== 'function') {\n return;\n }\n if (registered) {\n return;\n }\n registered = true;\n\n afterAll(async () => {\n await Promise.all(\n backendInstancesToCleanUp.map(async backend => {\n try {\n await backend.stop();\n } catch (error) {\n console.error(`Failed to stop backend after tests, ${error}`);\n }\n }),\n );\n backendInstancesToCleanUp.length = 0;\n });\n}\n\nregisterTestHooks();\n\nfunction toInternalBackendFeature(\n feature: BackendFeature,\n): InternalBackendFeature {\n if (feature.$$type !== '@backstage/BackendFeature') {\n throw new Error(`Invalid BackendFeature, bad type '${feature.$$type}'`);\n }\n const internal = feature as InternalBackendFeature;\n if (internal.version !== 'v1') {\n throw new Error(\n `Invalid BackendFeature, bad version '${internal.version}'`,\n );\n }\n return internal;\n}\n\nfunction isInternalBackendRegistrations(\n feature: BackendFeature,\n): feature is InternalBackendRegistrations {\n const internal = toInternalBackendFeature(feature);\n if (internal.featureType === 'registrations') {\n return true;\n }\n // Backwards compatibility for v1 registrations that use duck typing\n return 'getRegistrations' in internal;\n}\n"],"names":["mockServices","createBackendPlugin","createBackendModule","createServiceFactory","coreServices","DefaultRootHttpRouter","express","MiddlewareFactory","createHealthRouter","createHttpServer","discovery","HostDiscovery","ConfigReader","createSpecializedBackend"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TestBackend.cjs.js","sources":["../../../src/next/wiring/TestBackend.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Backend, createSpecializedBackend } from '@backstage/backend-app-api';\nimport {\n createServiceFactory,\n BackendFeature,\n ExtensionPoint,\n coreServices,\n createBackendModule,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { mockServices } from '../services';\nimport { ConfigReader } from '@backstage/config';\nimport express from 'express';\n// Direct internal import to avoid duplication\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport {\n InternalBackendFeature,\n InternalBackendRegistrations,\n} from '../../../../backend-plugin-api/src/wiring/types';\nimport {\n DefaultRootHttpRouter,\n ExtendedHttpServer,\n MiddlewareFactory,\n createHealthRouter,\n createHttpServer,\n} from '@backstage/backend-defaults/rootHttpRouter';\nimport { HostDiscovery } from '@backstage/backend-defaults/discovery';\n\n/** @public */\nexport interface TestBackendOptions<TExtensionPoints extends any[]> {\n extensionPoints?: readonly [\n ...{\n [index in keyof TExtensionPoints]: [\n ExtensionPoint<TExtensionPoints[index]>,\n Partial<TExtensionPoints[index]>,\n ];\n },\n ];\n features?: Array<BackendFeature | Promise<{ default: BackendFeature }>>;\n}\n\n/** @public */\nexport interface TestBackend extends Backend {\n /**\n * Provides access to the underling HTTP server for use with utilities\n * such as `supertest`.\n *\n * If the root http router service has been replaced, this will throw an error.\n */\n readonly server: ExtendedHttpServer;\n}\n\nexport const defaultServiceFactories = [\n mockServices.auth.factory(),\n mockServices.auditor.factory(),\n mockServices.cache.factory(),\n mockServices.rootConfig.factory(),\n mockServices.database.factory(),\n mockServices.httpAuth.factory(),\n mockServices.httpRouter.factory(),\n mockServices.lifecycle.factory(),\n mockServices.logger.factory(),\n mockServices.permissions.factory(),\n mockServices.permissionsRegistry.factory(),\n mockServices.rootHealth.factory(),\n mockServices.rootLifecycle.factory(),\n mockServices.rootLogger.factory(),\n mockServices.scheduler.factory(),\n mockServices.userInfo.factory(),\n mockServices.urlReader.factory(),\n mockServices.events.factory(),\n];\n\n/**\n * Given a set of features, return an array of plugins that ensures that each\n * module in the provided set of features has a corresponding plugin.\n * @internal\n */\nfunction createPluginsForOrphanModules(features: Array<BackendFeature>) {\n const pluginIds = new Set<string>();\n const modulePluginIds = new Set<string>();\n\n for (const feature of features) {\n if (isInternalBackendRegistrations(feature)) {\n const registrations = feature.getRegistrations();\n for (const registration of registrations) {\n if (registration.type === 'plugin') {\n pluginIds.add(registration.pluginId);\n } else if (registration.type === 'module') {\n modulePluginIds.add(registration.pluginId);\n }\n }\n }\n }\n\n for (const pluginId of pluginIds) {\n modulePluginIds.delete(pluginId);\n }\n\n return Array.from(modulePluginIds).map(pluginId =>\n createBackendPlugin({\n pluginId,\n register(reg) {\n reg.registerInit({ deps: {}, async init() {} });\n },\n }),\n );\n}\n\n/**\n * Given a set of extension points and features, find the extension\n * points that we mock and tie them to the correct plugin ID.\n * @returns\n */\nfunction createExtensionPointTestModules(\n features: Array<BackendFeature>,\n extensionPointTuples?: readonly [\n ref: ExtensionPoint<unknown>,\n impl: unknown,\n ][],\n): Array<BackendFeature> {\n if (!extensionPointTuples) {\n return [];\n }\n\n const registrations = features.flatMap(feature => {\n if (isInternalBackendRegistrations(feature)) {\n return feature.getRegistrations();\n }\n return [];\n });\n\n const extensionPointMap = new Map(\n extensionPointTuples.map(ep => [ep[0].id, ep]),\n );\n const extensionPointsToSort = new Set(extensionPointMap.keys());\n const extensionPointsByPlugin = new Map<string, string[]>();\n\n for (const registration of registrations) {\n if (registration.type === 'module') {\n const testDep = Object.values(registration.init.deps).filter(dep =>\n extensionPointsToSort.has(dep.id),\n );\n if (testDep.length > 0) {\n let points = extensionPointsByPlugin.get(registration.pluginId);\n if (!points) {\n points = [];\n extensionPointsByPlugin.set(registration.pluginId, points);\n }\n for (const { id } of testDep) {\n points.push(id);\n extensionPointsToSort.delete(id);\n }\n }\n }\n }\n\n if (extensionPointsToSort.size > 0) {\n const list = Array.from(extensionPointsToSort)\n .map(id => `'${id}'`)\n .join(', ');\n throw new Error(\n `Unable to determine the plugin ID of extension point(s) ${list}. ` +\n 'Tested extension points must be depended on by one or more tested modules.',\n );\n }\n\n const modules = [];\n\n for (const [pluginId, pluginExtensionPointIds] of extensionPointsByPlugin) {\n modules.push(\n createBackendModule({\n pluginId,\n moduleId: 'test-extension-point-registration',\n register(reg) {\n for (const id of pluginExtensionPointIds) {\n const tuple = extensionPointMap.get(id)!;\n reg.registerExtensionPoint(...tuple);\n }\n\n reg.registerInit({ deps: {}, async init() {} });\n },\n }),\n );\n }\n\n return modules;\n}\n\nfunction isPromise<T>(value: unknown | Promise<T>): value is Promise<T> {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'then' in value &&\n typeof value.then === 'function'\n );\n}\n\n// Same as in the backend-app-api, handles double defaults from dynamic imports\nfunction unwrapFeature(\n feature: BackendFeature | { default: BackendFeature },\n): BackendFeature {\n if ('$$type' in feature) {\n return feature;\n }\n\n if ('default' in feature) {\n return feature.default;\n }\n\n return feature;\n}\n\nconst backendInstancesToCleanUp = new Array<Backend>();\n\n/** @public */\nexport async function startTestBackend<TExtensionPoints extends any[]>(\n options: TestBackendOptions<TExtensionPoints>,\n): Promise<TestBackend> {\n const { extensionPoints, ...otherOptions } = options;\n\n // Unpack input into awaited plain BackendFeatures\n const features: BackendFeature[] = await Promise.all(\n options.features?.map(async val => {\n if (isPromise(val)) {\n const { default: feature } = await val;\n return unwrapFeature(feature);\n }\n return unwrapFeature(val);\n }) ?? [],\n );\n\n let server: ExtendedHttpServer;\n\n const rootHttpRouterFactory = createServiceFactory({\n service: coreServices.rootHttpRouter,\n deps: {\n config: coreServices.rootConfig,\n lifecycle: coreServices.rootLifecycle,\n rootLogger: coreServices.rootLogger,\n health: coreServices.rootHealth,\n },\n async factory({ config, lifecycle, rootLogger, health }) {\n const router = DefaultRootHttpRouter.create();\n const logger = rootLogger.child({ service: 'rootHttpRouter' });\n\n const app = express();\n\n const middleware = MiddlewareFactory.create({ config, logger });\n const healthRouter = createHealthRouter({ config, health });\n\n app.use(healthRouter);\n app.use(router.handler());\n app.use(middleware.notFound());\n app.use(middleware.error());\n\n server = await createHttpServer(\n app,\n { listen: { host: '', port: 0 } },\n { logger },\n );\n\n lifecycle.addShutdownHook(() => server.stop(), { logger });\n\n await server.start();\n\n return router;\n },\n });\n\n const discoveryFactory = createServiceFactory({\n service: coreServices.discovery,\n deps: {\n rootHttpRouter: coreServices.rootHttpRouter,\n },\n async factory() {\n if (!server) {\n throw new Error('Test server not started yet');\n }\n const port = server.port();\n const discovery = HostDiscovery.fromConfig(\n new ConfigReader({\n backend: { baseUrl: `http://localhost:${port}`, listen: { port } },\n }),\n );\n return discovery;\n },\n });\n\n const backend = createSpecializedBackend({\n ...otherOptions,\n defaultServiceFactories: [\n ...defaultServiceFactories,\n rootHttpRouterFactory,\n discoveryFactory,\n ],\n });\n\n backendInstancesToCleanUp.push(backend);\n\n for (const m of createExtensionPointTestModules(features, extensionPoints)) {\n backend.add(m);\n }\n for (const p of createPluginsForOrphanModules(features)) {\n backend.add(p);\n }\n for (const feature of features) {\n backend.add(feature);\n }\n\n await backend.start();\n\n return Object.assign(backend, {\n get server() {\n if (!server) {\n throw new Error('TestBackend server is not available');\n }\n return server;\n },\n });\n}\n\nlet registered = false;\nfunction registerTestHooks() {\n if (typeof afterAll !== 'function') {\n return;\n }\n if (registered) {\n return;\n }\n registered = true;\n\n afterAll(async () => {\n await Promise.all(\n backendInstancesToCleanUp.map(async backend => {\n try {\n await backend.stop();\n } catch (error) {\n console.error(`Failed to stop backend after tests, ${error}`);\n }\n }),\n );\n backendInstancesToCleanUp.length = 0;\n });\n}\n\nregisterTestHooks();\n\nfunction toInternalBackendFeature(\n feature: BackendFeature,\n): InternalBackendFeature {\n if (feature.$$type !== '@backstage/BackendFeature') {\n throw new Error(`Invalid BackendFeature, bad type '${feature.$$type}'`);\n }\n const internal = feature as InternalBackendFeature;\n if (internal.version !== 'v1') {\n throw new Error(\n `Invalid BackendFeature, bad version '${internal.version}'`,\n );\n }\n return internal;\n}\n\nfunction isInternalBackendRegistrations(\n feature: BackendFeature,\n): feature is InternalBackendRegistrations {\n const internal = toInternalBackendFeature(feature);\n if (internal.featureType === 'registrations') {\n return true;\n }\n // Backwards compatibility for v1 registrations that use duck typing\n return 'getRegistrations' in internal;\n}\n"],"names":["mockServices","createBackendPlugin","createBackendModule","createServiceFactory","coreServices","DefaultRootHttpRouter","express","MiddlewareFactory","createHealthRouter","createHttpServer","discovery","HostDiscovery","ConfigReader","createSpecializedBackend"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/backend-test-utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0-next.0",
|
|
4
4
|
"description": "Test helpers library for Backstage backends",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "node-library"
|
|
@@ -49,14 +49,14 @@
|
|
|
49
49
|
"test": "backstage-cli package test"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@backstage/backend-app-api": "1.1.
|
|
53
|
-
"@backstage/backend-defaults": "0.
|
|
54
|
-
"@backstage/backend-plugin-api": "1.
|
|
55
|
-
"@backstage/config": "1.3.2
|
|
56
|
-
"@backstage/errors": "1.2.7
|
|
57
|
-
"@backstage/plugin-auth-node": "0.5.
|
|
58
|
-
"@backstage/plugin-events-node": "0.4.
|
|
59
|
-
"@backstage/types": "1.2.1
|
|
52
|
+
"@backstage/backend-app-api": "1.1.2-next.0",
|
|
53
|
+
"@backstage/backend-defaults": "0.8.0-next.0",
|
|
54
|
+
"@backstage/backend-plugin-api": "1.2.0-next.0",
|
|
55
|
+
"@backstage/config": "1.3.2",
|
|
56
|
+
"@backstage/errors": "1.2.7",
|
|
57
|
+
"@backstage/plugin-auth-node": "0.5.7-next.0",
|
|
58
|
+
"@backstage/plugin-events-node": "0.4.8-next.0",
|
|
59
|
+
"@backstage/types": "1.2.1",
|
|
60
60
|
"@keyv/memcache": "^2.0.1",
|
|
61
61
|
"@keyv/redis": "^4.0.1",
|
|
62
62
|
"@types/express": "^4.17.6",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"yn": "^4.0.0"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
|
-
"@backstage/cli": "0.
|
|
81
|
+
"@backstage/cli": "0.30.0-next.0",
|
|
82
82
|
"@types/supertest": "^2.0.8",
|
|
83
83
|
"supertest": "^7.0.0"
|
|
84
84
|
},
|