diff --git a/.changeset/thin-chairs-ring.md b/.changeset/thin-chairs-ring.md
index dc3c7a0a25..5561b6f551 100644
--- a/.changeset/thin-chairs-ring.md
+++ b/.changeset/thin-chairs-ring.md
@@ -8,3 +8,4 @@ Added a `mockApis` export, which will replace the `MockX` API implementation cla
- Deprecated `MockAnalyticsApi`, please use `mockApis.analytics` instead.
- Deprecated `MockConfigApi`, please use `mockApis.config` instead.
- Deprecated `MockPermissionApi`, please use `mockApis.permission` instead.
+- Deprecated `MockStorageApi`, please use `mockApis.storage` instead.
diff --git a/packages/core-components/src/components/DismissableBanner/DismissableBanner.test.tsx b/packages/core-components/src/components/DismissableBanner/DismissableBanner.test.tsx
index 8d93186ccc..6f6da1231f 100644
--- a/packages/core-components/src/components/DismissableBanner/DismissableBanner.test.tsx
+++ b/packages/core-components/src/components/DismissableBanner/DismissableBanner.test.tsx
@@ -16,24 +16,18 @@
import React from 'react';
import { fireEvent } from '@testing-library/react';
-import { TestApiRegistry, renderInTestApp } from '@backstage/test-utils';
+import {
+ TestApiRegistry,
+ renderInTestApp,
+ mockApis,
+} from '@backstage/test-utils';
import { DismissableBanner } from './DismissableBanner';
-import { ApiProvider, WebStorage } from '@backstage/core-app-api';
-import { storageApiRef, StorageApi } from '@backstage/core-plugin-api';
+import { ApiProvider } from '@backstage/core-app-api';
+import { storageApiRef } from '@backstage/core-plugin-api';
import { screen } from '@testing-library/react';
describe('', () => {
- let apis: TestApiRegistry;
- const mockErrorApi = { post: jest.fn(), error$: jest.fn() };
- const createWebStorage = (): StorageApi => {
- return WebStorage.create({
- errorApi: mockErrorApi,
- });
- };
-
- beforeEach(() => {
- apis = TestApiRegistry.from([storageApiRef, createWebStorage()]);
- });
+ const apis = TestApiRegistry.from([storageApiRef, mockApis.storage()]);
it('renders the message and the popover', async () => {
await renderInTestApp(
diff --git a/packages/test-utils/report.api.md b/packages/test-utils/report.api.md
index 4f29b2cdc1..0845218a33 100644
--- a/packages/test-utils/report.api.md
+++ b/packages/test-utils/report.api.md
@@ -174,6 +174,25 @@ export namespace mockApis {
partialImpl?: Partial | undefined,
) => ApiMock;
}
+ // (undocumented)
+ export function storage(options?: {
+ data?: JsonObject;
+ }): jest.Mocked;
+ // (undocumented)
+ export namespace storage {
+ const // (undocumented)
+ factory: (
+ options?:
+ | {
+ data?: JsonObject | undefined;
+ }
+ | undefined,
+ ) => ApiFactory;
+ const // (undocumented)
+ mock: (
+ partialImpl?: Partial | undefined,
+ ) => ApiMock;
+ }
}
// @public @deprecated
@@ -260,7 +279,9 @@ export class MockPermissionApi implements PermissionApi {
): Promise;
}
-// @public
+// Warning: (ae-unresolved-link) The @link reference could not be resolved: The reference is ambiguous because "storage" has more than one declaration; you need to add a TSDoc member reference selector
+//
+// @public @deprecated
export class MockStorageApi implements StorageApi {
// (undocumented)
static create(data?: MockStorageBucket): MockStorageApi;
@@ -278,7 +299,9 @@ export class MockStorageApi implements StorageApi {
snapshot(key: string): StorageValueSnapshot;
}
-// @public
+// Warning: (ae-unresolved-link) The @link reference could not be resolved: The reference is ambiguous because "storage" has more than one declaration; you need to add a TSDoc member reference selector
+//
+// @public @deprecated
export type MockStorageBucket = {
[key: string]: any;
};
@@ -384,12 +407,12 @@ export function wrapInTestApp(
// src/testUtils/apis/ErrorApi/MockErrorApi.d.ts:33:5 - (ae-undocumented) Missing documentation for "getErrors".
// src/testUtils/apis/ErrorApi/MockErrorApi.d.ts:34:5 - (ae-undocumented) Missing documentation for "waitForError".
// src/testUtils/apis/PermissionApi/MockPermissionApi.d.ts:14:5 - (ae-undocumented) Missing documentation for "authorize".
-// src/testUtils/apis/StorageApi/MockStorageApi.d.ts:19:5 - (ae-undocumented) Missing documentation for "create".
-// src/testUtils/apis/StorageApi/MockStorageApi.d.ts:20:5 - (ae-undocumented) Missing documentation for "forBucket".
-// src/testUtils/apis/StorageApi/MockStorageApi.d.ts:21:5 - (ae-undocumented) Missing documentation for "snapshot".
-// src/testUtils/apis/StorageApi/MockStorageApi.d.ts:22:5 - (ae-undocumented) Missing documentation for "set".
-// src/testUtils/apis/StorageApi/MockStorageApi.d.ts:23:5 - (ae-undocumented) Missing documentation for "remove".
-// src/testUtils/apis/StorageApi/MockStorageApi.d.ts:24:5 - (ae-undocumented) Missing documentation for "observe$".
+// src/testUtils/apis/StorageApi/MockStorageApi.d.ts:21:5 - (ae-undocumented) Missing documentation for "create".
+// src/testUtils/apis/StorageApi/MockStorageApi.d.ts:22:5 - (ae-undocumented) Missing documentation for "forBucket".
+// src/testUtils/apis/StorageApi/MockStorageApi.d.ts:23:5 - (ae-undocumented) Missing documentation for "snapshot".
+// src/testUtils/apis/StorageApi/MockStorageApi.d.ts:24:5 - (ae-undocumented) Missing documentation for "set".
+// src/testUtils/apis/StorageApi/MockStorageApi.d.ts:25:5 - (ae-undocumented) Missing documentation for "remove".
+// src/testUtils/apis/StorageApi/MockStorageApi.d.ts:26:5 - (ae-undocumented) Missing documentation for "observe$".
// src/testUtils/apis/mockApis.d.ts:46:5 - (ae-undocumented) Missing documentation for "analytics".
// src/testUtils/apis/mockApis.d.ts:47:5 - (ae-undocumented) Missing documentation for "analytics".
// src/testUtils/apis/mockApis.d.ts:48:15 - (ae-undocumented) Missing documentation for "factory".
@@ -402,4 +425,8 @@ export function wrapInTestApp(
// src/testUtils/apis/mockApis.d.ts:122:5 - (ae-undocumented) Missing documentation for "permission".
// src/testUtils/apis/mockApis.d.ts:123:15 - (ae-undocumented) Missing documentation for "factory".
// src/testUtils/apis/mockApis.d.ts:126:15 - (ae-undocumented) Missing documentation for "mock".
+// src/testUtils/apis/mockApis.d.ts:128:5 - (ae-undocumented) Missing documentation for "storage".
+// src/testUtils/apis/mockApis.d.ts:131:5 - (ae-undocumented) Missing documentation for "storage".
+// src/testUtils/apis/mockApis.d.ts:132:15 - (ae-undocumented) Missing documentation for "factory".
+// src/testUtils/apis/mockApis.d.ts:135:15 - (ae-undocumented) Missing documentation for "mock".
```
diff --git a/packages/test-utils/src/testUtils/apis/StorageApi/MockStorageApi.test.ts b/packages/test-utils/src/testUtils/apis/StorageApi/MockStorageApi.test.ts
index 63aa4235e1..cdae96d5e4 100644
--- a/packages/test-utils/src/testUtils/apis/StorageApi/MockStorageApi.test.ts
+++ b/packages/test-utils/src/testUtils/apis/StorageApi/MockStorageApi.test.ts
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
import { StorageApi } from '@backstage/core-plugin-api';
import { MockStorageApi } from './MockStorageApi';
diff --git a/packages/test-utils/src/testUtils/apis/StorageApi/MockStorageApi.ts b/packages/test-utils/src/testUtils/apis/StorageApi/MockStorageApi.ts
index 30d523aed2..5ef3846bfa 100644
--- a/packages/test-utils/src/testUtils/apis/StorageApi/MockStorageApi.ts
+++ b/packages/test-utils/src/testUtils/apis/StorageApi/MockStorageApi.ts
@@ -20,12 +20,14 @@ import ObservableImpl from 'zen-observable';
/**
* Type for map holding data in {@link MockStorageApi}
+ * @deprecated Use {@link mockApis.storage} instead
* @public
*/
export type MockStorageBucket = { [key: string]: any };
/**
* Mock implementation of the {@link core-plugin-api#StorageApi} to be used in tests
+ * @deprecated Use {@link mockApis.storage} instead
* @public
*/
export class MockStorageApi implements StorageApi {
@@ -44,7 +46,21 @@ export class MockStorageApi implements StorageApi {
}
static create(data?: MockStorageBucket) {
- return new MockStorageApi('', new Map(), data);
+ // Translate a nested data object structure into a flat object with keys
+ // like `/a/b` with their corresponding leaf values
+ const keyValues: { [key: string]: any } = {};
+ function put(value: { [key: string]: any }, namespace: string) {
+ for (const [key, val] of Object.entries(value)) {
+ if (typeof val === 'object' && val !== null) {
+ put(val, `${namespace}/${key}`);
+ } else {
+ const namespacedKey = `${namespace}/${key.replace(/^\//, '')}`;
+ keyValues[namespacedKey] = val;
+ }
+ }
+ }
+ put(data ?? {}, '');
+ return new MockStorageApi('', new Map(), keyValues);
}
forBucket(name: string): StorageApi {
diff --git a/packages/test-utils/src/testUtils/apis/mockApis.test.tsx b/packages/test-utils/src/testUtils/apis/mockApis.test.tsx
index f64aae9901..87b9472377 100644
--- a/packages/test-utils/src/testUtils/apis/mockApis.test.tsx
+++ b/packages/test-utils/src/testUtils/apis/mockApis.test.tsx
@@ -255,4 +255,288 @@ describe('mockApis', () => {
expect(notEmpty.authorize).toHaveBeenCalledTimes(2);
});
});
+
+ describe('storage', () => {
+ describe('instance deep tests', () => {
+ it('should return undefined for values which are unset', async () => {
+ const storage = mockApis.storage();
+
+ expect(storage.snapshot('myfakekey').value).toBeUndefined();
+ expect(storage.snapshot('myfakekey')).toEqual({
+ key: 'myfakekey',
+ presence: 'absent',
+ value: undefined,
+ newValue: undefined,
+ });
+ });
+
+ it('should allow the setting and snapshotting of the simple data structures', async () => {
+ const storage = mockApis.storage();
+
+ await storage.set('myfakekey', 'helloimastring');
+ await storage.set('mysecondfakekey', 1234);
+ await storage.set('mythirdfakekey', true);
+ expect(storage.snapshot('myfakekey').value).toBe('helloimastring');
+ expect(storage.snapshot('mysecondfakekey').value).toBe(1234);
+ expect(storage.snapshot('mythirdfakekey').value).toBe(true);
+ expect(storage.snapshot('myfakekey')).toEqual({
+ key: 'myfakekey',
+ presence: 'present',
+ value: 'helloimastring',
+ });
+ expect(storage.snapshot('mysecondfakekey')).toEqual({
+ key: 'mysecondfakekey',
+ presence: 'present',
+ value: 1234,
+ });
+ expect(storage.snapshot('mythirdfakekey')).toEqual({
+ key: 'mythirdfakekey',
+ presence: 'present',
+ value: true,
+ });
+ });
+
+ it('should allow setting of complex datastructures', async () => {
+ const storage = mockApis.storage();
+
+ const mockData = {
+ something: 'here',
+ is: [{ super: { complex: [{ but: 'something', why: true }] } }],
+ };
+
+ await storage.set('myfakekey', mockData);
+
+ expect(storage.snapshot('myfakekey').value).toEqual(mockData);
+ expect(storage.snapshot('myfakekey')).toEqual({
+ key: 'myfakekey',
+ presence: 'present',
+ value: mockData,
+ });
+ });
+
+ it('should subscribe to key changes when setting a new value', async () => {
+ const storage = mockApis.storage();
+
+ const wrongKeyNextHandler = jest.fn();
+ const selectedKeyNextHandler = jest.fn();
+ const mockData = { hello: 'im a great new value' };
+
+ await new Promise(resolve => {
+ storage.observe$('correctKey').subscribe({
+ next: (...args) => {
+ selectedKeyNextHandler(...args);
+ resolve();
+ },
+ });
+
+ storage.observe$('wrongKey').subscribe({ next: wrongKeyNextHandler });
+
+ storage.set('correctKey', mockData);
+ });
+
+ expect(wrongKeyNextHandler).not.toHaveBeenCalled();
+ expect(selectedKeyNextHandler).toHaveBeenCalledTimes(1);
+ expect(selectedKeyNextHandler).toHaveBeenCalledWith({
+ key: 'correctKey',
+ presence: 'present',
+ value: mockData,
+ });
+ });
+
+ it('should subscribe to key changes when deleting a value', async () => {
+ const storage = mockApis.storage();
+
+ const wrongKeyNextHandler = jest.fn();
+ const selectedKeyNextHandler = jest.fn();
+ const mockData = { hello: 'im a great new value' };
+
+ storage.set('correctKey', mockData);
+
+ await new Promise(resolve => {
+ storage.observe$('correctKey').subscribe({
+ next: (...args) => {
+ selectedKeyNextHandler(...args);
+ resolve();
+ },
+ });
+
+ storage.observe$('wrongKey').subscribe({ next: wrongKeyNextHandler });
+
+ storage.remove('correctKey');
+ });
+
+ expect(wrongKeyNextHandler).not.toHaveBeenCalled();
+ expect(selectedKeyNextHandler).toHaveBeenCalledTimes(1);
+ expect(selectedKeyNextHandler).toHaveBeenCalledWith({
+ key: 'correctKey',
+ presence: 'absent',
+ value: undefined,
+ newValue: undefined,
+ });
+ });
+
+ it('should be able to create different buckets for different uses', async () => {
+ const rootStorage = mockApis.storage();
+
+ const firstStorage = rootStorage.forBucket('userSettings');
+ const secondStorage = rootStorage.forBucket('profileSettings');
+ const keyName = 'blobby';
+
+ await firstStorage.set(keyName, 'boop');
+ await secondStorage.set(keyName, 'deerp');
+
+ expect(firstStorage.snapshot(keyName)).not.toBe(
+ secondStorage.snapshot(keyName),
+ );
+ expect(firstStorage.snapshot(keyName).value).toBe('boop');
+ expect(secondStorage.snapshot(keyName).value).toBe('deerp');
+ expect(firstStorage.snapshot(keyName)).not.toEqual(
+ secondStorage.snapshot(keyName),
+ );
+ expect(firstStorage.snapshot(keyName)).toEqual({
+ key: keyName,
+ presence: 'present',
+ value: 'boop',
+ });
+ expect(secondStorage.snapshot(keyName)).toEqual({
+ key: keyName,
+ presence: 'present',
+ value: 'deerp',
+ });
+ });
+
+ it('should not clash with other namespaces when creating buckets', async () => {
+ const rootStorage = mockApis.storage();
+
+ // when getting key test2 it will translate to /profile/something/deep/test2
+ const firstStorage = rootStorage
+ .forBucket('profile')
+ .forBucket('something')
+ .forBucket('deep');
+ // when getting key deep/test2 it will translate to /profile/something/deep/test2
+ const secondStorage = rootStorage.forBucket('profile/something');
+
+ await firstStorage.set('test2', { error: true });
+
+ expect(secondStorage.snapshot('deep/test2').value).toBe(undefined);
+ expect(secondStorage.snapshot('deep/test2')).toMatchObject({
+ presence: 'absent',
+ });
+ });
+
+ it('should not reuse storage instances between different rootStorages', async () => {
+ const rootStorage1 = mockApis.storage();
+ const rootStorage2 = mockApis.storage();
+
+ const firstStorage = rootStorage1.forBucket('something');
+ const secondStorage = rootStorage2.forBucket('something');
+
+ await firstStorage.set('test2', true);
+
+ expect(firstStorage.snapshot('test2').value).toBe(true);
+ expect(secondStorage.snapshot('test2').value).toBe(undefined);
+ expect(firstStorage.snapshot('test2')).toEqual({
+ key: 'test2',
+ presence: 'present',
+ value: true,
+ });
+ expect(secondStorage.snapshot('test2')).toEqual({
+ key: 'test2',
+ presence: 'absent',
+ value: undefined,
+ });
+ });
+
+ it('should freeze the snapshot value', async () => {
+ const storage = mockApis.storage();
+
+ const data = { foo: 'bar', baz: [{ foo: 'bar' }] };
+ storage.set('foo', data);
+
+ const snapshot = storage.snapshot('foo');
+ expect(snapshot.value).not.toBe(data);
+
+ if (snapshot.presence !== 'present') {
+ throw new Error('Invalid presence');
+ }
+
+ expect(() => {
+ snapshot.value.foo = 'buzz';
+ }).toThrow(/Cannot assign to read only property/);
+ expect(() => {
+ snapshot.value.baz[0].foo = 'buzz';
+ }).toThrow(/Cannot assign to read only property/);
+ expect(() => {
+ snapshot.value.baz.push({ foo: 'buzz' });
+ }).toThrow(/Cannot add property 1, object is not extensible/);
+ });
+
+ it('should freeze observed values', async () => {
+ const storage = mockApis.storage();
+
+ const snapshotPromise = new Promise(resolve => {
+ storage.observe$('test').subscribe({
+ next: resolve,
+ });
+ });
+
+ storage.set('test', {
+ foo: {
+ bar: 'baz',
+ },
+ });
+
+ const snapshot = await snapshotPromise;
+ expect(snapshot.presence).toBe('present');
+ expect(() => {
+ snapshot.value!.foo.bar = 'qux';
+ }).toThrow(/Cannot assign to read only property 'bar' of object/);
+ });
+
+ it('should JSON serialize stored values', async () => {
+ const storage = mockApis.storage();
+
+ storage.set('test', {
+ foo: {
+ toJSON() {
+ return {
+ bar: 'baz',
+ };
+ },
+ },
+ });
+
+ expect(storage.snapshot('test')).toMatchObject({
+ presence: 'present',
+ value: {
+ foo: {
+ bar: 'baz',
+ },
+ },
+ });
+ });
+ });
+
+ it('can create an instance and make assertions on it', () => {
+ const empty = mockApis.storage();
+ expect(empty.snapshot('a')).toEqual({ key: 'a', presence: 'absent' });
+ expect(empty.snapshot).toHaveBeenCalledTimes(1);
+
+ const notEmpty = mockApis.storage({ data: { a: 1, b: { c: 2 } } });
+ expect(notEmpty.snapshot('a')).toEqual({
+ key: 'a',
+ presence: 'present',
+ value: 1,
+ });
+ expect(notEmpty.forBucket('b').snapshot('c')).toEqual({
+ key: 'c',
+ presence: 'present',
+ value: 2,
+ });
+ expect(notEmpty.snapshot).toHaveBeenCalledTimes(1); // "inner" (forBucket returned) instances aren't mocked
+ expect(notEmpty.forBucket).toHaveBeenCalledTimes(1);
+ });
+
+ it('can create a mock and make assertions on it', () => {});
+ });
});
diff --git a/packages/test-utils/src/testUtils/apis/mockApis.ts b/packages/test-utils/src/testUtils/apis/mockApis.ts
index 7ed886d577..7a334c69b6 100644
--- a/packages/test-utils/src/testUtils/apis/mockApis.ts
+++ b/packages/test-utils/src/testUtils/apis/mockApis.ts
@@ -21,10 +21,12 @@ import {
ApiRef,
ConfigApi,
IdentityApi,
+ StorageApi,
analyticsApiRef,
configApiRef,
createApiFactory,
identityApiRef,
+ storageApiRef,
} from '@backstage/core-plugin-api';
import {
AuthorizeResult,
@@ -37,6 +39,7 @@ import {
import { JsonObject } from '@backstage/types';
import { ApiMock } from './ApiMock';
import { MockPermissionApi } from './PermissionApi';
+import { MockStorageApi } from './StorageApi';
/** @internal */
function simpleFactory(
@@ -268,4 +271,23 @@ export namespace mockApis {
export const factory = simpleFactory(permissionApiRef, permission);
export const mock = simpleMock(permissionApiRef, permissionMockSkeleton);
}
+
+ const storageMockSkeleton = (): jest.Mocked => ({
+ forBucket: jest.fn(),
+ set: jest.fn(),
+ remove: jest.fn(),
+ observe$: jest.fn(),
+ snapshot: jest.fn(),
+ });
+ export function storage(options?: { data?: JsonObject }) {
+ return simpleInstance(
+ storageApiRef,
+ MockStorageApi.create(options?.data),
+ storageMockSkeleton,
+ );
+ }
+ export namespace storage {
+ export const factory = simpleFactory(storageApiRef, storage);
+ export const mock = simpleMock(storageApiRef, storageMockSkeleton);
+ }
}
diff --git a/plugins/api-docs/src/components/ApiExplorerPage/DefaultApiExplorerPage.test.tsx b/plugins/api-docs/src/components/ApiExplorerPage/DefaultApiExplorerPage.test.tsx
index 7847ac8336..34706e8136 100644
--- a/plugins/api-docs/src/components/ApiExplorerPage/DefaultApiExplorerPage.test.tsx
+++ b/plugins/api-docs/src/components/ApiExplorerPage/DefaultApiExplorerPage.test.tsx
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-import { ConfigReader } from '@backstage/core-app-api';
import { TableColumn, TableProps } from '@backstage/core-components';
import { configApiRef, storageApiRef } from '@backstage/core-plugin-api';
import {
@@ -29,7 +28,6 @@ import {
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import {
mockApis,
- MockStorageApi,
TestApiProvider,
renderInTestApp,
} from '@backstage/test-utils';
@@ -72,17 +70,15 @@ describe('DefaultApiExplorerPage', () => {
}),
});
- const configApi = new ConfigReader({
- organization: {
- name: 'My Company',
- },
+ const configApi = mockApis.config({
+ data: { organization: { name: 'My Company' } },
});
const apiDocsConfig = {
getApiDefinitionWidget: () => undefined,
};
- const storageApi = MockStorageApi.create();
+ const storageApi = mockApis.storage();
const renderWrapped = (children: React.ReactNode) =>
renderInTestApp(
diff --git a/plugins/auth-react/src/components/CookieAuthRefreshProvider/CookieAuthRefreshProvider.test.tsx b/plugins/auth-react/src/components/CookieAuthRefreshProvider/CookieAuthRefreshProvider.test.tsx
index bba876e6be..6ff9d8a1c5 100644
--- a/plugins/auth-react/src/components/CookieAuthRefreshProvider/CookieAuthRefreshProvider.test.tsx
+++ b/plugins/auth-react/src/components/CookieAuthRefreshProvider/CookieAuthRefreshProvider.test.tsx
@@ -19,7 +19,7 @@ import { screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { CookieAuthRefreshProvider } from './CookieAuthRefreshProvider';
import {
- MockStorageApi,
+ mockApis,
TestApiProvider,
renderInTestApp,
} from '@backstage/test-utils';
@@ -30,7 +30,6 @@ import {
} from '@backstage/core-plugin-api';
describe('CookieAuthRefreshProvider', () => {
- const storageApiMock = MockStorageApi.create();
const discoveryApiMock = {
getBaseUrl: jest
.fn()
@@ -51,7 +50,7 @@ describe('CookieAuthRefreshProvider', () => {
@@ -76,7 +75,7 @@ describe('CookieAuthRefreshProvider', () => {
@@ -107,7 +106,7 @@ describe('CookieAuthRefreshProvider', () => {
@@ -153,7 +152,7 @@ describe('CookieAuthRefreshProvider', () => {
diff --git a/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.test.tsx b/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.test.tsx
index d36700452a..ac06b3a34d 100644
--- a/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.test.tsx
+++ b/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.test.tsx
@@ -21,7 +21,7 @@ import { MockStarredEntitiesApi, starredEntitiesApiRef } from '../../apis';
import { FavoriteEntity } from './FavoriteEntity';
import { ComponentEntity } from '@backstage/catalog-model';
import {
- MockStorageApi,
+ mockApis,
renderInTestApp,
TestApiProvider,
} from '@backstage/test-utils';
@@ -41,14 +41,12 @@ const entity: ComponentEntity = {
},
};
-const mockStorage = MockStorageApi.create();
-
describe('', () => {
it('should add to favorites', async () => {
await renderInTestApp(
@@ -79,7 +77,7 @@ describe('', () => {
await renderInTestApp(
diff --git a/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx b/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx
index 3f7c2034a0..7ff30dbf5f 100644
--- a/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx
+++ b/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx
@@ -34,7 +34,6 @@ import {
} from '@backstage/catalog-client';
import { catalogApiRef } from '../../api';
import {
- MockStorageApi,
TestApiRegistry,
mockApis,
renderInTestApp,
@@ -79,7 +78,7 @@ const apis = TestApiRegistry.from(
[configApiRef, mockConfigApi],
[catalogApiRef, mockCatalogApi],
[identityApiRef, mockIdentityApi],
- [storageApiRef, MockStorageApi.create()],
+ [storageApiRef, mockApis.storage()],
[starredEntitiesApiRef, mockStarredEntitiesApi],
);
@@ -134,19 +133,13 @@ describe('', () => {
beforeEach(() => {
mockCatalogApi.getEntityByRef?.mockResolvedValue(mockUser);
- mockIdentityApi.getBackstageIdentity?.mockResolvedValue({
- ownershipEntityRefs,
- type: 'user',
- userEntityRef: 'user:default/testuser',
- });
-
mockCatalogApi.queryEntities?.mockImplementation(
mockQueryEntitiesImplementation,
);
});
afterEach(() => {
- jest.resetAllMocks();
+ jest.clearAllMocks();
});
it('renders filter groups', async () => {
diff --git a/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx b/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx
index 067ca33fa3..4ef6b175ae 100644
--- a/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx
+++ b/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx
@@ -23,11 +23,7 @@ import {
identityApiRef,
storageApiRef,
} from '@backstage/core-plugin-api';
-import {
- MockStorageApi,
- TestApiProvider,
- mockApis,
-} from '@backstage/test-utils';
+import { TestApiProvider, mockApis } from '@backstage/test-utils';
import { act, renderHook, waitFor } from '@testing-library/react';
import qs from 'qs';
import React, { PropsWithChildren } from 'react';
@@ -69,8 +65,6 @@ const entities: Entity[] = [
},
];
-const mockConfigApi = mockApis.config();
-
const ownershipEntityRefs = ['user:default/guest'];
const mockIdentityApi = mockApis.identity({
@@ -104,10 +98,10 @@ const createWrapper =
{
describe('constructor', () => {
it('should call migration', () => {
const api = new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
});
expect(performMigrationToTheNewBucket).toHaveBeenCalledTimes(1);
expect(api).toBeDefined();
@@ -54,7 +54,7 @@ describe('DefaultStarredEntitiesApi', () => {
it('should notify and toggle starred entities', async () => {
const entityRef = 'component:default/mock';
- const storageApi = MockStorageApi.create();
+ const storageApi = mockApis.storage();
const storageBucket = storageApi.forBucket('starredEntities');
const api = new DefaultStarredEntitiesApi({ storageApi });
@@ -85,7 +85,7 @@ describe('DefaultStarredEntitiesApi', () => {
it('should read starred entities from storage', async () => {
const entityRef = 'component:default/mock';
- const storageApi = MockStorageApi.create();
+ const storageApi = mockApis.storage();
const storageBucket = storageApi.forBucket('starredEntities');
storageBucket.set('entityRefs', [entityRef]);
const api = new DefaultStarredEntitiesApi({ storageApi });
diff --git a/plugins/catalog/src/apis/StarredEntitiesApi/migration.test.ts b/plugins/catalog/src/apis/StarredEntitiesApi/migration.test.ts
index c9083969ee..9f99c6e2dd 100644
--- a/plugins/catalog/src/apis/StarredEntitiesApi/migration.test.ts
+++ b/plugins/catalog/src/apis/StarredEntitiesApi/migration.test.ts
@@ -15,18 +15,18 @@
*/
import { StorageApi } from '@backstage/core-plugin-api';
-import { MockStorageApi } from '@backstage/test-utils';
+import { mockApis } from '@backstage/test-utils';
import { performMigrationToTheNewBucket } from './migration';
describe('performMigrationToTheNewBucket', () => {
let mockStorage: StorageApi;
beforeEach(() => {
- mockStorage = MockStorageApi.create();
+ mockStorage = mockApis.storage();
});
afterEach(() => {
- jest.resetAllMocks();
+ jest.clearAllMocks();
});
it('should migrate', async () => {
diff --git a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx
index 38310bbbf5..07cf98359e 100644
--- a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx
+++ b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx
@@ -26,7 +26,6 @@ import {
} from '@backstage/plugin-catalog-react';
import { mockBreakpoint } from '@backstage/core-components/testUtils';
import {
- MockStorageApi,
TestApiProvider,
mockApis,
renderInTestApp,
@@ -49,7 +48,6 @@ describe('DefaultCatalogPage', () => {
});
afterEach(() => {
window.history.replaceState = origReplaceState;
-
jest.clearAllMocks();
});
@@ -166,7 +164,6 @@ describe('DefaultCatalogPage', () => {
ownershipEntityRefs: ['user:default/guest', 'group:default/tools'],
displayName: 'Display Name',
});
- const storageApi = MockStorageApi.create();
const renderWrapped = (children: React.ReactNode) =>
renderInTestApp(
@@ -174,7 +171,7 @@ describe('DefaultCatalogPage', () => {
apis={[
[catalogApiRef, catalogApi],
[identityApiRef, identityApi],
- [storageApiRef, storageApi],
+ [storageApiRef, mockApis.storage()],
[starredEntitiesApiRef, new MockStarredEntitiesApi()],
[permissionApiRef, mockApis.permission()],
]}
diff --git a/plugins/home/src/api/VisitsStorageApi.test.ts b/plugins/home/src/api/VisitsStorageApi.test.ts
index 206cf42689..55cf623149 100644
--- a/plugins/home/src/api/VisitsStorageApi.test.ts
+++ b/plugins/home/src/api/VisitsStorageApi.test.ts
@@ -15,7 +15,7 @@
*/
import { VisitsStorageApi } from './VisitsStorageApi';
-import { MockStorageApi, mockApis } from '@backstage/test-utils';
+import { mockApis } from '@backstage/test-utils';
import { Visit, VisitsApi } from './VisitsApi';
describe('VisitsStorageApi.create', () => {
@@ -42,7 +42,7 @@ describe('VisitsStorageApi.create', () => {
it('instantiates', () => {
const api = VisitsStorageApi.create({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
identityApi: mockIdentityApi,
});
expect(api).toBeTruthy();
@@ -51,7 +51,7 @@ describe('VisitsStorageApi.create', () => {
describe('.save()', () => {
it('saves a visit', async () => {
const api = VisitsStorageApi.create({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
identityApi: mockIdentityApi,
});
const visit = {
@@ -68,7 +68,7 @@ describe('VisitsStorageApi.create', () => {
it('can control the number of stored entities', async () => {
const api = VisitsStorageApi.create({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
identityApi: mockIdentityApi,
limit: 2,
});
@@ -102,7 +102,7 @@ describe('VisitsStorageApi.create', () => {
it('correctly bumps the hits from a previous visit', async () => {
const api = VisitsStorageApi.create({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
identityApi: mockIdentityApi,
});
const visit = {
@@ -144,7 +144,7 @@ describe('VisitsStorageApi.create', () => {
beforeEach(() => {
api = VisitsStorageApi.create({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
identityApi: mockIdentityApi,
});
diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx
index 58033b718c..9ae2a507dd 100644
--- a/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx
+++ b/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx
@@ -13,13 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
import React from 'react';
import { fireEvent } from '@testing-library/react';
import { CardHeader } from './CardHeader';
import { ThemeProvider } from '@material-ui/core/styles';
import { lightTheme } from '@backstage/theme';
import {
- MockStorageApi,
+ mockApis,
renderInTestApp,
TestApiProvider,
} from '@backstage/test-utils';
@@ -44,7 +45,7 @@ describe('CardHeader', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
]}
@@ -75,7 +76,7 @@ describe('CardHeader', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
]}
@@ -135,7 +136,7 @@ describe('CardHeader', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
]}
@@ -164,7 +165,7 @@ describe('CardHeader', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
]}
diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.test.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.test.tsx
index 5b2324b222..673f1e4a9e 100644
--- a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.test.tsx
+++ b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.test.tsx
@@ -21,7 +21,6 @@ import {
} from '@backstage/plugin-catalog-react';
import {
mockApis,
- MockStorageApi,
renderInTestApp,
TestApiProvider,
} from '@backstage/test-utils';
@@ -52,7 +51,7 @@ describe('TemplateCard', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
[permissionApiRef, mockApis.permission()],
@@ -82,7 +81,7 @@ describe('TemplateCard', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
[permissionApiRef, mockApis.permission()],
@@ -114,7 +113,7 @@ describe('TemplateCard', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
[permissionApiRef, mockApis.permission()],
@@ -144,7 +143,7 @@ describe('TemplateCard', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
[permissionApiRef, mockApis.permission()],
@@ -180,7 +179,7 @@ describe('TemplateCard', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
[permissionApiRef, mockApis.permission()],
@@ -220,7 +219,7 @@ describe('TemplateCard', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
[permissionApiRef, mockApis.permission()],
@@ -265,7 +264,7 @@ describe('TemplateCard', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
[permissionApiRef, mockApis.permission()],
@@ -314,7 +313,7 @@ describe('TemplateCard', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
[permissionApiRef, mockApis.permission()],
@@ -357,7 +356,7 @@ describe('TemplateCard', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
[permissionApiRef, mockApis.permission()],
@@ -397,7 +396,7 @@ describe('TemplateCard', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
[permissionApiRef, mockApis.permission()],
@@ -437,7 +436,7 @@ describe('TemplateCard', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
[
diff --git a/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.test.tsx
index a02c90f687..01274cf6a6 100644
--- a/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.test.tsx
+++ b/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.test.tsx
@@ -22,7 +22,6 @@ import {
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { permissionApiRef } from '@backstage/plugin-permission-react';
import {
- MockStorageApi,
renderInTestApp,
TestApiProvider,
mockApis,
@@ -53,7 +52,7 @@ describe('TemplateListPage', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
[permissionApiRef, mockApis.permission()],
@@ -75,7 +74,7 @@ describe('TemplateListPage', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
[permissionApiRef, mockApis.permission()],
@@ -98,7 +97,7 @@ describe('TemplateListPage', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
[permissionApiRef, mockApis.permission()],
@@ -120,7 +119,7 @@ describe('TemplateListPage', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
[permissionApiRef, mockApis.permission()],
@@ -143,7 +142,7 @@ describe('TemplateListPage', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
[permissionApiRef, mockApis.permission()],
@@ -165,7 +164,7 @@ describe('TemplateListPage', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
[permissionApiRef, mockApis.permission()],
@@ -186,7 +185,7 @@ describe('TemplateListPage', () => {
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
- storageApi: MockStorageApi.create(),
+ storageApi: mockApis.storage(),
}),
],
[permissionApiRef, mockApis.permission()],
diff --git a/plugins/techdocs/src/home/components/DefaultTechDocsHome.test.tsx b/plugins/techdocs/src/home/components/DefaultTechDocsHome.test.tsx
index 513a56265c..4c3be25325 100644
--- a/plugins/techdocs/src/home/components/DefaultTechDocsHome.test.tsx
+++ b/plugins/techdocs/src/home/components/DefaultTechDocsHome.test.tsx
@@ -14,22 +14,18 @@
* limitations under the License.
*/
-import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
-import {
- ConfigApi,
- configApiRef,
- storageApiRef,
-} from '@backstage/core-plugin-api';
+import { ApiProvider } from '@backstage/core-app-api';
+import { configApiRef, storageApiRef } from '@backstage/core-plugin-api';
import {
+ MockStarredEntitiesApi,
catalogApiRef,
starredEntitiesApiRef,
- MockStarredEntitiesApi,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import {
- MockStorageApi,
- renderInTestApp,
TestApiRegistry,
+ mockApis,
+ renderInTestApp,
} from '@backstage/test-utils';
import { screen } from '@testing-library/react';
import React from 'react';
@@ -50,18 +46,14 @@ const mockCatalogApi = catalogApiMock({
});
describe('TechDocs Home', () => {
- const configApi: ConfigApi = new ConfigReader({
- organization: {
- name: 'My Company',
- },
+ const configApi = mockApis.config({
+ data: { organization: { name: 'My Company' } },
});
- const storageApi = MockStorageApi.create();
-
const apiRegistry = TestApiRegistry.from(
[catalogApiRef, mockCatalogApi],
[configApiRef, configApi],
- [storageApiRef, storageApi],
+ [storageApiRef, mockApis.storage()],
[starredEntitiesApiRef, new MockStarredEntitiesApi()],
);
diff --git a/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.test.tsx b/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.test.tsx
index 947c81ae85..25471d0769 100644
--- a/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.test.tsx
+++ b/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.test.tsx
@@ -14,12 +14,8 @@
* limitations under the License.
*/
-import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
-import {
- ConfigApi,
- configApiRef,
- storageApiRef,
-} from '@backstage/core-plugin-api';
+import { ApiProvider } from '@backstage/core-app-api';
+import { configApiRef, storageApiRef } from '@backstage/core-plugin-api';
import {
catalogApiRef,
starredEntitiesApiRef,
@@ -30,9 +26,9 @@ import {
catalogApiMock,
} from '@backstage/plugin-catalog-react/testUtils';
import {
- MockStorageApi,
renderInTestApp,
TestApiRegistry,
+ mockApis,
} from '@backstage/test-utils';
import { screen } from '@testing-library/react';
import React from 'react';
@@ -68,21 +64,17 @@ const mockCatalogApi = catalogApiMock({ entities });
describe('Entity List Docs Grid', () => {
beforeEach(() => {
- jest.resetAllMocks();
+ jest.clearAllMocks();
});
- const configApi: ConfigApi = new ConfigReader({
- organization: {
- name: 'My Company',
- },
+ const configApi = mockApis.config({
+ data: { organization: { name: 'My Company' } },
});
- const storageApi = MockStorageApi.create();
-
const apiRegistry = TestApiRegistry.from(
[catalogApiRef, mockCatalogApi],
[configApiRef, configApi],
- [storageApiRef, storageApi],
+ [storageApiRef, mockApis.storage()],
[starredEntitiesApiRef, new MockStarredEntitiesApi()],
);