catalog-react: removed loadCatalogOwnerRefs

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2022-03-04 15:43:51 +01:00
parent 02875d4d56
commit 7ffb2c73c9
6 changed files with 11 additions and 182 deletions
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/plugin-catalog-react': minor
---
**BREAKING**: Removed the deprecated `loadCatalogOwnerRefs` function. Usages of this function can be directly replaced with `ownershipEntityRefs` from `identityApi.getBackstageIdentity()`.
This also affects the `useEntityOwnership` hook in that it no longer uses `loadCatalogOwnerRefs`, meaning it will no longer load in additional relations and instead only rely on the `ownershipEntityRefs` from the `IdentityApi`.
-13
View File
@@ -13,7 +13,6 @@ import { ComponentEntity } from '@backstage/catalog-model';
import { ComponentProps } from 'react';
import { CompoundEntityRef } from '@backstage/catalog-model';
import { Entity } from '@backstage/catalog-model';
import { GetEntitiesResponse } from '@backstage/catalog-client';
import { IconButton } from '@material-ui/core';
import { LinkProps } from '@backstage/core-components';
import { Observable } from '@backstage/types';
@@ -455,12 +454,6 @@ export function InspectEntityDialog(props: {
// @alpha
export function isOwnerOf(owner: Entity, entity: Entity): boolean;
// @public @deprecated
export function loadCatalogOwnerRefs(
catalogApi: CatalogApi,
identityOwnerRefs: string[],
): Promise<string[]>;
// @public (undocumented)
export const MockEntityListContextProvider: ({
children,
@@ -571,12 +564,6 @@ export function useEntityTypeFilter(): {
setSelectedTypes: (types: string[]) => void;
};
// @public @deprecated
export function useOwnedEntities(allowedKinds?: string[]): {
loading: boolean;
ownedEntities: GetEntitiesResponse | undefined;
};
// @public @deprecated
export function useOwnUser(): AsyncState<UserEntity | undefined>;
+1 -2
View File
@@ -43,6 +43,5 @@ export { useOwnUser } from './useOwnUser';
export { useRelatedEntities } from './useRelatedEntities';
export { useStarredEntities } from './useStarredEntities';
export { useStarredEntity } from './useStarredEntity';
export { loadCatalogOwnerRefs, useEntityOwnership } from './useEntityOwnership';
export { useOwnedEntities } from './useOwnedEntities';
export { useEntityOwnership } from './useEntityOwnership';
export { useEntityPermission } from './useEntityPermission';
@@ -15,18 +15,13 @@
*/
import { CatalogApi } from '@backstage/catalog-client';
import {
ComponentEntity,
RELATION_MEMBER_OF,
RELATION_OWNED_BY,
UserEntity,
} from '@backstage/catalog-model';
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 } from '@testing-library/react-hooks';
import React from 'react';
import { catalogApiRef } from '../api';
import { loadCatalogOwnerRefs, useEntityOwnership } from './useEntityOwnership';
import { useEntityOwnership } from './useEntityOwnership';
describe('useEntityOwnership', () => {
type MockIdentityApi = jest.Mocked<Pick<IdentityApi, 'getBackstageIdentity'>>;
@@ -77,55 +72,10 @@ describe('useEntityOwnership', () => {
],
};
const user2Entity: UserEntity = {
apiVersion: 'backstage.io/v1beta1',
kind: 'User',
metadata: {
name: 'user2',
namespace: 'default',
},
spec: {
/* should not be accessed */
} as any,
relations: [
{
type: RELATION_MEMBER_OF,
targetRef: 'group:default/group1',
target: { kind: 'Group', namespace: 'default', name: 'group1' },
},
],
};
afterEach(() => {
jest.resetAllMocks();
});
describe('loadCatalogOwnerRefs', () => {
it('loads the first user from the catalog', async () => {
mockCatalogApi.getEntityByRef.mockResolvedValueOnce(user2Entity);
await expect(
loadCatalogOwnerRefs(catalogApi, ['user:default/user2']),
).resolves.toEqual(['group:default/group1']);
expect(mockCatalogApi.getEntityByRef).toBeCalledWith({
kind: 'user',
namespace: 'default',
name: 'user2',
});
});
it('gracefully handles missing user', async () => {
mockCatalogApi.getEntityByRef.mockResolvedValueOnce(undefined);
await expect(
loadCatalogOwnerRefs(catalogApi, ['user:default/user2']),
).resolves.toEqual([]);
expect(mockCatalogApi.getEntityByRef).toBeCalledWith({
kind: 'user',
namespace: 'default',
name: 'user2',
});
});
});
describe('useEntityOwnership', () => {
it('matches ownership via ownership entity refs', async () => {
mockIdentityApi.getBackstageIdentity.mockResolvedValue({
@@ -14,56 +14,16 @@
* limitations under the License.
*/
import { CatalogApi } from '@backstage/catalog-client';
import {
Entity,
parseEntityRef,
RELATION_MEMBER_OF,
RELATION_OWNED_BY,
stringifyEntityRef,
} from '@backstage/catalog-model';
import { identityApiRef, useApi } from '@backstage/core-plugin-api';
import { useMemo } from 'react';
import useAsync from 'react-use/lib/useAsync';
import { catalogApiRef } from '../api';
import { getEntityRelations } from '../utils/getEntityRelations';
/**
* Takes the relevant parts of the User entity corresponding to the Backstage
* identity, and translates them into a list of entity refs on string form that
* represent the user's ownership connections.
*
* @public
*
* @param catalogApi - The Catalog API implementation
* @param identityOwnerRefs - List of identity owner refs as strings
* @returns OwnerRefs as a string array
* @deprecated Use `ownershipEntityRefs` from `identityApi.getBackstageIdentity()` instead.
*/
export async function loadCatalogOwnerRefs(
catalogApi: CatalogApi,
identityOwnerRefs: string[],
): Promise<string[]> {
const result = new Array<string>();
const primaryUserRef = identityOwnerRefs.find(ref => ref.startsWith('user:'));
if (primaryUserRef) {
const entity = await catalogApi.getEntityByRef(
parseEntityRef(primaryUserRef),
);
if (entity) {
const memberOf = getEntityRelations(entity, RELATION_MEMBER_OF, {
kind: 'Group',
});
for (const group of memberOf) {
result.push(stringifyEntityRef(group));
}
}
}
return result;
}
/**
* Returns a function that checks whether the currently signed-in user is an
* owner of a given entity. When the hook is initially mounted, the loading
@@ -79,16 +39,11 @@ export function useEntityOwnership(): {
isOwnedEntity: (entity: Entity) => boolean;
} {
const identityApi = useApi(identityApiRef);
const catalogApi = useApi(catalogApiRef);
// Trigger load only on mount
const { loading, value: refs } = useAsync(async () => {
const { ownershipEntityRefs } = await identityApi.getBackstageIdentity();
const catalogRefs = await loadCatalogOwnerRefs(
catalogApi,
ownershipEntityRefs,
);
return new Set([...ownershipEntityRefs, ...catalogRefs]);
return ownershipEntityRefs;
}, []);
const isOwnedEntity = useMemo(() => {
@@ -1,69 +0,0 @@
/*
* Copyright 2021 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 { catalogApiRef } from './../api';
import { loadCatalogOwnerRefs } from './useEntityOwnership';
import { identityApiRef, useApi } from '@backstage/core-plugin-api';
import { RELATION_OWNED_BY } from '@backstage/catalog-model';
import { GetEntitiesResponse } from '@backstage/catalog-client';
import useAsync from 'react-use/lib/useAsync';
import { useMemo } from 'react';
/**
* Takes the relevant parts of the Backstage identity, and translates them into
* a list of entities which are owned by the user. Takes an optional parameter
* to filter the entities based on allowedKinds
*
* @public
*
* @param allowedKinds - Array of allowed kinds to filter the entities
* @deprecated Use `ownershipEntityRefs` from `identityApi.getBackstageIdentity()` instead.
*/
export function useOwnedEntities(allowedKinds?: string[]): {
loading: boolean;
ownedEntities: GetEntitiesResponse | undefined;
} {
const identityApi = useApi(identityApiRef);
const catalogApi = useApi(catalogApiRef);
const { loading, value: refs } = useAsync(async () => {
const identity = await identityApi.getBackstageIdentity();
const identityRefs = identity.ownershipEntityRefs;
const catalogRefs = await loadCatalogOwnerRefs(catalogApi, identityRefs);
const catalogs = await catalogApi.getEntities(
allowedKinds
? {
filter: {
kind: allowedKinds,
[`relations.${RELATION_OWNED_BY}`]:
[...identityRefs, ...catalogRefs] || [],
},
}
: {
filter: {
[`relations.${RELATION_OWNED_BY}`]:
[...identityRefs, ...catalogRefs] || [],
},
},
);
return catalogs;
}, []);
const ownedEntities = useMemo(() => {
return refs;
}, [refs]);
return useMemo(() => ({ loading, ownedEntities }), [loading, ownedEntities]);
}