fix: 🐛 actions not displaying for templates in grants editor (#3296)
* fix: 🐛 actions not displaying for templates in grants editor * fix: 🐛 invalid ids check * fix: 🐛 update check for ids type * test: 💍 fix broken strings * test: 💍 fix test case * test: 💍 remove log
This commit is contained in:
1 parent
4a206c82dc
commit
ecefa39b98
5 files changed
+76
-75
No files matched your search
@@ -28,7 +28,7 @@ export default class GrantStringFormatsIndex extends Component {
|
||||
|
||||
stringFormats = {
|
||||
[this.stringFormatTypes.resourceType]: {
|
||||
text: `type=<${this.intl.t('resources.role.edit-grants.string-formats.insert-resource-types')}>;actions=<${this.intl.t('resources.role.edit-grants.string-formats.insert-actions')}>`,
|
||||
text: `type=<${this.intl.t('resources.role.edit-grants.string-formats.insert-resource-type')}>;actions=<${this.intl.t('resources.role.edit-grants.string-formats.insert-actions')}>`,
|
||||
link: 'role.grant-string-format.resource-type',
|
||||
},
|
||||
[this.stringFormatTypes.resource]: {
|
||||
@@ -36,7 +36,7 @@ export default class GrantStringFormatsIndex extends Component {
|
||||
link: 'role.grant-string-format.resource',
|
||||
},
|
||||
[this.stringFormatTypes.pinnedId]: {
|
||||
text: `ids=<${this.intl.t('resources.role.edit-grants.string-formats.insert-id')}>;type=<${this.intl.t('resources.role.edit-grants.string-formats.insert-resource-types')}>;actions=<${this.intl.t('resources.role.edit-grants.string-formats.insert-actions')}>`,
|
||||
text: `ids=<${this.intl.t('resources.role.edit-grants.string-formats.insert-ids')}>;type=<${this.intl.t('resources.role.edit-grants.string-formats.insert-resource-type')}>;actions=<${this.intl.t('resources.role.edit-grants.string-formats.insert-actions')}>`,
|
||||
link: 'role.grant-string-format.pinned-id',
|
||||
},
|
||||
[this.stringFormatTypes.outputFields]: {
|
||||
|
||||
@@ -101,18 +101,12 @@ export const analyzeGrantString = (grantsSchema, grantString = '') => {
|
||||
const hasSpecificIds = Boolean(idsValue) && !idsValue.includes('*');
|
||||
const hasExplicitType = Boolean(typeValue) && typeValue !== '*';
|
||||
|
||||
const hasTemplateIds =
|
||||
hasSpecificIds &&
|
||||
parseIds(idsValue).some((id) => id.startsWith('{{') && id.endsWith('}}'));
|
||||
|
||||
const hasLiteralIds = hasSpecificIds && !hasTemplateIds;
|
||||
|
||||
const compatibleIdsResourceType = hasLiteralIds
|
||||
const compatibleIdsResourceType = hasSpecificIds
|
||||
? getCompatibleResourceTypeForIds(schema, idsValue)
|
||||
: null;
|
||||
|
||||
const hasInvalidType = hasExplicitType && !schema.resourcesByType[typeValue];
|
||||
const hasInvalidIds = hasLiteralIds && !compatibleIdsResourceType;
|
||||
const hasInvalidIds = hasSpecificIds && !compatibleIdsResourceType;
|
||||
|
||||
const hasInvalidPinnedIdTypeCombination =
|
||||
hasSpecificIds &&
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'admin/tests/helpers';
|
||||
import { setupIntl } from 'ember-intl/test-support';
|
||||
import { setupMirage } from 'admin/tests/helpers/mirage';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import * as commonSelectors from 'admin/tests/helpers/selectors';
|
||||
@@ -19,40 +20,18 @@ const GRANT_ACTIONS_INVALID_ID_OR_TYPE =
|
||||
|
||||
module('Integration | Component | grant-actions/index', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIntl(hooks, 'en-us');
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.grantsSchema = {
|
||||
resource_types: [
|
||||
{
|
||||
type: 'host-catalog',
|
||||
collection_actions: ['create', 'list'],
|
||||
id_actions: ['read', 'update', 'delete'],
|
||||
id_prefixes: ['hcst'],
|
||||
},
|
||||
{
|
||||
type: 'host',
|
||||
parent_type: 'host-catalog',
|
||||
collection_actions: ['create', 'list'],
|
||||
id_actions: ['read', 'update', 'delete'],
|
||||
id_prefixes: ['h'],
|
||||
},
|
||||
{
|
||||
type: 'host-set',
|
||||
parent_type: 'host-catalog',
|
||||
collection_actions: ['create', 'list'],
|
||||
id_actions: [
|
||||
'delete',
|
||||
'add-hosts',
|
||||
'set-hosts',
|
||||
'remove-hosts',
|
||||
'read',
|
||||
'update',
|
||||
],
|
||||
id_prefixes: ['hs'],
|
||||
},
|
||||
],
|
||||
};
|
||||
hooks.beforeEach(async function () {
|
||||
const response = await fetch('/grants-schema.json');
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch grants schema: ${response.status}`);
|
||||
}
|
||||
|
||||
const grantsSchemaData = await response.json();
|
||||
this.grantsSchema = grantsSchemaData;
|
||||
});
|
||||
|
||||
test('it renders the actions relevant to the current grant line', async function (assert) {
|
||||
@@ -68,16 +47,13 @@ module('Integration | Component | grant-actions/index', function (hooks) {
|
||||
assert.dom(GRANT_ACTIONS_TABLE).isVisible();
|
||||
assert.dom(commonSelectors.TABLE_ROWS).isVisible({ count: 8 });
|
||||
|
||||
const rows = [...this.element.querySelectorAll(commonSelectors.TABLE_ROWS)];
|
||||
const rowData = rows.map((row) => {
|
||||
const cells = [...row.querySelectorAll('td')].map((cell) =>
|
||||
const rowData = [
|
||||
...this.element.querySelectorAll(commonSelectors.TABLE_ROWS),
|
||||
].map((row) => {
|
||||
const [name, description] = [...row.querySelectorAll('td')].map((cell) =>
|
||||
cell.textContent.trim(),
|
||||
);
|
||||
|
||||
return {
|
||||
name: cells[0],
|
||||
description: cells[1],
|
||||
};
|
||||
return { name, description };
|
||||
});
|
||||
|
||||
assert.deepEqual(
|
||||
@@ -98,12 +74,10 @@ module('Integration | Component | grant-actions/index', function (hooks) {
|
||||
name: 'add-hosts',
|
||||
description: 'Add hosts to a host set',
|
||||
});
|
||||
|
||||
assert.deepEqual(rowData[1], {
|
||||
name: 'create',
|
||||
description: 'Create a new host-set',
|
||||
});
|
||||
|
||||
assert.deepEqual(rowData.at(-1), {
|
||||
name: 'update',
|
||||
description: 'Update a host-set',
|
||||
@@ -113,6 +87,58 @@ module('Integration | Component | grant-actions/index', function (hooks) {
|
||||
assert.dom(GRANT_ACTIONS_NO_TYPE_DETECTED).doesNotExist();
|
||||
});
|
||||
|
||||
test('it renders relevant actions for template IDs', async function (assert) {
|
||||
this.grantString = 'ids={{.User.Id}}';
|
||||
|
||||
await render(hbs`
|
||||
<GrantActions
|
||||
@grantsSchema={{this.grantsSchema}}
|
||||
@grantString={{this.grantString}}
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.dom(GRANT_ACTIONS_TABLE).isVisible();
|
||||
assert.dom(commonSelectors.TABLE_ROWS).isVisible({ count: 7 });
|
||||
|
||||
const rowData = [
|
||||
...this.element.querySelectorAll(commonSelectors.TABLE_ROWS),
|
||||
].map((row) => {
|
||||
const [name, description] = [...row.querySelectorAll('td')].map((cell) =>
|
||||
cell.textContent.trim(),
|
||||
);
|
||||
return { name, description };
|
||||
});
|
||||
|
||||
assert.deepEqual(
|
||||
rowData.map(({ name }) => name),
|
||||
[
|
||||
'add-accounts',
|
||||
'delete',
|
||||
'list-resolvable-aliases',
|
||||
'read',
|
||||
'remove-accounts',
|
||||
'set-accounts',
|
||||
'update',
|
||||
],
|
||||
);
|
||||
|
||||
assert.deepEqual(rowData[0], {
|
||||
name: 'add-accounts',
|
||||
description: 'Add accounts to a user',
|
||||
});
|
||||
assert.deepEqual(rowData[1], {
|
||||
name: 'delete',
|
||||
description: 'Delete a user',
|
||||
});
|
||||
assert.deepEqual(rowData.at(-1), {
|
||||
name: 'update',
|
||||
description: 'Update a user',
|
||||
});
|
||||
|
||||
assert.dom(GRANT_ACTIONS_EMPTY_STATE).doesNotExist();
|
||||
assert.dom(GRANT_ACTIONS_NO_TYPE_DETECTED).doesNotExist();
|
||||
});
|
||||
|
||||
test('it renders the no resource type detected state when the current line has no detectable type', async function (assert) {
|
||||
this.grantString = 'output_fields=*';
|
||||
|
||||
@@ -201,24 +227,6 @@ module('Integration | Component | grant-actions/index', function (hooks) {
|
||||
assert.dom(GRANT_ACTIONS_EMPTY_STATE).doesNotExist();
|
||||
});
|
||||
|
||||
test('it renders the no-type-detected state for template IDs', async function (assert) {
|
||||
this.grantString = 'ids={{.User.Id}}';
|
||||
|
||||
await render(hbs`
|
||||
<GrantActions
|
||||
@grantsSchema={{this.grantsSchema}}
|
||||
@grantString={{this.grantString}}
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.dom(GRANT_ACTIONS_TABLE).doesNotExist();
|
||||
assert.dom(GRANT_ACTIONS_INVALID_ID_OR_TYPE).doesNotExist();
|
||||
assert
|
||||
.dom(GRANT_ACTIONS_NO_TYPE_DETECTED)
|
||||
.hasText('No resource type detected.');
|
||||
assert.dom(GRANT_ACTIONS_EMPTY_STATE).doesNotExist();
|
||||
});
|
||||
|
||||
test('it renders the invalid state for a pinned id paired with its own type instead of a child type', async function (assert) {
|
||||
this.grantString = 'ids=hcst_1234567890;type=host-catalog';
|
||||
|
||||
|
||||
@@ -39,8 +39,7 @@ module(
|
||||
[
|
||||
{
|
||||
selectedOption: 'resourceType',
|
||||
expectedValue:
|
||||
'type=<insert resource types>;actions=<insert actions>',
|
||||
expectedValue: 'type=<insert resource type>;actions=<insert actions>',
|
||||
},
|
||||
{
|
||||
optionToClick: RESOURCE_OPTION,
|
||||
@@ -51,7 +50,7 @@ module(
|
||||
optionToClick: PINNED_ID_OPTION,
|
||||
selectedOption: 'pinnedId',
|
||||
expectedValue:
|
||||
'ids=<insert id>;type=<insert resource types>;actions=<insert actions>',
|
||||
'ids=<insert ids>;type=<insert resource type>;actions=<insert actions>',
|
||||
},
|
||||
{
|
||||
optionToClick: OUTPUT_FIELDS_OPTION,
|
||||
|
||||
Reference in new issue
Block a user