From 31bdcbc81a1d42b9cd670923941298a98ad49e53 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Fri, 9 Jun 2023 23:20:14 +0200 Subject: [PATCH] catalog-react: add useFacetsEntities tests Signed-off-by: Vincenzo Scamporlino --- .../useFacetsEntities.test.ts | 244 ++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.test.ts diff --git a/plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.test.ts b/plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.test.ts new file mode 100644 index 0000000000..abad3c38dc --- /dev/null +++ b/plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.test.ts @@ -0,0 +1,244 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { renderHook } from '@testing-library/react-hooks'; +import { useFacetsEntities } from './useFacetsEntities'; +import { CatalogApi } from '@backstage/catalog-client'; + +const mockedGetEntityFacets: jest.MockedFn = + jest.fn(); + +const mockCatalogApi: Partial = { + getEntityFacets: mockedGetEntityFacets, +}; + +jest.mock('@backstage/core-plugin-api', () => ({ + ...jest.requireActual('@backstage/core-plugin-api'), + useApi: () => mockCatalogApi, +})); + +describe('useFacetsEntities', () => { + afterEach(() => { + jest.resetAllMocks(); + }); + + it(`should return empty items when facets are loading`, () => { + mockedGetEntityFacets.mockReturnValue(new Promise(() => {})); + const { result } = renderHook(() => useFacetsEntities({ enabled: true })); + expect(result.current[0]).toEqual({ value: { items: [] }, loading: true }); + }); + + it(`should return the owners`, async () => { + mockedGetEntityFacets.mockResolvedValue({ + facets: { + 'relations.ownedBy': [ + { count: 1, value: 'component:default/e2' }, + { count: 1, value: 'component:default/e1' }, + ], + }, + }); + + const { result, waitFor } = renderHook(() => + useFacetsEntities({ enabled: true }), + ); + + result.current[1]({ text: '' }); + await waitFor(() => { + expect(result.current[0]).toEqual({ + value: { + items: [ + { + apiVersion: 'backstage.io/v1beta1', + kind: 'component', + metadata: { name: 'e1', namespace: 'default' }, + }, + { + apiVersion: 'backstage.io/v1beta1', + kind: 'component', + metadata: { name: 'e2', namespace: 'default' }, + }, + ], + }, + loading: false, + }); + }); + }); + + it(`should return the owners sorted by namespace, name and kind`, async () => { + const entityRefs = [ + 'group:namespace/team-b', + 'component:default/c', + 'group:default/a', + 'component:default/a', + 'component:default/b', + ]; + + mockedGetEntityFacets.mockResolvedValue({ + facets: { + 'relations.ownedBy': entityRefs.map(value => ({ count: 1, value })), + }, + }); + + const { result, waitFor } = renderHook(() => + useFacetsEntities({ enabled: true }), + ); + + result.current[1]({ text: '' }); + await waitFor(() => { + expect(result.current[0]).toEqual({ + value: { + items: [ + { + apiVersion: 'backstage.io/v1beta1', + kind: 'component', + metadata: { name: 'a', namespace: 'default' }, + }, + { + apiVersion: 'backstage.io/v1beta1', + kind: 'group', + metadata: { name: 'a', namespace: 'default' }, + }, + { + apiVersion: 'backstage.io/v1beta1', + kind: 'component', + metadata: { name: 'b', namespace: 'default' }, + }, + { + apiVersion: 'backstage.io/v1beta1', + kind: 'component', + metadata: { name: 'c', namespace: 'default' }, + }, + { + apiVersion: 'backstage.io/v1beta1', + kind: 'group', + metadata: { name: 'team-b', namespace: 'namespace' }, + }, + ], + }, + loading: false, + }); + }); + }); + + it(`should paginate the data accordingly`, async () => { + const entityRefs = [ + 'group:namespace/team-b', + 'component:default/c', + 'group:default/a', + 'component:default/a', + 'component:default/b', + ]; + + mockedGetEntityFacets.mockResolvedValue({ + facets: { + 'relations.ownedBy': entityRefs.map(value => ({ count: 1, value })), + }, + }); + + const { result, waitFor } = renderHook(() => + useFacetsEntities({ enabled: true }), + ); + + result.current[1]({ text: '' }, { limit: 2 }); + await waitFor(() => { + expect(result.current[0]).toEqual({ + value: { + items: [ + { + apiVersion: 'backstage.io/v1beta1', + kind: 'component', + metadata: { name: 'a', namespace: 'default' }, + }, + { + apiVersion: 'backstage.io/v1beta1', + kind: 'group', + metadata: { name: 'a', namespace: 'default' }, + }, + ], + cursor: 'eyJ0ZXh0IjoiIiwic3RhcnQiOjJ9', + }, + loading: false, + }); + }); + + result.current[1](result.current[0].value!, { limit: 2 }); + await waitFor(() => { + expect(result.current[0]).toEqual({ + value: { + items: [ + { + apiVersion: 'backstage.io/v1beta1', + kind: 'component', + metadata: { name: 'a', namespace: 'default' }, + }, + { + apiVersion: 'backstage.io/v1beta1', + kind: 'group', + metadata: { name: 'a', namespace: 'default' }, + }, + { + apiVersion: 'backstage.io/v1beta1', + kind: 'component', + metadata: { name: 'b', namespace: 'default' }, + }, + { + apiVersion: 'backstage.io/v1beta1', + kind: 'component', + metadata: { name: 'c', namespace: 'default' }, + }, + ], + cursor: 'eyJ0ZXh0IjoiIiwic3RhcnQiOjR9', + }, + loading: false, + }); + }); + + result.current[1](result.current[0].value!, { limit: 2 }); + await waitFor(() => { + expect(result.current[0]).toEqual({ + value: { + items: [ + { + apiVersion: 'backstage.io/v1beta1', + kind: 'component', + metadata: { name: 'a', namespace: 'default' }, + }, + { + apiVersion: 'backstage.io/v1beta1', + kind: 'group', + metadata: { name: 'a', namespace: 'default' }, + }, + { + apiVersion: 'backstage.io/v1beta1', + kind: 'component', + metadata: { name: 'b', namespace: 'default' }, + }, + { + apiVersion: 'backstage.io/v1beta1', + kind: 'component', + metadata: { name: 'c', namespace: 'default' }, + }, + { + apiVersion: 'backstage.io/v1beta1', + kind: 'group', + metadata: { name: 'team-b', namespace: 'namespace' }, + }, + ], + }, + loading: false, + }); + }); + }); +});