use the catalog mock in more tests

Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
Fredrik Adelöw
2024-10-07 14:17:34 +02:00
parent 3459f9390d
commit 033c957321
65 changed files with 525 additions and 799 deletions
@@ -25,6 +25,7 @@ import {
entityRouteRef,
catalogApiRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { wrapInTestApp, TestApiProvider } from '@backstage/test-utils';
import { configApiRef } from '@backstage/core-plugin-api';
import { ConfigReader } from '@backstage/config';
@@ -67,9 +68,7 @@ const entities = [
},
];
const mockCatalogApi = {
getEntities: async () => ({ items: entities }),
};
const catalogApi = catalogApiMock({ entities });
const starredEntitiesApi = new MockStarredEntitiesApi();
starredEntitiesApi.toggleStarred('component:default/example-starred-entity');
@@ -85,7 +84,7 @@ export default {
<>
<TestApiProvider
apis={[
[catalogApiRef, mockCatalogApi],
[catalogApiRef, catalogApi],
[starredEntitiesApiRef, starredEntitiesApi],
[searchApiRef, { query: () => Promise.resolve({ results: [] }) }],
[
@@ -29,6 +29,7 @@ import {
entityRouteRef,
catalogApiRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { configApiRef } from '@backstage/core-plugin-api';
import { ConfigReader } from '@backstage/config';
import { HomePageSearchBar, searchPlugin } from '@backstage/plugin-search';
@@ -74,9 +75,7 @@ const entities = [
},
];
const mockCatalogApi = {
getEntities: async () => ({ items: entities }),
};
const catalogApi = catalogApiMock({ entities });
const starredEntitiesApi = new MockStarredEntitiesApi();
starredEntitiesApi.toggleStarred('component:default/example-starred-entity');
@@ -92,7 +91,7 @@ export default {
<>
<TestApiProvider
apis={[
[catalogApiRef, mockCatalogApi],
[catalogApiRef, catalogApi],
[starredEntitiesApiRef, starredEntitiesApi],
[searchApiRef, { query: () => Promise.resolve({ results: [] }) }],
[
@@ -16,21 +16,17 @@
import { ConfigReader } from '@backstage/core-app-api';
import { TableColumn, TableProps } from '@backstage/core-components';
import {
ConfigApi,
configApiRef,
storageApiRef,
} from '@backstage/core-plugin-api';
import { configApiRef, storageApiRef } from '@backstage/core-plugin-api';
import {
CatalogTableRow,
DefaultStarredEntitiesApi,
} from '@backstage/plugin-catalog';
import {
CatalogApi,
catalogApiRef,
entityRouteRef,
starredEntitiesApiRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import {
MockPermissionApi,
MockStorageApi,
@@ -45,7 +41,7 @@ import { DefaultApiExplorerPage } from './DefaultApiExplorerPage';
import { permissionApiRef } from '@backstage/plugin-permission-react';
describe('DefaultApiExplorerPage', () => {
const catalogApi: Partial<CatalogApi> = {
const catalogApi = catalogApiMock.mock({
getEntities: () =>
Promise.resolve({
items: [
@@ -74,9 +70,9 @@ describe('DefaultApiExplorerPage', () => {
pageInfo: {},
totalItems: 0,
}),
};
});
const configApi: ConfigApi = new ConfigReader({
const configApi = new ConfigReader({
organization: {
name: 'My Company',
},
@@ -16,11 +16,11 @@
import { Entity, RELATION_CONSUMES_API } from '@backstage/catalog-model';
import {
CatalogApi,
catalogApiRef,
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
@@ -31,9 +31,7 @@ describe('<ConsumedApisCard />', () => {
const apiDocsConfig: jest.Mocked<ApiDocsConfig> = {
getApiDefinitionWidget: jest.fn(),
} as any;
const catalogApi: jest.Mocked<CatalogApi> = {
getEntitiesByRefs: jest.fn(),
} as any;
const catalogApi = catalogApiMock.mock();
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
beforeEach(() => {
@@ -16,7 +16,6 @@
import { Entity, RELATION_HAS_PART } from '@backstage/catalog-model';
import {
CatalogApi,
catalogApiRef,
EntityProvider,
entityRouteRef,
@@ -26,14 +25,13 @@ import { waitFor } from '@testing-library/react';
import React from 'react';
import { ApiDocsConfig, apiDocsConfigRef } from '../../config';
import { HasApisCard } from './HasApisCard';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
describe('<HasApisCard />', () => {
const apiDocsConfig: jest.Mocked<ApiDocsConfig> = {
getApiDefinitionWidget: jest.fn(),
} as any;
const catalogApi: jest.Mocked<CatalogApi> = {
getEntitiesByRefs: jest.fn(),
} as any;
const catalogApi = catalogApiMock.mock();
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
beforeEach(() => {
@@ -16,7 +16,6 @@
import { Entity, RELATION_PROVIDES_API } from '@backstage/catalog-model';
import {
CatalogApi,
catalogApiRef,
EntityProvider,
entityRouteRef,
@@ -26,14 +25,13 @@ import { waitFor } from '@testing-library/react';
import React from 'react';
import { ApiDocsConfig, apiDocsConfigRef } from '../../config';
import { ProvidedApisCard } from './ProvidedApisCard';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
describe('<ProvidedApisCard />', () => {
const apiDocsConfig: jest.Mocked<ApiDocsConfig> = {
getApiDefinitionWidget: jest.fn(),
} as any;
const catalogApi: jest.Mocked<CatalogApi> = {
getEntitiesByRefs: jest.fn(),
} as any;
const catalogApi = catalogApiMock.mock();
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
beforeEach(() => {
@@ -16,20 +16,18 @@
import { Entity, RELATION_API_CONSUMED_BY } from '@backstage/catalog-model';
import {
CatalogApi,
catalogApiRef,
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { ConsumingComponentsCard } from './ConsumingComponentsCard';
describe('<ConsumingComponentsCard />', () => {
const catalogApi: jest.Mocked<CatalogApi> = {
getEntitiesByRefs: jest.fn(),
} as any;
const catalogApi = catalogApiMock.mock();
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
beforeEach(() => {
@@ -16,7 +16,6 @@
import { Entity, RELATION_API_PROVIDED_BY } from '@backstage/catalog-model';
import {
CatalogApi,
catalogApiRef,
EntityProvider,
entityRouteRef,
@@ -25,11 +24,10 @@ import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { ProvidingComponentsCard } from './ProvidingComponentsCard';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
describe('<ProvidingComponentsCard />', () => {
const catalogApi: jest.Mocked<CatalogApi> = {
getEntitiesByRefs: jest.fn(),
} as any;
const catalogApi = catalogApiMock.mock();
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
beforeEach(() => {
@@ -15,34 +15,37 @@
*/
import { CatalogAuthResolverContext } from './CatalogAuthResolverContext';
import { CatalogApi } from '@backstage/catalog-client';
import { mockServices } from '@backstage/backend-test-utils';
import { TokenIssuer } from '../../identity/types';
import { DiscoveryService } from '@backstage/backend-plugin-api';
import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils';
import { NotFoundError } from '@backstage/errors';
describe('CatalogAuthResolverContext', () => {
beforeEach(() => {
jest.clearAllMocks();
});
const mockCatalogApi = {
getEntities: jest.fn().mockResolvedValue({ items: [{}] }),
} as Partial<jest.Mocked<CatalogApi>>;
const catalogApi = catalogServiceMock.mock({
getEntities: jest.fn().mockResolvedValue({ items: [] }),
});
it('adds kind to filter when missing', async () => {
const context = CatalogAuthResolverContext.create({
logger: mockServices.logger.mock(),
catalogApi: mockCatalogApi as CatalogApi,
catalogApi,
tokenIssuer: {} as TokenIssuer,
discovery: {} as DiscoveryService,
auth: mockServices.auth(),
httpAuth: mockServices.httpAuth(),
});
await context.findCatalogUser({
filter: [{}, { kind: 'group' }, { KIND: 'USER' }],
});
expect(mockCatalogApi.getEntities).toHaveBeenCalledWith(
await expect(
context.findCatalogUser({
filter: [{}, { kind: 'group' }, { KIND: 'USER' }],
}),
).rejects.toThrow(NotFoundError);
expect(catalogApi.getEntities).toHaveBeenCalledWith(
{
filter: [{ kind: 'user' }, { kind: 'group' }, { KIND: 'USER' }],
},
@@ -56,7 +56,7 @@ jest.mock('./AzureRepoApiClient', () => {
import { ConfigReader, UrlPatternDiscovery } from '@backstage/core-app-api';
import { ScmIntegrations } from '@backstage/integration';
import { ScmAuthApi } from '@backstage/integration-react';
import { CatalogApi } from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { MockFetchApi, registerMswTestHooks } from '@backstage/test-utils';
import { Octokit } from '@octokit/rest';
import { rest } from 'msw';
@@ -94,19 +94,7 @@ describe('CatalogImportClient', () => {
}),
);
const catalogApi = {
getEntities: jest.fn(),
addLocation: jest.fn(),
removeLocationById: jest.fn(),
getEntityByRef: jest.fn(),
getLocationByRef: jest.fn(),
getLocationById: jest.fn(),
removeEntityByUid: jest.fn(),
refreshEntity: jest.fn(),
getEntityAncestors: jest.fn(),
getEntityFacets: jest.fn(),
validateEntity: jest.fn(),
};
const catalogApi = catalogApiMock.mock();
let catalogImportClient: CatalogImportClient;
@@ -116,7 +104,7 @@ describe('CatalogImportClient', () => {
scmAuthApi,
scmIntegrationsApi,
fetchApi,
catalogApi: catalogApi as Partial<CatalogApi> as CatalogApi,
catalogApi: catalogApi,
configApi: new ConfigReader({
app: {
baseUrl: 'https://demo.backstage.io/',
@@ -462,7 +450,7 @@ describe('CatalogImportClient', () => {
scmAuthApi,
scmIntegrationsApi,
fetchApi,
catalogApi: catalogApi as Partial<CatalogApi> as CatalogApi,
catalogApi: catalogApi,
configApi: new ConfigReader({
catalog: {
import: {
@@ -720,7 +708,7 @@ describe('CatalogImportClient', () => {
scmAuthApi,
scmIntegrationsApi,
fetchApi,
catalogApi: catalogApi as Partial<CatalogApi> as CatalogApi,
catalogApi: catalogApi,
configApi: new ConfigReader({
catalog: {
import: {
@@ -806,7 +794,7 @@ describe('CatalogImportClient', () => {
scmAuthApi,
scmIntegrationsApi,
fetchApi,
catalogApi: catalogApi as Partial<CatalogApi> as CatalogApi,
catalogApi: catalogApi,
configApi: new ConfigReader({
catalog: {
import: {
@@ -14,10 +14,10 @@
* limitations under the License.
*/
import { CatalogClient } from '@backstage/catalog-client';
import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
import { configApiRef } from '@backstage/core-plugin-api';
import { catalogApiRef } from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
import { screen } from '@testing-library/react';
import React from 'react';
@@ -34,7 +34,7 @@ describe('<DefaultImportPage />', () => {
beforeEach(() => {
apis = TestApiRegistry.from(
[configApiRef, new ConfigReader({ integrations: {} })],
[catalogApiRef, new CatalogClient({ discoveryApi: {} as any })],
[catalogApiRef, catalogApiMock()],
[
catalogImportApiRef,
new CatalogImportClient({
@@ -14,10 +14,10 @@
* limitations under the License.
*/
import { CatalogClient } from '@backstage/catalog-client';
import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
import { FetchApi, configApiRef } from '@backstage/core-plugin-api';
import { catalogApiRef } from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
import { screen } from '@testing-library/react';
import React from 'react';
@@ -40,7 +40,7 @@ describe('<ImportPage />', () => {
beforeEach(() => {
apis = TestApiRegistry.from(
[configApiRef, new ConfigReader({ integrations: {} })],
[catalogApiRef, new CatalogClient({ discoveryApi: {} as any })],
[catalogApiRef, catalogApiMock()],
[
catalogImportApiRef,
new CatalogImportClient({
@@ -21,15 +21,13 @@ import React from 'react';
import { AnalyzeResult } from '../../api';
import { StepPrepareSelectLocations } from './StepPrepareSelectLocations';
import {
CatalogApi,
catalogApiRef,
entityPresentationApiRef,
} from '@backstage/plugin-catalog-react';
import { DefaultEntityPresentationApi } from '@backstage/plugin-catalog';
import { Entity } from '@backstage/catalog-model';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
describe('<StepPrepareSelectLocations />', () => {
let entities: Entity[];
const analyzeResult = {
type: 'locations',
locations: [
@@ -61,19 +59,11 @@ describe('<StepPrepareSelectLocations />', () => {
],
} as Extract<AnalyzeResult, { type: 'locations' }>;
const catalogApi: jest.Mocked<CatalogApi> = {
getLocationById: jest.fn(),
getEntityByName: jest.fn(),
getEntities: jest.fn(async () => ({ items: entities })),
addLocation: jest.fn(),
getLocationByRef: jest.fn(),
removeEntityByUid: jest.fn(),
} as any;
const catalogApi = catalogApiMock();
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
beforeEach(() => {
jest.resetAllMocks();
catalogApi.getEntities.mockResolvedValue({ items: entities });
Wrapper = ({ children }: { children?: React.ReactNode }) => (
<TestApiProvider
apis={[
@@ -16,11 +16,13 @@
import { fireEvent, render, waitFor, screen } from '@testing-library/react';
import React from 'react';
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
import {
MockEntityListContextProvider,
catalogApiMock,
} from '@backstage/plugin-catalog-react/testUtils';
import { EntityAutocompletePicker } from './EntityAutocompletePicker';
import { TestApiProvider } from '@backstage/test-utils';
import { catalogApiRef } from '../../api';
import { CatalogApi } from '@backstage/catalog-client';
import { DefaultEntityFilters } from '../../hooks';
import { Entity } from '@backstage/catalog-model';
import { EntityFilter } from '../../types';
@@ -46,17 +48,15 @@ class EntityOptionFilter implements EntityFilter {
}
}
const makeMockCatalogApi = (
opts: string[] = defaultOptions,
): Partial<jest.Mocked<CatalogApi>> => {
return {
function makeMockCatalogApi(opts: string[] = defaultOptions) {
return catalogApiMock.mock({
getEntityFacets: jest.fn().mockResolvedValue({
facets: {
'spec.options': opts.map((value, idx) => ({ value, count: idx })),
},
}),
};
};
});
}
describe('<EntityAutocompletePicker/>', () => {
beforeEach(() => {
@@ -64,9 +64,9 @@ describe('<EntityAutocompletePicker/>', () => {
});
it('renders all options', async () => {
const mockCatalogApi = makeMockCatalogApi();
const catalogApi = makeMockCatalogApi();
render(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApi]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
<MockEntityListContextProvider value={{}}>
<EntityAutocompletePicker<EntityFilters>
label="Options"
@@ -82,7 +82,7 @@ describe('<EntityAutocompletePicker/>', () => {
);
// should have called catalog backend without any filters applied
expect(mockCatalogApi.getEntityFacets).toHaveBeenCalledWith({
expect(catalogApi.getEntityFacets).toHaveBeenCalledWith({
facets: ['spec.options'],
filter: {},
});
@@ -16,17 +16,17 @@
import { fireEvent, screen, waitFor } from '@testing-library/react';
import React from 'react';
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
import {
MockEntityListContextProvider,
catalogApiMock,
} from '@backstage/plugin-catalog-react/testUtils';
import { EntityLifecycleFilter } from '../../filters';
import { EntityLifecyclePicker } from './EntityLifecyclePicker';
import { TestApiProvider, renderInTestApp } from '@backstage/test-utils';
import { catalogApiRef } from '../../api';
import { CatalogApi } from '@backstage/catalog-client';
describe('<EntityLifecyclePicker/>', () => {
const catalogApi = {
getEntityFacets: jest.fn(),
} as unknown as jest.Mocked<CatalogApi>;
const catalogApi = catalogApiMock.mock();
beforeEach(() => {
catalogApi.getEntityFacets.mockResolvedValue({
@@ -16,17 +16,19 @@
import { fireEvent, screen, waitFor } from '@testing-library/react';
import React from 'react';
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
import {
MockEntityListContextProvider,
catalogApiMock,
} from '@backstage/plugin-catalog-react/testUtils';
import { EntityNamespaceFilter } from '../../filters';
import { EntityNamespacePicker } from './EntityNamespacePicker';
import { TestApiProvider, renderInTestApp } from '@backstage/test-utils';
import { catalogApiRef } from '../../api';
import { CatalogApi } from '@backstage/catalog-client';
const namespaces = ['namespace-1', 'namespace-2', 'namespace-3'];
describe('<EntityNamespacePicker/>', () => {
const mockCatalogApiRef = {
const catalogApi = catalogApiMock.mock({
getEntityFacets: async () => ({
facets: {
'metadata.namespace': namespaces.map((value, idx) => ({
@@ -35,11 +37,11 @@ describe('<EntityNamespacePicker/>', () => {
})),
},
}),
} as unknown as CatalogApi;
});
it('renders all namespaces', async () => {
await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
<MockEntityListContextProvider value={{}}>
<EntityNamespacePicker />
</MockEntityListContextProvider>
@@ -57,7 +59,7 @@ describe('<EntityNamespacePicker/>', () => {
it('renders unique namespaces in alphabetical order', async () => {
await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
<MockEntityListContextProvider value={{}}>
<EntityNamespacePicker />
</MockEntityListContextProvider>
@@ -80,7 +82,7 @@ describe('<EntityNamespacePicker/>', () => {
const updateFilters = jest.fn();
const queryParameters = { namespace: ['namespace-1'] };
await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
<MockEntityListContextProvider
value={{
updateFilters,
@@ -102,7 +104,7 @@ describe('<EntityNamespacePicker/>', () => {
it('adds namespaces to filters', async () => {
const updateFilters = jest.fn();
await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
<MockEntityListContextProvider
value={{
updateFilters,
@@ -126,7 +128,7 @@ describe('<EntityNamespacePicker/>', () => {
it('removes namespaces from filters', async () => {
const updateFilters = jest.fn();
await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
<MockEntityListContextProvider
value={{
updateFilters,
@@ -155,7 +157,7 @@ describe('<EntityNamespacePicker/>', () => {
it('responds to external queryParameters changes', async () => {
const updateFilters = jest.fn();
const rendered = await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
<MockEntityListContextProvider
value={{
updateFilters,
@@ -172,7 +174,7 @@ describe('<EntityNamespacePicker/>', () => {
}),
);
rendered.rerender(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
<MockEntityListContextProvider
value={{
updateFilters,
@@ -189,13 +191,13 @@ describe('<EntityNamespacePicker/>', () => {
});
it('removes namespaces from filters if there are no available namespaces', async () => {
const updateFilters = jest.fn();
const mockCatalogApiRefNoNamespace = {
const mockCatalogApiRefNoNamespace = catalogApiMock.mock({
getEntityFacets: async () => ({
facets: {
'metadata.namespace': {},
'metadata.namespace': [],
},
}),
} as unknown as CatalogApi;
});
await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRefNoNamespace]]}>
@@ -217,7 +219,7 @@ describe('<EntityNamespacePicker/>', () => {
});
it('namespace picker is visible if there are only 1 available option', async () => {
const defaultNamespaces = ['default', 'default', 'default'];
const mockCatalogApiRefDefaultNamespace = {
const mockCatalogApiRefDefaultNamespace = catalogApiMock.mock({
getEntityFacets: async () => ({
facets: {
'metadata.namespace': defaultNamespaces.map((value, idx) => ({
@@ -226,7 +228,7 @@ describe('<EntityNamespacePicker/>', () => {
})),
},
}),
} as unknown as CatalogApi;
});
await renderInTestApp(
<TestApiProvider
apis={[[catalogApiRef, mockCatalogApiRefDefaultNamespace]]}
@@ -241,13 +243,13 @@ describe('<EntityNamespacePicker/>', () => {
);
});
it('namespace picker is invisible if there is zero available option', async () => {
const mockCatalogApiRefDefaultNamespace = {
const mockCatalogApiRefDefaultNamespace = catalogApiMock.mock({
getEntityFacets: async () => ({
facets: {
'metadata.namespace': [],
},
}),
} as unknown as CatalogApi;
});
await renderInTestApp(
<TestApiProvider
apis={[[catalogApiRef, mockCatalogApiRefDefaultNamespace]]}
@@ -263,7 +265,7 @@ describe('<EntityNamespacePicker/>', () => {
});
it('renders initially selected namespaces', async () => {
renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
<MockEntityListContextProvider value={{}}>
<EntityNamespacePicker
initiallySelectedNamespaces={['namespace-2', 'namespace-3']}
@@ -17,7 +17,10 @@
import { Entity, stringifyEntityRef } from '@backstage/catalog-model';
import { fireEvent, screen, waitFor } from '@testing-library/react';
import React from 'react';
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
import {
MockEntityListContextProvider,
catalogApiMock,
} from '@backstage/plugin-catalog-react/testUtils';
import { EntityOwnerFilter } from '../../filters';
import { EntityOwnerPicker } from './EntityOwnerPicker';
import { ApiProvider } from '@backstage/core-app-api';
@@ -26,7 +29,7 @@ import {
renderInTestApp,
TestApiRegistry,
} from '@backstage/test-utils';
import { catalogApiRef, CatalogApi } from '../..';
import { catalogApiRef } from '../..';
import { errorApiRef } from '@backstage/core-plugin-api';
import { QueryEntitiesCursorRequest } from '@backstage/catalog-client';
@@ -108,21 +111,7 @@ const ownerEntitiesBatch2: Entity[] = [
},
];
const mockedQueryEntities: jest.MockedFn<CatalogApi['queryEntities']> =
jest.fn();
const mockedGetEntitiesByRef: jest.MockedFn<CatalogApi['getEntitiesByRefs']> =
jest.fn();
const mockedGetEntityFacets: jest.MockedFn<CatalogApi['getEntityFacets']> =
jest.fn();
const mockCatalogApi: Partial<CatalogApi> = {
queryEntities: mockedQueryEntities,
getEntitiesByRefs: mockedGetEntitiesByRef,
getEntityFacets: mockedGetEntityFacets,
};
const mockCatalogApi = catalogApiMock.mock();
const mockErrorApi = new MockErrorApi();
describe('<EntityOwnerPicker mode="all" />', () => {
@@ -134,7 +123,7 @@ describe('<EntityOwnerPicker mode="all" />', () => {
beforeEach(() => {
jest.resetAllMocks();
mockedQueryEntities.mockImplementation(async request => {
mockCatalogApi.queryEntities.mockImplementation(async request => {
const totalItems =
ownerEntitiesBatch1.length + ownerEntitiesBatch2.length;
if ((request as QueryEntitiesCursorRequest).cursor) {
@@ -178,8 +167,8 @@ describe('<EntityOwnerPicker mode="all" />', () => {
expect(screen.getByText(owner)).toBeInTheDocument();
});
expect(mockedQueryEntities).toHaveBeenCalledTimes(1);
expect(mockedGetEntitiesByRef).not.toHaveBeenCalled();
expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(1);
expect(mockCatalogApi.getEntitiesByRefs).not.toHaveBeenCalled();
fireEvent.scroll(screen.getByTestId('owner-picker-listbox'));
@@ -195,7 +184,7 @@ describe('<EntityOwnerPicker mode="all" />', () => {
expect(screen.getByText(owner)).toBeInTheDocument();
});
expect(mockedQueryEntities).toHaveBeenCalledTimes(2);
expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(2);
});
it('respects the query parameter filter value', async () => {
@@ -214,7 +203,7 @@ describe('<EntityOwnerPicker mode="all" />', () => {
</ApiProvider>,
);
expect(mockedGetEntitiesByRef).toHaveBeenCalledWith({
expect(mockCatalogApi.getEntitiesByRefs).toHaveBeenCalledWith({
entityRefs: ['another-owner'],
});
expect(updateFilters).toHaveBeenLastCalledWith({
@@ -226,7 +215,7 @@ describe('<EntityOwnerPicker mode="all" />', () => {
const updateFilters = jest.fn();
const queryParameters = { owners: ['another-owner'] };
mockedGetEntitiesByRef.mockResolvedValue({
mockCatalogApi.getEntitiesByRefs.mockResolvedValue({
items: [
{
metadata: {
@@ -260,7 +249,7 @@ describe('<EntityOwnerPicker mode="all" />', () => {
).toBeInTheDocument(),
);
expect(mockedGetEntitiesByRef).toHaveBeenCalledWith({
expect(mockCatalogApi.getEntitiesByRefs).toHaveBeenCalledWith({
entityRefs: ['another-owner'],
});
@@ -268,7 +257,7 @@ describe('<EntityOwnerPicker mode="all" />', () => {
await waitFor(() => screen.getByText('Some Owner 2'));
fireEvent.click(screen.getByText('Some Owner 2'));
expect(mockedGetEntitiesByRef).toHaveBeenCalledTimes(1);
expect(mockCatalogApi.getEntitiesByRefs).toHaveBeenCalledTimes(1);
await waitFor(() =>
expect(
@@ -292,7 +281,7 @@ describe('<EntityOwnerPicker mode="all" />', () => {
</MockEntityListContextProvider>
</ApiProvider>,
);
expect(mockedGetEntitiesByRef).not.toHaveBeenCalled();
expect(mockCatalogApi.getEntitiesByRefs).not.toHaveBeenCalled();
expect(updateFilters).toHaveBeenLastCalledWith({
owners: undefined,
});
@@ -320,7 +309,7 @@ describe('<EntityOwnerPicker mode="all" />', () => {
</MockEntityListContextProvider>
</ApiProvider>,
);
expect(mockedGetEntitiesByRef).toHaveBeenCalledWith({
expect(mockCatalogApi.getEntitiesByRefs).toHaveBeenCalledWith({
entityRefs: ['group:default/some-owner'],
});
expect(updateFilters).toHaveBeenLastCalledWith({
@@ -352,7 +341,7 @@ describe('<EntityOwnerPicker mode="all" />', () => {
</MockEntityListContextProvider>
</ApiProvider>,
);
expect(mockedGetEntitiesByRef).toHaveBeenCalledWith({
expect(mockCatalogApi.getEntitiesByRefs).toHaveBeenCalledWith({
entityRefs: ['team-a'],
});
expect(updateFilters).toHaveBeenLastCalledWith({
@@ -385,7 +374,7 @@ describe('<EntityOwnerPicker mode="owners-only" />', () => {
beforeEach(() => {
jest.resetAllMocks();
mockedGetEntityFacets.mockResolvedValue({
mockCatalogApi.getEntityFacets.mockResolvedValue({
facets: {
'relations.ownedBy': [
...[...ownerEntitiesBatch1, ...ownerEntitiesBatch2].map(o => ({
@@ -396,7 +385,7 @@ describe('<EntityOwnerPicker mode="owners-only" />', () => {
},
});
mockedGetEntitiesByRef.mockResolvedValue({
mockCatalogApi.getEntitiesByRefs.mockResolvedValue({
items: [...ownerEntitiesBatch1, ...ownerEntitiesBatch2],
});
});
@@ -425,7 +414,7 @@ describe('<EntityOwnerPicker mode="owners-only" />', () => {
expect(screen.getByText(owner)).toBeInTheDocument();
});
expect(mockedGetEntityFacets).toHaveBeenCalledTimes(1);
expect(mockCatalogApi.getEntityFacets).toHaveBeenCalledTimes(1);
fireEvent.scroll(screen.getByTestId('owner-picker-listbox'));
@@ -476,7 +465,7 @@ describe('<EntityOwnerPicker mode="owners-only" />', () => {
</MockEntityListContextProvider>
</ApiProvider>,
);
expect(mockedGetEntitiesByRef).toHaveBeenCalledWith({
expect(mockCatalogApi.getEntitiesByRefs).toHaveBeenCalledWith({
entityRefs: [...ownerEntitiesBatch1, ...ownerEntitiesBatch2].map(entity =>
stringifyEntityRef(entity),
),
@@ -13,21 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { renderHook, waitFor } from '@testing-library/react';
import { useFacetsEntities } from './useFacetsEntities';
import { CatalogApi } from '@backstage/catalog-client';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { Entity, parseEntityRef } from '@backstage/catalog-model';
const mockedGetEntityFacets: jest.MockedFn<CatalogApi['getEntityFacets']> =
jest.fn();
const mockedGetEntitiesByRefs: jest.MockedFn<CatalogApi['getEntitiesByRefs']> =
jest.fn();
const mockCatalogApi: Partial<CatalogApi> = {
getEntityFacets: mockedGetEntityFacets,
getEntitiesByRefs: mockedGetEntitiesByRefs,
};
const mockCatalogApi = catalogApiMock.mock();
jest.mock('@backstage/core-plugin-api', () => ({
...jest.requireActual('@backstage/core-plugin-api'),
@@ -65,16 +57,16 @@ describe('useFacetsEntities', () => {
});
it(`should return empty items when facets are loading`, () => {
mockedGetEntityFacets.mockReturnValue(new Promise(() => {}));
mockCatalogApi.getEntityFacets.mockReturnValue(new Promise(() => {}));
const { result } = renderHook(() => useFacetsEntities({ enabled: true }));
expect(result.current[0]).toEqual({ value: { items: [] }, loading: true });
});
it(`should return empty response when facet is not present`, async () => {
mockedGetEntityFacets.mockResolvedValueOnce({
mockCatalogApi.getEntityFacets.mockResolvedValueOnce({
facets: { 'metadata.tags': [{ value: 'tag', count: 1 }] },
});
mockedGetEntitiesByRefs.mockResolvedValueOnce({ items: [] });
mockCatalogApi.getEntitiesByRefs.mockResolvedValueOnce({ items: [] });
const { result } = renderHook(() => useFacetsEntities({ enabled: true }));
result.current[1]({ text: '' });
await waitFor(() => {
@@ -87,8 +79,10 @@ describe('useFacetsEntities', () => {
it(`should return the owners`, async () => {
const entityRefs = ['component:default/e1', 'component:default/e2'];
mockedGetEntityFacets.mockResolvedValue(facetsFromEntityRefs(entityRefs));
mockedGetEntitiesByRefs.mockResolvedValue(
mockCatalogApi.getEntityFacets.mockResolvedValue(
facetsFromEntityRefs(entityRefs),
);
mockCatalogApi.getEntitiesByRefs.mockResolvedValue(
entitiesFromEntityRefs(entityRefs),
);
@@ -152,8 +146,10 @@ describe('useFacetsEntities', () => {
},
};
mockedGetEntityFacets.mockResolvedValue(facetsFromEntityRefs(entityRefs));
mockedGetEntitiesByRefs.mockResolvedValue(
mockCatalogApi.getEntityFacets.mockResolvedValue(
facetsFromEntityRefs(entityRefs),
);
mockCatalogApi.getEntitiesByRefs.mockResolvedValue(
entitiesFromEntityRefs(entityRefs, enrichedEntities),
);
@@ -225,8 +221,10 @@ describe('useFacetsEntities', () => {
'component:default/b',
];
mockedGetEntityFacets.mockResolvedValue(facetsFromEntityRefs(entityRefs));
mockedGetEntitiesByRefs.mockResolvedValue(
mockCatalogApi.getEntityFacets.mockResolvedValue(
facetsFromEntityRefs(entityRefs),
);
mockCatalogApi.getEntitiesByRefs.mockResolvedValue(
entitiesFromEntityRefs(entityRefs),
);
@@ -336,7 +334,9 @@ describe('useFacetsEntities', () => {
'component:default/nade',
];
mockedGetEntityFacets.mockResolvedValue(facetsFromEntityRefs(entityRefs));
mockCatalogApi.getEntityFacets.mockResolvedValue(
facetsFromEntityRefs(entityRefs),
);
const enrichedEntities: { [key: string]: Entity } = {
'group:default/go': {
apiVersion: 'backstage.io/v1beta1',
@@ -352,7 +352,7 @@ describe('useFacetsEntities', () => {
},
},
};
mockedGetEntitiesByRefs.mockResolvedValue(
mockCatalogApi.getEntitiesByRefs.mockResolvedValue(
entitiesFromEntityRefs(entityRefs, enrichedEntities),
);
@@ -13,16 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { renderHook, waitFor } from '@testing-library/react';
import { CatalogApi } from '@backstage/catalog-client';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { useQueryEntities } from './useQueryEntities';
const mockedQueryEntities: jest.MockedFn<CatalogApi['queryEntities']> =
jest.fn();
const mockCatalogApi: Partial<CatalogApi> = {
queryEntities: mockedQueryEntities,
};
const mockCatalogApi = catalogApiMock.mock();
jest.mock('@backstage/core-plugin-api', () => ({
...jest.requireActual('@backstage/core-plugin-api'),
@@ -35,18 +31,18 @@ describe('useQueryEntities', () => {
});
it(`should not invoke queryEntities on mount`, () => {
mockedQueryEntities.mockResolvedValue({
mockCatalogApi.queryEntities.mockResolvedValue({
items: [],
pageInfo: {},
totalItems: 0,
});
renderHook(() => useQueryEntities());
expect(mockedQueryEntities).not.toHaveBeenCalled();
expect(mockCatalogApi.queryEntities).not.toHaveBeenCalled();
});
it(`should fetch the data accordingly`, async () => {
mockedQueryEntities
mockCatalogApi.queryEntities
.mockResolvedValueOnce({
items: [
{ apiVersion: '1', kind: 'kind', metadata: { name: 'name-1' } },
@@ -74,7 +70,7 @@ describe('useQueryEntities', () => {
cursor: 'next',
}),
);
expect(mockedQueryEntities).toHaveBeenCalledWith({
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
filter: { kind: ['User', 'Group'] },
fullTextFilter: {
fields: [
@@ -98,7 +94,7 @@ describe('useQueryEntities', () => {
],
}),
);
expect(mockedQueryEntities).toHaveBeenCalledWith({
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
cursor: 'next',
limit: 20,
});
@@ -24,15 +24,16 @@ import { wrapInTestApp, TestApiProvider } from '@backstage/test-utils';
import { catalogApiRef } from '../../api';
import {
CompoundEntityRef,
Entity,
parseEntityRef,
stringifyEntityRef,
} from '@backstage/catalog-model';
import { entityRouteRef } from '../../routes';
import { CatalogApi } from '@backstage/catalog-client';
import { Table, TableColumn } from '@backstage/core-components';
import { EntityRefLink } from '../EntityRefLink';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
const mockCatalogApi = {
const mockCatalogApi = catalogApiMock.mock({
getEntityByRef: async (entityRef: string) => {
if (entityRef === 'component:default/playback') {
return {
@@ -42,7 +43,7 @@ const mockCatalogApi = {
namespace: 'default',
description: 'Details about the playback service',
},
};
} as unknown as Entity;
}
if (entityRef === 'user:default/fname.lname') {
return {
@@ -56,7 +57,7 @@ const mockCatalogApi = {
email: 'fname.lname@example.com',
},
},
};
} as unknown as Entity;
}
if (entityRef === 'component:default/slow.catalog.item') {
await new Promise(resolve => setTimeout(resolve, 3000));
@@ -67,11 +68,11 @@ const mockCatalogApi = {
namespace: 'default',
description: 'Details about the slow.catalog.item service',
},
};
} as unknown as Entity;
}
return undefined;
},
};
});
const defaultArgs = {
entityRef: 'component:default/playback',
@@ -83,9 +84,7 @@ export default {
(Story: ComponentType<PropsWithChildren<{}>>) =>
wrapInTestApp(
<>
<TestApiProvider
apis={[[catalogApiRef, mockCatalogApi as any as CatalogApi]]}
>
<TestApiProvider apis={[[catalogApiRef, mockCatalogApi]]}>
<Story />
</TestApiProvider>
</>,
@@ -20,30 +20,26 @@ import React from 'react';
import { EntityPeekAheadPopover } from './EntityPeekAheadPopover';
import { ApiProvider } from '@backstage/core-app-api';
import { TestApiRegistry, renderInTestApp } from '@backstage/test-utils';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { catalogApiRef } from '../../api';
import { Entity } from '@backstage/catalog-model';
import { CatalogApi } from '@backstage/catalog-client';
import Button from '@material-ui/core/Button';
import { entityRouteRef } from '../../routes';
const catalogApi: Partial<CatalogApi> = {
getEntityByRef: async (entityRef: string): Promise<Entity | undefined> => {
if (entityRef === 'component:default/service1') {
return {
apiVersion: '',
kind: 'Component',
metadata: {
namespace: 'default',
name: 'service1',
},
spec: {
tags: ['java'],
},
};
}
return undefined;
},
};
const catalogApi = catalogApiMock({
entities: [
{
apiVersion: '',
kind: 'Component',
metadata: {
namespace: 'default',
name: 'service1',
},
spec: {
tags: ['java'],
},
},
],
});
const apis = TestApiRegistry.from([catalogApiRef, catalogApi]);
@@ -16,27 +16,29 @@
import { fireEvent, waitFor, screen, act } from '@testing-library/react';
import React from 'react';
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
import {
MockEntityListContextProvider,
catalogApiMock,
} from '@backstage/plugin-catalog-react/testUtils';
import { EntityTagFilter } from '../../filters';
import { EntityTagPicker } from './EntityTagPicker';
import { TestApiProvider, renderInTestApp } from '@backstage/test-utils';
import { catalogApiRef } from '../../api';
import { CatalogApi } from '@backstage/catalog-client';
const tags = ['tag1', 'tag2', 'tag3', 'tag4'];
describe('<EntityTagPicker/>', () => {
const mockCatalogApiRef = {
const catalogApi = catalogApiMock.mock({
getEntityFacets: async () => ({
facets: {
'metadata.tags': tags.map((value, idx) => ({ value, count: idx })),
},
}),
} as unknown as CatalogApi;
});
it('renders all tags', async () => {
await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
<MockEntityListContextProvider value={{}}>
<EntityTagPicker />
</MockEntityListContextProvider>
@@ -52,7 +54,7 @@ describe('<EntityTagPicker/>', () => {
it('renders unique tags in alphabetical order', async () => {
await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
<MockEntityListContextProvider value={{}}>
<EntityTagPicker />
</MockEntityListContextProvider>
@@ -72,7 +74,7 @@ describe('<EntityTagPicker/>', () => {
it('renders tags with counts', async () => {
await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
<MockEntityListContextProvider value={{}}>
<EntityTagPicker showCounts />
</MockEntityListContextProvider>
@@ -94,7 +96,7 @@ describe('<EntityTagPicker/>', () => {
const updateFilters = jest.fn();
const queryParameters = { tags: ['tag3'] };
await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
<MockEntityListContextProvider
value={{
updateFilters,
@@ -116,7 +118,7 @@ describe('<EntityTagPicker/>', () => {
it('adds tags to filters', async () => {
const updateFilters = jest.fn();
await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
<MockEntityListContextProvider
value={{
updateFilters,
@@ -140,7 +142,7 @@ describe('<EntityTagPicker/>', () => {
it('removes tags from filters', async () => {
const updateFilters = jest.fn();
await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
<MockEntityListContextProvider
value={{
updateFilters,
@@ -168,7 +170,7 @@ describe('<EntityTagPicker/>', () => {
it('responds to external queryParameters changes', async () => {
const updateFilters = jest.fn();
const rendered = await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
<MockEntityListContextProvider
value={{
updateFilters,
@@ -185,7 +187,7 @@ describe('<EntityTagPicker/>', () => {
}),
);
rendered.rerender(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
<MockEntityListContextProvider
value={{
updateFilters,
@@ -204,7 +206,7 @@ describe('<EntityTagPicker/>', () => {
it('verify that user can select tags after query string has been set', async () => {
const updateFilters = jest.fn();
await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
<MockEntityListContextProvider
value={{
updateFilters,
@@ -233,13 +235,11 @@ describe('<EntityTagPicker/>', () => {
it('removes tags from filters if there are none available', async () => {
const updateFilters = jest.fn();
const mockCatalogApiRefNoTags = {
const mockCatalogApiRefNoTags = catalogApiMock.mock({
getEntityFacets: async () => ({
facets: {
'metadata.tags': {},
},
facets: {},
}),
} as unknown as CatalogApi;
});
await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRefNoTags]]}>
@@ -20,25 +20,15 @@ import userEvent from '@testing-library/user-event';
import React from 'react';
import { UnregisterEntityDialog } from './UnregisterEntityDialog';
import { ANNOTATION_ORIGIN_LOCATION } from '@backstage/catalog-model';
import { CatalogClient } from '@backstage/catalog-client';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { catalogApiRef } from '../../api';
import { entityRouteRef } from '../../routes';
import { screen, waitFor } from '@testing-library/react';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import * as state from './useUnregisterEntityDialogState';
import {
AlertApi,
alertApiRef,
DiscoveryApi,
} from '@backstage/core-plugin-api';
import { AlertApi, alertApiRef } from '@backstage/core-plugin-api';
describe('UnregisterEntityDialog', () => {
const discoveryApi: DiscoveryApi = {
async getBaseUrl(pluginId) {
return `http://example.com/${pluginId}`;
},
};
const alertApi: AlertApi = {
post() {
return undefined;
@@ -68,7 +58,7 @@ describe('UnregisterEntityDialog', () => {
const Wrapper = (props: { children?: React.ReactNode }) => (
<TestApiProvider
apis={[
[catalogApiRef, new CatalogClient({ discoveryApi })],
[catalogApiRef, catalogApiMock()],
[alertApiRef, alertApi],
]}
>
@@ -18,7 +18,10 @@ 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 '@backstage/plugin-catalog-react/testUtils';
import {
MockEntityListContextProvider,
catalogApiMock,
} from '@backstage/plugin-catalog-react/testUtils';
import {
EntityKindFilter,
EntityNamespaceFilter,
@@ -62,10 +65,7 @@ const mockConfigApi = {
getOptionalString: () => 'Test Company',
} as Partial<ConfigApi>;
const mockCatalogApi = {
getEntityByRef: jest.fn(),
queryEntities: jest.fn(),
} as Partial<jest.Mocked<CatalogApi>>;
const mockCatalogApi = catalogApiMock.mock();
const mockIdentityApi = {
getBackstageIdentity: jest.fn(),
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import React, { PropsWithChildren } from 'react';
import { CatalogApi } from '@backstage/catalog-client';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { useAllEntitiesCount } from './useAllEntitiesCount';
import { renderHook, waitFor } from '@testing-library/react';
import { EntityListProvider, useEntityList } from '../../hooks';
@@ -24,10 +24,7 @@ import { MemoryRouter } from 'react-router-dom';
import { EntityOwnerFilter } from '../../filters';
import { useMountEffect } from '@react-hookz/web';
const mockQueryEntities: jest.MockedFn<CatalogApi['queryEntities']> = jest.fn();
const mockCatalogApi: jest.Mocked<Partial<CatalogApi>> = {
queryEntities: mockQueryEntities,
};
const mockCatalogApi = catalogApiMock.mock();
jest.mock('@backstage/core-plugin-api', () => {
const actual = jest.requireActual('@backstage/core-plugin-api');
@@ -44,7 +41,7 @@ describe('useAllEntitiesCount', () => {
});
it('should return the count', async () => {
mockQueryEntities.mockResolvedValue({
mockCatalogApi.queryEntities.mockResolvedValue({
items: [],
totalItems: 10,
pageInfo: {},
@@ -72,7 +69,7 @@ describe('useAllEntitiesCount', () => {
});
await waitFor(() =>
expect(mockQueryEntities).toHaveBeenCalledWith({
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
filter: {
'relations.ownedBy': ['user:default/owner'],
},
@@ -83,7 +80,7 @@ describe('useAllEntitiesCount', () => {
});
it(`shouldn't invoke the endpoint at startup, when filters are missing`, async () => {
mockQueryEntities.mockResolvedValue({
mockCatalogApi.queryEntities.mockResolvedValue({
items: [],
totalItems: 10,
pageInfo: {},
@@ -98,7 +95,7 @@ describe('useAllEntitiesCount', () => {
});
await expect(
waitFor(() => expect(mockQueryEntities).toHaveBeenCalled()),
waitFor(() => expect(mockCatalogApi.queryEntities).toHaveBeenCalled()),
).rejects.toThrow();
expect(result.current).toEqual({ count: 0, loading: false });
});
@@ -13,8 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { PropsWithChildren } from 'react';
import { CatalogApi } from '@backstage/catalog-client';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { renderHook, waitFor } from '@testing-library/react';
import {
DefaultEntityFilters,
@@ -36,10 +37,7 @@ import {
} from '../../filters';
import { useMountEffect } from '@react-hookz/web';
const mockQueryEntities: jest.MockedFn<CatalogApi['queryEntities']> = jest.fn();
const mockCatalogApi: jest.Mocked<Partial<CatalogApi>> = {
queryEntities: mockQueryEntities,
};
const mockCatalogApi = catalogApiMock.mock();
const mockGetBackstageIdentity: jest.MockedFn<
IdentityApi['getBackstageIdentity']
@@ -76,7 +74,7 @@ describe('useOwnedEntitiesCount', () => {
});
it(`shouldn't invoke queryEntities when filters are loading`, async () => {
mockQueryEntities.mockResolvedValue({
mockCatalogApi.queryEntities.mockResolvedValue({
items: [],
totalItems: 10,
pageInfo: {},
@@ -89,7 +87,7 @@ describe('useOwnedEntitiesCount', () => {
await waitFor(() => expect(mockGetBackstageIdentity).toHaveBeenCalled());
await expect(
waitFor(() => expect(mockQueryEntities).toHaveBeenCalled()),
waitFor(() => expect(mockCatalogApi.queryEntities).toHaveBeenCalled()),
).rejects.toThrow();
expect(result.current).toEqual({
@@ -104,7 +102,7 @@ describe('useOwnedEntitiesCount', () => {
});
it(`should properly apply the filters`, async () => {
mockQueryEntities.mockResolvedValue({
mockCatalogApi.queryEntities.mockResolvedValue({
items: [],
totalItems: 10,
pageInfo: {},
@@ -119,7 +117,7 @@ describe('useOwnedEntitiesCount', () => {
await waitFor(() => expect(mockGetBackstageIdentity).toHaveBeenCalled());
await waitFor(() =>
expect(mockQueryEntities).toHaveBeenCalledWith({
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
filter: {
'metadata.namespace': ['a-namespace'],
'relations.ownedBy': ['user:default/spiderman', 'user:group/a-group'],
@@ -140,7 +138,7 @@ describe('useOwnedEntitiesCount', () => {
});
it(`should return count 0 without invoking queryEntities if owners filter doesn't have claims in common with logged in user`, async () => {
mockQueryEntities.mockResolvedValue({
mockCatalogApi.queryEntities.mockResolvedValue({
items: [],
totalItems: 10,
pageInfo: {},
@@ -156,7 +154,7 @@ describe('useOwnedEntitiesCount', () => {
await waitFor(() => expect(mockGetBackstageIdentity).toHaveBeenCalled());
await expect(
waitFor(() => expect(mockQueryEntities).toHaveBeenCalled()),
waitFor(() => expect(mockCatalogApi.queryEntities).toHaveBeenCalled()),
).rejects.toThrow();
expect(result.current).toEqual({
@@ -171,7 +169,7 @@ describe('useOwnedEntitiesCount', () => {
});
it(`should send claims in common between owners filter and logged in user`, async () => {
mockQueryEntities.mockResolvedValue({
mockCatalogApi.queryEntities.mockResolvedValue({
items: [],
totalItems: 10,
pageInfo: {},
@@ -190,7 +188,7 @@ describe('useOwnedEntitiesCount', () => {
await waitFor(() => expect(mockGetBackstageIdentity).toHaveBeenCalled());
await waitFor(() =>
expect(mockQueryEntities).toHaveBeenCalledWith({
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
filter: {
'metadata.namespace': ['a-namespace'],
'relations.ownedBy': ['user:group/a-group'],
@@ -13,8 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import { CatalogApi } from '@backstage/catalog-client';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { EntityListProvider, useStarredEntities } from '../../hooks';
import { catalogApiRef } from '../../api';
import { ApiRef } from '@backstage/core-plugin-api';
@@ -22,10 +23,7 @@ import { MemoryRouter } from 'react-router-dom';
import { useStarredEntitiesCount } from './useStarredEntitiesCount';
import { renderHook, waitFor } from '@testing-library/react';
const mockQueryEntities: jest.MockedFn<CatalogApi['queryEntities']> = jest.fn();
const mockCatalogApi: jest.Mocked<Partial<CatalogApi>> = {
queryEntities: mockQueryEntities,
};
const mockCatalogApi = catalogApiMock.mock();
const mockStarredEntities: jest.MockedFn<() => Set<string>> = jest.fn();
@@ -58,7 +56,7 @@ describe('useStarredEntitiesCount', () => {
mockStarredEntities.mockReturnValue(
new Set(['component:default/favourite1', 'component:default/favourite2']),
);
mockQueryEntities.mockResolvedValue({
mockCatalogApi.queryEntities.mockResolvedValue({
items: [
{
apiVersion: '1',
@@ -84,7 +82,7 @@ describe('useStarredEntitiesCount', () => {
});
await waitFor(() => {
expect(mockQueryEntities).toHaveBeenCalledWith({
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
filter: {
'metadata.name': ['favourite1', 'favourite2'],
},
@@ -116,7 +114,7 @@ describe('useStarredEntitiesCount', () => {
});
await expect(
waitFor(() => expect(mockQueryEntities).toHaveBeenCalled()),
waitFor(() => expect(mockCatalogApi.queryEntities).toHaveBeenCalled()),
).rejects.toThrow();
expect(result.current).toEqual({
count: 0,
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { CatalogApi } from '@backstage/catalog-client';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { Entity } from '@backstage/catalog-model';
import {
alertApiRef,
@@ -81,7 +81,7 @@ const mockIdentityApi: Partial<IdentityApi> = {
}),
getCredentials: async () => ({ token: undefined }),
};
const mockCatalogApi: Partial<jest.Mocked<CatalogApi>> = {
const mockCatalogApi = catalogApiMock.mock({
getEntities: jest.fn().mockResolvedValue({ items: entities }),
queryEntities: jest.fn().mockResolvedValue({
items: entities,
@@ -89,7 +89,7 @@ const mockCatalogApi: Partial<jest.Mocked<CatalogApi>> = {
totalItems: 10,
}),
getEntityByRef: jest.fn().mockResolvedValue(undefined),
};
});
const createWrapper =
(options: { location?: string; pagination: EntityListPagination }) =>
@@ -14,36 +14,24 @@
* limitations under the License.
*/
import { CatalogApi } from '@backstage/catalog-client';
import { ComponentEntity, RELATION_OWNED_BY } from '@backstage/catalog-model';
import { IdentityApi, identityApiRef } from '@backstage/core-plugin-api';
import { TestApiProvider } from '@backstage/test-utils';
import { renderHook, waitFor } from '@testing-library/react';
import React from 'react';
import { catalogApiRef } from '../api';
import { useEntityOwnership } from './useEntityOwnership';
describe('useEntityOwnership', () => {
type MockIdentityApi = jest.Mocked<Pick<IdentityApi, 'getBackstageIdentity'>>;
type MockCatalogApi = jest.Mocked<Pick<CatalogApi, 'getEntityByRef'>>;
const mockIdentityApi: MockIdentityApi = {
getBackstageIdentity: jest.fn(),
};
const mockCatalogApi: MockCatalogApi = {
getEntityByRef: jest.fn(),
};
const identityApi = mockIdentityApi as unknown as IdentityApi;
const catalogApi = mockCatalogApi as unknown as CatalogApi;
const Wrapper = (props: { children?: React.ReactNode }) => (
<TestApiProvider
apis={[
[identityApiRef, identityApi],
[catalogApiRef, catalogApi],
]}
>
<TestApiProvider apis={[[identityApiRef, identityApi]]}>
{props.children}
</TestApiProvider>
);
@@ -81,7 +69,6 @@ describe('useEntityOwnership', () => {
userEntityRef: 'user:default/user1',
ownershipEntityRefs: ['user:default/user1', 'group:default/group1'],
});
mockCatalogApi.getEntityByRef.mockResolvedValue(undefined);
const { result } = renderHook(() => useEntityOwnership(), {
wrapper: Wrapper,
@@ -14,13 +14,13 @@
* limitations under the License.
*/
import { CatalogApi } from '@backstage/catalog-client';
import { Entity } from '@backstage/catalog-model';
import {
EntityRefPresentation,
EntityRefPresentationSnapshot,
} from '@backstage/plugin-catalog-react';
import { DefaultEntityPresentationApi } from './DefaultEntityPresentationApi';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
describe('DefaultEntityPresentationApi', () => {
it('works in local mode', async () => {
@@ -99,12 +99,8 @@ describe('DefaultEntityPresentationApi', () => {
});
it('works in catalog mode', async () => {
const catalogApi = {
getEntitiesByRefs: jest.fn(),
};
const api = DefaultEntityPresentationApi.create({
catalogApi: catalogApi as Partial<CatalogApi> as any,
});
const catalogApi = catalogApiMock.mock();
const api = DefaultEntityPresentationApi.create({ catalogApi });
catalogApi.getEntitiesByRefs.mockResolvedValueOnce({
items: [
@@ -15,11 +15,11 @@
*/
import {
CatalogApi,
EntityProvider,
catalogApiRef,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import {
ScmIntegrationsApi,
scmIntegrationsApiRef,
@@ -42,16 +42,7 @@ const mockAuthorize = jest.fn();
const mockPermissionApi = { authorize: mockAuthorize };
describe('<AboutCard />', () => {
const catalogApi: jest.Mocked<CatalogApi> = {
getLocationById: jest.fn(),
getEntityByName: jest.fn(),
getEntityByRef: jest.fn(),
getEntities: jest.fn(),
addLocation: jest.fn(),
getLocationByRef: jest.fn(),
removeEntityByUid: jest.fn(),
refreshEntity: jest.fn(),
} as any;
const catalogApi = catalogApiMock.mock();
beforeEach(() => {
jest.clearAllMocks();
@@ -14,10 +14,7 @@
* limitations under the License.
*/
import {
CatalogApi,
QueryEntitiesInitialRequest,
} from '@backstage/catalog-client';
import { QueryEntitiesInitialRequest } from '@backstage/catalog-client';
import { RELATION_OWNED_BY } from '@backstage/catalog-model';
import { TableColumn, TableProps } from '@backstage/core-components';
import {
@@ -48,6 +45,7 @@ import { DefaultCatalogPage } from './DefaultCatalogPage';
import { CatalogTableColumnsFunc } from '../CatalogTable/types';
import { permissionApiRef } from '@backstage/plugin-permission-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
describe('DefaultCatalogPage', () => {
const origReplaceState = window.history.replaceState;
@@ -60,7 +58,7 @@ describe('DefaultCatalogPage', () => {
jest.clearAllMocks();
});
const catalogApi: jest.Mocked<Partial<CatalogApi>> = {
const catalogApi = catalogApiMock.mock({
getEntities: jest.fn().mockImplementation(() =>
Promise.resolve({
items: [
@@ -166,7 +164,7 @@ describe('DefaultCatalogPage', () => {
// all items
return { items: [], totalItems: 2, pageInfo: {} };
}),
};
});
const testProfile: Partial<ProfileInfo> = {
displayName: 'Display Name',
@@ -16,25 +16,23 @@
import { Entity, RELATION_DEPENDENCY_OF } from '@backstage/catalog-model';
import {
CatalogApi,
catalogApiRef,
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { screen, waitFor } from '@testing-library/react';
import React from 'react';
import { DependencyOfComponentsCard } from './DependencyOfComponentsCard';
describe('<DependencyOfComponentsCard />', () => {
const getEntitiesByRefs: jest.MockedFunction<
CatalogApi['getEntitiesByRefs']
> = jest.fn();
const catalogApi = catalogApiMock.mock();
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
beforeEach(() => {
Wrapper = ({ children }: { children?: React.ReactNode }) => (
<TestApiProvider apis={[[catalogApiRef, { getEntitiesByRefs }]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
{children}
</TestApiProvider>
);
@@ -87,7 +85,7 @@ describe('<DependencyOfComponentsCard />', () => {
},
],
};
getEntitiesByRefs.mockResolvedValue({
catalogApi.getEntitiesByRefs.mockResolvedValue({
items: [
{
apiVersion: 'v1',
@@ -16,25 +16,23 @@
import { Entity, RELATION_DEPENDS_ON } from '@backstage/catalog-model';
import {
CatalogApi,
catalogApiRef,
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor, screen } from '@testing-library/react';
import React from 'react';
import { DependsOnComponentsCard } from './DependsOnComponentsCard';
describe('<DependsOnComponentsCard />', () => {
const getEntitiesByRefs: jest.MockedFunction<
CatalogApi['getEntitiesByRefs']
> = jest.fn();
const catalogApi = catalogApiMock.mock();
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
beforeEach(() => {
Wrapper = ({ children }: { children?: React.ReactNode }) => (
<TestApiProvider apis={[[catalogApiRef, { getEntitiesByRefs }]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
{children}
</TestApiProvider>
);
@@ -87,7 +85,7 @@ describe('<DependsOnComponentsCard />', () => {
},
],
};
getEntitiesByRefs.mockResolvedValue({
catalogApi.getEntitiesByRefs.mockResolvedValue({
items: [
{
apiVersion: 'v1',
@@ -16,25 +16,23 @@
import { Entity, RELATION_DEPENDS_ON } from '@backstage/catalog-model';
import {
CatalogApi,
catalogApiRef,
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor, screen } from '@testing-library/react';
import React from 'react';
import { DependsOnResourcesCard } from './DependsOnResourcesCard';
describe('<DependsOnResourcesCard />', () => {
const getEntitiesByRefs: jest.MockedFunction<
CatalogApi['getEntitiesByRefs']
> = jest.fn();
const catalogApi = catalogApiMock.mock();
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
beforeEach(() => {
Wrapper = ({ children }: { children?: React.ReactNode }) => (
<TestApiProvider apis={[[catalogApiRef, { getEntitiesByRefs }]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
{children}
</TestApiProvider>
);
@@ -87,7 +85,7 @@ describe('<DependsOnResourcesCard />', () => {
},
],
};
getEntitiesByRefs.mockResolvedValue({
catalogApi.getEntitiesByRefs.mockResolvedValue({
items: [
{
apiVersion: 'v1',
@@ -14,7 +14,6 @@
* limitations under the License.
*/
import { CatalogApi } from '@backstage/catalog-client';
import {
ANNOTATION_ORIGIN_LOCATION,
Entity,
@@ -30,6 +29,7 @@ import {
starredEntitiesApiRef,
MockStarredEntitiesApi,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { permissionApiRef } from '@backstage/plugin-permission-react';
import {
MockPermissionApi,
@@ -52,7 +52,7 @@ describe('EntityLayout', () => {
} as Entity;
const mockApis = TestApiRegistry.from(
[catalogApiRef, {} as CatalogApi],
[catalogApiRef, catalogApiMock()],
[alertApiRef, {} as AlertApi],
[starredEntitiesApiRef, new MockStarredEntitiesApi()],
[permissionApiRef, new MockPermissionApi()],
@@ -302,20 +302,13 @@ describe('EntityLayout - CleanUpAfterRemoval', () => {
},
],
};
const getLocationByRef: jest.MockedFunction<CatalogApi['getLocationByRef']> =
jest.fn();
const getEntities: jest.MockedFunction<CatalogApi['getEntities']> = jest.fn();
const removeEntityByUid: jest.MockedFunction<
CatalogApi['removeEntityByUid']
> = jest.fn();
const getEntityFacets: jest.MockedFunction<CatalogApi['getEntityFacets']> =
jest.fn();
getLocationByRef.mockResolvedValue(undefined);
getEntities.mockResolvedValue({ items: [{ ...entity }] });
getEntityFacets.mockResolvedValue({
facets: {
'relations.ownedBy': [{ count: 1, value: 'group:default/tools' }],
},
const catalogApi = catalogApiMock.mock({
getEntities: async () => ({ items: [{ ...entity }] }),
getEntityFacets: async () => ({
facets: {
'relations.ownedBy': [{ count: 1, value: 'group:default/tools' }],
},
}),
});
const alertApi: AlertApi = {
@@ -331,15 +324,7 @@ describe('EntityLayout - CleanUpAfterRemoval', () => {
await renderInTestApp(
<TestApiProvider
apis={[
[
catalogApiRef,
{
getLocationByRef,
getEntities,
removeEntityByUid,
getEntityFacets,
},
],
[catalogApiRef, catalogApi],
[alertApiRef, alertApi],
[starredEntitiesApiRef, new MockStarredEntitiesApi()],
[permissionApiRef, new MockPermissionApi()],
@@ -390,15 +375,7 @@ describe('EntityLayout - CleanUpAfterRemoval', () => {
await renderInTestApp(
<TestApiProvider
apis={[
[
catalogApiRef,
{
getLocationByRef,
getEntities,
removeEntityByUid,
getEntityFacets,
},
],
[catalogApiRef, catalogApi],
[alertApiRef, alertApi],
[starredEntitiesApiRef, new MockStarredEntitiesApi()],
[permissionApiRef, new MockPermissionApi()],
@@ -18,7 +18,7 @@ import userEvent from '@testing-library/user-event';
import React from 'react';
import { DeleteEntityDialog } from './DeleteEntityDialog';
import { ANNOTATION_ORIGIN_LOCATION } from '@backstage/catalog-model';
import { CatalogApi } from '@backstage/catalog-client';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { catalogApiRef } from '@backstage/plugin-catalog-react';
import { screen, waitFor } from '@testing-library/react';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
@@ -30,9 +30,7 @@ describe('DeleteEntityDialog', () => {
alert$: jest.fn(),
};
const catalogClient: jest.Mocked<CatalogApi> = {
removeEntityByUid: jest.fn(),
} as any;
const catalogClient = catalogApiMock.mock();
const entity = {
apiVersion: 'backstage.io/v1alpha1',
@@ -18,21 +18,19 @@ import { AlphaEntity } from '@backstage/catalog-model/alpha';
import { stringifyEntityRef } from '@backstage/catalog-model';
import { ApiProvider } from '@backstage/core-app-api';
import {
CatalogApi,
catalogApiRef,
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
import { screen } from '@testing-library/react';
import React from 'react';
import { EntityProcessingErrorsPanel } from './EntityProcessingErrorsPanel';
describe('<EntityProcessErrors />', () => {
const getEntityAncestors: jest.MockedFunction<
CatalogApi['getEntityAncestors']
> = jest.fn();
const apis = TestApiRegistry.from([catalogApiRef, { getEntityAncestors }]);
const catalogApi = catalogApiMock.mock();
const apis = TestApiRegistry.from([catalogApiRef, catalogApi]);
it('renders EntityProcessErrors if the entity has errors', async () => {
const entity: AlphaEntity = {
@@ -98,7 +96,7 @@ describe('<EntityProcessErrors />', () => {
},
};
getEntityAncestors.mockResolvedValue({
catalogApi.getEntityAncestors.mockResolvedValue({
rootEntityRef: stringifyEntityRef(entity),
items: [{ entity, parentEntityRefs: [] }],
});
@@ -199,7 +197,7 @@ describe('<EntityProcessErrors />', () => {
],
},
};
getEntityAncestors.mockResolvedValue({
catalogApi.getEntityAncestors.mockResolvedValue({
rootEntityRef: stringifyEntityRef(entity),
items: [
{ entity, parentEntityRefs: [stringifyEntityRef(parent)] },
@@ -16,11 +16,8 @@
import { Entity } from '@backstage/catalog-model';
import { ApiProvider } from '@backstage/core-app-api';
import {
CatalogApi,
catalogApiRef,
EntityProvider,
} from '@backstage/plugin-catalog-react';
import { catalogApiRef, EntityProvider } from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
import { screen } from '@testing-library/react';
import React from 'react';
@@ -30,10 +27,8 @@ import {
} from './EntityRelationWarning';
describe('<EntityRelationWarning />', () => {
const getEntitiesByRefs: jest.MockedFunction<
CatalogApi['getEntitiesByRefs']
> = jest.fn();
const apis = TestApiRegistry.from([catalogApiRef, { getEntitiesByRefs }]);
const catalogApi = catalogApiMock.mock();
const apis = TestApiRegistry.from([catalogApiRef, catalogApi]);
const entityExisting: Entity = {
apiVersion: 'v1',
@@ -62,7 +57,7 @@ describe('<EntityRelationWarning />', () => {
],
};
getEntitiesByRefs.mockResolvedValue({
catalogApi.getEntitiesByRefs.mockResolvedValue({
items: [undefined, entityExisting],
});
await renderInTestApp(
@@ -102,7 +97,7 @@ describe('<EntityRelationWarning />', () => {
],
};
getEntitiesByRefs.mockResolvedValue({
catalogApi.getEntitiesByRefs.mockResolvedValue({
items: [entityExisting],
});
await renderInTestApp(
@@ -141,7 +136,7 @@ describe('<EntityRelationWarning />', () => {
],
};
getEntitiesByRefs.mockResolvedValue({
catalogApi.getEntitiesByRefs.mockResolvedValue({
items: [undefined, entityExisting],
});
@@ -165,7 +160,7 @@ describe('<EntityRelationWarning />', () => {
],
};
getEntitiesByRefs.mockResolvedValue({
catalogApi.getEntitiesByRefs.mockResolvedValue({
items: [entityExisting],
});
@@ -16,7 +16,6 @@
import { Entity, RELATION_HAS_PART } from '@backstage/catalog-model';
import {
CatalogApi,
catalogApiRef,
EntityProvider,
entityRouteRef,
@@ -25,16 +24,15 @@ import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor, screen } from '@testing-library/react';
import React from 'react';
import { HasComponentsCard } from './HasComponentsCard';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
describe('<HasComponentsCard />', () => {
const getEntitiesByRefs: jest.MockedFunction<
CatalogApi['getEntitiesByRefs']
> = jest.fn();
const catalogApi = catalogApiMock.mock();
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
beforeEach(() => {
Wrapper = ({ children }: { children?: React.ReactNode }) => (
<TestApiProvider apis={[[catalogApiRef, { getEntitiesByRefs }]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
{children}
</TestApiProvider>
);
@@ -87,7 +85,7 @@ describe('<HasComponentsCard />', () => {
},
],
};
getEntitiesByRefs.mockResolvedValue({
catalogApi.getEntitiesByRefs.mockResolvedValue({
items: [
{
apiVersion: 'v1',
@@ -16,25 +16,23 @@
import { Entity, RELATION_HAS_PART } from '@backstage/catalog-model';
import {
CatalogApi,
catalogApiRef,
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor, screen } from '@testing-library/react';
import React from 'react';
import { HasResourcesCard } from './HasResourcesCard';
describe('<HasResourcesCard />', () => {
const getEntitiesByRefs: jest.MockedFunction<
CatalogApi['getEntitiesByRefs']
> = jest.fn();
const catalogApi = catalogApiMock.mock();
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
beforeEach(() => {
Wrapper = ({ children }: { children?: React.ReactNode }) => (
<TestApiProvider apis={[[catalogApiRef, { getEntitiesByRefs }]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
{children}
</TestApiProvider>
);
@@ -82,7 +80,7 @@ describe('<HasResourcesCard />', () => {
},
],
};
getEntitiesByRefs.mockResolvedValue({
catalogApi.getEntitiesByRefs.mockResolvedValue({
items: [
{
apiVersion: 'v1',
@@ -16,25 +16,23 @@
import { Entity, RELATION_HAS_PART } from '@backstage/catalog-model';
import {
CatalogApi,
catalogApiRef,
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor, screen } from '@testing-library/react';
import React from 'react';
import { HasSubcomponentsCard } from './HasSubcomponentsCard';
describe('<HasSubcomponentsCard />', () => {
const getEntitiesByRefs: jest.MockedFunction<
CatalogApi['getEntitiesByRefs']
> = jest.fn();
const catalogApi = catalogApiMock.mock();
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
beforeEach(() => {
Wrapper = ({ children }: { children?: React.ReactNode }) => (
<TestApiProvider apis={[[catalogApiRef, { getEntitiesByRefs }]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
{children}
</TestApiProvider>
);
@@ -87,7 +85,7 @@ describe('<HasSubcomponentsCard />', () => {
},
],
};
getEntitiesByRefs.mockResolvedValue({
catalogApi.getEntitiesByRefs.mockResolvedValue({
items: [
{
apiVersion: 'v1',
@@ -16,25 +16,23 @@
import { Entity, RELATION_HAS_PART } from '@backstage/catalog-model';
import {
CatalogApi,
catalogApiRef,
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor, screen } from '@testing-library/react';
import React from 'react';
import { HasSubdomainsCard } from './HasSubdomainsCard';
describe('<HasSubdomainsCard />', () => {
const getEntitiesByRefs: jest.MockedFunction<
CatalogApi['getEntitiesByRefs']
> = jest.fn();
const catalogApi = catalogApiMock.mock();
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
beforeEach(() => {
Wrapper = ({ children }: { children?: React.ReactNode }) => (
<TestApiProvider apis={[[catalogApiRef, { getEntitiesByRefs }]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
{children}
</TestApiProvider>
);
@@ -87,7 +85,7 @@ describe('<HasSubdomainsCard />', () => {
},
],
};
getEntitiesByRefs.mockResolvedValue({
catalogApi.getEntitiesByRefs.mockResolvedValue({
items: [
{
apiVersion: 'v1',
@@ -16,25 +16,23 @@
import { Entity, RELATION_HAS_PART } from '@backstage/catalog-model';
import {
CatalogApi,
catalogApiRef,
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor, screen } from '@testing-library/react';
import React from 'react';
import { HasSystemsCard } from './HasSystemsCard';
describe('<HasSystemsCard />', () => {
const getEntitiesByRefs: jest.MockedFunction<
CatalogApi['getEntitiesByRefs']
> = jest.fn();
const catalogApi = catalogApiMock.mock();
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
beforeEach(() => {
Wrapper = ({ children }: { children?: React.ReactNode }) => (
<TestApiProvider apis={[[catalogApiRef, { getEntitiesByRefs }]]}>
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
{children}
</TestApiProvider>
);
@@ -87,7 +85,7 @@ describe('<HasSystemsCard />', () => {
},
],
};
getEntitiesByRefs.mockResolvedValue({
catalogApi.getEntitiesByRefs.mockResolvedValue({
items: [
{
apiVersion: 'v1',
@@ -16,7 +16,6 @@
import {
catalogApiRef,
CatalogApi,
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
@@ -25,6 +24,7 @@ import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { screen } from '@testing-library/react';
import React from 'react';
import { SystemDiagramCard } from './SystemDiagramCard';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
describe('<SystemDiagramCard />', () => {
beforeAll(() => {
@@ -37,12 +37,7 @@ describe('<SystemDiagramCard />', () => {
afterEach(() => jest.resetAllMocks());
it('shows empty list if no relations', async () => {
const catalogApi: Partial<CatalogApi> = {
getEntities: () =>
Promise.resolve({
items: [] as Entity[],
}),
};
const catalogApi = catalogApiMock();
const entity: Entity = {
apiVersion: 'v1',
@@ -73,26 +68,25 @@ describe('<SystemDiagramCard />', () => {
});
it('shows related systems', async () => {
const catalogApi: Partial<CatalogApi> = {
getEntities: () =>
Promise.resolve({
items: [
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'entity',
namespace: 'namespace',
},
spec: {
owner: 'not-tools@example.com',
type: 'service',
system: 'system',
},
const catalogApi = catalogApiMock.mock({
getEntities: async () => ({
items: [
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'entity',
namespace: 'namespace',
},
] as Entity[],
}),
};
spec: {
owner: 'not-tools@example.com',
type: 'service',
system: 'system',
},
},
],
}),
});
const entity: Entity = {
apiVersion: 'v1',
@@ -128,26 +122,25 @@ describe('<SystemDiagramCard />', () => {
});
it('should truncate long domains, systems or entities', async () => {
const catalogApi: Partial<CatalogApi> = {
getEntities: () =>
Promise.resolve({
items: [
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'alongentitythatshouldgettruncated',
namespace: 'namespace',
},
spec: {
owner: 'not-tools@example.com',
type: 'service',
system: 'system',
},
const catalogApi = catalogApiMock.mock({
getEntities: async () => ({
items: [
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'alongentitythatshouldgettruncated',
namespace: 'namespace',
},
] as Entity[],
}),
};
spec: {
owner: 'not-tools@example.com',
type: 'service',
system: 'system',
},
},
] as Entity[],
}),
});
const entity: Entity = {
apiVersion: 'v1',
@@ -18,6 +18,7 @@ import { Content } from './Content';
import React from 'react';
import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
const docsEntities = [
{
@@ -34,20 +35,14 @@ const docsEntities = [
];
describe('<FeaturedDocsCard />', () => {
const mockCatalogApi = {
getEntities: jest
.fn()
.mockImplementation(async () => ({ items: docsEntities })),
};
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
<TestApiProvider
apis={[[catalogApiRef, catalogApiMock({ entities: docsEntities })]]}
>
{children}
</TestApiProvider>
);
beforeAll(() => {
Wrapper = ({ children }: { children?: React.ReactNode }) => (
<TestApiProvider apis={[[catalogApiRef, mockCatalogApi]]}>
{children}
</TestApiProvider>
);
});
it('should show expected featured doc and title', async () => {
const { getByTestId, getByText } = await renderInTestApp(
<Wrapper>
@@ -18,6 +18,7 @@ import { FeaturedDocsCard } from '../../plugin';
import React, { ComponentType, PropsWithChildren } from 'react';
import { wrapInTestApp, TestApiProvider } from '@backstage/test-utils';
import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import Grid from '@material-ui/core/Grid';
const docsEntities = [
@@ -36,16 +37,14 @@ const docsEntities = [
},
];
const mockCatalogApi = {
getEntities: async () => ({ items: docsEntities }),
};
export default {
title: 'Plugins/Home/Components/FeaturedDocsCard',
decorators: [
(Story: ComponentType<PropsWithChildren<{}>>) =>
wrapInTestApp(
<TestApiProvider apis={[[catalogApiRef, mockCatalogApi]]}>
<TestApiProvider
apis={[[catalogApiRef, catalogApiMock({ entities: docsEntities })]]}
>
<Story />
</TestApiProvider>,
{
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import {
catalogApiRef,
@@ -20,6 +21,7 @@ import {
MockStarredEntitiesApi,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import React from 'react';
import { Content } from './Content';
@@ -48,11 +50,7 @@ describe('StarredEntitiesContent', () => {
mockedApi.toggleStarred('component:default/mock-starred-entity-2');
mockedApi.toggleStarred('component:default/mock-starred-entity-3');
const mockCatalogApi = {
getEntitiesByRefs: jest
.fn()
.mockImplementation(async () => ({ items: entities })),
};
const mockCatalogApi = catalogApiMock({ entities });
const { getByText, queryByText } = await renderInTestApp(
<TestApiProvider
@@ -22,6 +22,7 @@ import {
MockStarredEntitiesApi,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import Grid from '@material-ui/core/Grid';
import React, { ComponentType, PropsWithChildren } from 'react';
@@ -66,9 +67,7 @@ const entities = [
},
];
const mockCatalogApi = {
getEntities: async () => ({ items: entities }),
};
const mockCatalogApi = catalogApiMock({ entities });
export default {
title: 'Plugins/Home/Components/StarredEntities',
@@ -19,10 +19,10 @@ import { render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { ApiProvider } from '@backstage/core-app-api';
import { catalogApiRef } from '@backstage/plugin-catalog-react';
import { CatalogApi } from '@backstage/catalog-client';
import { GroupListPicker } from '../GroupListPicker';
import { GroupEntity } from '@backstage/catalog-model';
import { TestApiRegistry } from '@backstage/test-utils';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
const mockGroups: GroupEntity[] = [
{
@@ -57,9 +57,9 @@ const mockGroups: GroupEntity[] = [
},
];
const mockCatalogApi = {
getEntities: () => Promise.resolve({ items: mockGroups }),
} as Partial<CatalogApi>;
const mockCatalogApi = catalogApiMock.mock({
getEntities: jest.fn(() => Promise.resolve({ items: mockGroups })),
});
const apis = TestApiRegistry.from([catalogApiRef, mockCatalogApi]);
@@ -15,7 +15,6 @@
*/
import {
CatalogApi,
GetEntitiesByRefsRequest,
GetEntitiesRequest,
} from '@backstage/catalog-client';
@@ -25,6 +24,7 @@ import {
GroupEntity,
stringifyEntityRef,
} from '@backstage/catalog-model';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
export const groupA: GroupEntity = {
apiVersion: 'backstage.io/v1alpha1',
@@ -308,7 +308,7 @@ const mockedMembersMapping = new Map<string, Entity[]>([
type Nullable<T> = T | undefined;
export const mockedCatalogApiSupportingGroups: Partial<CatalogApi> = {
export const mockedCatalogApiSupportingGroups = catalogApiMock.mock({
getEntities: async (request?: GetEntitiesRequest) => {
const actualFilter = (request?.filter as Nullable<{
'relations.memberof': string[];
@@ -331,4 +331,4 @@ export const mockedCatalogApiSupportingGroups: Partial<CatalogApi> = {
);
return { items };
},
};
});
@@ -14,9 +14,8 @@
* limitations under the License.
*/
import { Entity, GroupEntity } from '@backstage/catalog-model';
import { GroupEntity } from '@backstage/catalog-model';
import {
CatalogApi,
catalogApiRef,
EntityProvider,
entityRouteRef,
@@ -35,6 +34,7 @@ import { EntityLayout, catalogPlugin } from '@backstage/plugin-catalog';
import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Observable } from '@backstage/types';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
const mockedStarredEntitiesApi: Partial<StarredEntitiesApi> = {
starredEntitie$: () => {
@@ -68,38 +68,36 @@ describe('MemberTab Test', () => {
},
};
const catalogApi: Partial<CatalogApi> = {
getEntities: () =>
Promise.resolve({
items: [
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'User',
metadata: {
name: 'tara.macgovern',
namespace: 'foo-bar',
uid: 'a5gerth56',
description: 'Super Awesome Developer',
},
relations: [
{
type: 'memberOf',
targetRef: 'group:default/team-d',
},
],
spec: {
profile: {
displayName: 'Tara MacGovern',
email: 'tara-macgovern@example.com',
picture: 'https://example.com/staff/tara.jpeg',
},
memberOf: ['team-d'],
},
const catalogApi = catalogApiMock.mock({
getEntities: async () => ({
items: [
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'User',
metadata: {
name: 'tara.macgovern',
namespace: 'foo-bar',
uid: 'a5gerth56',
description: 'Super Awesome Developer',
},
] as Entity[],
}),
};
const getEntitiesSpy = jest.spyOn(catalogApi, 'getEntities');
relations: [
{
type: 'memberOf',
targetRef: 'group:default/team-d',
},
],
spec: {
profile: {
displayName: 'Tara MacGovern',
email: 'tara-macgovern@example.com',
picture: 'https://example.com/staff/tara.jpeg',
},
memberOf: ['team-d'],
},
},
],
}),
});
it('Display Profile Card', async () => {
await renderInTestApp(
@@ -116,7 +114,7 @@ describe('MemberTab Test', () => {
},
},
);
expect(getEntitiesSpy).toHaveBeenCalledWith({
expect(catalogApi.getEntities).toHaveBeenCalledWith({
filter: {
kind: 'User',
'relations.memberof': ['group:default/team-d'],
@@ -171,7 +169,7 @@ describe('MemberTab Test', () => {
},
);
expect(getEntitiesSpy).toHaveBeenCalledWith({
expect(catalogApi.getEntities).toHaveBeenCalledWith({
filter: {
kind: 'User',
'relations.leaderof': ['group:default/team-d'],
@@ -19,16 +19,13 @@ import {
GetEntitiesResponse,
} from '@backstage/catalog-client';
import { Entity, GroupEntity, UserEntity } from '@backstage/catalog-model';
import {
CatalogApi,
catalogApiRef,
EntityProvider,
} from '@backstage/plugin-catalog-react';
import { catalogApiRef, EntityProvider } from '@backstage/plugin-catalog-react';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { queryByText } from '@testing-library/react';
import React from 'react';
import { catalogIndexRouteRef } from '../../../routes';
import { OwnershipCard } from './OwnershipCard';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
const items = [
{
@@ -161,11 +158,7 @@ describe('OwnershipCard', () => {
};
it('displays entity counts', async () => {
const catalogApi: jest.Mocked<CatalogApi> = {
getEntities: jest.fn(),
} as any;
catalogApi.getEntities.mockImplementation(getEntitiesMock);
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
const { getByText } = await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
@@ -215,11 +208,7 @@ describe('OwnershipCard', () => {
});
it('applies CustomFilterDefinition', async () => {
const catalogApi: jest.Mocked<CatalogApi> = {
getEntities: jest.fn(),
} as any;
catalogApi.getEntities.mockImplementation(getEntitiesMock);
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
const { getByText } = await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
@@ -252,11 +241,7 @@ describe('OwnershipCard', () => {
});
it('links to the catalog with the group filter', async () => {
const catalogApi: jest.Mocked<CatalogApi> = {
getEntities: jest.fn(),
} as any;
catalogApi.getEntities.mockImplementation(getEntitiesMock);
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
const { getByText } = await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
@@ -279,11 +264,7 @@ describe('OwnershipCard', () => {
});
it('links to the catalog with the user and groups filters from an user profile', async () => {
const catalogApi: jest.Mocked<CatalogApi> = {
getEntities: jest.fn(),
} as any;
catalogApi.getEntities.mockImplementation(getEntitiesMock);
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
const { getByText } = await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
@@ -308,11 +289,7 @@ describe('OwnershipCard', () => {
describe('OwnershipCard relations', () => {
it('shows relations toggle', async () => {
const catalogApi: jest.Mocked<CatalogApi> = {
getEntities: jest.fn(),
} as any;
catalogApi.getEntities.mockImplementation(getEntitiesMock);
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
const { getByTitle } = await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
@@ -331,11 +308,7 @@ describe('OwnershipCard', () => {
});
it('hides relations toggle', async () => {
const catalogApi: jest.Mocked<CatalogApi> = {
getEntities: jest.fn(),
} as any;
catalogApi.getEntities.mockImplementation(getEntitiesMock);
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
const rendered = await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
@@ -352,12 +325,9 @@ describe('OwnershipCard', () => {
expect(rendered.queryByText('Direct Relations')).toBeNull();
});
it('overrides relation type', async () => {
const catalogApi: jest.Mocked<CatalogApi> = {
getEntities: jest.fn(),
} as any;
catalogApi.getEntities.mockImplementation(getEntitiesMock);
it('overrides relation type', async () => {
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
const { getByTitle } = await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
@@ -376,11 +346,7 @@ describe('OwnershipCard', () => {
});
it('defaults to aggregated for User entity kind', async () => {
const catalogApi: jest.Mocked<CatalogApi> = {
getEntities: jest.fn(),
} as any;
catalogApi.getEntities.mockImplementation(getEntitiesMock);
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
const { getByLabelText } = await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
@@ -399,11 +365,7 @@ describe('OwnershipCard', () => {
});
it('defaults to direct for all entity kinds except User', async () => {
const catalogApi: jest.Mocked<CatalogApi> = {
getEntities: jest.fn(),
} as any;
catalogApi.getEntities.mockImplementation(getEntitiesMock);
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
const { getByLabelText } = await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
@@ -422,11 +384,7 @@ describe('OwnershipCard', () => {
});
it('defaults to provided relationsType', async () => {
const catalogApi: jest.Mocked<CatalogApi> = {
getEntities: jest.fn(),
} as any;
catalogApi.getEntities.mockImplementation(getEntitiesMock);
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
const { getByLabelText } = await renderInTestApp(
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
@@ -19,9 +19,9 @@ import React from 'react';
import { MyGroupsSidebarItem } from './MyGroupsSidebarItem';
import GroupIcon from '@material-ui/icons/People';
import { IdentityApi, identityApiRef } from '@backstage/core-plugin-api';
import { CatalogApi } from '@backstage/catalog-client';
import { Entity } from '@backstage/catalog-model';
import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
describe('MyGroupsSidebarItem Test', () => {
describe('For guests or users with no groups', () => {
@@ -33,12 +33,7 @@ describe('MyGroupsSidebarItem Test', () => {
ownershipEntityRefs: ['user:default/guest'],
}),
};
const catalogApi: Partial<CatalogApi> = {
getEntities: () =>
Promise.resolve({
items: [] as Entity[],
}),
};
const catalogApi = catalogApiMock();
const rendered = await renderInTestApp(
<TestApiProvider
apis={[
@@ -71,26 +66,25 @@ describe('MyGroupsSidebarItem Test', () => {
ownershipEntityRefs: ['user:default/nigel.manning'],
}),
};
const catalogApi: Partial<CatalogApi> = {
getEntities: () =>
Promise.resolve({
items: [
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'Group',
metadata: {
name: 'team-a',
title: 'Team A',
namespace: 'default',
},
spec: {
type: 'team',
children: [],
},
const catalogApi = catalogApiMock.mock({
getEntities: async () => ({
items: [
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'Group',
metadata: {
name: 'team-a',
title: 'Team A',
namespace: 'default',
},
] as Entity[],
}),
};
spec: {
type: 'team',
children: [],
},
},
] as Entity[],
}),
});
const rendered = await renderInTestApp(
<TestApiProvider
apis={[
@@ -127,52 +121,51 @@ describe('MyGroupsSidebarItem Test', () => {
ownershipEntityRefs: ['user:default/nigel.manning'],
}),
};
const catalogApi: Partial<CatalogApi> = {
getEntities: () =>
Promise.resolve({
items: [
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'Group',
metadata: {
name: 'team-a',
title: 'Team A',
namespace: 'default',
},
spec: {
type: 'team',
children: [],
},
const catalogApi = catalogApiMock.mock({
getEntities: async () => ({
items: [
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'Group',
metadata: {
name: 'team-a',
title: 'Team A',
namespace: 'default',
},
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'Group',
metadata: {
name: 'team-b',
title: 'Team B',
namespace: 'default',
},
spec: {
type: 'team',
children: [],
},
spec: {
type: 'team',
children: [],
},
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'Group',
metadata: {
name: 'team-c',
title: 'Team C',
namespace: 'default',
},
spec: {
type: 'team',
children: [],
},
},
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'Group',
metadata: {
name: 'team-b',
title: 'Team B',
namespace: 'default',
},
] as Entity[],
}),
};
spec: {
type: 'team',
children: [],
},
},
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'Group',
metadata: {
name: 'team-c',
title: 'Team C',
namespace: 'default',
},
spec: {
type: 'team',
children: [],
},
},
] as Entity[],
}),
});
const rendered = await renderInTestApp(
<TestApiProvider
apis={[
@@ -206,9 +199,7 @@ describe('MyGroupsSidebarItem Test', () => {
ownershipEntityRefs: ['user:default/guest'],
}),
};
const mockCatalogApi: Partial<CatalogApi> = {
getEntities: jest.fn(),
};
const mockCatalogApi = catalogApiMock.mock();
await renderInTestApp(
<TestApiProvider
apis={[
@@ -249,9 +240,7 @@ describe('MyGroupsSidebarItem Test', () => {
ownershipEntityRefs: ['user:default/guest'],
}),
};
const mockCatalogApi: Partial<CatalogApi> = {
getEntities: jest.fn(),
};
const mockCatalogApi = catalogApiMock.mock();
await renderInTestApp(
<TestApiProvider
apis={[
+3 -4
View File
@@ -14,7 +14,6 @@
* limitations under the License.
*/
import { CatalogApi } from '@backstage/catalog-client';
import {
getAllDesendantMembersForGroupEntity,
getMembersFromGroups,
@@ -42,7 +41,7 @@ import {
describe('Helper functions', () => {
it('getAllDesendantMembersForGroupEntity correctly recursively returns all descendant members', async () => {
const catalogApi = mockedCatalogApiSupportingGroups as CatalogApi;
const catalogApi = mockedCatalogApiSupportingGroups;
const actualGroupADescendantMembers =
await getAllDesendantMembersForGroupEntity(groupA, catalogApi);
@@ -60,7 +59,7 @@ describe('Helper functions', () => {
});
it('getMembersFromGroups correctly returns all members of provided groups', async () => {
const catalogApi = mockedCatalogApiSupportingGroups as CatalogApi;
const catalogApi = mockedCatalogApiSupportingGroups;
const actualNoGroupsMembers = await getMembersFromGroups([], catalogApi);
const actualGroupAMembers = await getMembersFromGroups(
@@ -123,7 +122,7 @@ describe('Helper functions', () => {
it('getDescendantGroupsFromGroup correctly recursively returns descendant groups, ignoring duplicates', async () => {
const actualDescendantGroups = await getDescendantGroupsFromGroup(
groupA,
mockedCatalogApiSupportingGroups as CatalogApi,
mockedCatalogApiSupportingGroups,
);
expect(actualDescendantGroups).toStrictEqual([
groupBRef,
@@ -13,11 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { DefaultStarredEntitiesApi } from '@backstage/plugin-catalog';
import {
catalogApiRef,
starredEntitiesApiRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { permissionApiRef } from '@backstage/plugin-permission-react';
import {
MockStorageApi,
@@ -29,26 +31,18 @@ import { rootRouteRef } from '../../../routes';
import { TemplateListPage } from './TemplateListPage';
describe('TemplateListPage', () => {
const mockCatalogApi = {
getEntities: async () => ({
items: [
{
apiVersion: 'scaffolder.backstage.io/v1beta3',
kind: 'Template',
metadata: { name: 'blob', tags: ['blob'] },
spec: {
type: 'service',
},
const mockCatalogApi = catalogApiMock({
entities: [
{
apiVersion: 'scaffolder.backstage.io/v1beta3',
kind: 'Template',
metadata: { name: 'blob', tags: ['blob'] },
spec: {
type: 'service',
},
],
}),
getEntityFacets: async () => ({
facets: { 'spec.type': [{ value: 'service', count: 1 }] },
}),
getEntitiesByRefs: async () => ({
items: [],
}),
};
},
],
});
it('should render the search bar for templates', async () => {
const { getByPlaceholderText } = await renderInTestApp(
@@ -16,11 +16,8 @@
import { Entity } from '@backstage/catalog-model';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import {
CatalogApi,
catalogApiRef,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import React from 'react';
import { identityApiRef } from '@backstage/core-plugin-api';
import { ListTasksPage } from './ListTasksPage';
@@ -32,9 +29,7 @@ import { act, fireEvent } from '@testing-library/react';
import { rootRouteRef } from '../../routes';
describe('<ListTasksPage />', () => {
const catalogApi: jest.Mocked<CatalogApi> = {
getEntityByRef: jest.fn(),
} as any;
const catalogApi = catalogApiMock.mock();
const identityApi = {
getBackstageIdentity: jest.fn(),
@@ -16,19 +16,14 @@
import { Entity } from '@backstage/catalog-model';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import {
CatalogApi,
catalogApiRef,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import React from 'react';
import { OwnerEntityColumn } from './OwnerEntityColumn';
import { identityApiRef } from '@backstage/core-plugin-api';
describe('<OwnerEntityColumn />', () => {
const catalogApi: jest.Mocked<CatalogApi> = {
getEntityByRef: jest.fn(),
} as any;
const catalogApi = catalogApiMock.mock();
const identityApi = {
getBackstageIdentity: jest.fn(),
@@ -17,7 +17,6 @@
import { CATALOG_FILTER_EXISTS } from '@backstage/catalog-client';
import { Entity } from '@backstage/catalog-model';
import {
CatalogApi,
catalogApiRef,
entityPresentationApiRef,
} from '@backstage/plugin-catalog-react';
@@ -28,6 +27,7 @@ import { EntityPicker } from './EntityPicker';
import { EntityPickerProps } from './schema';
import { ScaffolderRJSFFieldProps as FieldProps } from '@backstage/plugin-scaffolder-react';
import { DefaultEntityPresentationApi } from '@backstage/plugin-catalog';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
const makeEntity = (kind: string, namespace: string, name: string): Entity => ({
apiVersion: 'scaffolder.backstage.io/v1beta3',
@@ -36,7 +36,10 @@ const makeEntity = (kind: string, namespace: string, name: string): Entity => ({
});
describe('<EntityPicker />', () => {
let entities: Entity[];
const entities: Entity[] = [
makeEntity('Group', 'default', 'team-a'),
makeEntity('Group', 'default', 'squad-b'),
];
const onChange = jest.fn();
const schema = {};
const required = false;
@@ -46,23 +49,13 @@ describe('<EntityPicker />', () => {
let props: FieldProps<string>;
const catalogApi: jest.Mocked<CatalogApi> = {
getLocationById: jest.fn(),
getEntityByName: jest.fn(),
const catalogApi = catalogApiMock.mock({
getEntities: jest.fn(async () => ({ items: entities })),
addLocation: jest.fn(),
getLocationByRef: jest.fn(),
removeEntityByUid: jest.fn(),
} as any;
});
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
beforeEach(() => {
entities = [
makeEntity('Group', 'default', 'team-a'),
makeEntity('Group', 'default', 'squad-b'),
];
Wrapper = ({ children }: { children?: React.ReactNode }) => (
<TestApiProvider
apis={[
@@ -91,8 +84,6 @@ describe('<EntityPicker />', () => {
rawErrors,
formData,
} as unknown as FieldProps;
catalogApi.getEntities.mockResolvedValue({ items: entities });
});
it('searches for all entities', async () => {
@@ -17,7 +17,6 @@
import { CATALOG_FILTER_EXISTS } from '@backstage/catalog-client';
import { Entity } from '@backstage/catalog-model';
import {
CatalogApi,
catalogApiRef,
entityPresentationApiRef,
} from '@backstage/plugin-catalog-react';
@@ -30,6 +29,7 @@ import { MultiEntityPicker } from './MultiEntityPicker';
import { MultiEntityPickerProps } from './schema';
import { ScaffolderRJSFFieldProps as FieldProps } from '@backstage/plugin-scaffolder-react';
import { DefaultEntityPresentationApi } from '@backstage/plugin-catalog';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
const makeEntity = (kind: string, namespace: string, name: string): Entity => ({
apiVersion: 'scaffolder.backstage.io/v1beta3',
@@ -38,7 +38,10 @@ const makeEntity = (kind: string, namespace: string, name: string): Entity => ({
});
describe('<MultiEntityPicker />', () => {
let entities: Entity[];
const entities: Entity[] = [
makeEntity('Group', 'default', 'team-a'),
makeEntity('Group', 'default', 'squad-b'),
];
const onChange = jest.fn();
const schema = {};
const required = false;
@@ -48,22 +51,12 @@ describe('<MultiEntityPicker />', () => {
let props: FieldProps<string[]>;
const catalogApi: jest.Mocked<CatalogApi> = {
getLocationById: jest.fn(),
getEntityByName: jest.fn(),
const catalogApi = catalogApiMock.mock({
getEntities: jest.fn(async () => ({ items: entities })),
addLocation: jest.fn(),
getLocationByRef: jest.fn(),
removeEntityByUid: jest.fn(),
} as any;
});
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
beforeEach(() => {
entities = [
makeEntity('Group', 'default', 'team-a'),
makeEntity('Group', 'default', 'squad-b'),
];
Wrapper = ({ children }: { children?: React.ReactNode }) => (
<TestApiProvider
apis={[
@@ -92,8 +85,6 @@ describe('<MultiEntityPicker />', () => {
rawErrors,
formData,
} as unknown as FieldProps;
catalogApi.getEntities.mockResolvedValue({ items: entities });
});
it('searches for all entities', async () => {
@@ -16,7 +16,7 @@
import React from 'react';
import { waitFor } from '@testing-library/react';
import { CatalogApi } from '@backstage/catalog-client';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { MyGroupsPicker } from './MyGroupsPicker';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import {
@@ -60,9 +60,9 @@ describe('<MyGroupsPicker />', () => {
const schema = {};
const required = false;
const catalogApi: jest.Mocked<CatalogApi> = {
const catalogApi = catalogApiMock.mock({
getEntities: jest.fn(async () => ({ items: entities })),
} as any;
});
const mockErrorApi: jest.Mocked<ErrorApi> = {
post: jest.fn(),
@@ -17,10 +17,10 @@
import { type EntityFilterQuery } from '@backstage/catalog-client';
import { Entity } from '@backstage/catalog-model';
import {
CatalogApi,
catalogApiRef,
entityPresentationApiRef,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { ScaffolderRJSFFieldProps as FieldProps } from '@backstage/plugin-scaffolder-react';
import React from 'react';
@@ -34,7 +34,10 @@ const makeEntity = (kind: string, namespace: string, name: string): Entity => ({
});
describe('<OwnerPicker />', () => {
let entities: Entity[];
const entities: Entity[] = [
makeEntity('Group', 'default', 'team-a'),
makeEntity('Group', 'default', 'squad-b'),
];
const onChange = jest.fn();
const schema = {};
const required = false;
@@ -52,22 +55,12 @@ describe('<OwnerPicker />', () => {
let props: FieldProps<string>;
const catalogApi: jest.Mocked<CatalogApi> = {
getLocationById: jest.fn(),
getEntityByName: jest.fn(),
const catalogApi = catalogApiMock.mock({
getEntities: jest.fn(async () => ({ items: entities })),
addLocation: jest.fn(),
getLocationByRef: jest.fn(),
removeEntityByUid: jest.fn(),
} as any;
});
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
beforeEach(() => {
entities = [
makeEntity('Group', 'default', 'team-a'),
makeEntity('Group', 'default', 'squad-b'),
];
Wrapper = ({ children }: { children?: React.ReactNode }) => (
<TestApiProvider
apis={[
@@ -96,8 +89,6 @@ describe('<OwnerPicker />', () => {
rawErrors,
formData,
} as unknown as FieldProps<any>;
catalogApi.getEntities.mockResolvedValue({ items: entities });
});
it('searches for users and groups', async () => {
@@ -134,8 +125,6 @@ describe('<OwnerPicker />', () => {
rawErrors,
formData,
} as unknown as FieldProps<any>;
catalogApi.getEntities.mockResolvedValue({ items: entities });
});
it('searches for users', async () => {
@@ -228,8 +217,6 @@ describe('<OwnerPicker />', () => {
rawErrors,
formData,
} as unknown as FieldProps<any>;
catalogApi.getEntities.mockResolvedValue({ items: entities });
});
it('searches for users and groups or teams and business units', async () => {
@@ -21,11 +21,11 @@ import {
storageApiRef,
} from '@backstage/core-plugin-api';
import {
CatalogApi,
catalogApiRef,
starredEntitiesApiRef,
MockStarredEntitiesApi,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import {
MockStorageApi,
renderInTestApp,
@@ -36,22 +36,18 @@ import React from 'react';
import { rootDocsRouteRef } from '../../routes';
import { DefaultTechDocsHome } from './DefaultTechDocsHome';
const mockCatalogApi: Partial<CatalogApi> = {
getEntityFacets: async () => ({ facets: { 'relations.ownedBy': [] } }),
getEntitiesByRefs: () => Promise.resolve({ items: [] }),
getEntities: async () => ({
items: [
{
apiVersion: 'version',
kind: 'User',
metadata: {
name: 'owned',
namespace: 'default',
},
const mockCatalogApi = catalogApiMock({
entities: [
{
apiVersion: 'version',
kind: 'User',
metadata: {
name: 'owned',
namespace: 'default',
},
],
}),
};
},
],
});
describe('TechDocs Home', () => {
const configApi: ConfigApi = new ConfigReader({
@@ -21,12 +21,14 @@ import {
storageApiRef,
} from '@backstage/core-plugin-api';
import {
CatalogApi,
catalogApiRef,
starredEntitiesApiRef,
MockStarredEntitiesApi,
} from '@backstage/plugin-catalog-react';
import { MockEntityListContextProvider } from '@backstage/plugin-catalog-react/testUtils';
import {
MockEntityListContextProvider,
catalogApiMock,
} from '@backstage/plugin-catalog-react/testUtils';
import {
MockStorageApi,
renderInTestApp,
@@ -62,12 +64,7 @@ const entities = [
},
];
const mockCatalogApi = {
getEntityByRef: () => Promise.resolve(),
getEntities: async () => ({
items: entities,
}),
} as Partial<CatalogApi>;
const mockCatalogApi = catalogApiMock({ entities });
describe('Entity List Docs Grid', () => {
beforeEach(() => {
@@ -14,7 +14,8 @@
* limitations under the License.
*/
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
import { catalogApiRef } from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
import { screen } from '@testing-library/react';
import React from 'react';
@@ -22,21 +23,18 @@ import { TechDocsCustomHome, PanelType } from './TechDocsCustomHome';
import { ApiProvider } from '@backstage/core-app-api';
import { rootDocsRouteRef } from '../../routes';
const mockCatalogApi = {
getEntityByRef: jest.fn(),
getEntities: async () => ({
items: [
{
apiVersion: 'version',
kind: 'User',
metadata: {
name: 'owned',
namespace: 'default',
},
const mockCatalogApi = catalogApiMock({
entities: [
{
apiVersion: 'version',
kind: 'User',
metadata: {
name: 'owned',
namespace: 'default',
},
],
}),
} as Partial<CatalogApi>;
},
],
});
describe('TechDocsCustomHome', () => {
const apiRegistry = TestApiRegistry.from([catalogApiRef, mockCatalogApi]);