fix: allow multiple kinds on the InMemoryCatalogClient
Signed-off-by: JPeer264 <jan.oster94@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/catalog-client': patch
|
||||
---
|
||||
|
||||
allow arrays in the InMemoryCatalogClient to filter entities
|
||||
@@ -26,12 +26,12 @@ const entity1: Entity = {
|
||||
name: 'e1',
|
||||
uid: 'u1',
|
||||
},
|
||||
relations: [{ type: 'relatedTo', targetRef: 'customkind:default/e2' }],
|
||||
relations: [{ type: 'relatedTo', targetRef: 'secondcustomkind:default/e2' }],
|
||||
};
|
||||
|
||||
const entity2: Entity = {
|
||||
apiVersion: 'v1',
|
||||
kind: 'CustomKind',
|
||||
kind: 'SecondCustomKind',
|
||||
metadata: {
|
||||
namespace: 'default',
|
||||
name: 'e2',
|
||||
@@ -67,9 +67,21 @@ describe('InMemoryCatalogClient', () => {
|
||||
|
||||
await expect(
|
||||
client.getEntities({
|
||||
filter: { 'relations.relatedTo': 'customkind:default/e2' },
|
||||
filter: { 'relations.relatedTo': 'secondcustomkind:default/e2' },
|
||||
}),
|
||||
).resolves.toEqual({ items: [entity1] });
|
||||
|
||||
await expect(
|
||||
client.getEntities({
|
||||
filter: { kind: ['not-existing', 'CustomKind'] },
|
||||
}),
|
||||
).resolves.toEqual({ items: [entity1] });
|
||||
|
||||
await expect(
|
||||
client.getEntities({
|
||||
filter: { kind: ['SecondCustomKind', 'also-not-existing'] },
|
||||
}),
|
||||
).resolves.toEqual({ items: [entity2] });
|
||||
});
|
||||
|
||||
it('getEntitiesByRefs', async () => {
|
||||
@@ -77,7 +89,7 @@ describe('InMemoryCatalogClient', () => {
|
||||
await expect(
|
||||
client.getEntitiesByRefs({
|
||||
entityRefs: [
|
||||
'customkind:default/e2',
|
||||
'secondcustomkind:default/e2',
|
||||
'customkind:missing/missing',
|
||||
'customkind:default/e1',
|
||||
],
|
||||
@@ -86,7 +98,7 @@ describe('InMemoryCatalogClient', () => {
|
||||
await expect(
|
||||
client.getEntitiesByRefs({
|
||||
entityRefs: [
|
||||
'customkind:default/e2',
|
||||
'secondcustomkind:default/e2',
|
||||
'customkind:missing/missing',
|
||||
'customkind:default/e1',
|
||||
],
|
||||
@@ -114,9 +126,9 @@ describe('InMemoryCatalogClient', () => {
|
||||
it('getEntityAncestors', async () => {
|
||||
const client = new InMemoryCatalogClient({ entities });
|
||||
await expect(
|
||||
client.getEntityAncestors({ entityRef: 'customkind:default/e2' }),
|
||||
client.getEntityAncestors({ entityRef: 'secondcustomkind:default/e2' }),
|
||||
).resolves.toEqual({
|
||||
rootEntityRef: 'customkind:default/e2',
|
||||
rootEntityRef: 'secondcustomkind:default/e2',
|
||||
items: [{ entity: entity2, parentEntityRefs: [] }],
|
||||
});
|
||||
});
|
||||
@@ -124,7 +136,7 @@ describe('InMemoryCatalogClient', () => {
|
||||
it('getEntityByRef', async () => {
|
||||
const client = new InMemoryCatalogClient({ entities });
|
||||
await expect(
|
||||
client.getEntityByRef('customkind:default/e2'),
|
||||
client.getEntityByRef('secondcustomkind:default/e2'),
|
||||
).resolves.toEqual(entity2);
|
||||
await expect(
|
||||
client.getEntityByRef('customkind:missing/missing'),
|
||||
@@ -147,7 +159,7 @@ describe('InMemoryCatalogClient', () => {
|
||||
it('refreshEntity', async () => {
|
||||
const client = new InMemoryCatalogClient({ entities });
|
||||
await expect(
|
||||
client.refreshEntity('customkind:default/e2'),
|
||||
client.refreshEntity('secondcustomkind:default/e2'),
|
||||
).resolves.toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -106,6 +106,11 @@ function createFilter(
|
||||
if (expectedValue === CATALOG_FILTER_EXISTS) {
|
||||
continue;
|
||||
}
|
||||
if (Array.isArray(expectedValue)) {
|
||||
return expectedValue.some(value =>
|
||||
searchValues?.includes(String(value).toLocaleLowerCase('en-US')),
|
||||
);
|
||||
}
|
||||
if (
|
||||
!searchValues?.includes(
|
||||
String(expectedValue).toLocaleLowerCase('en-US'),
|
||||
|
||||
@@ -14,10 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
GetEntitiesRequest,
|
||||
GetEntitiesResponse,
|
||||
} from '@backstage/catalog-client';
|
||||
import { Entity, GroupEntity, UserEntity } from '@backstage/catalog-model';
|
||||
import { catalogApiRef, EntityProvider } from '@backstage/plugin-catalog-react';
|
||||
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
|
||||
@@ -104,18 +100,6 @@ const items = [
|
||||
},
|
||||
] as Entity[];
|
||||
|
||||
const getEntitiesMock = (
|
||||
request?: GetEntitiesRequest,
|
||||
): Promise<GetEntitiesResponse> => {
|
||||
const filterKinds =
|
||||
Array.isArray(request?.filter) && Array.isArray(request?.filter[0].kind)
|
||||
? request?.filter[0].kind ?? []
|
||||
: []; // we expect the request to be like { filter: [{ kind: ['API','System'], 'relations.ownedBy': [group:default/my-team], .... }]. If changed in OwnerShipCard, let's change in also here
|
||||
return Promise.resolve({
|
||||
items: items.filter(item => filterKinds.find(k => k === item.kind)),
|
||||
} as GetEntitiesResponse);
|
||||
};
|
||||
|
||||
describe('OwnershipCard', () => {
|
||||
const groupEntity: GroupEntity = {
|
||||
apiVersion: 'backstage.io/v1alpha1',
|
||||
@@ -157,7 +141,8 @@ describe('OwnershipCard', () => {
|
||||
};
|
||||
|
||||
it('displays entity counts', async () => {
|
||||
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
|
||||
const catalogApi = catalogApiMock({ entities: items });
|
||||
const mockedGetEntities = jest.spyOn(catalogApi, 'getEntities');
|
||||
|
||||
const { getByText } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
@@ -172,7 +157,7 @@ describe('OwnershipCard', () => {
|
||||
},
|
||||
);
|
||||
|
||||
expect(catalogApi.getEntities).toHaveBeenCalledWith({
|
||||
expect(mockedGetEntities).toHaveBeenCalledWith({
|
||||
filter: [
|
||||
{
|
||||
kind: ['Component', 'API', 'System'],
|
||||
@@ -207,7 +192,7 @@ describe('OwnershipCard', () => {
|
||||
});
|
||||
|
||||
it('applies CustomFilterDefinition', async () => {
|
||||
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
|
||||
const catalogApi = catalogApiMock({ entities: items });
|
||||
|
||||
const { getByText } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
@@ -240,7 +225,7 @@ describe('OwnershipCard', () => {
|
||||
});
|
||||
|
||||
it('links to the catalog with the group filter', async () => {
|
||||
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
|
||||
const catalogApi = catalogApiMock({ entities: items });
|
||||
|
||||
const { getByText } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
@@ -263,7 +248,7 @@ describe('OwnershipCard', () => {
|
||||
});
|
||||
|
||||
it('links to the catalog with the user and groups filters from an user profile', async () => {
|
||||
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
|
||||
const catalogApi = catalogApiMock({ entities: items });
|
||||
|
||||
const { getByText } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
@@ -288,7 +273,7 @@ describe('OwnershipCard', () => {
|
||||
|
||||
describe('OwnershipCard relations', () => {
|
||||
it('shows relations toggle', async () => {
|
||||
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
|
||||
const catalogApi = catalogApiMock({ entities: items });
|
||||
|
||||
const { getByTitle } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
@@ -307,7 +292,7 @@ describe('OwnershipCard', () => {
|
||||
});
|
||||
|
||||
it('hides relations toggle', async () => {
|
||||
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
|
||||
const catalogApi = catalogApiMock({ entities: items });
|
||||
|
||||
const rendered = await renderInTestApp(
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
@@ -326,7 +311,7 @@ describe('OwnershipCard', () => {
|
||||
});
|
||||
|
||||
it('overrides relation type', async () => {
|
||||
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
|
||||
const catalogApi = catalogApiMock({ entities: items });
|
||||
|
||||
const { getByTitle } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
@@ -345,7 +330,7 @@ describe('OwnershipCard', () => {
|
||||
});
|
||||
|
||||
it('defaults to aggregated for User entity kind', async () => {
|
||||
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
|
||||
const catalogApi = catalogApiMock({ entities: items });
|
||||
|
||||
const { getByLabelText } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
@@ -364,7 +349,7 @@ describe('OwnershipCard', () => {
|
||||
});
|
||||
|
||||
it('defaults to direct for all entity kinds except User', async () => {
|
||||
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
|
||||
const catalogApi = catalogApiMock({ entities: items });
|
||||
|
||||
const { getByLabelText } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
@@ -383,7 +368,7 @@ describe('OwnershipCard', () => {
|
||||
});
|
||||
|
||||
it('defaults to provided relationsType', async () => {
|
||||
const catalogApi = catalogApiMock.mock({ getEntities: getEntitiesMock });
|
||||
const catalogApi = catalogApiMock({ entities: items });
|
||||
|
||||
const { getByLabelText } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
|
||||
Reference in New Issue
Block a user