mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Roles] Added optional role description (#183145)
## Summary 1. Added optional role description field for Save/Edit Role page. 2. Added tooltip with description for roles ComboBox that we render on the User and Role Mappings pages. <details> <summary>3. Updated <b>RolesGridPage </b>table responsive setup.</summary> <br> <table> <tr> <td>[Before] responsiveBreakpoint={false}</td> <td>[After] responsiveBreakpoint={true}</td> </tr> <tr> <td><img alt="Before" src="d8290299
-e8c8-4c00-abee-ad1fe909df1d"></td> <td><img alt="After" src="917e2c78
-6291-43f0-ab7e-7583c51fd69d"></td> </tr> </table> </details>7035c05b
-85c6-4da0-97d3-85f6d2dbc313 ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [x] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed. [Report](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5960) - [x] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [x] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [x] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [x] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### For maintainers - [x] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) __Fixes: https://github.com/elastic/kibana/issues/173570__ ## Release note Added optional role description field for Save/Edit Role page. --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
e53ff4411b
commit
4fade37313
12 changed files with 294 additions and 41 deletions
|
@ -32,6 +32,7 @@ The API returns the following:
|
|||
[
|
||||
{
|
||||
"name": "my_kibana_role",
|
||||
"description": "My kibana role description",
|
||||
"metadata" : {
|
||||
"version" : 1
|
||||
},
|
||||
|
@ -55,6 +56,7 @@ The API returns the following:
|
|||
},
|
||||
{
|
||||
"name": "my_admin_role",
|
||||
"description": "My admin role description",
|
||||
"metadata" : {
|
||||
"version" : 1
|
||||
},
|
||||
|
|
|
@ -31,6 +31,7 @@ The API returns the following:
|
|||
--------------------------------------------------
|
||||
{
|
||||
"name": "my_restricted_kibana_role",
|
||||
"description": "My restricted kibana role description",
|
||||
"metadata" : {
|
||||
"version" : 1
|
||||
},
|
||||
|
|
|
@ -21,6 +21,9 @@ To use the create or update role API, you must have the `manage_security` cluste
|
|||
[[role-management-api-response-body]]
|
||||
==== Request body
|
||||
|
||||
`description`::
|
||||
(Optional, string) Description for the role.
|
||||
|
||||
`metadata`::
|
||||
(Optional, object) In the `metadata` object, keys that begin with `_` are reserved for system usage.
|
||||
|
||||
|
@ -74,6 +77,7 @@ Grant access to various features in all spaces:
|
|||
--------------------------------------------------
|
||||
$ curl -X PUT api/security/role/my_kibana_role
|
||||
{
|
||||
"description": "my_kibana_role_description",
|
||||
"metadata": {
|
||||
"version": 1
|
||||
},
|
||||
|
@ -112,6 +116,7 @@ Grant dashboard-only access to only the Marketing space:
|
|||
--------------------------------------------------
|
||||
$ curl -X PUT api/security/role/my_kibana_role
|
||||
{
|
||||
"description": "Grants dashboard-only access to only the Marketing space.",
|
||||
"metadata": {
|
||||
"version": 1
|
||||
},
|
||||
|
@ -138,6 +143,7 @@ Grant full access to all features in the Default space:
|
|||
--------------------------------------------------
|
||||
$ curl -X PUT api/security/role/my_kibana_role
|
||||
{
|
||||
"description": "Grants full access to all features in the Default space.",
|
||||
"metadata": {
|
||||
"version": 1
|
||||
},
|
||||
|
@ -162,6 +168,7 @@ Grant different access to different spaces:
|
|||
--------------------------------------------------
|
||||
$ curl -X PUT api/security/role/my_kibana_role
|
||||
{
|
||||
"description": "Grants full access to discover and dashboard features in the default space. Grants read access in the marketing, and sales spaces.",
|
||||
"metadata": {
|
||||
"version": 1
|
||||
},
|
||||
|
@ -193,6 +200,7 @@ Grant access to {kib} and {es}:
|
|||
--------------------------------------------------
|
||||
$ curl -X PUT api/security/role/my_kibana_role
|
||||
{
|
||||
"description": "Grants all cluster privileges and full access to index1 and index2. Grants full access to remote_index1 and remote_index2, and the monitor_enrich cluster privilege on remote_cluster1. Grants all Kibana privileges in the default space.",
|
||||
"metadata": {
|
||||
"version": 1
|
||||
},
|
||||
|
|
|
@ -42,6 +42,7 @@ describe('RoleComboBox', () => {
|
|||
},
|
||||
{
|
||||
name: 'deprecated_role',
|
||||
description: 'Deprecated role description',
|
||||
elasticsearch: { cluster: [], indices: [], run_as: [] },
|
||||
kibana: [],
|
||||
metadata: { _reserved: true, _deprecated: true },
|
||||
|
@ -72,6 +73,7 @@ describe('RoleComboBox', () => {
|
|||
"label": "custom_role",
|
||||
"value": Object {
|
||||
"deprecatedReason": undefined,
|
||||
"description": undefined,
|
||||
"isAdmin": false,
|
||||
"isDeprecated": false,
|
||||
"isReserved": false,
|
||||
|
@ -89,6 +91,7 @@ describe('RoleComboBox', () => {
|
|||
"label": "reserved_role",
|
||||
"value": Object {
|
||||
"deprecatedReason": undefined,
|
||||
"description": undefined,
|
||||
"isAdmin": false,
|
||||
"isDeprecated": false,
|
||||
"isReserved": true,
|
||||
|
@ -106,6 +109,7 @@ describe('RoleComboBox', () => {
|
|||
"label": "some_admin",
|
||||
"value": Object {
|
||||
"deprecatedReason": undefined,
|
||||
"description": undefined,
|
||||
"isAdmin": true,
|
||||
"isDeprecated": false,
|
||||
"isReserved": true,
|
||||
|
@ -123,6 +127,7 @@ describe('RoleComboBox', () => {
|
|||
"label": "some_system",
|
||||
"value": Object {
|
||||
"deprecatedReason": undefined,
|
||||
"description": undefined,
|
||||
"isAdmin": false,
|
||||
"isDeprecated": false,
|
||||
"isReserved": true,
|
||||
|
@ -140,6 +145,7 @@ describe('RoleComboBox', () => {
|
|||
"label": "deprecated_role",
|
||||
"value": Object {
|
||||
"deprecatedReason": undefined,
|
||||
"description": "Deprecated role description",
|
||||
"isAdmin": false,
|
||||
"isDeprecated": true,
|
||||
"isReserved": true,
|
||||
|
|
|
@ -6,7 +6,14 @@
|
|||
*/
|
||||
|
||||
import type { EuiComboBoxOptionOption, EuiComboBoxProps } from '@elastic/eui';
|
||||
import { EuiBadge, EuiComboBox, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import {
|
||||
EuiBadge,
|
||||
EuiComboBox,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiText,
|
||||
EuiToolTip,
|
||||
} from '@elastic/eui';
|
||||
import React from 'react';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
@ -34,6 +41,7 @@ type Option = EuiComboBoxOptionOption<{
|
|||
isSystem: boolean;
|
||||
isAdmin: boolean;
|
||||
deprecatedReason?: string;
|
||||
description?: string;
|
||||
}>;
|
||||
|
||||
export const RoleComboBox = (props: Props) => {
|
||||
|
@ -57,6 +65,7 @@ export const RoleComboBox = (props: Props) => {
|
|||
isSystem,
|
||||
isAdmin,
|
||||
deprecatedReason: roleDefinition?.metadata?._deprecated_reason,
|
||||
description: roleDefinition?.description,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -134,7 +143,15 @@ export const RoleComboBox = (props: Props) => {
|
|||
function renderOption(option: Option) {
|
||||
return (
|
||||
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center" responsive={false}>
|
||||
<EuiFlexItem>{option.label}</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
{option.value?.description ? (
|
||||
<EuiToolTip position="left" content={option.value?.description}>
|
||||
<EuiText size="s">{option.label}</EuiText>
|
||||
</EuiToolTip>
|
||||
) : (
|
||||
<EuiText size="s">{option.label}</EuiText>
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
{option.value?.isDeprecated ? (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiBadge color={option.color}>
|
||||
|
|
|
@ -541,6 +541,69 @@ describe('<EditRolePage />', () => {
|
|||
expectSaveFormButtons(wrapper);
|
||||
});
|
||||
|
||||
it('can render a user defined role with description', async () => {
|
||||
const wrapper = mountWithIntl(
|
||||
<KibanaContextProvider services={coreStart}>
|
||||
<EditRolePage
|
||||
{...getProps({
|
||||
action: 'edit',
|
||||
spacesEnabled: false,
|
||||
role: {
|
||||
description: 'my custom role description',
|
||||
name: 'my custom role',
|
||||
metadata: {},
|
||||
elasticsearch: { cluster: ['all'], indices: [], run_as: ['*'] },
|
||||
kibana: [],
|
||||
},
|
||||
})}
|
||||
/>
|
||||
</KibanaContextProvider>
|
||||
);
|
||||
|
||||
await waitForRender(wrapper);
|
||||
|
||||
expect(wrapper.find('input[data-test-subj="roleFormDescriptionInput"]').prop('value')).toBe(
|
||||
'my custom role description'
|
||||
);
|
||||
expect(
|
||||
wrapper.find('input[data-test-subj="roleFormDescriptionInput"]').prop('disabled')
|
||||
).toBe(undefined);
|
||||
expectSaveFormButtons(wrapper);
|
||||
});
|
||||
|
||||
it('can render a reserved role with description', async () => {
|
||||
const wrapper = mountWithIntl(
|
||||
<KibanaContextProvider services={coreStart}>
|
||||
<EditRolePage
|
||||
{...getProps({
|
||||
action: 'edit',
|
||||
spacesEnabled: false,
|
||||
role: {
|
||||
description: 'my reserved role description',
|
||||
name: 'my custom role',
|
||||
metadata: {
|
||||
_reserved: true,
|
||||
},
|
||||
elasticsearch: { cluster: ['all'], indices: [], run_as: ['*'] },
|
||||
kibana: [],
|
||||
},
|
||||
})}
|
||||
/>
|
||||
</KibanaContextProvider>
|
||||
);
|
||||
|
||||
await waitForRender(wrapper);
|
||||
|
||||
expect(wrapper.find('[data-test-subj="roleFormDescriptionTooltip"]')).toHaveLength(1);
|
||||
|
||||
expect(wrapper.find('input[data-test-subj="roleFormDescriptionInput"]').prop('value')).toBe(
|
||||
'my reserved role description'
|
||||
);
|
||||
expect(
|
||||
wrapper.find('input[data-test-subj="roleFormDescriptionInput"]').prop('disabled')
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('can render when creating a new role', async () => {
|
||||
const wrapper = mountWithIntl(
|
||||
<KibanaContextProvider services={coreStart}>
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
EuiSpacer,
|
||||
EuiText,
|
||||
EuiTitle,
|
||||
EuiToolTip,
|
||||
} from '@elastic/eui';
|
||||
import type { ChangeEvent, FocusEvent, FunctionComponent, HTMLProps } from 'react';
|
||||
import React, { Fragment, useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
@ -211,6 +212,7 @@ function useRole(
|
|||
? rolesAPIClient.getRole(roleName)
|
||||
: Promise.resolve({
|
||||
name: '',
|
||||
description: '',
|
||||
elasticsearch: { cluster: [], indices: [], run_as: [], remote_cluster: [] },
|
||||
kibana: [],
|
||||
_unrecognized_applications: [],
|
||||
|
@ -452,45 +454,82 @@ export const EditRolePage: FunctionComponent<Props> = ({
|
|||
return null;
|
||||
};
|
||||
|
||||
const getRoleName = () => {
|
||||
const getRoleNameAndDescription = () => {
|
||||
return (
|
||||
<EuiPanel hasShadow={false} hasBorder={true}>
|
||||
<EuiFormRow
|
||||
data-test-subj={'roleNameFormRow'}
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="xpack.security.management.editRole.roleNameFormRowTitle"
|
||||
defaultMessage="Role name"
|
||||
/>
|
||||
}
|
||||
helpText={
|
||||
!isEditingExistingRole ? (
|
||||
<FormattedMessage
|
||||
id="xpack.security.management.createRole.roleNameFormRowHelpText"
|
||||
defaultMessage="Once the role is created you can no longer edit its name."
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiFormRow
|
||||
data-test-subj={'roleNameFormRow'}
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="xpack.security.management.editRole.roleNameFormRowTitle"
|
||||
defaultMessage="Role name"
|
||||
/>
|
||||
}
|
||||
helpText={
|
||||
!isEditingExistingRole ? (
|
||||
<FormattedMessage
|
||||
id="xpack.security.management.createRole.roleNameFormRowHelpText"
|
||||
defaultMessage="Once the role is created you can no longer edit its name."
|
||||
/>
|
||||
) : !isRoleReserved ? (
|
||||
<FormattedMessage
|
||||
id="xpack.security.management.editRole.roleNameFormRowHelpText"
|
||||
defaultMessage="A role's name cannot be changed once it has been created."
|
||||
/>
|
||||
) : undefined
|
||||
}
|
||||
{...validator.validateRoleName(role)}
|
||||
{...(creatingRoleAlreadyExists
|
||||
? { error: 'A role with this name already exists.', isInvalid: true }
|
||||
: {})}
|
||||
>
|
||||
<EuiFieldText
|
||||
name={'name'}
|
||||
value={role.name || ''}
|
||||
onChange={onNameChange}
|
||||
onBlur={onNameBlur}
|
||||
data-test-subj={'roleFormNameInput'}
|
||||
disabled={isRoleReserved || isEditingExistingRole || isRoleReadOnly}
|
||||
isInvalid={creatingRoleAlreadyExists}
|
||||
/>
|
||||
) : !isRoleReserved ? (
|
||||
<FormattedMessage
|
||||
id="xpack.security.management.editRole.roleNameFormRowHelpText"
|
||||
defaultMessage="A role's name cannot be changed once it has been created."
|
||||
/>
|
||||
) : undefined
|
||||
}
|
||||
{...validator.validateRoleName(role)}
|
||||
{...(creatingRoleAlreadyExists
|
||||
? { error: 'A role with this name already exists.', isInvalid: true }
|
||||
: {})}
|
||||
>
|
||||
<EuiFieldText
|
||||
name={'name'}
|
||||
value={role.name || ''}
|
||||
onChange={onNameChange}
|
||||
onBlur={onNameBlur}
|
||||
data-test-subj={'roleFormNameInput'}
|
||||
disabled={isRoleReserved || isEditingExistingRole || isRoleReadOnly}
|
||||
isInvalid={creatingRoleAlreadyExists}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFormRow
|
||||
data-test-subj="roleDescriptionFormRow"
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="xpack.security.management.editRole.roleDescriptionFormRowTitle"
|
||||
defaultMessage="Role description"
|
||||
/>
|
||||
}
|
||||
>
|
||||
{isRoleReserved || isRoleReadOnly ? (
|
||||
<EuiToolTip
|
||||
content={role.description}
|
||||
display="block"
|
||||
data-test-subj="roleFormDescriptionTooltip"
|
||||
>
|
||||
<EuiFieldText
|
||||
name="description"
|
||||
value={role.description ?? ''}
|
||||
data-test-subj="roleFormDescriptionInput"
|
||||
disabled
|
||||
/>
|
||||
</EuiToolTip>
|
||||
) : (
|
||||
<EuiFieldText
|
||||
name="description"
|
||||
value={role.description ?? ''}
|
||||
onChange={onDescriptionChange}
|
||||
data-test-subj="roleFormDescriptionInput"
|
||||
/>
|
||||
)}
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiPanel>
|
||||
);
|
||||
};
|
||||
|
@ -510,6 +549,12 @@ export const EditRolePage: FunctionComponent<Props> = ({
|
|||
}
|
||||
};
|
||||
|
||||
const onDescriptionChange = (e: ChangeEvent<HTMLInputElement>) =>
|
||||
setRole({
|
||||
...role,
|
||||
description: e.target.value.trim().length ? e.target.value : undefined,
|
||||
});
|
||||
|
||||
const getElasticsearchPrivileges = () => {
|
||||
return (
|
||||
<div>
|
||||
|
@ -787,7 +832,7 @@ export const EditRolePage: FunctionComponent<Props> = ({
|
|||
</Fragment>
|
||||
)}
|
||||
<EuiSpacer />
|
||||
{getRoleName()}
|
||||
{getRoleNameAndDescription()}
|
||||
{getElasticsearchPrivileges()}
|
||||
{getKibanaPrivileges()}
|
||||
<EuiSpacer />
|
||||
|
|
|
@ -85,7 +85,6 @@ export class RoleValidator {
|
|||
}
|
||||
return valid();
|
||||
}
|
||||
|
||||
public validateRemoteClusterPrivileges(role: Role): RoleValidationResult {
|
||||
if (!this.shouldValidate) {
|
||||
return valid();
|
||||
|
|
|
@ -56,6 +56,12 @@ describe('<RolesGridPage />', () => {
|
|||
elasticsearch: { cluster: [], indices: [], run_as: [] },
|
||||
kibana: [{ base: [], spaces: [], feature: {} }],
|
||||
},
|
||||
{
|
||||
name: 'test-role-with-description',
|
||||
description: 'role-description',
|
||||
elasticsearch: { cluster: [], indices: [], run_as: [] },
|
||||
kibana: [{ base: [], spaces: [], feature: {} }],
|
||||
},
|
||||
{
|
||||
name: 'reserved-role',
|
||||
elasticsearch: { cluster: [], indices: [], run_as: [] },
|
||||
|
@ -162,6 +168,10 @@ describe('<RolesGridPage />', () => {
|
|||
|
||||
expect(wrapper.find('a[data-test-subj="edit-role-action-disabled-role"]')).toHaveLength(1);
|
||||
expect(wrapper.find('a[data-test-subj="clone-role-action-disabled-role"]')).toHaveLength(1);
|
||||
|
||||
expect(findTestSubject(wrapper, 'roleRowDescription-test-role-with-description')).toHaveLength(
|
||||
1
|
||||
);
|
||||
});
|
||||
|
||||
it('hides reserved roles when instructed to', async () => {
|
||||
|
@ -201,6 +211,12 @@ describe('<RolesGridPage />', () => {
|
|||
elasticsearch: { cluster: [], indices: [], run_as: [] },
|
||||
kibana: [{ base: [], spaces: [], feature: {} }],
|
||||
},
|
||||
{
|
||||
name: 'test-role-with-description',
|
||||
description: 'role-description',
|
||||
elasticsearch: { cluster: [], indices: [], run_as: [] },
|
||||
kibana: [{ base: [], spaces: [], feature: {} }],
|
||||
},
|
||||
]);
|
||||
|
||||
findTestSubject(wrapper, 'showReservedRolesSwitch').simulate('click');
|
||||
|
@ -222,6 +238,12 @@ describe('<RolesGridPage />', () => {
|
|||
elasticsearch: { cluster: [], indices: [], run_as: [] },
|
||||
kibana: [{ base: [], spaces: [], feature: {} }],
|
||||
},
|
||||
{
|
||||
name: 'test-role-with-description',
|
||||
description: 'role-description',
|
||||
elasticsearch: { cluster: [], indices: [], run_as: [] },
|
||||
kibana: [{ base: [], spaces: [], feature: {} }],
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
EuiSpacer,
|
||||
EuiSwitch,
|
||||
EuiText,
|
||||
EuiToolTip,
|
||||
} from '@elastic/eui';
|
||||
import _ from 'lodash';
|
||||
import React, { Component } from 'react';
|
||||
|
@ -183,7 +184,6 @@ export class RolesGridPage extends Component<Props, State> {
|
|||
|
||||
<EuiInMemoryTable
|
||||
itemId="name"
|
||||
responsiveBreakpoint={false}
|
||||
columns={this.getColumnConfig()}
|
||||
selection={
|
||||
this.props.readOnly
|
||||
|
@ -254,6 +254,27 @@ export class RolesGridPage extends Component<Props, State> {
|
|||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'description',
|
||||
name: i18n.translate('xpack.security.management.roles.descriptionColumnName', {
|
||||
defaultMessage: 'Role Description',
|
||||
}),
|
||||
sortable: true,
|
||||
truncateText: { lines: 3 },
|
||||
render: (description: string, record: Role) => {
|
||||
return (
|
||||
<EuiToolTip position="top" content={description} display="block">
|
||||
<EuiText
|
||||
color="subdued"
|
||||
size="s"
|
||||
data-test-subj={`roleRowDescription-${record.name}`}
|
||||
>
|
||||
{description}
|
||||
</EuiText>
|
||||
</EuiToolTip>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
if (this.props.buildFlavor !== 'serverless') {
|
||||
config.push({
|
||||
|
|
|
@ -18,5 +18,6 @@ export default function ({ loadTestFile }: FtrProviderContext) {
|
|||
loadTestFile(require.resolve('./user_email'));
|
||||
loadTestFile(require.resolve('./role_mappings'));
|
||||
loadTestFile(require.resolve('./remote_cluster_security_roles'));
|
||||
loadTestFile(require.resolve('./role_description'));
|
||||
});
|
||||
}
|
||||
|
|
68
x-pack/test/functional/apps/security/role_description.ts
Normal file
68
x-pack/test/functional/apps/security/role_description.ts
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const testSubjects = getService('testSubjects');
|
||||
const security = getService('security');
|
||||
const PageObjects = getPageObjects(['security', 'settings', 'common', 'header']);
|
||||
|
||||
describe('Role Description', function () {
|
||||
before(async () => {
|
||||
await security.testUser.setRoles(['cluster_security_manager']);
|
||||
await PageObjects.security.initTests();
|
||||
await PageObjects.settings.navigateTo();
|
||||
await PageObjects.security.clickElasticsearchRoles();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
// NOTE: Logout needs to happen before anything else to avoid flaky behavior
|
||||
await PageObjects.security.forceLogout();
|
||||
await security.role.delete('a-role-with-description');
|
||||
await security.role.delete('a-role-without-description');
|
||||
await security.testUser.restoreDefaults();
|
||||
});
|
||||
|
||||
it('Can create role with description', async () => {
|
||||
await PageObjects.security.clickCreateNewRole();
|
||||
await testSubjects.setValue('roleFormNameInput', 'a-role-with-description');
|
||||
await testSubjects.setValue('roleFormDescriptionInput', 'role description');
|
||||
await PageObjects.security.clickSaveEditRole();
|
||||
|
||||
const columnDescription = await testSubjects.getVisibleText(
|
||||
'roleRowDescription-a-role-with-description'
|
||||
);
|
||||
expect(columnDescription).to.equal('role description');
|
||||
|
||||
await PageObjects.settings.clickLinkText('a-role-with-description');
|
||||
const name = await testSubjects.getAttribute('roleFormNameInput', 'value');
|
||||
const description = await testSubjects.getAttribute('roleFormDescriptionInput', 'value');
|
||||
|
||||
expect(name).to.equal('a-role-with-description');
|
||||
expect(description).to.equal('role description');
|
||||
|
||||
await PageObjects.security.clickCancelEditRole();
|
||||
});
|
||||
|
||||
it('Can create role without description', async () => {
|
||||
await PageObjects.security.clickCreateNewRole();
|
||||
await testSubjects.setValue('roleFormNameInput', 'a-role-without-description');
|
||||
await PageObjects.security.clickSaveEditRole();
|
||||
|
||||
await PageObjects.settings.clickLinkText('a-role-without-description');
|
||||
const name = await testSubjects.getAttribute('roleFormNameInput', 'value');
|
||||
const description = await testSubjects.getAttribute('roleFormDescriptionInput', 'value');
|
||||
|
||||
expect(name).to.equal('a-role-without-description');
|
||||
expect(description).to.equal('');
|
||||
|
||||
await PageObjects.security.clickCancelEditRole();
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue