Feature Controls - Simplify Saved Objects Management UI Capabilities (#38461)

* start simplifying saved objects management UI Capabilities

* update tests

* simplify UI

* address PR feedback

* remove savedObjectsManagement UI Capabilities tests
This commit is contained in:
Larry Gregory 2019-06-10 18:08:59 -04:00 committed by GitHub
parent 9c36f5e343
commit ee27bc4083
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 31 additions and 579 deletions

View file

@ -240,9 +240,7 @@ export default function (kibana) {
migrations,
},
uiCapabilities: async function (server) {
const { savedObjects } = server;
uiCapabilities: async function () {
return {
discover: {
show: true,
@ -275,14 +273,11 @@ export default function (kibana) {
indexPatterns: {
save: true,
},
savedObjectsManagement: savedObjects.types.reduce((acc, type) => ({
...acc,
[type]: {
delete: true,
edit: true,
read: true,
}
}), {}),
savedObjectsManagement: {
delete: true,
edit: true,
read: true,
},
management: {
/*
* Management settings correspond to management section/link ids, and should not be changed

View file

@ -139,7 +139,7 @@ uiModules.get('apps/management', ['monospaced.elastic'])
}
};
const { edit: canEdit, delete: canDelete } = uiCapabilities.savedObjectsManagement[service.type];
const { edit: canEdit, delete: canDelete } = uiCapabilities.savedObjectsManagement;
$scope.canEdit = canEdit;
$scope.canDelete = canDelete;
$scope.canViewInApp = canViewInApp(uiCapabilities, service.type);

View file

@ -257,7 +257,7 @@ exports[`ObjectsTable should render normally 1`] = `
size="xs"
/>
<InjectIntl(TableUI)
canDeleteSavedObjectTypes={Array []}
canDelete={false}
filterOptions={
Array [
Object {

View file

@ -134,26 +134,12 @@ const defaultProps = {
services: [],
uiCapabilities: {
savedObjectsManagement: {
'index-pattern': {
read: true
},
visualization: {
read: true
},
dashboard: {
read: true
},
search: {
read: true
}
read: true,
edit: false,
delete: false,
}
},
canDeleteSavedObjectTypes: [
'index-pattern',
'visualization',
'dashboard',
'search'
]
canDelete: true,
};
beforeEach(() => {
@ -272,41 +258,6 @@ describe('ObjectsTable', () => {
expect(addDangerMock).toHaveBeenCalled();
});
it('should filter find operation based on the uiCapabilities', async () => {
const uiCapabilities = {
savedObjectsManagement: {
'index-pattern': {
read: false,
},
visualization: {
read: false,
},
dashboard: {
read: false,
},
search: {
read: true,
}
}
};
const customizedProps = { ...defaultProps, uiCapabilities };
const component = shallowWithIntl(
<ObjectsTable.WrappedComponent
{...customizedProps}
perPageConfig={15}
/>
);
// Ensure all promises resolve
await new Promise(resolve => process.nextTick(resolve));
// Ensure the state changes are reflected
component.update();
expect(findObjects).toHaveBeenCalledWith(expect.objectContaining({
type: ['search']
}));
});
describe('export', () => {
it('should export selected objects', async () => {
const mockSelectedSavedObjects = [
@ -452,42 +403,6 @@ describe('ObjectsTable', () => {
expect(getRelationships).toHaveBeenCalledWith('search', '1', savedObjectTypes, defaultProps.$http, defaultProps.basePath);
});
it('should fetch relationships filtered based on the uiCapabilities', async () => {
const { getRelationships } = require('../../../lib/get_relationships');
const uiCapabilities = {
savedObjectsManagement: {
'index-pattern': {
read: false,
},
visualization: {
read: false,
},
dashboard: {
read: false,
},
search: {
read: true,
}
}
};
const customizedProps = { ...defaultProps, uiCapabilities };
const component = shallowWithIntl(
<ObjectsTable.WrappedComponent
{...customizedProps}
/>
);
// Ensure all promises resolve
await new Promise(resolve => process.nextTick(resolve));
// Ensure the state changes are reflected
component.update();
await component.instance().getRelationships('search', '1');
const savedObjectTypes = ['search'];
expect(getRelationships).toHaveBeenCalledWith('search', '1', savedObjectTypes, defaultProps.$http, defaultProps.basePath);
});
it('should show the flyout', async () => {
const component = shallowWithIntl(
<ObjectsTable.WrappedComponent

View file

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Table restricts which saved objects can be deleted based on type 1`] = `
exports[`Table prevents saved objects from being deleted 1`] = `
<Fragment>
<EuiSearchBar
box={
@ -35,7 +35,7 @@ exports[`Table restricts which saved objects can be deleted based on type 1`] =
isDisabled={true}
onClick={[Function]}
size="m"
title="Unable to delete search, index-pattern"
title="Unable to delete saved objects"
type="button"
>
<FormattedMessage
@ -247,10 +247,9 @@ exports[`Table should render normally 1`] = `
fill={false}
iconSide="left"
iconType="trash"
isDisabled={true}
isDisabled={false}
onClick={[Function]}
size="m"
title="Unable to delete index-pattern"
type="button"
>
<FormattedMessage

View file

@ -86,7 +86,7 @@ const defaultProps = {
onTableChange: () => {},
isSearching: false,
onShowRelationships: () => {},
canDeleteSavedObjectTypes: ['visualization']
canDelete: true
};
describe('Table', () => {
@ -127,9 +127,9 @@ describe('Table', () => {
expect(component.state().isSearchTextValid).toBe(true);
});
it(`restricts which saved objects can be deleted based on type`, () => {
it(`prevents saved objects from being deleted`, () => {
const selectedSavedObjects = [{ type: 'visualization' }, { type: 'search' }, { type: 'index-pattern' }];
const customizedProps = { ...defaultProps, selectedSavedObjects, canDeleteSavedObjectTypes: ['visualization'] };
const customizedProps = { ...defaultProps, selectedSavedObjects, canDelete: false };
const component = shallowWithIntl(
<Table.WrappedComponent
{...customizedProps}

View file

@ -36,6 +36,7 @@ import {
EuiText
} from '@elastic/eui';
import { getDefaultTitle, getSavedObjectLabel } from '../../../../lib';
import { i18n } from '@kbn/i18n';
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
class TableUI extends PureComponent {
@ -47,7 +48,7 @@ class TableUI extends PureComponent {
onSelectionChange: PropTypes.func.isRequired,
}).isRequired,
filterOptions: PropTypes.array.isRequired,
canDeleteSavedObjectTypes: PropTypes.array.isRequired,
canDelete: PropTypes.bool.isRequired,
onDelete: PropTypes.func.isRequired,
onExport: PropTypes.func.isRequired,
goInspectObject: PropTypes.func.isRequired,
@ -254,10 +255,6 @@ class TableUI extends PureComponent {
);
}
const unableToDeleteSavedObjectTypes = selectedSavedObjects
.map(({ type }) => type)
.filter(type => !this.props.canDeleteSavedObjectTypes.includes(type));
const button = (
<EuiButton
iconType="arrowDown"
@ -286,10 +283,15 @@ class TableUI extends PureComponent {
onClick={onDelete}
isDisabled={
selectedSavedObjects.length === 0 ||
unableToDeleteSavedObjectTypes.length > 0
!this.props.canDelete
}
title={
unableToDeleteSavedObjectTypes.length > 0 ? `Unable to delete ${unableToDeleteSavedObjectTypes.join(', ')}` : undefined
this.props.canDelete
? undefined
: i18n.translate(
'kbn.management.objects.objectsTable.table.deleteButtonTitle',
{ defaultMessage: 'Unable to delete saved objects' }
)
}
data-test-subj="savedObjectsManagementDelete"
>

View file

@ -82,9 +82,7 @@ class ObjectsTableUI extends Component {
constructor(props) {
super(props);
this.savedObjectTypes = POSSIBLE_TYPES.filter(type => {
return this.props.uiCapabilities.savedObjectsManagement[type].read;
});
this.savedObjectTypes = POSSIBLE_TYPES;
this.state = {
totalCount: 0,
@ -677,10 +675,6 @@ class ObjectsTableUI extends Component {
view: `${type} (${savedObjectCounts[type] || 0})`,
}));
const canDeleteSavedObjectTypes = POSSIBLE_TYPES.filter(type => {
return this.props.uiCapabilities.savedObjectsManagement[type].delete;
});
return (
<EuiPageContent
horizontalPosition="center"
@ -706,7 +700,7 @@ class ObjectsTableUI extends Component {
onTableChange={this.onTableChange}
filterOptions={filterOptions}
onExport={this.onExport}
canDeleteSavedObjectTypes={canDeleteSavedObjectTypes}
canDelete={this.props.uiCapabilities.savedObjectsManagement.delete}
onDelete={this.onDelete}
goInspectObject={this.props.goInspectObject}
pageIndex={page}

View file

@ -14,7 +14,6 @@ import { FeaturePrivilegeBuilder } from './feature_privilege_builder';
import { FeaturePrivilegeManagementBuilder } from './management';
import { FeaturePrivilegeNavlinkBuilder } from './navlink';
import { FeaturePrivilegeSavedObjectBuilder } from './saved_object';
import { FeaturePrivilegeSavedObjectsManagementBuilder } from './saved_objects_management';
import { FeaturePrivilegeUIBuilder } from './ui';
export { FeaturePrivilegeBuilder };
@ -26,7 +25,6 @@ export const featurePrivilegeBuilderFactory = (actions: Actions): FeaturePrivile
new FeaturePrivilegeManagementBuilder(actions),
new FeaturePrivilegeNavlinkBuilder(actions),
new FeaturePrivilegeSavedObjectBuilder(actions),
new FeaturePrivilegeSavedObjectsManagementBuilder(actions),
new FeaturePrivilegeUIBuilder(actions),
];

View file

@ -1,33 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { flatten, uniq } from 'lodash';
import {
Feature,
FeatureKibanaPrivileges,
} from '../../../../../../xpack_main/server/lib/feature_registry/feature_registry';
import { BaseFeaturePrivilegeBuilder } from './feature_privilege_builder';
export class FeaturePrivilegeSavedObjectsManagementBuilder extends BaseFeaturePrivilegeBuilder {
public getActions(privilegeDefinition: FeatureKibanaPrivileges, feature: Feature): string[] {
// TODO: Revisit if/when savedObjectsManagement UI Capabilities are refactored
if (feature.id !== 'savedObjectsManagement') {
return [];
}
return uniq([
...flatten(
privilegeDefinition.savedObject.all.map(type => [
this.actions.ui.get('savedObjectsManagement', type, 'delete'),
this.actions.ui.get('savedObjectsManagement', type, 'edit'),
this.actions.ui.get('savedObjectsManagement', type, 'read'),
])
),
...privilegeDefinition.savedObject.read.map(type =>
this.actions.ui.get('savedObjectsManagement', type, 'read')
),
]);
}
}

View file

@ -622,90 +622,6 @@ describe('features', () => {
});
});
describe('savedObjectsManagement feature', () => {
test(`saved objects privileges create 'savedObjectsManagement' actions`, () => {
const features: Feature[] = [
{
id: 'savedObjectsManagement',
name: 'Saved Objects Management',
icon: 'arrowDown',
app: [],
catalogue: [],
management: {},
privileges: {
all: {
ui: [],
savedObject: {
all: ['all-savedObject-all-1'],
read: ['all-savedObject-read-1'],
},
},
read: {
ui: [],
savedObject: {
all: ['read-savedObject-all-1'],
read: ['read-savedObject-read-1'],
},
},
},
},
];
const mockXPackMainPlugin = {
getFeatures: jest.fn().mockReturnValue(features),
};
const privileges = privilegesFactory(actions, mockXPackMainPlugin as any);
const actual = privileges.get();
expect(actual).toHaveProperty('features.savedObjectsManagement.all', [
actions.login,
actions.version,
actions.savedObject.get('all-savedObject-all-1', 'bulk_get'),
actions.savedObject.get('all-savedObject-all-1', 'get'),
actions.savedObject.get('all-savedObject-all-1', 'find'),
actions.savedObject.get('all-savedObject-all-1', 'create'),
actions.savedObject.get('all-savedObject-all-1', 'bulk_create'),
actions.savedObject.get('all-savedObject-all-1', 'update'),
actions.savedObject.get('all-savedObject-all-1', 'delete'),
actions.savedObject.get('all-savedObject-read-1', 'bulk_get'),
actions.savedObject.get('all-savedObject-read-1', 'get'),
actions.savedObject.get('all-savedObject-read-1', 'find'),
actions.ui.get('savedObjectsManagement', 'all-savedObject-all-1', 'delete'),
actions.ui.get('savedObjectsManagement', 'all-savedObject-all-1', 'edit'),
actions.ui.get('savedObjectsManagement', 'all-savedObject-all-1', 'read'),
actions.ui.get('savedObjectsManagement', 'all-savedObject-read-1', 'read'),
actions.allHack,
]);
expect(actual).toHaveProperty('features.savedObjectsManagement.read', [
actions.login,
actions.version,
actions.savedObject.get('read-savedObject-all-1', 'bulk_get'),
actions.savedObject.get('read-savedObject-all-1', 'get'),
actions.savedObject.get('read-savedObject-all-1', 'find'),
actions.savedObject.get('read-savedObject-all-1', 'create'),
actions.savedObject.get('read-savedObject-all-1', 'bulk_create'),
actions.savedObject.get('read-savedObject-all-1', 'update'),
actions.savedObject.get('read-savedObject-all-1', 'delete'),
actions.savedObject.get('read-savedObject-read-1', 'bulk_get'),
actions.savedObject.get('read-savedObject-read-1', 'get'),
actions.savedObject.get('read-savedObject-read-1', 'find'),
actions.ui.get('savedObjectsManagement', 'read-savedObject-all-1', 'delete'),
actions.ui.get('savedObjectsManagement', 'read-savedObject-all-1', 'edit'),
actions.ui.get('savedObjectsManagement', 'read-savedObject-all-1', 'read'),
actions.ui.get('savedObjectsManagement', 'read-savedObject-read-1', 'read'),
]);
});
});
describe('reserved', () => {
test('actions defined at the feature cascade to the privileges', () => {
const features: Feature[] = [

View file

@ -60,21 +60,6 @@ function toggleDisabledFeatures(
});
});
// TODO: Revisit if/when savedObjectsManagement UI Capabilities are refactored
if (feature.id === 'savedObjectsManagement') {
const capability: Record<string, Record<string, boolean>> = uiCapabilities[
feature.id
] as Record<string, Record<string, boolean>>;
Object.keys(capability).forEach(savedObjectType => {
Object.keys(capability[savedObjectType]).forEach(typeCapability => {
capability[savedObjectType][typeCapability] = false;
});
});
continue;
}
// Disable "sub features" that match the disabled feature
if (uiCapabilities.hasOwnProperty(feature.id)) {
const capability = uiCapabilities[feature.id];

View file

@ -206,14 +206,14 @@ const buildKibanaFeatures = (savedObjectTypes: string[]) => {
all: [...savedObjectTypes],
read: [],
},
ui: [],
ui: ['read', 'edit', 'delete'],
},
read: {
savedObject: {
all: [],
read: [...savedObjectTypes],
},
ui: [],
ui: ['read'],
},
},
},

View file

@ -1,93 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
/* eslint-disable max-classes-per-file */
class SavedObjectsTypeUICapabilitiesGroup {
public all = ['delete', 'edit', 'read'];
public read = ['read'];
public none = [] as string[];
}
const savedObjectsTypeUICapabilitiesGroup = new SavedObjectsTypeUICapabilitiesGroup();
interface OnlyParameters {
all?: string | string[];
read?: string | string[];
}
const coerceToArray = <T>(itemOrItemsOrNil: T | T[] | undefined): T[] => {
if (itemOrItemsOrNil == null) {
return [];
}
return Array.isArray(itemOrItemsOrNil) ? itemOrItemsOrNil : [itemOrItemsOrNil];
};
export class SavedObjectsManagementBuilder {
private allSavedObjectTypes: string[];
constructor(spacesEnabled: boolean) {
this.allSavedObjectTypes = [
...(spacesEnabled ? ['space'] : []),
'config',
'telemetry',
'graph-workspace',
'ml-telemetry',
'apm-telemetry',
'map',
'maps-telemetry',
'canvas-workpad',
'canvas-element',
'infrastructure-ui-source',
'upgrade-assistant-reindex-operation',
'upgrade-assistant-telemetry',
'index-pattern',
'visualization',
'search',
'dashboard',
'url',
'server',
'kql-telemetry',
'timelion-sheet',
'ui-metric',
'sample-data-telemetry',
'siem-ui-timeline',
'siem-ui-timeline-note',
'siem-ui-timeline-pinned-event',
];
}
public uiCapabilities(group: keyof SavedObjectsTypeUICapabilitiesGroup) {
return savedObjectsTypeUICapabilitiesGroup.all.reduce(
(acc2, uiCapability) => ({
...acc2,
[uiCapability]: savedObjectsTypeUICapabilitiesGroup[group].includes(uiCapability),
}),
{}
);
}
public build(parameters: OnlyParameters): Record<string, boolean> {
const readTypes = coerceToArray(parameters.read);
const allTypes = coerceToArray(parameters.all);
return this.allSavedObjectTypes.reduce(
(acc, savedObjectType) => ({
...acc,
[savedObjectType]: savedObjectsTypeUICapabilitiesGroup.all.reduce(
(acc2, uiCapability) => ({
...acc2,
[uiCapability]:
(readTypes.includes(savedObjectType) &&
savedObjectsTypeUICapabilitiesGroup.read.includes(uiCapability)) ||
(allTypes.includes(savedObjectType) &&
savedObjectsTypeUICapabilitiesGroup.all.includes(uiCapability)),
}),
{}
),
}),
{}
);
}
}

View file

@ -73,6 +73,5 @@ export default function uiCapabilitiesTests({
loadTestFile(require.resolve('./catalogue'));
loadTestFile(require.resolve('./foo'));
loadTestFile(require.resolve('./nav_links'));
loadTestFile(require.resolve('./saved_objects_management'));
});
}

View file

@ -1,91 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import expect from '@kbn/expect';
import { mapValues } from 'lodash';
import { KibanaFunctionalTestDefaultProviders } from '../../../types/providers';
import { SavedObjectsManagementBuilder } from '../../common/saved_objects_management_builder';
import {
UICapabilitiesService,
GetUICapabilitiesFailureReason,
} from '../../common/services/ui_capabilities';
import { UserAtSpaceScenarios } from '../scenarios';
const savedObjectsManagementBuilder = new SavedObjectsManagementBuilder(true);
// eslint-disable-next-line import/no-default-export
export default function savedObjectsManagementTests({
getService,
}: KibanaFunctionalTestDefaultProviders) {
const uiCapabilitiesService: UICapabilitiesService = getService('uiCapabilities');
describe('savedObjectsManagement', () => {
UserAtSpaceScenarios.forEach(scenario => {
it(`${scenario.id}`, async () => {
const { user, space } = scenario;
const uiCapabilities = await uiCapabilitiesService.get({
credentials: { username: user.username, password: user.password },
spaceId: space.id,
});
switch (scenario.id) {
case 'superuser at everything_space':
case 'global_all at everything_space':
case 'dual_privileges_all at everything_space':
case 'everything_space_all at everything_space':
expect(uiCapabilities.success).to.be(true);
expect(uiCapabilities.value).to.have.property('savedObjectsManagement');
const expected = mapValues(uiCapabilities.value!.savedObjectsManagement, () =>
savedObjectsManagementBuilder.uiCapabilities('all')
);
expect(uiCapabilities.value!.savedObjectsManagement).to.eql(expected);
break;
case 'dual_privileges_read at everything_space':
case 'global_read at everything_space':
case 'everything_space_read at everything_space':
expect(uiCapabilities.success).to.be(true);
expect(uiCapabilities.value).to.have.property('savedObjectsManagement');
const readExpected = mapValues(uiCapabilities.value!.savedObjectsManagement, () =>
savedObjectsManagementBuilder.uiCapabilities('read')
);
expect(uiCapabilities.value!.savedObjectsManagement).to.eql(readExpected);
break;
case 'superuser at nothing_space':
case 'nothing_space_all at nothing_space':
case 'nothing_space_read at nothing_space':
case 'global_all at nothing_space':
case 'global_read at nothing_space':
case 'dual_privileges_all at nothing_space':
case 'dual_privileges_read at nothing_space':
expect(uiCapabilities.success).to.be(true);
expect(uiCapabilities.value).to.have.property('savedObjectsManagement');
const noneExpected = mapValues(uiCapabilities.value!.savedObjectsManagement, () =>
savedObjectsManagementBuilder.uiCapabilities('none')
);
expect(uiCapabilities.value!.savedObjectsManagement).to.eql(noneExpected);
break;
case 'no_kibana_privileges at everything_space':
case 'no_kibana_privileges at nothing_space':
case 'legacy_all at everything_space':
case 'legacy_all at nothing_space':
case 'everything_space_all at nothing_space':
case 'everything_space_read at nothing_space':
case 'nothing_space_all at everything_space':
case 'nothing_space_read at everything_space':
expect(uiCapabilities.success).to.be(false);
expect(uiCapabilities.failureReason).to.be(
GetUICapabilitiesFailureReason.RedirectedToRoot
);
break;
default:
throw new UnreachableError(scenario);
}
});
});
});
}

View file

@ -55,6 +55,5 @@ export default function uiCapabilitesTests({
loadTestFile(require.resolve('./catalogue'));
loadTestFile(require.resolve('./foo'));
loadTestFile(require.resolve('./nav_links'));
loadTestFile(require.resolve('./saved_objects_management'));
});
}

View file

@ -1,78 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import expect from '@kbn/expect';
import { mapValues } from 'lodash';
import { KibanaFunctionalTestDefaultProviders } from '../../../types/providers';
import { SavedObjectsManagementBuilder } from '../../common/saved_objects_management_builder';
import {
UICapabilitiesService,
GetUICapabilitiesFailureReason,
} from '../../common/services/ui_capabilities';
import { UserScenarios } from '../scenarios';
const savedObjectsManagementBuilder = new SavedObjectsManagementBuilder(false);
// eslint-disable-next-line import/no-default-export
export default function savedObjectsManagementTests({
getService,
}: KibanaFunctionalTestDefaultProviders) {
const uiCapabilitiesService: UICapabilitiesService = getService('uiCapabilities');
describe('savedObjectsManagement', () => {
UserScenarios.forEach(scenario => {
it(`${scenario.fullName}`, async () => {
const uiCapabilities = await uiCapabilitiesService.get({
credentials: {
username: scenario.username,
password: scenario.password,
},
});
switch (scenario.username) {
case 'superuser':
case 'all':
case 'dual_privileges_all':
expect(uiCapabilities.success).to.be(true);
expect(uiCapabilities.value).to.have.property('savedObjectsManagement');
const expected = mapValues(uiCapabilities.value!.savedObjectsManagement, () =>
savedObjectsManagementBuilder.uiCapabilities('all')
);
expect(uiCapabilities.value!.savedObjectsManagement).to.eql(expected);
break;
case 'read':
case 'dual_privileges_read':
expect(uiCapabilities.success).to.be(true);
expect(uiCapabilities.value).to.have.property('savedObjectsManagement');
const expectedRead = mapValues(uiCapabilities.value!.savedObjectsManagement, () =>
savedObjectsManagementBuilder.uiCapabilities('read')
);
expect(uiCapabilities.value!.savedObjectsManagement).to.eql(expectedRead);
break;
case 'foo_all':
case 'foo_read':
expect(uiCapabilities.success).to.be(true);
expect(uiCapabilities.value).to.have.property('savedObjectsManagement');
expect(uiCapabilities.value!.savedObjectsManagement).to.eql(
savedObjectsManagementBuilder.build({
all: [],
read: [],
})
);
break;
case 'no_kibana_privileges':
// these users have no access to any ui capabilities
case 'legacy_all':
case 'no_kibana_privileges':
expect(uiCapabilities.success).to.be(false);
expect(uiCapabilities.failureReason).to.be(GetUICapabilitiesFailureReason.NotFound);
break;
default:
throw new UnreachableError(scenario);
}
});
});
});
}

View file

@ -41,6 +41,5 @@ export default function uiCapabilitesTests({
loadTestFile(require.resolve('./catalogue'));
loadTestFile(require.resolve('./foo'));
loadTestFile(require.resolve('./nav_links'));
loadTestFile(require.resolve('./saved_objects_management'));
});
}

View file

@ -1,54 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import expect from '@kbn/expect';
import { mapValues } from 'lodash';
import { KibanaFunctionalTestDefaultProviders } from '../../../types/providers';
import { SavedObjectsManagementBuilder } from '../../common/saved_objects_management_builder';
import { UICapabilitiesService } from '../../common/services/ui_capabilities';
import { SpaceScenarios } from '../scenarios';
const savedObjectsManagementBuilder = new SavedObjectsManagementBuilder(true);
// eslint-disable-next-line import/no-default-export
export default function savedObjectsManagementTests({
getService,
}: KibanaFunctionalTestDefaultProviders) {
const uiCapabilitiesService: UICapabilitiesService = getService('uiCapabilities');
describe('savedObjectsManagement', () => {
SpaceScenarios.forEach(scenario => {
it(`${scenario.name}`, async () => {
switch (scenario.id) {
case 'nothing_space':
// Saved Objects Managment is not available when everything is disabled.
const nothingSpaceCapabilities = await uiCapabilitiesService.get({
spaceId: scenario.id,
});
expect(nothingSpaceCapabilities.success).to.be(true);
expect(nothingSpaceCapabilities.value).to.have.property('savedObjectsManagement');
const nothingSpaceExpected = mapValues(
nothingSpaceCapabilities.value!.savedObjectsManagement,
() => savedObjectsManagementBuilder.uiCapabilities('none')
);
expect(nothingSpaceCapabilities.value!.savedObjectsManagement).to.eql(
nothingSpaceExpected
);
break;
default:
// Otherwise it's available without restriction
const uiCapabilities = await uiCapabilitiesService.get({ spaceId: scenario.id });
expect(uiCapabilities.success).to.be(true);
expect(uiCapabilities.value).to.have.property('savedObjectsManagement');
const expected = mapValues(uiCapabilities.value!.savedObjectsManagement, () =>
savedObjectsManagementBuilder.uiCapabilities('all')
);
expect(uiCapabilities.value!.savedObjectsManagement).to.eql(expected);
}
});
});
});
}