Files
threshold-ui/ui/admin/tests/acceptance/roles/edit-grants-test.js
T
Lisbet Alvarez 077200d792 test: 💍 fix a11y violations and ignore existing issues (#3275)
* test: 💍 fix a11y violations and ignore existing issues

* test: 💍 remove ignores for fixed violation

* test: 💍 more color contrast ignores for new tests
2026-05-15 13:05:19 -07:00

352 lines
10 KiB
JavaScript

/**
* Copyright IBM Corp. 2021, 2026
* SPDX-License-Identifier: BUSL-1.1
*/
import { module, test } from 'qunit';
import {
visit,
click,
currentURL,
find,
select,
waitFor,
triggerKeyEvent,
} from '@ember/test-helpers';
import { setupApplicationTest } from 'admin/tests/helpers';
import * as selectors from './selectors';
import * as commonSelectors from 'admin/tests/helpers/selectors';
import { setRunOptions } from 'ember-a11y-testing/test-support';
module('Acceptance | roles/edit grants', function (hooks) {
setupApplicationTest(hooks);
const instances = {
scopes: {
global: null,
},
role: null,
};
const urls = {
role: null,
editGrants: null,
};
hooks.beforeEach(async function () {
instances.scopes.global = this.server.schema.scopes.find('global');
instances.role = this.server.create('role', {
scope: instances.scopes.global,
grant_strings: [
'ids=*;type=role;actions=read',
'ids=ttcp_1234567890;type=target;actions=authorize-session',
],
});
urls.role = `/scopes/global/roles/${instances.role.id}`;
urls.editGrants = `${urls.role}/edit-grants`;
});
test('can navigate to edit grants for roles with proper authorization', async function (assert) {
setRunOptions({
rules: {
'color-contrast': {
// [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2026-02-27
enabled: false,
},
},
});
await visit(urls.role);
assert.true(instances.role.authorized_actions.includes('set-grants'));
await click(selectors.MANAGE_DROPDOWN_ROLES);
await click(selectors.MANAGE_DROPDOWN_EDIT_GRANTS);
assert.strictEqual(currentURL(), urls.editGrants);
});
test('cannot navigate to edit grants for roles without proper authorization', async function (assert) {
setRunOptions({
rules: {
'color-contrast': {
// [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2026-02-27
enabled: false,
},
},
});
instances.role.authorized_actions =
instances.role.authorized_actions.filter(
(action) => action !== 'set-grants',
);
await visit(urls.role);
assert.false(instances.role.authorized_actions.includes('set-grants'));
await click(selectors.MANAGE_DROPDOWN_ROLES);
assert.dom(selectors.MANAGE_DROPDOWN_EDIT_GRANTS).doesNotExist();
assert.strictEqual(currentURL(), urls.role);
});
test('user can export a terraform formatted grant string', async function (assert) {
setRunOptions({
rules: {
'color-contrast': {
// [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2026-03-17
enabled: false,
},
},
});
await visit(urls.role);
await click(selectors.MANAGE_DROPDOWN_ROLES);
await click(selectors.MANAGE_DROPDOWN_EDIT_GRANTS);
await click(selectors.EXPORT_GRANTS_BTN);
assert.dom(selectors.EXPORT_OPTIONS_FLYOUT).isVisible();
assert.dom(selectors.EXPORT_FORMAT_SELECT).hasValue('terraform');
assert.dom(selectors.FORMATTED_EXPORT_CODE_BLOCK).hasText(`
grant_strings = [
"${instances.role.grant_strings[0]}",
"${instances.role.grant_strings[1]}",
]
`);
});
test('user can export a hcl formatted grant string', async function (assert) {
setRunOptions({
rules: {
'color-contrast': {
// [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2026-03-17
enabled: false,
},
},
});
await visit(urls.role);
await click(selectors.MANAGE_DROPDOWN_ROLES);
await click(selectors.MANAGE_DROPDOWN_EDIT_GRANTS);
await click(selectors.EXPORT_GRANTS_BTN);
await select(selectors.EXPORT_FORMAT_SELECT, 'native-hcl');
assert.dom(selectors.EXPORT_OPTIONS_FLYOUT).isVisible();
assert.dom(selectors.EXPORT_FORMAT_SELECT).hasValue('native-hcl');
assert.dom(selectors.FORMATTED_EXPORT_CODE_BLOCK).hasText(`
[
"${instances.role.grant_strings[0]}",
"${instances.role.grant_strings[1]}",
]
`);
});
test('loads current grants in the editor and updates them', async function (assert) {
setRunOptions({
rules: {
'color-contrast': {
// [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2026-05-15
enabled: false,
},
},
});
assert.expect(4);
const newGrantString = 'ids=*;type=session;actions=list,read';
const expectedGrantStrings = [
...instances.role.grant_strings,
newGrantString,
];
await visit(urls.editGrants);
await waitFor(commonSelectors.CODE_EDITOR_CM);
assert
.dom(commonSelectors.CODE_EDITOR_CONTENT)
.includesText(instances.role.grant_strings[0]);
assert
.dom(commonSelectors.CODE_EDITOR_CONTENT)
.includesText(instances.role.grant_strings[1]);
const editorElement = find(commonSelectors.CODE_EDITOR_CODE);
const editorView = editorElement.editor;
editorView.dispatch({
changes: {
from: editorView.state.doc.length,
insert: `\n${newGrantString}`,
},
});
assert
.dom(commonSelectors.CODE_EDITOR_CONTENT)
.includesText(newGrantString);
await click(commonSelectors.SAVE_BTN);
assert.deepEqual(
this.server.schema.roles.find(instances.role.id).attrs.grantStrings,
expectedGrantStrings,
);
});
test('shows actions for the first grant on page load', async function (assert) {
setRunOptions({
rules: {
'color-contrast': {
// [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2026-05-15
enabled: false,
},
},
});
await visit(urls.editGrants);
assert.dom(selectors.GRANT_ACTIONS_NO_TYPE_DETECTED).doesNotExist();
// opted to not check for specific actions here since the grants schema
// may change and cause the test to fail even though the functionality
// is working as expected
assert.dom(selectors.GRANT_ACTIONS_TABLE).isVisible();
});
test('shows "no type detected" in actions sidebar when role has no grants', async function (assert) {
const emptyRole = this.server.create('role', {
scope: instances.scopes.global,
grant_strings: [],
});
const editGrantsUrl = `/scopes/global/roles/${emptyRole.id}/edit-grants`;
await visit(editGrantsUrl);
assert.dom(selectors.GRANT_ACTIONS_NO_TYPE_DETECTED).isVisible();
assert.dom(selectors.GRANT_ACTIONS_TABLE).doesNotExist();
});
test('actions sidebar updates to "no type detected" when cursor moves to an empty line', async function (assert) {
setRunOptions({
rules: {
'color-contrast': {
// [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2026-05-15
enabled: false,
},
},
});
const role = this.server.create('role', {
scope: instances.scopes.global,
grant_strings: ['ids=*;type=role;actions=read', ''],
});
const editGrantsUrl = `/scopes/global/roles/${role.id}/edit-grants`;
await visit(editGrantsUrl);
await waitFor(commonSelectors.CODE_EDITOR_CM);
// Line 1 is a valid grant — the actions table should be visible
assert.dom(selectors.GRANT_ACTIONS_TABLE).isVisible();
const editorElement = find(commonSelectors.CODE_EDITOR_CODE);
const editorView = editorElement.editor;
// Move cursor to the second (empty) line
const line2 = editorView.state.doc.line(2);
editorView.dispatch({ selection: { anchor: line2.from } });
await waitFor(selectors.GRANT_ACTIONS_NO_TYPE_DETECTED);
assert.dom(selectors.GRANT_ACTIONS_NO_TYPE_DETECTED).isVisible();
assert.dom(selectors.GRANT_ACTIONS_TABLE).doesNotExist();
});
test('actions sidebar shows "invalid id or type" for a grant with an unrecognised type', async function (assert) {
setRunOptions({
rules: {
'color-contrast': {
// [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2026-05-15
enabled: false,
},
},
});
const role = this.server.create('role', {
scope: instances.scopes.global,
grant_strings: ['type=not-a-valid-type;actions=read'],
});
const editGrantsUrl = `/scopes/global/roles/${role.id}/edit-grants`;
await visit(editGrantsUrl);
await waitFor(commonSelectors.CODE_EDITOR_CM);
assert.dom(selectors.GRANT_ACTIONS_INVALID_ID_OR_TYPE).isVisible();
assert.dom(selectors.GRANT_ACTIONS_TABLE).doesNotExist();
});
test('shows linting error markers for an invalid grant string', async function (assert) {
setRunOptions({
rules: {
'color-contrast': {
// [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2026-05-15
enabled: false,
},
},
});
await visit(urls.editGrants);
await waitFor(commonSelectors.CODE_EDITOR_CM);
const editorElement = find(commonSelectors.CODE_EDITOR_CODE);
const editorView = editorElement.editor;
// Replace the editor content with an invalid grant string:
editorView.dispatch({
changes: {
from: 0,
to: editorView.state.doc.length,
insert: 'ids=*',
},
});
await waitFor(selectors.LINT_ERROR_MARKER);
assert.dom(selectors.LINT_ERROR_MARKER).exists();
});
test('shows autocomplete suggestions when triggered', async function (assert) {
setRunOptions({
rules: {
'color-contrast': {
// [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2026-05-15
enabled: false,
},
},
});
await visit(urls.editGrants);
await waitFor(commonSelectors.CODE_EDITOR_CM);
const editorElement = find(commonSelectors.CODE_EDITOR_CODE);
const editorView = editorElement.editor;
// Insert a partial grant string ending with 'type=' so completions are expected
editorView.dispatch({
changes: {
from: editorView.state.doc.length,
insert: '\ntype=',
},
selection: { anchor: editorView.state.doc.length + '\ntype='.length },
});
// Trigger Ctrl+Space
await triggerKeyEvent(
find(commonSelectors.CODE_EDITOR_CONTENT),
'keydown',
' ',
{ ctrlKey: true },
);
await waitFor(selectors.AUTOCOMPLETE_TOOLTIP);
assert.dom(selectors.AUTOCOMPLETE_TOOLTIP).isVisible();
});
});