Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Versioned common Space interface #160237

Merged
merged 10 commits into from
Jun 28, 2023
8 changes: 7 additions & 1 deletion x-pack/plugins/spaces/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,10 @@ export {
DEFAULT_SPACE_ID,
} from './constants';
export { addSpaceIdToPath, getSpaceIdFromPath } from './lib/spaces_url_parser';
export type { Space, GetAllSpacesOptions, GetAllSpacesPurpose, GetSpaceResult } from './types';
export type {
Space,
GetAllSpacesOptions,
GetAllSpacesPurpose,
GetSpaceResult,
} from './types/latest';
export { spaceV1 } from './types';
2 changes: 1 addition & 1 deletion x-pack/plugins/spaces/common/is_reserved_space.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
* 2.0.
*/

import type { Space } from '.';
import { isReservedSpace } from './is_reserved_space';
import type { Space } from './types';

test('it returns true for reserved spaces', () => {
const space: Space = {
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/spaces/common/is_reserved_space.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { get } from 'lodash';

import type { Space } from './types';
import type { Space } from '.';

/**
* Returns whether the given Space is reserved or not.
Expand Down
8 changes: 8 additions & 0 deletions x-pack/plugins/spaces/common/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

export * as spaceV1 from './space/v1';
8 changes: 8 additions & 0 deletions x-pack/plugins/spaces/common/types/latest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

export * from './space/v1';
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ export const createMockSavedObjectsRepository = (spaces: any[] = []) => {
if (spaces.find((s) => s.id === id)) {
throw SavedObjectsErrorHelpers.decorateConflictError(new Error(), 'space conflict');
}
return {};
return { id, attributes };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning a non-empty object now to satisfy the explicit conversion in the client.

}),
update: jest.fn((type, id) => {
if (!spaces.find((s) => s.id === id)) {
const result = spaces.find((s) => s.id === id);
if (!result) {
throw SavedObjectsErrorHelpers.createGenericNotFoundError(type, id);
}
return {};
return result[0];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning a non-empty object now to satisfy the explicit conversion in the client.

}),
bulkUpdate: jest.fn(),
delete: jest.fn((type: string, id: string) => {
Expand Down
194 changes: 107 additions & 87 deletions x-pack/plugins/spaces/server/spaces_client/spaces_client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
* 2.0.
*/

import { SavedObject } from '@kbn/core-saved-objects-server';
import { savedObjectsRepositoryMock } from '@kbn/core/server/mocks';

import type { GetAllSpacesPurpose } from '../../common';
import type { GetAllSpacesPurpose, Space } from '../../common';
import type { ConfigType } from '../config';
import { ConfigSchema } from '../config';
import { SpacesClient } from './spaces_client';
Expand All @@ -21,51 +22,72 @@ const createMockConfig = (mockConfig: ConfigType = { enabled: true, maxSpaces: 1
};

describe('#getAll', () => {
const savedObjects = [
const savedObjects:SavedObject<unknown>[] = [
{
// foo has all of the attributes expected by the space interface
id: 'foo',
type: 'space',
references: [],
attributes: {
name: 'foo-name',
description: 'foo-description',
bar: 'foo-bar',
color: '#FFFFFF',
initials: 'FB',
imageUrl: 'go-bots/predates/transformers',
disabledFeatures: [],
_reserved: true,
bar: 'foo-bar', // an extra attribute that will be ignored during conversion
},
},
{
// bar his missing attributes of color and image url
id: 'bar',
type: 'space',
references: [],
attributes: {
name: 'bar-name',
description: 'bar-description',
bar: 'bar-bar',
initials: 'BA',
disabledFeatures: [],
bar: 'bar-bar', // an extra attribute that will be ignored during conversion
},
},
{
// baz only has the bare minumum atributes
id: 'baz',
type: 'space',
references: [],
attributes: {
name: 'baz-name',
description: 'baz-description',
bar: 'baz-bar',
bar: 'baz-bar', // an extra attribute that will be ignored during conversion
},
},
];

const expectedSpaces = [
const expectedSpaces:Space[] = [
{
id: 'foo',
name: 'foo-name',
description: 'foo-description',
bar: 'foo-bar',
color: "#FFFFFF",
initials: "FB",
imageUrl: "go-bots/predates/transformers",
disabledFeatures: [],
_reserved: true,
},
{
id: 'bar',
name: 'bar-name',
description: 'bar-description',
bar: 'bar-bar',
initials: "BA",
disabledFeatures: [],
},
{
id: 'baz',
name: 'baz-name',
description: 'baz-description',
bar: 'baz-bar',
disabledFeatures: [],
},
];

Expand Down Expand Up @@ -101,22 +123,31 @@ describe('#getAll', () => {
});

describe('#get', () => {
const savedObject = {
const savedObject:SavedObject = {
id: 'foo',
type: 'foo',
type: 'space',
references: [],
attributes: {
name: 'foo-name',
description: 'foo-description',
bar: 'foo-bar',
color: '#FFFFFF',
initials: 'FB',
imageUrl: 'go-bots/predates/transformers',
disabledFeatures: [],
_reserved: true,
bar: 'foo-bar', // an extra attribute that will be ignored during conversion
},
};

const expectedSpace = {
const expectedSpace:Space = {
id: 'foo',
name: 'foo-name',
description: 'foo-description',
bar: 'foo-bar',
color: "#FFFFFF",
initials: "FB",
imageUrl: "go-bots/predates/transformers",
disabledFeatures: [],
_reserved: true,
};

test(`gets space using callWithRequestRepository`, async () => {
Expand All @@ -136,41 +167,35 @@ describe('#get', () => {

describe('#create', () => {
const id = 'foo';
const attributes = {
name: 'foo-name',
description: 'foo-description',
color: '#FFFFFF',
initials: 'FB',
imageUrl: "go-bots/predates/transformers",
disabledFeatures: [],
};

const spaceToCreate = {
id,
name: 'foo-name',
description: 'foo-description',
bar: 'foo-bar',
...attributes,
_reserved: true,
disabledFeatures: [],
};

const attributes = {
name: 'foo-name',
description: 'foo-description',
bar: 'foo-bar',
disabledFeatures: [],
bar: 'foo-bar', // will not make it to the saved object attributes
};

const savedObject = {
const savedObject:SavedObject = {
id,
type: 'foo',
type: 'space',
references: [],
attributes: {
name: 'foo-name',
description: 'foo-description',
bar: 'foo-bar',
disabledFeatures: [],
...attributes,
foo: 'bar', // will get stripped in conversion
},
};

const expectedReturnedSpace = {
const expectedReturnedSpace:Space = {
id,
name: 'foo-name',
description: 'foo-description',
bar: 'foo-bar',
disabledFeatures: [],
...attributes,
};

test(`creates space using callWithRequestRepository when we're under the max`, async () => {
Expand Down Expand Up @@ -226,42 +251,37 @@ describe('#create', () => {
});

describe('#update', () => {
const spaceToUpdate = {
id: 'foo',
name: 'foo-name',
description: 'foo-description',
bar: 'foo-bar',
_reserved: false,
disabledFeatures: [],
const attributes = {
name: 'foo-name',
description: 'foo-description',
color: '#FFFFFF',
initials: 'FB',
imageUrl: "go-bots/predates/transformers",
disabledFeatures: [],
};

const attributes = {
name: 'foo-name',
description: 'foo-description',
bar: 'foo-bar',
disabledFeatures: [],
const spaceToUpdate = {
id: 'foo',
...attributes,
_reserved: false, // will have no affect
bar: 'foo-bar', // will not make it to the saved object attributes
};

const savedObject = {
const savedObject:SavedObject = {
id: 'foo',
type: 'foo',
type: 'space',
references: [],
attributes: {
name: 'foo-name',
description: 'foo-description',
bar: 'foo-bar',
...attributes,
_reserved: true,
disabledFeatures: [],
foo: 'bar', // will get stripped in conversion
},
};

const expectedReturnedSpace = {
const expectedReturnedSpace:Space = {
id: 'foo',
name: 'foo-name',
description: 'foo-description',
bar: 'foo-bar',
...attributes,
_reserved: true,
disabledFeatures: [],
};

test(`updates space using callWithRequestRepository`, async () => {
Expand All @@ -283,9 +303,9 @@ describe('#update', () => {
describe('#delete', () => {
const id = 'foo';

const reservedSavedObject = {
const reservedSavedObject:SavedObject = {
id,
type: 'foo',
type: 'space',
references: [],
attributes: {
name: 'foo-name',
Expand All @@ -295,9 +315,9 @@ describe('#delete', () => {
},
};

const notReservedSavedObject = {
const notReservedSavedObject:SavedObject = {
id,
type: 'foo',
type: 'space',
references: [],
attributes: {
name: 'foo-name',
Expand Down Expand Up @@ -335,30 +355,30 @@ describe('#delete', () => {
expect(mockCallWithRequestRepository.delete).toHaveBeenCalledWith('space', id);
expect(mockCallWithRequestRepository.deleteByNamespace).toHaveBeenCalledWith(id);
});
});

describe('#disableLegacyUrlAliases', () => {
test(`updates legacy URL aliases using callWithRequestRepository`, async () => {
const mockDebugLogger = createMockDebugLogger();
const mockConfig = createMockConfig();
const mockCallWithRequestRepository = savedObjectsRepositoryMock.create();

const client = new SpacesClient(
mockDebugLogger,
mockConfig,
mockCallWithRequestRepository,
[]
);
const aliases = [
{ targetSpace: 'space1', targetType: 'foo', sourceId: '123' },
{ targetSpace: 'space2', targetType: 'bar', sourceId: '456' },
];
await client.disableLegacyUrlAliases(aliases);

expect(mockCallWithRequestRepository.bulkUpdate).toHaveBeenCalledTimes(1);
expect(mockCallWithRequestRepository.bulkUpdate).toHaveBeenCalledWith([
{ type: 'legacy-url-alias', id: 'space1:foo:123', attributes: { disabled: true } },
{ type: 'legacy-url-alias', id: 'space2:bar:456', attributes: { disabled: true } },
]);
});
describe('#disableLegacyUrlAliases', () => {
test(`updates legacy URL aliases using callWithRequestRepository`, async () => {
const mockDebugLogger = createMockDebugLogger();
const mockConfig = createMockConfig();
const mockCallWithRequestRepository = savedObjectsRepositoryMock.create();

const client = new SpacesClient(
mockDebugLogger,
mockConfig,
mockCallWithRequestRepository,
[]
);
const aliases = [
{ targetSpace: 'space1', targetType: 'foo', sourceId: '123' },
{ targetSpace: 'space2', targetType: 'bar', sourceId: '456' },
];
await client.disableLegacyUrlAliases(aliases);

expect(mockCallWithRequestRepository.bulkUpdate).toHaveBeenCalledTimes(1);
expect(mockCallWithRequestRepository.bulkUpdate).toHaveBeenCalledWith([
{ type: 'legacy-url-alias', id: 'space1:foo:123', attributes: { disabled: true } },
{ type: 'legacy-url-alias', id: 'space2:bar:456', attributes: { disabled: true } },
]);
});
});
Loading