Merge pull request #26999 from backstage/freben/catalog-test-utils
Add `catalogApiMock` to `catalog-react/testUtils`
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/frontend-test-utils': patch
|
||||
---
|
||||
|
||||
Added an `ApiMock`, analogous to `ServiceMock` from the backend test utils.
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': minor
|
||||
---
|
||||
|
||||
Add catalog service mocks under the `/testUtils` subpath export.
|
||||
|
||||
You can now use e.g. `const catalog = catalogApiMock.mock()` in your test and then do assertions on `catalog.getEntities` without awkward type casting.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-node': patch
|
||||
---
|
||||
|
||||
Documentation for the `testUtils` named export
|
||||
@@ -50,6 +50,7 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@testing-library/react": "^16.0.0",
|
||||
"@types/jest": "*",
|
||||
"@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
||||
"react": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
||||
"react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
/// <reference types="jest" />
|
||||
/// <reference types="react" />
|
||||
|
||||
import { AnalyticsApi } from '@backstage/frontend-plugin-api';
|
||||
import { AnalyticsEvent } from '@backstage/frontend-plugin-api';
|
||||
import { AnyExtensionDataRef } from '@backstage/frontend-plugin-api';
|
||||
import { ApiFactory } from '@backstage/frontend-plugin-api';
|
||||
import { AppNode } from '@backstage/frontend-plugin-api';
|
||||
import { AppNodeInstance } from '@backstage/frontend-plugin-api';
|
||||
import { ErrorWithContext } from '@backstage/test-utils';
|
||||
@@ -32,6 +34,15 @@ import { TestApiProviderProps } from '@backstage/test-utils';
|
||||
import { TestApiRegistry } from '@backstage/test-utils';
|
||||
import { withLogCollector } from '@backstage/test-utils';
|
||||
|
||||
// @public
|
||||
export type ApiMock<TApi> = {
|
||||
factory: ApiFactory<TApi, TApi, {}>;
|
||||
} & {
|
||||
[Key in keyof TApi]: TApi[Key] extends (...args: infer Args) => infer Return
|
||||
? TApi[Key] & jest.MockInstance<Return, Args>
|
||||
: TApi[Key];
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export function createExtensionTester<T extends ExtensionDefinitionParameters>(
|
||||
subject: ExtensionDefinition<T>,
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ApiFactory } from '@backstage/frontend-plugin-api';
|
||||
|
||||
/**
|
||||
* Represents a mocked version of an API, where you automatically have access to
|
||||
* the mocked versions of all of its methods along with a factory that returns
|
||||
* that same mock.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type ApiMock<TApi> = {
|
||||
factory: ApiFactory<TApi, TApi, {}>;
|
||||
} & {
|
||||
[Key in keyof TApi]: TApi[Key] extends (...args: infer Args) => infer Return
|
||||
? TApi[Key] & jest.MockInstance<Return, Args>
|
||||
: TApi[Key];
|
||||
};
|
||||
@@ -26,4 +26,5 @@ export {
|
||||
type MockStorageBucket,
|
||||
} from '@backstage/test-utils';
|
||||
|
||||
export { type ApiMock } from './ApiMock';
|
||||
export { MockAnalyticsApi } from './AnalyticsApi/MockAnalyticsApi';
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"keywords": [
|
||||
"backstage"
|
||||
],
|
||||
"homepage": "https://backstage.io",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -22,6 +22,4 @@ export namespace catalogServiceMock {
|
||||
partialImpl?: Partial<CatalogApi> | undefined,
|
||||
) => ServiceMock<CatalogApi>;
|
||||
}
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
|
||||
@@ -14,4 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Backend test helpers for the Catalog plugin.
|
||||
*
|
||||
* @packageDocumentation
|
||||
*/
|
||||
|
||||
export { catalogServiceMock } from './testUtils/catalogServiceMock';
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./alpha": "./src/alpha/index.ts",
|
||||
"./testUtils": "./src/testUtils.ts",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"main": "src/index.ts",
|
||||
@@ -39,6 +40,9 @@
|
||||
"alpha": [
|
||||
"src/alpha/index.ts"
|
||||
],
|
||||
"testUtils": [
|
||||
"src/testUtils.ts"
|
||||
],
|
||||
"package.json": [
|
||||
"package.json"
|
||||
]
|
||||
@@ -64,6 +68,7 @@
|
||||
"@backstage/core-plugin-api": "workspace:^",
|
||||
"@backstage/errors": "workspace:^",
|
||||
"@backstage/frontend-plugin-api": "workspace:^",
|
||||
"@backstage/frontend-test-utils": "workspace:^",
|
||||
"@backstage/integration-react": "workspace:^",
|
||||
"@backstage/plugin-catalog-common": "workspace:^",
|
||||
"@backstage/plugin-permission-common": "workspace:^",
|
||||
@@ -85,7 +90,6 @@
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "workspace:^",
|
||||
"@backstage/core-app-api": "workspace:^",
|
||||
"@backstage/frontend-test-utils": "workspace:^",
|
||||
"@backstage/plugin-catalog-common": "workspace:^",
|
||||
"@backstage/plugin-scaffolder-common": "workspace:^",
|
||||
"@backstage/test-utils": "workspace:^",
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
## API Report File for "@backstage/plugin-catalog-react"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { ApiFactory } from '@backstage/frontend-plugin-api';
|
||||
import { ApiMock } from '@backstage/frontend-test-utils';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { DefaultEntityFilters } from '@backstage/plugin-catalog-react';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { EntityListContextProps } from '@backstage/plugin-catalog-react';
|
||||
import { PropsWithChildren } from 'react';
|
||||
import { default as React_2 } from 'react';
|
||||
|
||||
// @public
|
||||
export function catalogApiMock(options?: { entities?: Entity[] }): CatalogApi;
|
||||
|
||||
// @public
|
||||
export namespace catalogApiMock {
|
||||
const factory: (options?: {
|
||||
entities?: Entity[];
|
||||
}) => ApiFactory<CatalogApi, CatalogApi, {}>;
|
||||
const mock: (
|
||||
partialImpl?: Partial<CatalogApi> | undefined,
|
||||
) => ApiMock<CatalogApi>;
|
||||
}
|
||||
|
||||
// @public
|
||||
export function MockEntityListContextProvider<
|
||||
T extends DefaultEntityFilters = DefaultEntityFilters,
|
||||
>(
|
||||
props: PropsWithChildren<{
|
||||
value?: Partial<EntityListContextProps<T>>;
|
||||
}>,
|
||||
): React_2.JSX.Element;
|
||||
```
|
||||
@@ -695,7 +695,7 @@ export function MissingAnnotationEmptyState(props: {
|
||||
// @public (undocumented)
|
||||
export type MissingAnnotationEmptyStateClassKey = 'code';
|
||||
|
||||
// @public (undocumented)
|
||||
// @public @deprecated (undocumented)
|
||||
export function MockEntityListContextProvider<
|
||||
T extends DefaultEntityFilters = DefaultEntityFilters,
|
||||
>(
|
||||
@@ -887,6 +887,7 @@ export function useStarredEntity(
|
||||
// src/components/UserListPicker/UserListPicker.d.ts:5:1 - (ae-undocumented) Missing documentation for "CatalogReactUserListPickerClassKey".
|
||||
// src/components/UserListPicker/UserListPicker.d.ts:15:1 - (ae-undocumented) Missing documentation for "UserListPickerProps".
|
||||
// src/components/UserListPicker/UserListPicker.d.ts:20:22 - (ae-undocumented) Missing documentation for "UserListPicker".
|
||||
// src/deprecated.d.ts:7:1 - (ae-undocumented) Missing documentation for "MockEntityListContextProvider".
|
||||
// src/filters.d.ts:8:5 - (ae-undocumented) Missing documentation for "value".
|
||||
// src/filters.d.ts:10:5 - (ae-undocumented) Missing documentation for "getCatalogFilters".
|
||||
// src/filters.d.ts:11:5 - (ae-undocumented) Missing documentation for "toQueryValue".
|
||||
@@ -948,7 +949,6 @@ export function useStarredEntity(
|
||||
// src/hooks/useStarredEntity.d.ts:3:1 - (ae-undocumented) Missing documentation for "useStarredEntity".
|
||||
// src/overridableComponents.d.ts:6:1 - (ae-undocumented) Missing documentation for "CatalogReactComponentsNameToClassKey".
|
||||
// src/overridableComponents.d.ts:19:1 - (ae-undocumented) Missing documentation for "BackstageOverrides".
|
||||
// src/testUtils/providers.d.ts:4:1 - (ae-undocumented) Missing documentation for "MockEntityListContextProvider".
|
||||
// src/types.d.ts:3:1 - (ae-undocumented) Missing documentation for "EntityFilter".
|
||||
// src/types.d.ts:25:1 - (ae-undocumented) Missing documentation for "UserListFilterKind".
|
||||
// src/types.d.ts:27:1 - (ae-undocumented) Missing documentation for "EntityListPagination".
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
|
||||
import { fireEvent, render, waitFor, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { MockEntityListContextProvider } from '../../testUtils/providers';
|
||||
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import { EntityAutocompletePicker } from './EntityAutocompletePicker';
|
||||
import { TestApiProvider } from '@backstage/test-utils';
|
||||
import { catalogApiRef } from '../../api';
|
||||
|
||||
@@ -24,7 +24,7 @@ import { capitalize } from 'lodash';
|
||||
import { default as React } from 'react';
|
||||
import { catalogApiRef } from '../../api';
|
||||
import { EntityKindFilter } from '../../filters';
|
||||
import { MockEntityListContextProvider } from '../../testUtils/providers';
|
||||
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import { EntityKindPicker } from './EntityKindPicker';
|
||||
|
||||
const entities: Entity[] = [
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
|
||||
import { fireEvent, screen, waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { MockEntityListContextProvider } from '../../testUtils/providers';
|
||||
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import { EntityLifecycleFilter } from '../../filters';
|
||||
import { EntityLifecyclePicker } from './EntityLifecyclePicker';
|
||||
import { TestApiProvider, renderInTestApp } from '@backstage/test-utils';
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
|
||||
import { fireEvent, screen, waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { MockEntityListContextProvider } from '../../testUtils/providers';
|
||||
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import { EntityNamespaceFilter } from '../../filters';
|
||||
import { EntityNamespacePicker } from './EntityNamespacePicker';
|
||||
import { TestApiProvider, renderInTestApp } from '@backstage/test-utils';
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import { Entity, stringifyEntityRef } from '@backstage/catalog-model';
|
||||
import { fireEvent, screen, waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { MockEntityListContextProvider } from '../../testUtils/providers';
|
||||
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import { EntityOwnerFilter } from '../../filters';
|
||||
import { EntityOwnerPicker } from './EntityOwnerPicker';
|
||||
import { ApiProvider } from '@backstage/core-app-api';
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
import { fireEvent, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { EntityErrorFilter, EntityOrphanFilter } from '../../filters';
|
||||
import { MockEntityListContextProvider } from '../../testUtils/providers';
|
||||
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import { EntityProcessingStatusPicker } from './EntityProcessingStatusPicker';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import React from 'react';
|
||||
import { fireEvent, waitFor, screen } from '@testing-library/react';
|
||||
import { EntitySearchBar } from './EntitySearchBar';
|
||||
import { EntityTextFilter } from '../../filters';
|
||||
import { MockEntityListContextProvider } from '../../testUtils/providers';
|
||||
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
|
||||
describe('EntitySearchBar', () => {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import { fireEvent, waitFor, screen, act } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { MockEntityListContextProvider } from '../../testUtils/providers';
|
||||
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import { EntityTagFilter } from '../../filters';
|
||||
import { EntityTagPicker } from './EntityTagPicker';
|
||||
import { TestApiProvider, renderInTestApp } from '@backstage/test-utils';
|
||||
|
||||
@@ -18,7 +18,7 @@ import React from 'react';
|
||||
import { fireEvent, waitFor, screen, within } from '@testing-library/react';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { EntityTypePicker } from './EntityTypePicker';
|
||||
import { MockEntityListContextProvider } from '../../testUtils/providers';
|
||||
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import { catalogApiRef } from '../../api';
|
||||
import { EntityKindFilter, EntityTypeFilter } from '../../filters';
|
||||
import { alertApiRef } from '@backstage/core-plugin-api';
|
||||
|
||||
+5
-10
@@ -14,13 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CatalogApi, Location } from '@backstage/catalog-client';
|
||||
import { Location } from '@backstage/catalog-client';
|
||||
import { Entity, ANNOTATION_ORIGIN_LOCATION } from '@backstage/catalog-model';
|
||||
import { catalogApiRef } from '../../api';
|
||||
import { renderHook, waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { useUnregisterEntityDialogState } from './useUnregisterEntityDialogState';
|
||||
import { TestApiProvider } from '@backstage/test-utils';
|
||||
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
|
||||
|
||||
function defer<T>(): { promise: Promise<T>; resolve: (value: T) => void } {
|
||||
let resolve: (value: T) => void = () => {};
|
||||
@@ -31,13 +32,7 @@ function defer<T>(): { promise: Promise<T>; resolve: (value: T) => void } {
|
||||
}
|
||||
|
||||
describe('useUnregisterEntityDialogState', () => {
|
||||
const catalogApiMock = {
|
||||
getLocationByRef: jest.fn(),
|
||||
getEntities: jest.fn(),
|
||||
removeLocationById: jest.fn(),
|
||||
removeEntityByUid: jest.fn(),
|
||||
};
|
||||
const catalogApi = catalogApiMock as Partial<CatalogApi> as CatalogApi;
|
||||
const catalogApi = catalogApiMock.mock();
|
||||
|
||||
const Wrapper = (props: { children?: React.ReactNode }) => (
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
@@ -58,8 +53,8 @@ describe('useUnregisterEntityDialogState', () => {
|
||||
resolveLocation = deferredLocation.resolve;
|
||||
resolveColocatedEntities = deferredColocatedEntities.resolve;
|
||||
|
||||
catalogApiMock.getLocationByRef.mockReturnValue(deferredLocation.promise);
|
||||
catalogApiMock.getEntities.mockReturnValue(
|
||||
catalogApi.getLocationByRef.mockReturnValue(deferredLocation.promise);
|
||||
catalogApi.getEntities.mockReturnValue(
|
||||
deferredColocatedEntities.promise.then(items => ({ items })),
|
||||
);
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import React from 'react';
|
||||
import { fireEvent, waitFor, screen } from '@testing-library/react';
|
||||
import { UserEntity } from '@backstage/catalog-model';
|
||||
import { UserListPicker, UserListPickerProps } from './UserListPicker';
|
||||
import { MockEntityListContextProvider } from '../../testUtils/providers';
|
||||
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import {
|
||||
EntityKindFilter,
|
||||
EntityNamespaceFilter,
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, {
|
||||
PropsWithChildren,
|
||||
useCallback,
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react';
|
||||
import {
|
||||
DefaultEntityFilters,
|
||||
EntityListContext,
|
||||
EntityListContextProps,
|
||||
} from './hooks/useEntityListProvider';
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @deprecated Moved to `@backstage/plugin-catalog-react/testUtils`
|
||||
*/
|
||||
export function MockEntityListContextProvider<
|
||||
T extends DefaultEntityFilters = DefaultEntityFilters,
|
||||
>(
|
||||
props: PropsWithChildren<{
|
||||
value?: Partial<EntityListContextProps<T>>;
|
||||
}>,
|
||||
) {
|
||||
const { children, value } = props;
|
||||
|
||||
// Provides a default implementation that stores filter state, for testing components that
|
||||
// reflect filter state.
|
||||
const [filters, setFilters] = useState<T>(value?.filters ?? ({} as T));
|
||||
|
||||
const updateFilters = useCallback(
|
||||
(update: Partial<T> | ((prevFilters: T) => Partial<T>)) => {
|
||||
setFilters(prevFilters => {
|
||||
const newFilters =
|
||||
typeof update === 'function' ? update(prevFilters) : update;
|
||||
return { ...prevFilters, ...newFilters };
|
||||
});
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
// Memoize the default values since pickers have useEffect triggers on these; naively defaulting
|
||||
// below with `?? <X>` breaks referential equality on subsequent updates.
|
||||
const defaultValues = useMemo(
|
||||
() => ({
|
||||
entities: [],
|
||||
backendEntities: [],
|
||||
queryParameters: {},
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
const resolvedValue: EntityListContextProps<T> = useMemo(
|
||||
() => ({
|
||||
entities: value?.entities ?? defaultValues.entities,
|
||||
backendEntities: value?.backendEntities ?? defaultValues.backendEntities,
|
||||
updateFilters: value?.updateFilters ?? updateFilters,
|
||||
filters,
|
||||
loading: value?.loading ?? false,
|
||||
queryParameters: value?.queryParameters ?? defaultValues.queryParameters,
|
||||
error: value?.error,
|
||||
totalItems:
|
||||
value?.totalItems ?? (value?.entities ?? defaultValues.entities).length,
|
||||
limit: value?.limit ?? 20,
|
||||
offset: value?.offset,
|
||||
setLimit: value?.setLimit ?? (() => {}),
|
||||
setOffset: value?.setOffset,
|
||||
paginationMode: value?.paginationMode ?? 'none',
|
||||
}),
|
||||
[value, defaultValues, filters, updateFilters],
|
||||
);
|
||||
|
||||
return (
|
||||
<EntityListContext.Provider value={resolvedValue}>
|
||||
{children}
|
||||
</EntityListContext.Provider>
|
||||
);
|
||||
}
|
||||
@@ -28,8 +28,8 @@ export * from './components';
|
||||
export * from './hooks';
|
||||
export * from './filters';
|
||||
export { entityRouteParams, entityRouteRef } from './routes';
|
||||
export * from './testUtils';
|
||||
export * from './types';
|
||||
export * from './overridableComponents';
|
||||
export { getEntityRelations, getEntitySourceLocation } from './utils';
|
||||
export type { EntitySourceLocation } from './utils';
|
||||
export * from './deprecated';
|
||||
|
||||
+10
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,4 +13,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export { MockEntityListContextProvider } from './providers';
|
||||
|
||||
/**
|
||||
* Frontend test helpers for the Catalog plugin.
|
||||
*
|
||||
* @packageDocumentation
|
||||
*/
|
||||
|
||||
export { catalogApiMock } from './testUtils/catalogApiMock';
|
||||
export { MockEntityListContextProvider } from './testUtils/MockEntityListContextProvider';
|
||||
+6
-2
@@ -24,9 +24,13 @@ import {
|
||||
DefaultEntityFilters,
|
||||
EntityListContext,
|
||||
EntityListContextProps,
|
||||
} from '../hooks/useEntityListProvider';
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Simplifies testing of code that uses the entity list hooks.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function MockEntityListContextProvider<
|
||||
T extends DefaultEntityFilters = DefaultEntityFilters,
|
||||
>(
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { catalogApiMock } from './catalogApiMock';
|
||||
|
||||
const entity1: Entity = {
|
||||
apiVersion: 'v1',
|
||||
kind: 'CustomKind',
|
||||
metadata: {
|
||||
namespace: 'default',
|
||||
name: 'e1',
|
||||
uid: 'u1',
|
||||
},
|
||||
};
|
||||
|
||||
const entity2: Entity = {
|
||||
apiVersion: 'v1',
|
||||
kind: 'CustomKind',
|
||||
metadata: {
|
||||
namespace: 'default',
|
||||
name: 'e2',
|
||||
uid: 'u2',
|
||||
},
|
||||
};
|
||||
|
||||
const entities = [entity1, entity2];
|
||||
|
||||
describe('catalogApiMock', () => {
|
||||
it('exports the expected functionality', async () => {
|
||||
const emptyFake = catalogApiMock();
|
||||
const notEmptyFake = catalogApiMock({ entities });
|
||||
|
||||
await expect(emptyFake.getEntities()).resolves.toEqual({ items: [] });
|
||||
await expect(notEmptyFake.getEntities()).resolves.toEqual({
|
||||
items: entities,
|
||||
});
|
||||
|
||||
const mock = catalogApiMock.mock();
|
||||
expect(mock.getEntities).toHaveBeenCalledTimes(0);
|
||||
expect(mock.getEntities()).toBeUndefined();
|
||||
mock.getEntities.mockResolvedValue({ items: entities });
|
||||
await expect(mock.getEntities()).resolves.toEqual({ items: entities });
|
||||
|
||||
const mock2 = catalogApiMock.mock({
|
||||
getEntities: async () => ({ items: [entity1] }),
|
||||
});
|
||||
await expect(mock2.getEntities()).resolves.toEqual({ items: [entity1] });
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
ApiFactory,
|
||||
ApiRef,
|
||||
createApiFactory,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { InMemoryCatalogClient } from '@backstage/catalog-client/testUtils';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { ApiMock } from '@backstage/frontend-test-utils';
|
||||
|
||||
/** @internal */
|
||||
function simpleMock<TApi>(
|
||||
ref: ApiRef<TApi>,
|
||||
mockFactory: () => jest.Mocked<TApi>,
|
||||
): (partialImpl?: Partial<TApi>) => ApiMock<TApi> {
|
||||
return partialImpl => {
|
||||
const mock = mockFactory();
|
||||
if (partialImpl) {
|
||||
for (const [key, impl] of Object.entries(partialImpl)) {
|
||||
if (typeof impl === 'function') {
|
||||
(mock as any)[key].mockImplementation(impl);
|
||||
} else {
|
||||
(mock as any)[key] = impl;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Object.assign(mock, {
|
||||
factory: createApiFactory({
|
||||
api: ref,
|
||||
deps: {},
|
||||
factory: () => mock,
|
||||
}),
|
||||
}) as ApiMock<TApi>;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fake catalog client that handles entities in memory storage. Note
|
||||
* that this client may be severely limited in functionality, and advanced
|
||||
* functions may not be available at all.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function catalogApiMock(options?: { entities?: Entity[] }): CatalogApi {
|
||||
return new InMemoryCatalogClient(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* A collection of mock functionality for the catalog service.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export namespace catalogApiMock {
|
||||
/**
|
||||
* Creates a fake catalog client that handles entities in memory storage. Note
|
||||
* that this client may be severely limited in functionality, and advanced
|
||||
* functions may not be available at all.
|
||||
*/
|
||||
export const factory = (options?: {
|
||||
entities?: Entity[];
|
||||
}): ApiFactory<CatalogApi, CatalogApi, {}> =>
|
||||
createApiFactory({
|
||||
api: catalogApiRef,
|
||||
deps: {},
|
||||
factory: () => new InMemoryCatalogClient(options),
|
||||
});
|
||||
/**
|
||||
* Creates a catalog client whose methods are mock functions, possibly with
|
||||
* some of them overloaded by the caller.
|
||||
*/
|
||||
export const mock = simpleMock(catalogApiRef, () => ({
|
||||
getEntities: jest.fn(),
|
||||
getEntitiesByRefs: jest.fn(),
|
||||
queryEntities: jest.fn(),
|
||||
getEntityAncestors: jest.fn(),
|
||||
getEntityByRef: jest.fn(),
|
||||
removeEntityByUid: jest.fn(),
|
||||
refreshEntity: jest.fn(),
|
||||
getEntityFacets: jest.fn(),
|
||||
getLocationById: jest.fn(),
|
||||
getLocationByRef: jest.fn(),
|
||||
addLocation: jest.fn(),
|
||||
removeLocationById: jest.fn(),
|
||||
getLocationByEntity: jest.fn(),
|
||||
validateEntity: jest.fn(),
|
||||
}));
|
||||
}
|
||||
@@ -21,8 +21,8 @@ import { Entity } from '@backstage/catalog-model';
|
||||
import {
|
||||
catalogApiRef,
|
||||
EntityKindFilter,
|
||||
MockEntityListContextProvider,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import { ApiProvider } from '@backstage/core-app-api';
|
||||
import {
|
||||
MockErrorApi,
|
||||
|
||||
@@ -23,11 +23,11 @@ import { ApiProvider } from '@backstage/core-app-api';
|
||||
import {
|
||||
EntityKindFilter,
|
||||
entityRouteRef,
|
||||
MockEntityListContextProvider,
|
||||
MockStarredEntitiesApi,
|
||||
starredEntitiesApiRef,
|
||||
UserListFilter,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
|
||||
import { act, fireEvent, screen } from '@testing-library/react';
|
||||
import * as React from 'react';
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { ReactNode } from 'react';
|
||||
import { fireEvent, screen, waitFor } from '@testing-library/react';
|
||||
import { CursorPaginatedCatalogTable } from './CursorPaginatedCatalogTable';
|
||||
@@ -22,8 +23,8 @@ import {
|
||||
DefaultEntityFilters,
|
||||
EntityKindFilter,
|
||||
EntityListContextProps,
|
||||
MockEntityListContextProvider,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
|
||||
|
||||
describe('CursorPaginatedCatalogTable', () => {
|
||||
const data = new Array(100).fill(0).map((_, index) => {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { ReactNode } from 'react';
|
||||
import { fireEvent, screen } from '@testing-library/react';
|
||||
import { CatalogTableRow } from './types';
|
||||
@@ -20,8 +21,8 @@ import { renderInTestApp } from '@backstage/test-utils';
|
||||
import {
|
||||
DefaultEntityFilters,
|
||||
EntityListContextProps,
|
||||
MockEntityListContextProvider,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import { OffsetPaginatedCatalogTable } from './OffsetPaginatedCatalogTable';
|
||||
|
||||
describe('OffsetPaginatedCatalogTable', () => {
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CompoundEntityRef, Entity } from '@backstage/catalog-model';
|
||||
import { useGetEntities } from './useGetEntities';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { renderHook, waitFor } from '@testing-library/react';
|
||||
import { getEntityRelations } from '@backstage/plugin-catalog-react';
|
||||
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
|
||||
|
||||
const givenParentGroup = 'team.squad1';
|
||||
const givenLeafGroup = 'team.squad2';
|
||||
@@ -31,15 +31,14 @@ const givenUserEntity = {
|
||||
},
|
||||
} as Partial<Entity> as Entity;
|
||||
|
||||
const getEntitiesByRefsMock = jest.fn();
|
||||
const catalogApiMock: Pick<CatalogApi, 'getEntities' | 'getEntitiesByRefs'> = {
|
||||
const catalogApi = catalogApiMock.mock({
|
||||
getEntities: jest.fn(async () => Promise.resolve({ items: [] })),
|
||||
getEntitiesByRefs: getEntitiesByRefsMock,
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('@backstage/core-plugin-api', () => ({
|
||||
useApi: jest.fn(() => catalogApiMock),
|
||||
}));
|
||||
jest.mock('@backstage/core-plugin-api', () => {
|
||||
const actual = jest.requireActual('@backstage/core-plugin-api');
|
||||
return { ...actual, useApi: jest.fn(() => catalogApi) };
|
||||
});
|
||||
|
||||
const getEntityRelationsMock: jest.Mock<
|
||||
CompoundEntityRef[],
|
||||
@@ -50,7 +49,7 @@ jest.mock('@backstage/plugin-catalog-react', () => {
|
||||
catalogApiRef: {},
|
||||
getEntityRelations: jest.fn(entity => {
|
||||
return getEntityRelationsMock(entity);
|
||||
}) as typeof getEntityRelations,
|
||||
}) as any,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -77,16 +76,17 @@ describe('useGetEntities', () => {
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
getEntitiesByRefsMock.mockImplementation(async ({ entityRefs: [ref] }) =>
|
||||
ref.includes(givenParentGroup)
|
||||
? { items: [givenParentGroupEntity] }
|
||||
: { items: [givenLeafGroupEntity] },
|
||||
catalogApi.getEntitiesByRefs.mockImplementation(
|
||||
async ({ entityRefs: [ref] }) =>
|
||||
ref.includes(givenParentGroup)
|
||||
? { items: [givenParentGroupEntity] }
|
||||
: { items: [givenLeafGroupEntity] },
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
getEntityRelationsMock.mockRestore();
|
||||
getEntitiesByRefsMock.mockRestore();
|
||||
catalogApi.getEntitiesByRefs.mockRestore();
|
||||
});
|
||||
|
||||
describe('when given entity is a group', () => {
|
||||
@@ -98,7 +98,7 @@ describe('useGetEntities', () => {
|
||||
|
||||
it('should aggregate child ownership', async () => {
|
||||
await whenHookIsCalledWith(givenParentGroupEntity);
|
||||
expect(catalogApiMock.getEntities).toHaveBeenCalledWith(
|
||||
expect(catalogApi.getEntities).toHaveBeenCalledWith(
|
||||
ownersFilter(
|
||||
`group:default/${givenParentGroup}`,
|
||||
`group:default/${givenLeafGroup}`,
|
||||
@@ -108,7 +108,7 @@ describe('useGetEntities', () => {
|
||||
|
||||
it('should retrieve child with their relations', async () => {
|
||||
await whenHookIsCalledWith(givenParentGroupEntity);
|
||||
expect(catalogApiMock.getEntitiesByRefs).toHaveBeenCalledWith({
|
||||
expect(catalogApi.getEntitiesByRefs).toHaveBeenCalledWith({
|
||||
entityRefs: [`group:default/${givenLeafGroup}`],
|
||||
fields: ['kind', 'metadata.namespace', 'metadata.name', 'relations'],
|
||||
});
|
||||
@@ -121,8 +121,8 @@ describe('useGetEntities', () => {
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
getEntitiesByRefsMock.mockRestore();
|
||||
getEntitiesByRefsMock.mockImplementation(
|
||||
catalogApi.getEntitiesByRefs.mockRestore();
|
||||
catalogApi.getEntitiesByRefs.mockImplementation(
|
||||
async ({ entityRefs: [ref] }) => {
|
||||
if (ref.includes(givenParentGroup)) {
|
||||
return { items: [givenParentGroupEntity] };
|
||||
@@ -152,7 +152,7 @@ describe('useGetEntities', () => {
|
||||
});
|
||||
|
||||
await whenHookIsCalledWith(givenParentGroupEntity);
|
||||
expect(catalogApiMock.getEntities).toHaveBeenCalledWith(
|
||||
expect(catalogApi.getEntities).toHaveBeenCalledWith(
|
||||
ownersFilter(
|
||||
`group:default/${givenParentGroup}`,
|
||||
`group:default/${givenIntermediateGroup}`,
|
||||
@@ -177,7 +177,7 @@ describe('useGetEntities', () => {
|
||||
});
|
||||
|
||||
await whenHookIsCalledWith(givenParentGroupEntity);
|
||||
expect(catalogApiMock.getEntities).toHaveBeenCalledWith(
|
||||
expect(catalogApi.getEntities).toHaveBeenCalledWith(
|
||||
ownersFilter(
|
||||
`group:default/${givenParentGroup}`,
|
||||
`group:default/${givenIntermediateGroup}`,
|
||||
@@ -195,7 +195,7 @@ describe('useGetEntities', () => {
|
||||
]);
|
||||
|
||||
await whenHookIsCalledWith(givenUserEntity);
|
||||
expect(catalogApiMock.getEntities).toHaveBeenCalledWith(
|
||||
expect(catalogApi.getEntities).toHaveBeenCalledWith(
|
||||
ownersFilter(
|
||||
`group:default/${givenLeafGroup}`,
|
||||
`user:default/${givenUser}`,
|
||||
@@ -219,14 +219,14 @@ describe('useGetEntities', () => {
|
||||
|
||||
it('given group entity should return directly owned entities', async () => {
|
||||
await whenHookIsCalledWith(givenLeafGroupEntity);
|
||||
expect(catalogApiMock.getEntities).toHaveBeenCalledWith(
|
||||
expect(catalogApi.getEntities).toHaveBeenCalledWith(
|
||||
ownersFilter(`group:default/${givenLeafGroup}`),
|
||||
);
|
||||
});
|
||||
|
||||
it('given user entity should return directly owned entities', async () => {
|
||||
await whenHookIsCalledWith(givenUserEntity);
|
||||
expect(catalogApiMock.getEntities).toHaveBeenCalledWith(
|
||||
expect(catalogApi.getEntities).toHaveBeenCalledWith(
|
||||
ownersFilter(`user:default/${givenUser}`),
|
||||
);
|
||||
});
|
||||
@@ -255,7 +255,7 @@ describe('useGetEntities', () => {
|
||||
? manyGroups.map(group => createGroupRefFromName(group.metadata.name))
|
||||
: [],
|
||||
);
|
||||
(catalogApiMock.getEntities as jest.Mock).mockClear();
|
||||
catalogApi.getEntities.mockClear();
|
||||
});
|
||||
|
||||
it('should handle 500+ relations without exceeding URL length limits', async () => {
|
||||
@@ -270,14 +270,13 @@ describe('useGetEntities', () => {
|
||||
timeout: 5000,
|
||||
});
|
||||
|
||||
const callArgs = (catalogApiMock.getEntities as jest.Mock).mock
|
||||
.calls[0][0];
|
||||
const callArgs = catalogApi.getEntities.mock.calls[0][0];
|
||||
|
||||
expect(
|
||||
callArgs.filter[0]['relations.ownedBy'].length,
|
||||
(callArgs!.filter as any)[0]['relations.ownedBy'].length,
|
||||
).toBeLessThanOrEqual(100);
|
||||
|
||||
const owners = callArgs.filter[0]['relations.ownedBy'];
|
||||
const owners = (callArgs!.filter as any)[0]['relations.ownedBy'];
|
||||
|
||||
expect(Array.isArray(owners)).toBeTruthy();
|
||||
expect(owners.length).toBeLessThanOrEqual(100);
|
||||
@@ -309,7 +308,7 @@ describe('useGetEntities', () => {
|
||||
)
|
||||
: [],
|
||||
);
|
||||
(catalogApiMock.getEntities as jest.Mock).mockClear();
|
||||
catalogApi.getEntities.mockClear();
|
||||
});
|
||||
|
||||
it('should batch the request to avoid exceeding header size limits', async () => {
|
||||
@@ -323,8 +322,7 @@ describe('useGetEntities', () => {
|
||||
await waitFor(() => expect(result.current.loading).toBe(false), {
|
||||
timeout: 5000,
|
||||
});
|
||||
const callArgs = (catalogApiMock.getEntities as jest.Mock).mock
|
||||
.calls[0][0];
|
||||
const callArgs = catalogApi.getEntities.mock.calls[0][0];
|
||||
|
||||
const url = new URL(
|
||||
`http://localhost/api/catalog/entities?${new URLSearchParams(
|
||||
@@ -334,7 +332,7 @@ describe('useGetEntities', () => {
|
||||
const headerSize = url.href.length;
|
||||
expect(headerSize).toBeLessThanOrEqual(16384);
|
||||
|
||||
const owners = callArgs.filter[0]['relations.ownedBy'];
|
||||
const owners = (callArgs!.filter as any)[0]['relations.ownedBy'];
|
||||
expect(Array.isArray(owners)).toBeTruthy();
|
||||
expect(owners.length).toBeLessThanOrEqual(100);
|
||||
});
|
||||
|
||||
@@ -25,7 +25,8 @@ import React from 'react';
|
||||
import { Workflow } from './Workflow';
|
||||
import { analyticsApiRef } from '@backstage/core-plugin-api';
|
||||
import { ScaffolderApi, scaffolderApiRef } from '../../../api';
|
||||
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
|
||||
|
||||
const scaffolderApiMock: jest.Mocked<ScaffolderApi> = {
|
||||
cancelTask: jest.fn(),
|
||||
@@ -38,14 +39,13 @@ const scaffolderApiMock: jest.Mocked<ScaffolderApi> = {
|
||||
listTasks: jest.fn(),
|
||||
autocomplete: jest.fn(),
|
||||
};
|
||||
const catalogApiMock: jest.Mocked<CatalogApi> = {
|
||||
getEntityByRef: jest.fn(),
|
||||
} as any;
|
||||
|
||||
const catalogApi = catalogApiMock.mock();
|
||||
|
||||
const analyticsMock = new MockAnalyticsApi();
|
||||
const apis = TestApiRegistry.from(
|
||||
[scaffolderApiRef, scaffolderApiMock],
|
||||
[catalogApiRef, catalogApiMock],
|
||||
[catalogApiRef, catalogApi],
|
||||
[analyticsApiRef, analyticsMock],
|
||||
);
|
||||
|
||||
|
||||
+8
-9
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ApiProvider } from '@backstage/core-app-api';
|
||||
import { analyticsApiRef } from '@backstage/core-plugin-api';
|
||||
import {
|
||||
@@ -30,8 +31,8 @@ import {
|
||||
import { TemplateWizardPage } from './TemplateWizardPage';
|
||||
import { rootRouteRef } from '../../../routes';
|
||||
import { ANNOTATION_EDIT_URL } from '@backstage/catalog-model';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
|
||||
|
||||
jest.mock('react-router-dom', () => {
|
||||
return {
|
||||
@@ -54,16 +55,14 @@ const scaffolderApiMock: jest.Mocked<ScaffolderApi> = {
|
||||
autocomplete: jest.fn(),
|
||||
};
|
||||
|
||||
const catalogApiMock: jest.Mocked<CatalogApi> = {
|
||||
getEntityByRef: jest.fn(),
|
||||
} as any;
|
||||
const catalogApi = catalogApiMock.mock();
|
||||
|
||||
const analyticsMock = new MockAnalyticsApi();
|
||||
const apis = TestApiRegistry.from(
|
||||
[scaffolderApiRef, scaffolderApiMock],
|
||||
[catalogApiRef, catalogApiMock],
|
||||
[catalogApiRef, catalogApi],
|
||||
[analyticsApiRef, analyticsMock],
|
||||
[catalogApiRef, catalogApiMock],
|
||||
[catalogApiRef, catalogApi],
|
||||
);
|
||||
|
||||
const entityRefResponse = {
|
||||
@@ -100,7 +99,7 @@ describe('TemplateWizardPage', () => {
|
||||
],
|
||||
title: 'React JSON Schema Form Test',
|
||||
});
|
||||
catalogApiMock.getEntityByRef.mockResolvedValue(entityRefResponse);
|
||||
catalogApi.getEntityByRef.mockResolvedValue(entityRefResponse);
|
||||
|
||||
const { findByRole, getByRole } = await renderInTestApp(
|
||||
<ApiProvider apis={apis}>
|
||||
@@ -147,7 +146,7 @@ describe('TemplateWizardPage', () => {
|
||||
});
|
||||
describe('scaffolder page context menu', () => {
|
||||
it('should render if editUrl is set to url', async () => {
|
||||
catalogApiMock.getEntityByRef.mockResolvedValue({
|
||||
catalogApi.getEntityByRef.mockResolvedValue({
|
||||
apiVersion: 'v1',
|
||||
kind: 'service',
|
||||
metadata: {
|
||||
@@ -177,7 +176,7 @@ describe('TemplateWizardPage', () => {
|
||||
expect(queryByTestId('menu-button')).toBeInTheDocument();
|
||||
});
|
||||
it('should not render if editUrl is undefined', async () => {
|
||||
catalogApiMock.getEntityByRef.mockResolvedValue({
|
||||
catalogApi.getEntityByRef.mockResolvedValue({
|
||||
apiVersion: 'v1',
|
||||
kind: 'service',
|
||||
metadata: {
|
||||
|
||||
@@ -22,8 +22,8 @@ import { TemplateTypePicker } from './TemplateTypePicker';
|
||||
import {
|
||||
catalogApiRef,
|
||||
EntityKindFilter,
|
||||
MockEntityListContextProvider,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import { AlertApi, alertApiRef } from '@backstage/core-plugin-api';
|
||||
import { ApiProvider } from '@backstage/core-app-api';
|
||||
import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
|
||||
|
||||
@@ -24,9 +24,9 @@ import {
|
||||
CatalogApi,
|
||||
catalogApiRef,
|
||||
starredEntitiesApiRef,
|
||||
MockEntityListContextProvider,
|
||||
MockStarredEntitiesApi,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import {
|
||||
MockStorageApi,
|
||||
renderInTestApp,
|
||||
|
||||
Reference in New Issue
Block a user