@backstage/backend-test-utils 1.0.1-next.2 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # @backstage/backend-test-utils
2
2
 
3
+ ## 1.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @backstage/plugin-events-node@0.4.2
9
+ - @backstage/backend-defaults@0.5.2
10
+ - @backstage/backend-app-api@1.0.1
11
+ - @backstage/backend-plugin-api@1.0.1
12
+ - @backstage/plugin-auth-node@0.5.3
13
+
14
+ ## 1.0.1
15
+
16
+ ### Patch Changes
17
+
18
+ - fd6e6f4: build(deps): bump `cookie` from 0.6.0 to 0.7.0
19
+ - a19ce00: The `createMockDirectory` cleanup strategy has been changed, no longer requiring it to be called outside individual tests.
20
+ - 9cc7dd6: Minor doc string changes
21
+ - Updated dependencies
22
+ - @backstage/backend-defaults@0.5.1
23
+ - @backstage/backend-app-api@1.0.1
24
+ - @backstage/plugin-auth-node@0.5.3
25
+ - @backstage/plugin-events-node@0.4.1
26
+ - @backstage/backend-plugin-api@1.0.1
27
+ - @backstage/config@1.2.0
28
+ - @backstage/errors@1.2.4
29
+ - @backstage/types@1.1.1
30
+
3
31
  ## 1.0.1-next.2
4
32
 
5
33
  ### Patch Changes
@@ -113,6 +113,30 @@ class MockDirectoryImpl {
113
113
  return entries;
114
114
  }
115
115
  }
