feat: 🎸 implement host set host association capabilities
This commit is contained in:
7 files changed
+107
-24
No files matched your search
@@ -0,0 +1,22 @@
|
||||
import ModelAbility from './model';
|
||||
|
||||
/**
|
||||
* Provides abilities for host sets.
|
||||
*/
|
||||
export default class UserAbility extends ModelAbility {
|
||||
// =permissions
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
get canAddHosts() {
|
||||
return this.hasAuthorizedAction('add-hosts');
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
get canRemoveHosts() {
|
||||
return this.hasAuthorizedAction('remove-hosts');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/abilities/host-set';
|
||||
@@ -8,6 +8,8 @@ export default factory.extend({
|
||||
'read',
|
||||
'update',
|
||||
'delete',
|
||||
'add-hosts',
|
||||
'remove-hosts',
|
||||
],
|
||||
id: (i) => `host-set-id-${i}`,
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Abilities | Host Set', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it reflects when a given host set resource may add hosts based on authorized_actions', function (assert) {
|
||||
assert.expect(2);
|
||||
const service = this.owner.lookup('service:can');
|
||||
const model = {
|
||||
authorized_actions: ['add-hosts'],
|
||||
};
|
||||
assert.ok(service.can('addHosts hostSet', model));
|
||||
model.authorized_actions = [];
|
||||
assert.notOk(service.can('addHosts hostSet', model));
|
||||
});
|
||||
|
||||
test('it reflects when a given hostSet resource may remove hosts based on authorized_actions', function (assert) {
|
||||
assert.expect(2);
|
||||
const service = this.owner.lookup('service:can');
|
||||
const model = {
|
||||
authorized_actions: ['remove-hosts'],
|
||||
};
|
||||
assert.ok(service.can('removeHosts hostSet', model));
|
||||
model.authorized_actions = [];
|
||||
assert.notOk(service.can('removeHosts hostSet', model));
|
||||
});
|
||||
});
|
||||
+12
-10
@@ -3,16 +3,18 @@
|
||||
@dropdownRight={{true}}
|
||||
as |dropdown|
|
||||
>
|
||||
<dropdown.link
|
||||
@route='scopes.scope.host-catalogs.host-catalog.host-sets.host-set.create-and-add-host'
|
||||
>
|
||||
{{t 'resources.host-set.actions.create-and-add-host'}}
|
||||
</dropdown.link>
|
||||
<dropdown.link
|
||||
@route='scopes.scope.host-catalogs.host-catalog.host-sets.host-set.add-hosts'
|
||||
>
|
||||
{{t 'resources.host-set.actions.add-hosts'}}
|
||||
</dropdown.link>
|
||||
{{#if (can 'addHosts hostSet' @model)}}
|
||||
<dropdown.link
|
||||
@route='scopes.scope.host-catalogs.host-catalog.host-sets.host-set.create-and-add-host'
|
||||
>
|
||||
{{t 'resources.host-set.actions.create-and-add-host'}}
|
||||
</dropdown.link>
|
||||
<dropdown.link
|
||||
@route='scopes.scope.host-catalogs.host-catalog.host-sets.host-set.add-hosts'
|
||||
>
|
||||
{{t 'resources.host-set.actions.add-hosts'}}
|
||||
</dropdown.link>
|
||||
{{/if}}
|
||||
{{#if (can 'delete model' @model)}}
|
||||
<dropdown.separator />
|
||||
<dropdown.button
|
||||
|
||||
+16
-14
@@ -36,21 +36,23 @@
|
||||
</Copyable>
|
||||
</row.cell>
|
||||
<row.cell>
|
||||
<Rose::Dropdown
|
||||
@icon='flight-icons/svg/more-horizontal-16'
|
||||
@iconOnly={{true}}
|
||||
@showCaret={{false}}
|
||||
@dropdownRight={{true}}
|
||||
@text='{{t 'actions.manage'}}'
|
||||
as |dropdown|
|
||||
>
|
||||
<dropdown.button
|
||||
@style='danger'
|
||||
{{on 'click' (route-action 'removeHost' @model.hostSet host)}}
|
||||
{{#if (can 'removeHosts hostSet' @model.hostSet)}}
|
||||
<Rose::Dropdown
|
||||
@icon='flight-icons/svg/more-horizontal-16'
|
||||
@iconOnly={{true}}
|
||||
@showCaret={{false}}
|
||||
@dropdownRight={{true}}
|
||||
@text='{{t 'actions.manage'}}'
|
||||
as |dropdown|
|
||||
>
|
||||
{{t 'actions.remove'}}
|
||||
</dropdown.button>
|
||||
</Rose::Dropdown>
|
||||
<dropdown.button
|
||||
@style='danger'
|
||||
{{on 'click' (route-action 'removeHost' @model.hostSet host)}}
|
||||
>
|
||||
{{t 'actions.remove'}}
|
||||
</dropdown.button>
|
||||
</Rose::Dropdown>
|
||||
{{/if}}
|
||||
</row.cell>
|
||||
</body.row>
|
||||
{{/each}}
|
||||
|
||||
@@ -99,6 +99,16 @@ module('Acceptance | host-catalogs | host-sets | hosts', function (hooks) {
|
||||
assert.equal(findAll('tbody tr').length, count - 1);
|
||||
});
|
||||
|
||||
test('cannot remove a host without proper authorization', async function (assert) {
|
||||
assert.expect(1);
|
||||
const authorized_actions = instances.hostSet.authorized_actions.filter(
|
||||
(item) => item !== 'remove-hosts'
|
||||
);
|
||||
instances.hostSet.update({ authorized_actions });
|
||||
await visit(urls.hostSetHosts);
|
||||
assert.notOk(find('tbody tr .rose-dropdown-button-danger'));
|
||||
});
|
||||
|
||||
test('shows error message on host remove error', async function (assert) {
|
||||
assert.expect(2);
|
||||
this.server.post('/host-sets/:idMethod', () => {
|
||||
@@ -126,6 +136,22 @@ module('Acceptance | host-catalogs | host-sets | hosts', function (hooks) {
|
||||
assert.equal(currentURL(), urls.addHosts);
|
||||
});
|
||||
|
||||
test('can navigate to add hosts with proper authorization', async function (assert) {
|
||||
assert.expect(1);
|
||||
await visit(urls.hostSet);
|
||||
assert.ok(find(`[href="${urls.addHosts}"]`));
|
||||
});
|
||||
|
||||
test('cannot navigate to add hosts without proper authorization', async function (assert) {
|
||||
assert.expect(1);
|
||||
const authorized_actions = instances.hostSet.authorized_actions.filter(
|
||||
(item) => item !== 'add-hosts'
|
||||
);
|
||||
instances.hostSet.update({ authorized_actions });
|
||||
await visit(urls.hostSet);
|
||||
assert.notOk(find(`[href="${urls.addHosts}"]`));
|
||||
});
|
||||
|
||||
test('select and save hosts to add', async function (assert) {
|
||||
assert.expect(3);
|
||||
instances.hostSet.update({ hostIds: [] });
|
||||
|
||||
Reference in new issue
Block a user