@@ -6,7 +6,6 @@
|
||||
import { AddLocationRequest } from '@backstage/catalog-client';
|
||||
import { AddLocationResponse } from '@backstage/catalog-client';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { CatalogRequestOptions } from '@backstage/catalog-client';
|
||||
import { CompoundEntityRef } from '@backstage/catalog-model';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { GetEntitiesByRefsRequest } from '@backstage/catalog-client';
|
||||
@@ -24,76 +23,49 @@ import { ValidateEntityResponse } from '@backstage/catalog-client';
|
||||
|
||||
// @public (undocumented)
|
||||
export class InMemoryCatalogClient implements CatalogApi {
|
||||
constructor(options?: { entities?: Entity[] });
|
||||
// (undocumented)
|
||||
addLocation(
|
||||
_location: AddLocationRequest,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<AddLocationResponse>;
|
||||
addLocation(_location: AddLocationRequest): Promise<AddLocationResponse>;
|
||||
// (undocumented)
|
||||
getEntities(
|
||||
_request?: GetEntitiesRequest | undefined,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<GetEntitiesResponse>;
|
||||
getEntities(_request?: GetEntitiesRequest): Promise<GetEntitiesResponse>;
|
||||
// (undocumented)
|
||||
getEntitiesByRefs(
|
||||
_request: GetEntitiesByRefsRequest,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
request: GetEntitiesByRefsRequest,
|
||||
): Promise<GetEntitiesByRefsResponse>;
|
||||
// (undocumented)
|
||||
getEntityAncestors(
|
||||
_request: GetEntityAncestorsRequest,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
request: GetEntityAncestorsRequest,
|
||||
): Promise<GetEntityAncestorsResponse>;
|
||||
// (undocumented)
|
||||
getEntityByRef(
|
||||
_entityRef: string | CompoundEntityRef,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
entityRef: string | CompoundEntityRef,
|
||||
): Promise<Entity | undefined>;
|
||||
// (undocumented)
|
||||
getEntityFacets(
|
||||
_request: GetEntityFacetsRequest,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<GetEntityFacetsResponse>;
|
||||
// (undocumented)
|
||||
getLocationByEntity(
|
||||
_entityRef: string | CompoundEntityRef,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<Location_2 | undefined>;
|
||||
// (undocumented)
|
||||
getLocationById(
|
||||
_id: string,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<Location_2 | undefined>;
|
||||
getLocationById(_id: string): Promise<Location_2 | undefined>;
|
||||
// (undocumented)
|
||||
getLocationByRef(
|
||||
_locationRef: string,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<Location_2 | undefined>;
|
||||
getLocationByRef(_locationRef: string): Promise<Location_2 | undefined>;
|
||||
// (undocumented)
|
||||
queryEntities(
|
||||
_request?: QueryEntitiesRequest | undefined,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
_request?: QueryEntitiesRequest,
|
||||
): Promise<QueryEntitiesResponse>;
|
||||
// (undocumented)
|
||||
refreshEntity(
|
||||
_entityRef: string,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<void>;
|
||||
refreshEntity(_entityRef: string): Promise<void>;
|
||||
// (undocumented)
|
||||
removeEntityByUid(
|
||||
_uid: string,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<void>;
|
||||
removeEntityByUid(uid: string): Promise<void>;
|
||||
// (undocumented)
|
||||
removeLocationById(
|
||||
_id: string,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<void>;
|
||||
removeLocationById(_id: string): Promise<void>;
|
||||
// (undocumented)
|
||||
validateEntity(
|
||||
_entity: Entity,
|
||||
_locationRef: string,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<ValidateEntityResponse>;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ import {
|
||||
AddLocationRequest,
|
||||
AddLocationResponse,
|
||||
CatalogApi,
|
||||
CatalogRequestOptions,
|
||||
GetEntitiesByRefsRequest,
|
||||
GetEntitiesByRefsResponse,
|
||||
GetEntitiesRequest,
|
||||
@@ -32,106 +31,111 @@ import {
|
||||
QueryEntitiesResponse,
|
||||
ValidateEntityResponse,
|
||||
} from '@backstage/catalog-client';
|
||||
import { CompoundEntityRef, Entity } from '@backstage/catalog-model';
|
||||
import { NotImplementedError } from '@backstage/errors';
|
||||
import {
|
||||
CompoundEntityRef,
|
||||
Entity,
|
||||
stringifyEntityRef,
|
||||
} from '@backstage/catalog-model';
|
||||
import { NotFoundError, NotImplementedError } from '@backstage/errors';
|
||||
|
||||
/** @public */
|
||||
export class InMemoryCatalogClient implements CatalogApi {
|
||||
getEntities(
|
||||
_request?: GetEntitiesRequest | undefined,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
#entities: Entity[];
|
||||
|
||||
constructor(options?: { entities?: Entity[] }) {
|
||||
this.#entities = options?.entities ?? [];
|
||||
}
|
||||
|
||||
async getEntities(
|
||||
_request?: GetEntitiesRequest,
|
||||
): Promise<GetEntitiesResponse> {
|
||||
throw new NotImplementedError('Method not implemented.');
|
||||
}
|
||||
|
||||
getEntitiesByRefs(
|
||||
_request: GetEntitiesByRefsRequest,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
async getEntitiesByRefs(
|
||||
request: GetEntitiesByRefsRequest,
|
||||
): Promise<GetEntitiesByRefsResponse> {
|
||||
throw new NotImplementedError('Method not implemented.');
|
||||
const entitiesByRef = new Map<string, Entity>();
|
||||
for (const entity of this.#entities) {
|
||||
entitiesByRef.set(stringifyEntityRef(entity), entity);
|
||||
}
|
||||
|
||||
const items = request.entityRefs.map(candidateRef =>
|
||||
entitiesByRef.get(candidateRef),
|
||||
);
|
||||
|
||||
// TODO(freben): Fields, filters etc
|
||||
return { items };
|
||||
}
|
||||
|
||||
queryEntities(
|
||||
_request?: QueryEntitiesRequest | undefined,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
async queryEntities(
|
||||
_request?: QueryEntitiesRequest,
|
||||
): Promise<QueryEntitiesResponse> {
|
||||
throw new NotImplementedError('Method not implemented.');
|
||||
}
|
||||
|
||||
getEntityAncestors(
|
||||
_request: GetEntityAncestorsRequest,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
async getEntityAncestors(
|
||||
request: GetEntityAncestorsRequest,
|
||||
): Promise<GetEntityAncestorsResponse> {
|
||||
throw new NotImplementedError('Method not implemented.');
|
||||
const entity = this.#entities.find(
|
||||
e => stringifyEntityRef(e) === request.entityRef,
|
||||
);
|
||||
if (!entity) {
|
||||
throw new NotFoundError(`Entity with ref ${request.entityRef} not found`);
|
||||
}
|
||||
return {
|
||||
rootEntityRef: request.entityRef,
|
||||
items: [{ entity, parentEntityRefs: [] }],
|
||||
};
|
||||
}
|
||||
|
||||
getEntityByRef(
|
||||
_entityRef: string | CompoundEntityRef,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
async getEntityByRef(
|
||||
entityRef: string | CompoundEntityRef,
|
||||
): Promise<Entity | undefined> {
|
||||
throw new NotImplementedError('Method not implemented.');
|
||||
const ref =
|
||||
typeof entityRef === 'string' ? entityRef : stringifyEntityRef(entityRef);
|
||||
return this.#entities.find(e => stringifyEntityRef(e) === ref);
|
||||
}
|
||||
|
||||
removeEntityByUid(
|
||||
_uid: string,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<void> {
|
||||
throw new NotImplementedError('Method not implemented.');
|
||||
async removeEntityByUid(uid: string): Promise<void> {
|
||||
this.#entities = this.#entities.filter(e => e.metadata.uid !== uid);
|
||||
}
|
||||
|
||||
refreshEntity(
|
||||
_entityRef: string,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<void> {
|
||||
throw new NotImplementedError('Method not implemented.');
|
||||
}
|
||||
async refreshEntity(_entityRef: string): Promise<void> {}
|
||||
|
||||
getEntityFacets(
|
||||
async getEntityFacets(
|
||||
_request: GetEntityFacetsRequest,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<GetEntityFacetsResponse> {
|
||||
throw new NotImplementedError('Method not implemented.');
|
||||
}
|
||||
|
||||
getLocationById(
|
||||
_id: string,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<Location | undefined> {
|
||||
async getLocationById(_id: string): Promise<Location | undefined> {
|
||||
throw new NotImplementedError('Method not implemented.');
|
||||
}
|
||||
|
||||
getLocationByRef(
|
||||
_locationRef: string,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<Location | undefined> {
|
||||
async getLocationByRef(_locationRef: string): Promise<Location | undefined> {
|
||||
throw new NotImplementedError('Method not implemented.');
|
||||
}
|
||||
|
||||
addLocation(
|
||||
async addLocation(
|
||||
_location: AddLocationRequest,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<AddLocationResponse> {
|
||||
throw new NotImplementedError('Method not implemented.');
|
||||
}
|
||||
|
||||
removeLocationById(
|
||||
_id: string,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<void> {
|
||||
async removeLocationById(_id: string): Promise<void> {
|
||||
throw new NotImplementedError('Method not implemented.');
|
||||
}
|
||||
|
||||
getLocationByEntity(
|
||||
async getLocationByEntity(
|
||||
_entityRef: string | CompoundEntityRef,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<Location | undefined> {
|
||||
throw new NotImplementedError('Method not implemented.');
|
||||
}
|
||||
|
||||
validateEntity(
|
||||
async validateEntity(
|
||||
_entity: Entity,
|
||||
_locationRef: string,
|
||||
_options?: CatalogRequestOptions | undefined,
|
||||
): Promise<ValidateEntityResponse> {
|
||||
throw new NotImplementedError('Method not implemented.');
|
||||
}
|
||||
|
||||
@@ -14,19 +14,69 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createServiceFactory } from '@backstage/backend-plugin-api';
|
||||
import { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';
|
||||
import {
|
||||
ServiceRef,
|
||||
createServiceFactory,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { InMemoryCatalogClient } from '@backstage/catalog-client/testUtils';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';
|
||||
// eslint-disable-next-line @backstage/no-undeclared-imports
|
||||
import { ServiceMock } from '@backstage/backend-test-utils';
|
||||
|
||||
/** @internal */
|
||||
function simpleMock<TService>(
|
||||
ref: ServiceRef<TService, any>,
|
||||
mockFactory: () => jest.Mocked<TService>,
|
||||
): (partialImpl?: Partial<TService>) => ServiceMock<TService> {
|
||||
return partialImpl => {
|
||||
const mock = mockFactory();
|
||||
if (partialImpl) {
|
||||
for (const [key, impl] of Object.entries(partialImpl)) {
|
||||
if (typeof impl === 'function') {
|
||||
(mock as any)[key].mockImplementation(impl);
|
||||
} else {
|
||||
(mock as any)[key] = impl;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Object.assign(mock, {
|
||||
factory: createServiceFactory({
|
||||
service: ref,
|
||||
deps: {},
|
||||
factory: () => mock,
|
||||
}),
|
||||
}) as ServiceMock<TService>;
|
||||
};
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export function catalogServiceMock() {}
|
||||
export function catalogServiceMock(options?: { entities?: Entity[] }) {
|
||||
return new InMemoryCatalogClient(options);
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export namespace catalogServiceMock {
|
||||
export const factory = () =>
|
||||
export const factory = (options?: { entities?: Entity[] }) =>
|
||||
createServiceFactory({
|
||||
service: catalogServiceRef,
|
||||
deps: {},
|
||||
factory: () => new InMemoryCatalogClient(),
|
||||
factory: () => new InMemoryCatalogClient(options),
|
||||
});
|
||||
export const mock = simpleMock(catalogServiceRef, () => ({
|
||||
getEntities: jest.fn(),
|
||||
getEntitiesByRefs: jest.fn(),
|
||||
queryEntities: jest.fn(),
|
||||
getEntityAncestors: jest.fn(),
|
||||
getEntityByRef: jest.fn(),
|
||||
removeEntityByUid: jest.fn(),
|
||||
refreshEntity: jest.fn(),
|
||||
getEntityFacets: jest.fn(),
|
||||
getLocationById: jest.fn(),
|
||||
getLocationByRef: jest.fn(),
|
||||
addLocation: jest.fn(),
|
||||
removeLocationById: jest.fn(),
|
||||
getLocationByEntity: jest.fn(),
|
||||
validateEntity: jest.fn(),
|
||||
}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user