116
+ const cleanupCallbacks = new Array();
117
+ let registered = false;
118
+ function registerTestHooks() {
119
+ if (typeof afterAll !== "function") {
120
+ return;
121
+ }
122
+ if (registered) {
123
+ return;
124
+ }
125
+ registered = true;
126
+ afterAll(async () => {
127
+ for (const callback of cleanupCallbacks) {
128
+ try {
129
+ callback();
130
+ } catch (error) {
131
+ console.error(
132
+ `Failed to clean up mock directory after tests, ${error}`
133
+ );
134
+ }
135
+ }
136
+ cleanupCallbacks.length = 0;
137
+ });
138
+ }
139
+ registerTestHooks();
116
140
  function createMockDirectory(options) {
117
141
  const tmpDir = process.env.RUNNER_TEMP || os__default.default.tmpdir();
118
142
  const root = fs__default.default.mkdtempSync(path.join(tmpDir, "backstage-tmp-test-dir-"));
@@ -131,16 +155,13 @@ function createMockDirectory(options) {
131
155
  if (needsCleanup) {
132
156
  process.on("beforeExit", mocker.remove);
133
157
  }
134
- try {
158
+ if (needsCleanup) {
159
+ cleanupCallbacks.push(() => mocker.remove());
160
+ }
161
+ if (origTmpdir) {
135
162
  afterAll(() => {
136
- if (origTmpdir) {
137
- os__default.default.tmpdir = origTmpdir;
138
- }
139
- if (needsCleanup) {
140
- mocker.remove();
141
- }
163
+ os__default.default.tmpdir = origTmpdir;
142
164
  });
143
- } catch {
144
165
  }
145
166
  if (options?.content) {
146
167
  mocker.setContent(options.content);
@@ -1 +1 @@
1
- {"version":3,"file":"MockDirectory.cjs.js","sources":["../../src/filesystem/MockDirectory.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 os from 'os';\nimport { isChildPath } from '@backstage/backend-plugin-api';\nimport fs from 'fs-extra';\nimport textextensions from 'textextensions';\nimport {\n dirname,\n extname,\n join as joinPath,\n resolve as resolvePath,\n relative as relativePath,\n win32,\n posix,\n} from 'path';\n\nconst tmpdirMarker = Symbol('os-tmpdir-mock');\n\n/**\n * A context that allows for more advanced file system operations when writing mock directory content.\n *\n * @public\n */\nexport interface MockDirectoryContentCallbackContext {\n /** Absolute path to the location of this piece of content on the filesystem */\n path: string;\n\n /** Creates a symbolic link at the current location */\n symlink(target: string): void;\n}\n\n/**\n * A callback that allows for more advanced file system operations when writing mock directory content.\n *\n * @public\n */\nexport type MockDirectoryContentCallback = (\n ctx: MockDirectoryContentCallbackContext,\n) => void;\n\n/**\n * The content of a mock directory represented by a nested object structure.\n *\n * @remarks\n *\n * When used as input, the keys may contain forward slashes to indicate nested directories.\n * Then returned as output, each directory will always be represented as a separate object.\n *\n * @example\n * ```ts\n * {\n * 'test.txt': 'content',\n * 'sub-dir': {\n * 'file.txt': 'content',\n * 'nested-dir/file.txt': 'content',\n * },\n * 'empty-dir': {},\n * 'binary-file': Buffer.from([0, 1, 2]),\n * }\n * ```\n *\n * @public\n */\nexport type MockDirectoryContent = {\n [name in string]:\n | MockDirectoryContent\n | string\n | Buffer\n | MockDirectoryContentCallback;\n};\n\n/**\n * Options for {@link MockDirectory.content}.\n *\n * @public\n */\nexport interface MockDirectoryContentOptions {\n /**\n * The path to read content from. Defaults to the root of the mock directory.\n *\n * An absolute path can also be provided, as long as it is a child path of the mock directory.\n */\n path?: string;\n\n /**\n * Whether or not to return files as text rather than buffers.\n *\n * Defaults to checking the file extension against a list of known text extensions.\n */\n shouldReadAsText?: boolean | ((path: string, buffer: Buffer) => boolean);\n}\n\n/**\n * A utility for creating a mock directory that is automatically cleaned up.\n *\n * @public\n */\nexport interface MockDirectory {\n /**\n * The path to the root of the mock directory\n */\n readonly path: string;\n\n /**\n * Resolves a path relative to the root of the mock directory.\n */\n resolve(...paths: string[]): string;\n\n /**\n * Sets the content of the mock directory. This will remove any existing content.\n *\n * @example\n * ```ts\n * mockDir.setContent({\n * 'test.txt': 'content',\n * 'sub-dir': {\n * 'file.txt': 'content',\n * 'nested-dir/file.txt': 'content',\n * },\n * 'empty-dir': {},\n * 'binary-file': Buffer.from([0, 1, 2]),\n * });\n * ```\n */\n setContent(root: MockDirectoryContent): void;\n\n /**\n * Adds content of the mock directory. This will overwrite existing files.\n *\n * @example\n * ```ts\n * mockDir.addContent({\n * 'test.txt': 'content',\n * 'sub-dir': {\n * 'file.txt': 'content',\n * 'nested-dir/file.txt': 'content',\n * },\n * 'empty-dir': {},\n * 'binary-file': Buffer.from([0, 1, 2]),\n * });\n * ```\n */\n addContent(root: MockDirectoryContent): void;\n\n /**\n * Reads the content of the mock directory.\n *\n * @remarks\n *\n * Text files will be returned as strings, while binary files will be returned as buffers.\n * By default the file extension is used to determine whether a file should be read as text.\n *\n * @example\n * ```ts\n * expect(mockDir.content()).toEqual({\n * 'test.txt': 'content',\n * 'sub-dir': {\n * 'file.txt': 'content',\n * 'nested-dir': {\n * 'file.txt': 'content',\n * },\n * },\n * 'empty-dir': {},\n * 'binary-file': Buffer.from([0, 1, 2]),\n * });\n * ```\n */\n content(\n options?: MockDirectoryContentOptions,\n ): MockDirectoryContent | undefined;\n\n /**\n * Clears the content of the mock directory, ensuring that the directory itself exists.\n */\n clear(): void;\n\n /**\n * Removes the mock directory and all its contents.\n */\n remove(): void;\n}\n\n/** @internal */\ntype MockEntry =\n | {\n type: 'file';\n path: string;\n content: Buffer;\n }\n | {\n type: 'dir';\n path: string;\n }\n | {\n type: 'callback';\n path: string;\n callback: MockDirectoryContentCallback;\n };\n\n/** @internal */\nclass MockDirectoryImpl {\n readonly #root: string;\n\n constructor(root: string) {\n this.#root = root;\n }\n\n get path(): string {\n return this.#root;\n }\n\n resolve(...paths: string[]): string {\n return resolvePath(this.#root, ...paths);\n }\n\n setContent(root: MockDirectoryContent): void {\n this.remove();\n\n return this.addContent(root);\n }\n\n addContent(root: MockDirectoryContent): void {\n const entries = this.#transformInput(root);\n\n for (const entry of entries) {\n const fullPath = resolvePath(this.#root, entry.path);\n if (!isChildPath(this.#root, fullPath)) {\n throw new Error(\n `Provided path must resolve to a child path of the mock directory, got '${fullPath}'`,\n );\n }\n\n if (entry.type === 'dir') {\n fs.ensureDirSync(fullPath);\n } else if (entry.type === 'file') {\n fs.ensureDirSync(dirname(fullPath));\n fs.writeFileSync(fullPath, entry.content);\n } else if (entry.type === 'callback') {\n fs.ensureDirSync(dirname(fullPath));\n entry.callback({\n path: fullPath,\n symlink(target: string) {\n fs.symlinkSync(target, fullPath);\n },\n });\n }\n }\n }\n\n content(\n options?: MockDirectoryContentOptions,\n ): MockDirectoryContent | undefined {\n const shouldReadAsText =\n (typeof options?.shouldReadAsText === 'boolean'\n ? () => options?.shouldReadAsText\n : options?.shouldReadAsText) ??\n ((path: string) => textextensions.includes(extname(path).slice(1)));\n\n const root = resolvePath(this.#root, options?.path ?? '');\n if (!isChildPath(this.#root, root)) {\n throw new Error(\n `Provided path must resolve to a child path of the mock directory, got '${root}'`,\n );\n }\n\n function read(path: string): MockDirectoryContent | undefined {\n if (!fs.pathExistsSync(path)) {\n return undefined;\n }\n\n const entries = fs.readdirSync(path, { withFileTypes: true });\n return Object.fromEntries(\n entries.map(entry => {\n const fullPath = resolvePath(path, entry.name);\n\n if (entry.isDirectory()) {\n return [entry.name, read(fullPath)];\n }\n const content = fs.readFileSync(fullPath);\n const relativePosixPath = relativePath(root, fullPath)\n .split(win32.sep)\n .join(posix.sep);\n\n if (shouldReadAsText(relativePosixPath, content)) {\n return [entry.name, content.toString('utf8')];\n }\n return [entry.name, content];\n }),\n );\n }\n\n return read(root);\n }\n\n clear = (): void => {\n this.setContent({});\n };\n\n remove = (): void => {\n fs.rmSync(this.#root, { recursive: true, force: true, maxRetries: 10 });\n };\n\n #transformInput(input: MockDirectoryContent[string]): MockEntry[] {\n const entries: MockEntry[] = [];\n\n function traverse(node: MockDirectoryContent[string], path: string) {\n if (typeof node === 'string') {\n entries.push({\n type: 'file',\n path,\n content: Buffer.from(node, 'utf8'),\n });\n } else if (node instanceof Buffer) {\n entries.push({ type: 'file', path, content: node });\n } else if (typeof node === 'function') {\n entries.push({ type: 'callback', path, callback: node });\n } else {\n entries.push({ type: 'dir', path });\n for (const [name, child] of Object.entries(node)) {\n traverse(child, path ? `${path}/${name}` : name);\n }\n }\n }\n\n traverse(input, '');\n\n return entries;\n }\n}\n\n/**\n * Options for {@link createMockDirectory}.\n *\n * @public\n */\nexport interface CreateMockDirectoryOptions {\n /**\n * In addition to creating a temporary directory, also mock `os.tmpdir()` to return the\n * mock directory path until the end of the test suite.\n *\n * @returns\n */\n mockOsTmpDir?: boolean;\n\n /**\n * Initializes the directory with the given content, see {@link MockDirectory.setContent}.\n */\n content?: MockDirectoryContent;\n}\n\n/**\n * Creates a new temporary mock directory that will be removed after the tests have completed.\n *\n * @public\n * @remarks\n *\n * This method is intended to be called outside of any test, either at top-level or\n * within a `describe` block. It will call `afterAll` to make sure that the mock directory\n * is removed after the tests have run.\n *\n * @example\n * ```ts\n * describe('MySubject', () => {\n * const mockDir = createMockDirectory();\n *\n * beforeEach(mockDir.clear);\n *\n * it('should work', () => {\n * // ... use mockDir\n * })\n * })\n * ```\n */\nexport function createMockDirectory(\n options?: CreateMockDirectoryOptions,\n): MockDirectory {\n const tmpDir = process.env.RUNNER_TEMP || os.tmpdir(); // GitHub Actions\n const root = fs.mkdtempSync(joinPath(tmpDir, 'backstage-tmp-test-dir-'));\n\n const mocker = new MockDirectoryImpl(root);\n\n const origTmpdir = options?.mockOsTmpDir ? os.tmpdir : undefined;\n if (origTmpdir) {\n if (Object.hasOwn(origTmpdir, tmpdirMarker)) {\n throw new Error(\n 'Cannot mock os.tmpdir() when it has already been mocked',\n );\n }\n const mock = Object.assign(() => mocker.path, { [tmpdirMarker]: true });\n os.tmpdir = mock;\n }\n\n // In CI we expect there to be no need to clean up temporary directories\n const needsCleanup = !process.env.CI;\n if (needsCleanup) {\n process.on('beforeExit', mocker.remove);\n }\n\n try {\n afterAll(() => {\n if (origTmpdir) {\n os.tmpdir = origTmpdir;\n }\n if (needsCleanup) {\n mocker.remove();\n }\n });\n } catch {\n /* ignore */\n }\n\n if (options?.content) {\n mocker.setContent(options.content);\n }\n\n return mocker;\n}\n"],"names":["resolvePath","isChildPath","fs","dirname","path","textextensions","extname","relativePath","win32","posix","os","joinPath"],"mappings":"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"}
1
+ {"version":3,"file":"MockDirectory.cjs.js","sources":["../../src/filesystem/MockDirectory.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 os from 'os';\nimport { isChildPath } from '@backstage/backend-plugin-api';\nimport fs from 'fs-extra';\nimport textextensions from 'textextensions';\nimport {\n dirname,\n extname,\n join as joinPath,\n resolve as resolvePath,\n relative as relativePath,\n win32,\n posix,\n} from 'path';\n\nconst tmpdirMarker = Symbol('os-tmpdir-mock');\n\n/**\n * A context that allows for more advanced file system operations when writing mock directory content.\n *\n * @public\n */\nexport interface MockDirectoryContentCallbackContext {\n /** Absolute path to the location of this piece of content on the filesystem */\n path: string;\n\n /** Creates a symbolic link at the current location */\n symlink(target: string): void;\n}\n\n/**\n * A callback that allows for more advanced file system operations when writing mock directory content.\n *\n * @public\n */\nexport type MockDirectoryContentCallback = (\n ctx: MockDirectoryContentCallbackContext,\n) => void;\n\n/**\n * The content of a mock directory represented by a nested object structure.\n *\n * @remarks\n *\n * When used as input, the keys may contain forward slashes to indicate nested directories.\n * Then returned as output, each directory will always be represented as a separate object.\n *\n * @example\n * ```ts\n * {\n * 'test.txt': 'content',\n * 'sub-dir': {\n * 'file.txt': 'content',\n * 'nested-dir/file.txt': 'content',\n * },\n * 'empty-dir': {},\n * 'binary-file': Buffer.from([0, 1, 2]),\n * }\n * ```\n *\n * @public\n */\nexport type MockDirectoryContent = {\n [name in string]:\n | MockDirectoryContent\n | string\n | Buffer\n | MockDirectoryContentCallback;\n};\n\n/**\n * Options for {@link MockDirectory.content}.\n *\n * @public\n */\nexport interface MockDirectoryContentOptions {\n /**\n * The path to read content from. Defaults to the root of the mock directory.\n *\n * An absolute path can also be provided, as long as it is a child path of the mock directory.\n */\n path?: string;\n\n /**\n * Whether or not to return files as text rather than buffers.\n *\n * Defaults to checking the file extension against a list of known text extensions.\n */\n shouldReadAsText?: boolean | ((path: string, buffer: Buffer) => boolean);\n}\n\n/**\n * A utility for creating a mock directory that is automatically cleaned up.\n *\n * @public\n */\nexport interface MockDirectory {\n /**\n * The path to the root of the mock directory\n */\n readonly path: string;\n\n /**\n * Resolves a path relative to the root of the mock directory.\n */\n resolve(...paths: string[]): string;\n\n /**\n * Sets the content of the mock directory. This will remove any existing content.\n *\n * @example\n * ```ts\n * mockDir.setContent({\n * 'test.txt': 'content',\n * 'sub-dir': {\n * 'file.txt': 'content',\n * 'nested-dir/file.txt': 'content',\n * },\n * 'empty-dir': {},\n * 'binary-file': Buffer.from([0, 1, 2]),\n * });\n * ```\n */\n setContent(root: MockDirectoryContent): void;\n\n /**\n * Adds content of the mock directory. This will overwrite existing files.\n *\n * @example\n * ```ts\n * mockDir.addContent({\n * 'test.txt': 'content',\n * 'sub-dir': {\n * 'file.txt': 'content',\n * 'nested-dir/file.txt': 'content',\n * },\n * 'empty-dir': {},\n * 'binary-file': Buffer.from([0, 1, 2]),\n * });\n * ```\n */\n addContent(root: MockDirectoryContent): void;\n\n /**\n * Reads the content of the mock directory.\n *\n * @remarks\n *\n * Text files will be returned as strings, while binary files will be returned as buffers.\n * By default the file extension is used to determine whether a file should be read as text.\n *\n * @example\n * ```ts\n * expect(mockDir.content()).toEqual({\n * 'test.txt': 'content',\n * 'sub-dir': {\n * 'file.txt': 'content',\n * 'nested-dir': {\n * 'file.txt': 'content',\n * },\n * },\n * 'empty-dir': {},\n * 'binary-file': Buffer.from([0, 1, 2]),\n * });\n * ```\n */\n content(\n options?: MockDirectoryContentOptions,\n ): MockDirectoryContent | undefined;\n\n /**\n * Clears the content of the mock directory, ensuring that the directory itself exists.\n */\n clear(): void;\n\n /**\n * Removes the mock directory and all its contents.\n */\n remove(): void;\n}\n\n/** @internal */\ntype MockEntry =\n | {\n type: 'file';\n path: string;\n content: Buffer;\n }\n | {\n type: 'dir';\n path: string;\n }\n | {\n type: 'callback';\n path: string;\n callback: MockDirectoryContentCallback;\n };\n\n/** @internal */\nclass MockDirectoryImpl {\n readonly #root: string;\n\n constructor(root: string) {\n this.#root = root;\n }\n\n get path(): string {\n return this.#root;\n }\n\n resolve(...paths: string[]): string {\n return resolvePath(this.#root, ...paths);\n }\n\n setContent(root: MockDirectoryContent): void {\n this.remove();\n\n return this.addContent(root);\n }\n\n addContent(root: MockDirectoryContent): void {\n const entries = this.#transformInput(root);\n\n for (const entry of entries) {\n const fullPath = resolvePath(this.#root, entry.path);\n if (!isChildPath(this.#root, fullPath)) {\n throw new Error(\n `Provided path must resolve to a child path of the mock directory, got '${fullPath}'`,\n );\n }\n\n if (entry.type === 'dir') {\n fs.ensureDirSync(fullPath);\n } else if (entry.type === 'file') {\n fs.ensureDirSync(dirname(fullPath));\n fs.writeFileSync(fullPath, entry.content);\n } else if (entry.type === 'callback') {\n fs.ensureDirSync(dirname(fullPath));\n entry.callback({\n path: fullPath,\n symlink(target: string) {\n fs.symlinkSync(target, fullPath);\n },\n });\n }\n }\n }\n\n content(\n options?: MockDirectoryContentOptions,\n ): MockDirectoryContent | undefined {\n const shouldReadAsText =\n (typeof options?.shouldReadAsText === 'boolean'\n ? () => options?.shouldReadAsText\n : options?.shouldReadAsText) ??\n ((path: string) => textextensions.includes(extname(path).slice(1)));\n\n const root = resolvePath(this.#root, options?.path ?? '');\n if (!isChildPath(this.#root, root)) {\n throw new Error(\n `Provided path must resolve to a child path of the mock directory, got '${root}'`,\n );\n }\n\n function read(path: string): MockDirectoryContent | undefined {\n if (!fs.pathExistsSync(path)) {\n return undefined;\n }\n\n const entries = fs.readdirSync(path, { withFileTypes: true });\n return Object.fromEntries(\n entries.map(entry => {\n const fullPath = resolvePath(path, entry.name);\n\n if (entry.isDirectory()) {\n return [entry.name, read(fullPath)];\n }\n const content = fs.readFileSync(fullPath);\n const relativePosixPath = relativePath(root, fullPath)\n .split(win32.sep)\n .join(posix.sep);\n\n if (shouldReadAsText(relativePosixPath, content)) {\n return [entry.name, content.toString('utf8')];\n }\n return [entry.name, content];\n }),\n );\n }\n\n return read(root);\n }\n\n clear = (): void => {\n this.setContent({});\n };\n\n remove = (): void => {\n fs.rmSync(this.#root, { recursive: true, force: true, maxRetries: 10 });\n };\n\n #transformInput(input: MockDirectoryContent[string]): MockEntry[] {\n const entries: MockEntry[] = [];\n\n function traverse(node: MockDirectoryContent[string], path: string) {\n if (typeof node === 'string') {\n entries.push({\n type: 'file',\n path,\n content: Buffer.from(node, 'utf8'),\n });\n } else if (node instanceof Buffer) {\n entries.push({ type: 'file', path, content: node });\n } else if (typeof node === 'function') {\n entries.push({ type: 'callback', path, callback: node });\n } else {\n entries.push({ type: 'dir', path });\n for (const [name, child] of Object.entries(node)) {\n traverse(child, path ? `${path}/${name}` : name);\n }\n }\n }\n\n traverse(input, '');\n\n return entries;\n }\n}\n\n/**\n * Options for {@link createMockDirectory}.\n *\n * @public\n */\nexport interface CreateMockDirectoryOptions {\n /**\n * In addition to creating a temporary directory, also mock `os.tmpdir()` to\n * return the mock directory path until the end of the test suite.\n *\n * When this option is provided the `createMockDirectory` call must happen in\n * a scope where calling `afterAll` from Jest is allowed\n *\n * @returns\n */\n mockOsTmpDir?: boolean;\n\n /**\n * Initializes the directory with the given content, see {@link MockDirectory.setContent}.\n */\n content?: MockDirectoryContent;\n}\n\nconst cleanupCallbacks = new Array<() => void>();\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 for (const callback of cleanupCallbacks) {\n try {\n callback();\n } catch (error) {\n console.error(\n `Failed to clean up mock directory after tests, ${error}`,\n );\n }\n }\n cleanupCallbacks.length = 0;\n });\n}\n\nregisterTestHooks();\n\n/**\n * Creates a new temporary mock directory that will be removed after the tests have completed.\n *\n * @public\n * @remarks\n *\n * This method is intended to be called outside of any test, either at top-level or\n * within a `describe` block. It will call `afterAll` to make sure that the mock directory\n * is removed after the tests have run.\n *\n * @example\n * ```ts\n * describe('MySubject', () => {\n * const mockDir = createMockDirectory();\n *\n * beforeEach(mockDir.clear);\n *\n * it('should work', () => {\n * // ... use mockDir\n * })\n * })\n * ```\n */\nexport function createMockDirectory(\n options?: CreateMockDirectoryOptions,\n): MockDirectory {\n const tmpDir = process.env.RUNNER_TEMP || os.tmpdir(); // GitHub Actions\n const root = fs.mkdtempSync(joinPath(tmpDir, 'backstage-tmp-test-dir-'));\n\n const mocker = new MockDirectoryImpl(root);\n\n const origTmpdir = options?.mockOsTmpDir ? os.tmpdir : undefined;\n if (origTmpdir) {\n if (Object.hasOwn(origTmpdir, tmpdirMarker)) {\n throw new Error(\n 'Cannot mock os.tmpdir() when it has already been mocked',\n );\n }\n const mock = Object.assign(() => mocker.path, { [tmpdirMarker]: true });\n os.tmpdir = mock;\n }\n\n // In CI we expect there to be no need to clean up temporary directories\n const needsCleanup = !process.env.CI;\n if (needsCleanup) {\n process.on('beforeExit', mocker.remove);\n }\n\n if (needsCleanup) {\n cleanupCallbacks.push(() => mocker.remove());\n }\n\n if (origTmpdir) {\n afterAll(() => {\n os.tmpdir = origTmpdir;\n });\n }\n\n if (options?.content) {\n mocker.setContent(options.content);\n }\n\n return mocker;\n}\n"],"names":["resolvePath","isChildPath","fs","dirname","path","textextensions","extname","relativePath","win32","posix","os","joinPath"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -279,8 +279,11 @@ interface MockDirectory {
279
279
  */
280
280
  interface CreateMockDirectoryOptions {
281
281
  /**
282
- * In addition to creating a temporary directory, also mock `os.tmpdir()` to return the
283
- * mock directory path until the end of the test suite.
282
+ * In addition to creating a temporary directory, also mock `os.tmpdir()` to
283
+ * return the mock directory path until the end of the test suite.
284
+ *
285
+ * When this option is provided the `createMockDirectory` call must happen in
286
+ * a scope where calling `afterAll` from Jest is allowed
284
287
  *
285
288
  * @returns
286
289
  */
@@ -401,7 +404,46 @@ type ServiceMock<TService> = {
401
404
  [Key in keyof TService]: TService[Key] extends (...args: infer Args) => infer Return ? TService[Key] & jest.MockInstance<Return, Args> : TService[Key];
402
405
  };
403
406
  /**
407
+ * Mock implementations of the core services, to be used in tests.
408
+ *
404
409
  * @public
410
+ * @remarks
411
+ *
412
+ * There are some variations among the services depending on what needs tests
413
+ * might have, but overall there are three main usage patterns:
414
+ *
415
+ * 1. Creating an actual fake service instance, often with a simplified version
416
+ * of functionality, by calling the mock service itself as a function.
417
+ *
418
+ * ```ts
419
+ * // The function often accepts parameters that control its behavior
420
+ * const foo = mockServices.foo();
421
+ * ```
422
+ *
423
+ * 2. Creating a mock service, where all methods are replaced with jest mocks, by
424
+ * calling the service's `mock` function.
425
+ *
426
+ * ```ts
427
+ * // You can optionally supply a subset of its methods to implement
428
+ * const foo = mockServices.foo.mock({
429
+ * someMethod: () => 'mocked result',
430
+ * });
431
+ * // After exercising your test, you can make assertions on the mock:
432
+ * expect(foo.someMethod).toHaveBeenCalledTimes(2);
433
+ * expect(foo.otherMethod).toHaveBeenCalledWith(testData);
434
+ * ```
435
+ *
436
+ * 3. Creating a service factory that behaves similarly to the mock as per above.
437
+ *
438
+ * ```ts
439
+ * await startTestBackend({
440
+ * features: [
441
+ * mockServices.foo.factory({
442
+ * someMethod: () => 'mocked result',
443
+ * })
444
+ * ],
445
+ * });
446
+ * ```
405
447
  */
406
448
  declare namespace mockServices {
407
449
  function rootConfig(options?: rootConfig.Options): RootConfigService;
@@ -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 {\n HostDiscovery,\n discoveryServiceFactory,\n} from '@backstage/backend-defaults/discovery';\nimport { httpRouterServiceFactory } from '@backstage/backend-defaults/httpRouter';\nimport { lifecycleServiceFactory } from '@backstage/backend-defaults/lifecycle';\nimport { loggerServiceFactory } from '@backstage/backend-defaults/logger';\nimport { permissionsServiceFactory } from '@backstage/backend-defaults/permissions';\nimport { rootHealthServiceFactory } from '@backstage/backend-defaults/rootHealth';\nimport { rootHttpRouterServiceFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport { rootLifecycleServiceFactory } from '@backstage/backend-defaults/rootLifecycle';\nimport { schedulerServiceFactory } from '@backstage/backend-defaults/scheduler';\nimport { urlReaderServiceFactory } from '@backstage/backend-defaults/urlReader';\nimport {\n AuthService,\n BackstageCredentials,\n BackstageUserInfo,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n RootConfigService,\n ServiceFactory,\n ServiceRef,\n UserInfoService,\n coreServices,\n createServiceFactory,\n} from '@backstage/backend-plugin-api';\nimport { ConfigReader } from '@backstage/config';\nimport {\n eventsServiceFactory,\n eventsServiceRef,\n} from '@backstage/plugin-events-node';\nimport { JsonObject } from '@backstage/types';\nimport { MockAuthService } from './MockAuthService';\nimport { MockHttpAuthService } from './MockHttpAuthService';\nimport { MockRootLoggerService } from './MockRootLoggerService';\nimport { MockUserInfoService } from './MockUserInfoService';\nimport { mockCredentials } from './mockCredentials';\n\n/** @internal */\nfunction createLoggerMock() {\n return {\n child: jest.fn().mockImplementation(createLoggerMock),\n debug: jest.fn(),\n error: jest.fn(),\n info: jest.fn(),\n warn: jest.fn(),\n };\n}\n\n/** @internal */\nfunction simpleFactoryWithOptions<\n TService,\n TScope extends 'root' | 'plugin',\n TOptions extends [options?: object] = [],\n>(\n ref: ServiceRef<TService, TScope>,\n factory: (...options: TOptions) => TService,\n): (...options: TOptions) => ServiceFactory<TService, TScope> {\n const factoryWithOptions = (...options: TOptions) =>\n createServiceFactory({\n service: ref as ServiceRef<TService, any>,\n deps: {},\n async factory() {\n return factory(...options);\n },\n });\n return Object.assign(\n factoryWithOptions,\n factoryWithOptions(...([undefined] as unknown as TOptions)),\n ) as ServiceFactory<TService, TScope> &\n ((...options: TOptions) => ServiceFactory<TService, TScope>);\n}\n\n/** @public */\nexport type ServiceMock<TService> = {\n factory: ServiceFactory<TService>;\n} & {\n [Key in keyof TService]: TService[Key] extends (\n ...args: infer Args\n ) => infer Return\n ? TService[Key] & jest.MockInstance<Return, Args>\n : TService[Key];\n};\n\n/** @internal */\nfunction simpleMock<TService>(\n ref: ServiceRef<TService, any>,\n mockFactory: () => jest.Mocked<TService>,\n): (partialImpl?: Partial<TService>) => ServiceMock<TService> {\n return partialImpl => {\n const mock = mockFactory();\n if (partialImpl) {\n for (const [key, impl] of Object.entries(partialImpl)) {\n if (typeof impl === 'function') {\n (mock as any)[key].mockImplementation(impl);\n } else {\n (mock as any)[key] = impl;\n }\n }\n }\n return Object.assign(mock, {\n factory: createServiceFactory({\n service: ref,\n deps: {},\n factory: () => mock,\n }),\n }) as ServiceMock<TService>;\n };\n}\n\n/**\n * @public\n */\nexport namespace mockServices {\n export function rootConfig(options?: rootConfig.Options): RootConfigService {\n return new ConfigReader(options?.data, 'mock-config');\n }\n export namespace rootConfig {\n export type Options = { data?: JsonObject };\n\n export const factory = simpleFactoryWithOptions(\n coreServices.rootConfig,\n rootConfig,\n );\n export const mock = simpleMock(coreServices.rootConfig, () => ({\n get: jest.fn(),\n getBoolean: jest.fn(),\n getConfig: jest.fn(),\n getConfigArray: jest.fn(),\n getNumber: jest.fn(),\n getOptional: jest.fn(),\n getOptionalBoolean: jest.fn(),\n getOptionalConfig: jest.fn(),\n getOptionalConfigArray: jest.fn(),\n getOptionalNumber: jest.fn(),\n getOptionalString: jest.fn(),\n getOptionalStringArray: jest.fn(),\n getString: jest.fn(),\n getStringArray: jest.fn(),\n has: jest.fn(),\n keys: jest.fn(),\n }));\n }\n\n export function rootLogger(options?: rootLogger.Options): LoggerService {\n return MockRootLoggerService.create(options);\n }\n export namespace rootLogger {\n export type Options = {\n level?: 'none' | 'error' | 'warn' | 'info' | 'debug';\n };\n\n export const factory = simpleFactoryWithOptions(\n coreServices.rootLogger,\n rootLogger,\n );\n export const mock = simpleMock(coreServices.rootLogger, () => ({\n child: jest.fn(),\n debug: jest.fn(),\n error: jest.fn(),\n info: jest.fn(),\n warn: jest.fn(),\n }));\n }\n\n export function auth(options?: {\n pluginId?: string;\n disableDefaultAuthPolicy?: boolean;\n }): AuthService {\n return new MockAuthService({\n pluginId: options?.pluginId ?? 'test',\n disableDefaultAuthPolicy: Boolean(options?.disableDefaultAuthPolicy),\n });\n }\n export namespace auth {\n export const factory = () =>\n createServiceFactory({\n service: coreServices.auth,\n deps: {\n plugin: coreServices.pluginMetadata,\n config: coreServices.rootConfig,\n },\n factory({ plugin, config }) {\n const disableDefaultAuthPolicy = Boolean(\n config.getOptionalBoolean(\n 'backend.auth.dangerouslyDisableDefaultAuthPolicy',\n ),\n );\n return new MockAuthService({\n pluginId: plugin.getId(),\n disableDefaultAuthPolicy,\n });\n },\n });\n export const mock = simpleMock(coreServices.auth, () => ({\n authenticate: jest.fn(),\n getNoneCredentials: jest.fn(),\n getOwnServiceCredentials: jest.fn(),\n isPrincipal: jest.fn() as any,\n getPluginRequestToken: jest.fn(),\n getLimitedUserToken: jest.fn(),\n listPublicServiceKeys: jest.fn(),\n }));\n }\n\n export function discovery(): DiscoveryService {\n return HostDiscovery.fromConfig(\n new ConfigReader({\n backend: {\n // Invalid port to make sure that requests are always mocked\n baseUrl: 'http://localhost:0',\n listen: { port: 0 },\n },\n }),\n );\n }\n export namespace discovery {\n export const factory = () => discoveryServiceFactory;\n export const mock = simpleMock(coreServices.discovery, () => ({\n getBaseUrl: jest.fn(),\n getExternalBaseUrl: jest.fn(),\n }));\n }\n\n /**\n * Creates a mock implementation of the `HttpAuthService`.\n *\n * By default all requests without credentials are treated as requests from\n * the default mock user principal. This behavior can be configured with the\n * `defaultCredentials` option.\n */\n export function httpAuth(options?: {\n pluginId?: string;\n /**\n * The default credentials to use if there are no credentials present in the\n * incoming request.\n *\n * By default all requests without credentials are treated as authenticated\n * as the default mock user as returned from `mockCredentials.user()`.\n */\n defaultCredentials?: BackstageCredentials;\n }): HttpAuthService {\n return new MockHttpAuthService(\n options?.pluginId ?? 'test',\n options?.defaultCredentials ?? mockCredentials.user(),\n );\n }\n export namespace httpAuth {\n /**\n * Creates a mock service factory for the `HttpAuthService`.\n *\n * By default all requests without credentials are treated as requests from\n * the default mock user principal. This behavior can be configured with the\n * `defaultCredentials` option.\n */\n export const factory = (options?: {\n defaultCredentials?: BackstageCredentials;\n }) =>\n createServiceFactory({\n service: coreServices.httpAuth,\n deps: { plugin: coreServices.pluginMetadata },\n factory: ({ plugin }) =>\n new MockHttpAuthService(\n plugin.getId(),\n options?.defaultCredentials ?? mockCredentials.user(),\n ),\n });\n export const mock = simpleMock(coreServices.httpAuth, () => ({\n credentials: jest.fn(),\n issueUserCookie: jest.fn(),\n }));\n }\n\n /**\n * Creates a mock implementation of the `UserInfoService`.\n *\n * By default it extracts the user's entity ref from a user principal and\n * returns that as the only ownership entity ref, but this can be overridden\n * by passing in a custom set of user info.\n */\n export function userInfo(\n customInfo?: Partial<BackstageUserInfo>,\n ): UserInfoService {\n return new MockUserInfoService(customInfo);\n }\n export namespace userInfo {\n /**\n * Creates a mock service factory for the `UserInfoService`.\n *\n * By default it extracts the user's entity ref from a user principal and\n * returns that as the only ownership entity ref.\n */\n export const factory = () =>\n createServiceFactory({\n service: coreServices.userInfo,\n deps: {},\n factory() {\n return new MockUserInfoService();\n },\n });\n export const mock = simpleMock(coreServices.userInfo, () => ({\n getUserInfo: jest.fn(),\n }));\n }\n\n // TODO(Rugvip): Not all core services have implementations available here yet.\n // some may need a bit more refactoring for it to be simpler to\n // re-implement functioning mock versions here.\n export namespace cache {\n export const factory = () => cacheServiceFactory;\n export const mock = simpleMock(coreServices.cache, () => ({\n delete: jest.fn(),\n get: jest.fn(),\n set: jest.fn(),\n withOptions: jest.fn(),\n }));\n }\n\n export namespace database {\n export const factory = () => databaseServiceFactory;\n export const mock = simpleMock(coreServices.database, () => ({\n getClient: jest.fn(),\n }));\n }\n\n export namespace rootHealth {\n export const factory = () => rootHealthServiceFactory;\n export const mock = simpleMock(coreServices.rootHealth, () => ({\n getLiveness: jest.fn(),\n getReadiness: jest.fn(),\n }));\n }\n\n export namespace httpRouter {\n export const factory = () => httpRouterServiceFactory;\n export const mock = simpleMock(coreServices.httpRouter, () => ({\n use: jest.fn(),\n addAuthPolicy: jest.fn(),\n }));\n }\n\n export namespace rootHttpRouter {\n export const factory = () => rootHttpRouterServiceFactory();\n export const mock = simpleMock(coreServices.rootHttpRouter, () => ({\n use: jest.fn(),\n }));\n }\n\n export namespace lifecycle {\n export const factory = () => lifecycleServiceFactory;\n export const mock = simpleMock(coreServices.lifecycle, () => ({\n addShutdownHook: jest.fn(),\n addStartupHook: jest.fn(),\n }));\n }\n\n export namespace logger {\n export const factory = () => loggerServiceFactory;\n export const mock = simpleMock(coreServices.logger, () =>\n createLoggerMock(),\n );\n }\n\n export namespace permissions {\n export const factory = () => permissionsServiceFactory;\n export const mock = simpleMock(coreServices.permissions, () => ({\n authorize: jest.fn(),\n authorizeConditional: jest.fn(),\n }));\n }\n\n export namespace rootLifecycle {\n export const factory = () => rootLifecycleServiceFactory;\n export const mock = simpleMock(coreServices.rootLifecycle, () => ({\n addShutdownHook: jest.fn(),\n addStartupHook: jest.fn(),\n }));\n }\n\n export namespace scheduler {\n export const factory = () => schedulerServiceFactory;\n export const mock = simpleMock(coreServices.scheduler, () => ({\n createScheduledTaskRunner: jest.fn(),\n getScheduledTasks: jest.fn(),\n scheduleTask: jest.fn(),\n triggerTask: jest.fn(),\n }));\n }\n\n export namespace urlReader {\n export const factory = () => urlReaderServiceFactory;\n export const mock = simpleMock(coreServices.urlReader, () => ({\n readTree: jest.fn(),\n readUrl: jest.fn(),\n search: jest.fn(),\n }));\n }\n\n export namespace events {\n export const factory = () => eventsServiceFactory;\n export const mock = simpleMock(eventsServiceRef, () => ({\n publish: jest.fn(),\n subscribe: jest.fn(),\n }));\n }\n}\n"],"names":["createServiceFactory","mockServices","ConfigReader","rootConfig","coreServices","MockRootLoggerService","rootLogger","MockAuthService","auth","discovery","HostDiscovery","discoveryServiceFactory","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 {\n HostDiscovery,\n discoveryServiceFactory,\n} from '@backstage/backend-defaults/discovery';\nimport { httpRouterServiceFactory } from '@backstage/backend-defaults/httpRouter';\nimport { lifecycleServiceFactory } from '@backstage/backend-defaults/lifecycle';\nimport { loggerServiceFactory } from '@backstage/backend-defaults/logger';\nimport { permissionsServiceFactory } from '@backstage/backend-defaults/permissions';\nimport { rootHealthServiceFactory } from '@backstage/backend-defaults/rootHealth';\nimport { rootHttpRouterServiceFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport { rootLifecycleServiceFactory } from '@backstage/backend-defaults/rootLifecycle';\nimport { schedulerServiceFactory } from '@backstage/backend-defaults/scheduler';\nimport { urlReaderServiceFactory } from '@backstage/backend-defaults/urlReader';\nimport {\n AuthService,\n BackstageCredentials,\n BackstageUserInfo,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n RootConfigService,\n ServiceFactory,\n ServiceRef,\n UserInfoService,\n coreServices,\n createServiceFactory,\n} from '@backstage/backend-plugin-api';\nimport { ConfigReader } from '@backstage/config';\nimport {\n eventsServiceFactory,\n eventsServiceRef,\n} from '@backstage/plugin-events-node';\nimport { JsonObject } from '@backstage/types';\nimport { MockAuthService } from './MockAuthService';\nimport { MockHttpAuthService } from './MockHttpAuthService';\nimport { MockRootLoggerService } from './MockRootLoggerService';\nimport { MockUserInfoService } from './MockUserInfoService';\nimport { mockCredentials } from './mockCredentials';\n\n/** @internal */\nfunction createLoggerMock() {\n return {\n child: jest.fn().mockImplementation(createLoggerMock),\n debug: jest.fn(),\n error: jest.fn(),\n info: jest.fn(),\n warn: jest.fn(),\n };\n}\n\n/** @internal */\nfunction simpleFactoryWithOptions<\n TService,\n TScope extends 'root' | 'plugin',\n TOptions extends [options?: object] = [],\n>(\n ref: ServiceRef<TService, TScope>,\n factory: (...options: TOptions) => TService,\n): (...options: TOptions) => ServiceFactory<TService, TScope> {\n const factoryWithOptions = (...options: TOptions) =>\n createServiceFactory({\n service: ref as ServiceRef<TService, any>,\n deps: {},\n async factory() {\n return factory(...options);\n },\n });\n return Object.assign(\n factoryWithOptions,\n factoryWithOptions(...([undefined] as unknown as TOptions)),\n ) as ServiceFactory<TService, TScope> &\n ((...options: TOptions) => ServiceFactory<TService, TScope>);\n}\n\n/** @public */\nexport type ServiceMock<TService> = {\n factory: ServiceFactory<TService>;\n} & {\n [Key in keyof TService]: TService[Key] extends (\n ...args: infer Args\n ) => infer Return\n ? TService[Key] & jest.MockInstance<Return, Args>\n : TService[Key];\n};\n\n/** @internal */\nfunction simpleMock<TService>(\n ref: ServiceRef<TService, any>,\n mockFactory: () => jest.Mocked<TService>,\n): (partialImpl?: Partial<TService>) => ServiceMock<TService> {\n return partialImpl => {\n const mock = mockFactory();\n if (partialImpl) {\n for (const [key, impl] of Object.entries(partialImpl)) {\n if (typeof impl === 'function') {\n (mock as any)[key].mockImplementation(impl);\n } else {\n (mock as any)[key] = impl;\n }\n }\n }\n return Object.assign(mock, {\n factory: createServiceFactory({\n service: ref,\n deps: {},\n factory: () => mock,\n }),\n }) as ServiceMock<TService>;\n };\n}\n\n/**\n * 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 = () => discoveryServiceFactory;\n export const mock = simpleMock(coreServices.discovery, () => ({\n getBaseUrl: jest.fn(),\n getExternalBaseUrl: jest.fn(),\n }));\n }\n\n /**\n * Creates a mock implementation of the `HttpAuthService`.\n *\n * By default all requests without credentials are treated as requests from\n * the default mock user principal. This behavior can be configured with the\n * `defaultCredentials` option.\n */\n export function httpAuth(options?: {\n pluginId?: string;\n /**\n * The default credentials to use if there are no credentials present in the\n * incoming request.\n *\n * By default all requests without credentials are treated as authenticated\n * as the default mock user as returned from `mockCredentials.user()`.\n */\n defaultCredentials?: BackstageCredentials;\n }): HttpAuthService {\n return new MockHttpAuthService(\n options?.pluginId ?? 'test',\n options?.defaultCredentials ?? mockCredentials.user(),\n );\n }\n export namespace httpAuth {\n /**\n * Creates a mock service factory for the `HttpAuthService`.\n *\n * By default all requests without credentials are treated as requests from\n * the default mock user principal. This behavior can be configured with the\n * `defaultCredentials` option.\n */\n export const factory = (options?: {\n defaultCredentials?: BackstageCredentials;\n }) =>\n createServiceFactory({\n service: coreServices.httpAuth,\n deps: { plugin: coreServices.pluginMetadata },\n factory: ({ plugin }) =>\n new MockHttpAuthService(\n plugin.getId(),\n options?.defaultCredentials ?? mockCredentials.user(),\n ),\n });\n export const mock = simpleMock(coreServices.httpAuth, () => ({\n credentials: jest.fn(),\n issueUserCookie: jest.fn(),\n }));\n }\n\n /**\n * Creates a mock implementation of the `UserInfoService`.\n *\n * By default it extracts the user's entity ref from a user principal and\n * returns that as the only ownership entity ref, but this can be overridden\n * by passing in a custom set of user info.\n */\n export function userInfo(\n customInfo?: Partial<BackstageUserInfo>,\n ): UserInfoService {\n return new MockUserInfoService(customInfo);\n }\n export namespace userInfo {\n /**\n * Creates a mock service factory for the `UserInfoService`.\n *\n * By default it extracts the user's entity ref from a user principal and\n * returns that as the only ownership entity ref.\n */\n export const factory = () =>\n createServiceFactory({\n service: coreServices.userInfo,\n deps: {},\n factory() {\n return new MockUserInfoService();\n },\n });\n export const mock = simpleMock(coreServices.userInfo, () => ({\n getUserInfo: jest.fn(),\n }));\n }\n\n // TODO(Rugvip): Not all core services have implementations available here yet.\n // some may need a bit more refactoring for it to be simpler to\n // re-implement functioning mock versions here.\n export namespace cache {\n export const factory = () => cacheServiceFactory;\n export const mock = simpleMock(coreServices.cache, () => ({\n delete: jest.fn(),\n get: jest.fn(),\n set: jest.fn(),\n withOptions: jest.fn(),\n }));\n }\n\n export namespace database {\n export const factory = () => databaseServiceFactory;\n export const mock = simpleMock(coreServices.database, () => ({\n getClient: jest.fn(),\n }));\n }\n\n export namespace rootHealth {\n export const factory = () => rootHealthServiceFactory;\n export const mock = simpleMock(coreServices.rootHealth, () => ({\n getLiveness: jest.fn(),\n getReadiness: jest.fn(),\n }));\n }\n\n export namespace httpRouter {\n export const factory = () => httpRouterServiceFactory;\n export const mock = simpleMock(coreServices.httpRouter, () => ({\n use: jest.fn(),\n addAuthPolicy: jest.fn(),\n }));\n }\n\n export namespace rootHttpRouter {\n export const factory = () => rootHttpRouterServiceFactory();\n export const mock = simpleMock(coreServices.rootHttpRouter, () => ({\n use: jest.fn(),\n }));\n }\n\n export namespace lifecycle {\n export const factory = () => lifecycleServiceFactory;\n export const mock = simpleMock(coreServices.lifecycle, () => ({\n addShutdownHook: jest.fn(),\n addStartupHook: jest.fn(),\n }));\n }\n\n export namespace logger {\n export const factory = () => loggerServiceFactory;\n export const mock = simpleMock(coreServices.logger, () =>\n createLoggerMock(),\n );\n }\n\n export namespace permissions {\n export const factory = () => permissionsServiceFactory;\n export const mock = simpleMock(coreServices.permissions, () => ({\n authorize: jest.fn(),\n authorizeConditional: jest.fn(),\n }));\n }\n\n export namespace rootLifecycle {\n export const factory = () => rootLifecycleServiceFactory;\n export const mock = simpleMock(coreServices.rootLifecycle, () => ({\n addShutdownHook: jest.fn(),\n addStartupHook: jest.fn(),\n }));\n }\n\n export namespace scheduler {\n export const factory = () => schedulerServiceFactory;\n export const mock = simpleMock(coreServices.scheduler, () => ({\n createScheduledTaskRunner: jest.fn(),\n getScheduledTasks: jest.fn(),\n scheduleTask: jest.fn(),\n triggerTask: jest.fn(),\n }));\n }\n\n export namespace urlReader {\n export const factory = () => urlReaderServiceFactory;\n export const mock = simpleMock(coreServices.urlReader, () => ({\n readTree: jest.fn(),\n readUrl: jest.fn(),\n search: jest.fn(),\n }));\n }\n\n export namespace events {\n export const factory = () => eventsServiceFactory;\n export const mock = simpleMock(eventsServiceRef, () => ({\n publish: jest.fn(),\n subscribe: jest.fn(),\n }));\n }\n}\n"],"names":["createServiceFactory","mockServices","ConfigReader","rootConfig","coreServices","MockRootLoggerService","rootLogger","MockAuthService","auth","discovery","HostDiscovery","discoveryServiceFactory","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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/backend-test-utils",
3
- "version": "1.0.1-next.2",
3
+ "version": "1.0.2",
4
4
  "description": "Test helpers library for Backstage backends",
5
5
  "backstage": {
6
6
  "role": "node-library"
@@ -42,14 +42,14 @@
42
42
  "test": "backstage-cli package test"
43
43
  },
44
44
  "dependencies": {
45
- "@backstage/backend-app-api": "1.0.1-next.1",
46
- "@backstage/backend-defaults": "0.5.1-next.2",
47
- "@backstage/backend-plugin-api": "1.0.1-next.1",
48
- "@backstage/config": "1.2.0",
49
- "@backstage/errors": "1.2.4",
50
- "@backstage/plugin-auth-node": "0.5.3-next.1",
51
- "@backstage/plugin-events-node": "0.4.1-next.1",
52
- "@backstage/types": "1.1.1",
45
+ "@backstage/backend-app-api": "^1.0.1",
46
+ "@backstage/backend-defaults": "^0.5.2",
47
+ "@backstage/backend-plugin-api": "^1.0.1",
48
+ "@backstage/config": "^1.2.0",
49
+ "@backstage/errors": "^1.2.4",
50
+ "@backstage/plugin-auth-node": "^0.5.3",
51
+ "@backstage/plugin-events-node": "^0.4.2",
52
+ "@backstage/types": "^1.1.1",
53
53
  "@keyv/memcache": "^1.3.5",
54
54
  "@keyv/redis": "^2.5.3",
55
55
  "@types/express": "^4.17.6",
@@ -72,7 +72,7 @@
72
72
  "yn": "^4.0.0"
73
73
  },
74
74
  "devDependencies": {
75
- "@backstage/cli": "0.28.0-next.2",
75
+ "@backstage/cli": "^0.28.0",
76
76
  "@types/supertest": "^2.0.8",
77
77
  "supertest": "^7.0.0"
78
78
  },