Merge pull request #770 from hashicorp/chore-target-sources

Change target attributes and custom methods
This commit is contained in:
Randall Morey authored and GitHub committed 2021-09-24 16:08:24 -04:00
commit 4b2e319e33
53 files changed
+354 -362

No files matched your search

@@ -1,13 +1,13 @@
import Fragment from 'ember-data-model-fragments/fragment';
import { attr } from '@ember-data/model';
export default class FragmentHostSetModel extends Fragment {
export default class FragmentHostSourceModel extends Fragment {
// =attributes
@attr('string', {
description: 'ID of the related host set',
description: 'ID of the related host source',
})
host_set_id;
host_source_id;
@attr('string', {
description: 'ID of the catalog to which the host set belongs',
+32 -38
View File
@@ -12,23 +12,23 @@ export default class TargetModel extends GeneratedTargetModel {
@fragment('fragment-target-attributes', { defaultValue: {} }) attributes;
/**
* @type {[FragmentHostSetModel]}
* @type {[FragmentHostSourceModel]}
*/
@fragmentArray('fragment-host-set', {
@fragmentArray('fragment-host-source', {
readOnly: true,
emptyArrayIfMissing: true,
})
host_sets;
host_sources;
/**
* Credential library ids are read only and can be
* persisted via a dedicated call to `addCredentialLibraries()`.
* Credential source ids are read only and can be
* persisted via a dedicated call to `addCredentialSources()`.
*/
@fragmentArray('fragment-string', {
readOnly: true,
emptyArrayIfMissing: true,
})
application_credential_library_ids;
application_credential_source_ids;
/**
* An array of resolved host set and host catalog instances. Model instances
@@ -36,11 +36,11 @@ export default class TargetModel extends GeneratedTargetModel {
* instances). Unresolvable instances are excluded from the array.
* @type {[{model: HostSetModel, hostCatalog: HostCatalogModel}]}
*/
@computed('host_sets.[]', 'store')
@computed('host_sources.[]', 'store')
get hostSets() {
return this.host_sets
.map(({ host_set_id, host_catalog_id }) => ({
model: this.store.peekRecord('host-set', host_set_id),
return this.host_sources
.map(({ host_source_id, host_catalog_id }) => ({
model: this.store.peekRecord('host-set', host_source_id),
hostCatalog: this.store.peekRecord('host-catalog', host_catalog_id),
}))
.filter((hostSetRef) => hostSetRef.model !== null);
@@ -52,14 +52,11 @@ export default class TargetModel extends GeneratedTargetModel {
* instances). Unresolvable instances are excluded from the array.
* @type {[CredentialLibraryModel]}
*/
@computed('application_credential_library_ids.[]', 'store')
@computed('application_credential_source_ids.[]', 'store')
get credentialLibraries() {
return this.application_credential_library_ids
.map((credential_library_fragment) =>
this.store.peekRecord(
'credential-library',
credential_library_fragment.value
)
return this.application_credential_source_ids
.map((source) =>
this.store.peekRecord('credential-library', source.value)
)
.filter(Boolean);
}
@@ -96,16 +93,16 @@ export default class TargetModel extends GeneratedTargetModel {
// =methods
/**
* Adds host sets via the `add-host-sets` method.
* Adds host sets via the `add-host-sources` method.
* See serializer and adapter for more information.
* @param {[string]} hostSetIDs
* @param {object} options
* @param {object} options.adapterOptions
* @return {Promise}
*/
addHostSets(hostSetIDs, options = { adapterOptions: {} }) {
addHostSources(hostSetIDs, options = { adapterOptions: {} }) {
const defaultAdapterOptions = {
method: 'add-host-sets',
method: 'add-host-sources',
hostSetIDs,
};
// There is no "deep merge" in ES.
@@ -119,16 +116,16 @@ export default class TargetModel extends GeneratedTargetModel {
}
/**
* Delete host sets via the `remove-host-sets` method.
* Delete host sets via the `remove-host-sources` method.
* See serializer and adapter for more information.
* @param {[string]} hostSetIDs
* @param {object} options
* @param {object} options.adapterOptions
* @return {Promise}
*/
removeHostSets(hostSetIDs, options = { adapterOptions: {} }) {
removeHostSources(hostSetIDs, options = { adapterOptions: {} }) {
const defaultAdapterOptions = {
method: 'remove-host-sets',
method: 'remove-host-sources',
hostSetIDs,
};
// There is no "deep merge" in ES.
@@ -142,29 +139,26 @@ export default class TargetModel extends GeneratedTargetModel {
}
/**
* Delete a single host set via the `remove-host-sets` method.
* Delete a single host set via the `remove-host-sources` method.
* @param {number} hostSetID
* @param {object} options
* @return {Promise}
*/
removeHostSet(hostSetID, options) {
return this.removeHostSets([hostSetID], options);
removeHostSource(hostSetID, options) {
return this.removeHostSources([hostSetID], options);
}
/**
* Adds credential libraries via the `add-credential-libraries` method.
* Adds credential libraries via the `add-credential-sources` method.
* See serializer and adapter for more information.
* @param {[string]} credentialLibraryIDs
* @param {object} options
* @param {object} options.adapterOptions
* @return {Promise}
*/
addCredentialLibraries(
credentialLibraryIDs,
options = { adapterOptions: {} }
) {
addCredentialSources(credentialLibraryIDs, options = { adapterOptions: {} }) {
const defaultAdapterOptions = {
method: 'add-credential-libraries',
method: 'add-credential-sources',
credentialLibraryIDs,
};
// There is no "deep merge" in ES.
@@ -178,19 +172,19 @@ export default class TargetModel extends GeneratedTargetModel {
}
/**
* Delete credential libraries via the `remove-credential-libraries` method.
* Delete credential libraries via the `remove-credential-sources` method.
* See serializer and adapter for more information.
* @param {[string]} credentialLibraryIDs
* @param {object} options
* @param {object} options.adapterOptions
* @return {Promise}
*/
removeCredentialLibraries(
removeCredentialSources(
credentialLibraryIDs,
options = { adapterOptions: {} }
) {
const defaultAdapterOptions = {
method: 'remove-credential-libraries',
method: 'remove-credential-sources',
credentialLibraryIDs,
};
// There is no "deep merge" in ES.
@@ -204,12 +198,12 @@ export default class TargetModel extends GeneratedTargetModel {
}
/**
* Delete a single credential library set via the `remove-credential-libraries` method.
* Delete a single credential library set via the `remove-credential-sources` method.
* @param {number} credentialLibraryID
* @param {object} options
* @return {Promise}
*/
removeCredentialLibrary(credentialLibraryID, options) {
return this.removeCredentialLibraries([credentialLibraryID], options);
removeCredentialSource(credentialLibraryID, options) {
return this.removeCredentialSources([credentialLibraryID], options);
}
}
@@ -1,6 +1,6 @@
import JSONSerializer from '@ember-data/serializer/json';
export default class FragmentHostSetSerializer extends JSONSerializer {
export default class FragmentHostSourceSerializer extends JSONSerializer {
// =methods
/**
@@ -1,16 +0,0 @@
import JSONSerializer from '@ember-data/serializer/json';
export default class FragmentHostSetSerializer extends JSONSerializer {
// =methods
/**
* Renames `id` to `host_set_id` because fragments may not have IDs.
* Otherwise normalizes as normal.
* @param {ModelClass} typeClass
* @param {object} resourceHash
* @return {object}
*/
normalize(typeClass, { id: host_set_id, ...obj }) {
return super.normalize(typeClass, { host_set_id, ...obj });
}
}
@@ -0,0 +1,16 @@
import JSONSerializer from '@ember-data/serializer/json';
export default class FragmentHostSourceSerializer extends JSONSerializer {
// =methods
/**
* Renames `id` to `host_source_id` because fragments may not have IDs.
* Otherwise normalizes as normal.
* @param {ModelClass} typeClass
* @param {object} resourceHash
* @return {object}
*/
normalize(typeClass, { id: host_source_id, ...obj }) {
return super.normalize(typeClass, { host_source_id, ...obj });
}
}
+17 -16
View File
@@ -17,43 +17,44 @@ export default class TargetSerializer extends ApplicationSerializer {
*/
serialize(snapshot) {
let serialized = super.serialize(...arguments);
const hostSetIDs = snapshot?.adapterOptions?.hostSetIDs;
if (hostSetIDs)
serialized = this.serializeWithHostSets(snapshot, hostSetIDs);
const credentialLibraryIDs = snapshot?.adapterOptions?.credentialLibraryIDs;
if (credentialLibraryIDs)
serialized = this.serializeWithCredentialLibraries(
const hostSourceIDs = snapshot?.adapterOptions?.hostSetIDs;
if (hostSourceIDs) {
serialized = this.serializeWithHostSources(snapshot, hostSourceIDs);
}
const credentialSourceIDs = snapshot?.adapterOptions?.credentialLibraryIDs;
if (credentialSourceIDs)
serialized = this.serializeWithCredentialSources(
snapshot,
credentialLibraryIDs
credentialSourceIDs
);
return serialized;
}
/**
* Returns a payload containing only the host_set_ids array using IDs
* passed into the function (rather than existing host sets on the model).
* Returns a payload containing only version and an array of passed IDs,
* rather than existing instances on the model.
* @param {Snapshot} snapshot
* @param {[string]} hostSetIDs
* @return {object}
*/
serializeWithHostSets(snapshot, hostSetIDs) {
serializeWithHostSources(snapshot, hostSourceIDs) {
return {
version: snapshot.attr('version'),
host_set_ids: hostSetIDs,
host_source_ids: hostSourceIDs,
};
}
/**
* Returns a payload containing only the credential_library_ids array using IDs
* passed into the function (rather than existing credential libraries on the model).
* Returns a payload containing only version and an array of passed IDs,
* rather than existing instances on the model.
* @param {Snapshot} snapshot
* @param {[string]} credentialLibraryIDs
* @param {[string]} credentialSourceIDs
* @return {object}
*/
serializeWithCredentialLibraries(snapshot, credentialLibraryIDs) {
serializeWithCredentialSources(snapshot, credentialSourceIDs) {
return {
version: snapshot.attr('version'),
application_credential_library_ids: credentialLibraryIDs,
application_credential_source_ids: credentialSourceIDs,
};
}
}
@@ -1 +0,0 @@
export { default } from 'api/models/fragment-host-set';
@@ -0,0 +1 @@
export { default } from 'api/models/fragment-host-source';
@@ -1 +0,0 @@
export { default } from 'api/serializers/fragment-host-set';
@@ -0,0 +1 @@
export { default } from 'api/serializers/fragment-host-source';
+12 -12
View File
@@ -367,37 +367,37 @@ export default function () {
const updatedAttrs = {
version: attrs.version,
};
// If adding host sets, push them into the array
if (method === 'add-host-sets') {
// If adding host sources, push them into the array
if (method === 'add-host-sources') {
updatedAttrs.hostSetIds = target.hostSetIds;
attrs.hostSetIds.forEach((id) => {
attrs.hostSourceIds.forEach((id) => {
if (!updatedAttrs.hostSetIds.includes(id)) {
updatedAttrs.hostSetIds.push(id);
}
});
}
// If deleting host sets, filter them out of the array
if (method === 'remove-host-sets') {
// If deleting host sources, filter them out of the array
if (method === 'remove-host-sources') {
updatedAttrs.hostSetIds = target.hostSetIds;
updatedAttrs.hostSetIds = updatedAttrs.hostSetIds.filter((id) => {
return !attrs.hostSetIds.includes(id);
return !attrs.hostSourceIds.includes(id);
});
}
// If adding credential libraries, push them into the array
if (method === 'add-credential-libraries') {
// If adding credential sources, push them into the array
if (method === 'add-credential-sources') {
updatedAttrs.credentialLibraryIds = target.credentialLibraryIds;
attrs.applicationCredentialLibraryIds.forEach((id) => {
attrs.applicationCredentialSourceIds.forEach((id) => {
if (!updatedAttrs.credentialLibraryIds.includes(id)) {
updatedAttrs.credentialLibraryIds.push(id);
}
});
}
// If deleting credential libraries, filter them out of the array
if (method === 'remove-credential-libraries') {
// If deleting credential sources, filter them out of the array
if (method === 'remove-credential-sources') {
updatedAttrs.credentialLibraryIds = target.credentialLibraryIds;
updatedAttrs.credentialLibraryIds =
updatedAttrs.credentialLibraryIds.filter((id) => {
return !attrs.applicationCredentialLibraryIds.includes(id);
return !attrs.applicationCredentialSourceIds.includes(id);
});
}
return target.update(updatedAttrs);
+2 -2
View File
@@ -17,14 +17,14 @@ export default ApplicationSerializer.extend({
);
const { hostSets } = this.schema;
if (model.hostSetIds?.length) {
json.host_sets = model.hostSetIds.map((host_set_id) => {
json.host_sources = model.hostSetIds.map((host_set_id) => {
const hostSet = hostSets.find(host_set_id);
const host_catalog_id = hostSet?.hostCatalog?.id;
return { id: host_set_id, host_catalog_id };
});
}
if (model.credentialLibraryIds?.length) {
json.application_credential_library_ids = model.credentialLibraryIds;
json.application_credential_source_ids = model.credentialLibraryIds;
}
return json;
},
@@ -1,12 +1,12 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Model | fragment host set', function (hooks) {
module('Unit | Model | fragment host source', function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let store = this.owner.lookup('service:store');
let model = store.createRecord('fragment-host-set', {});
let model = store.createRecord('fragment-host-source', {});
assert.ok(model);
});
});
@@ -68,7 +68,7 @@ module('Unit | Model | host set', function (hooks) {
await model.addHost('foobar');
});
test('it has a `removeHostSets` method that targets a specific POST API endpoint and serialization', async function (assert) {
test('it has a `removeHosts` method that targets a specific POST API endpoint and serialization', async function (assert) {
assert.expect(1);
this.server.post('/v1/host-sets/123abc:remove-hosts', (schema, request) => {
const body = JSON.parse(request.requestBody);
+84 -81
View File
@@ -14,18 +14,18 @@ module('Unit | Model | target', function (hooks) {
id: '123abc',
type: 'target',
attributes: {
host_sets: [
{ host_set_id: '1', host_catalog_id: '2' },
{ host_set_id: '3', host_catalog_id: '2' },
host_sources: [
{ host_source_id: '1', host_catalog_id: '2' },
{ host_source_id: '3', host_catalog_id: '2' },
],
},
},
});
const target = store.peekRecord('target', '123abc');
assert.equal(
target.host_sets.length,
target.host_sources.length,
2,
'Target has two entires in host_sets'
'Target has two entires in host_sources'
);
assert.equal(
target.hostSets.length,
@@ -46,14 +46,14 @@ module('Unit | Model | target', function (hooks) {
attributes: {},
},
});
// Since `hostSets` is computed on `host_sets`, not the store itself,
// Since `hostSets` is computed on `host_sources`, not the store itself,
// it's necessary to do this assignment to kick-off the computed update.
// eslint-disable-next-line no-self-assign
target.host_sets = target.host_sets;
target.host_sources = target.host_sources;
assert.equal(
target.host_sets.length,
target.host_sources.length,
2,
'Target has two entires in host_sets'
'Target has two entires in host_sources'
);
assert.equal(target.hostSets.length, 2, 'Target has two resolved hostSets');
assert.notOk(
@@ -68,52 +68,18 @@ module('Unit | Model | target', function (hooks) {
},
});
// eslint-disable-next-line no-self-assign
target.host_sets = target.host_sets;
target.host_sources = target.host_sources;
assert.ok(target.hostSets[0].hostCatalog, 'Host catalog is resolved');
});
test('it has an `addHostSets` method that targets a specific POST API endpoint and serialization', async function (assert) {
assert.expect(1);
this.server.post('/v1/targets/123abc:add-host-sets', (schema, request) => {
const body = JSON.parse(request.requestBody);
assert.deepEqual(body, {
host_set_ids: ['123_abc', 'foobar'],
version: 1,
});
return { id: '123abc' };
});
const store = this.owner.lookup('service:store');
store.push({
data: {
id: '123abc',
type: 'target',
attributes: {
name: 'Target',
description: 'Description',
host_sets: [
{ host_set_id: '1', host_catalog_id: '2' },
{ host_set_id: '3', host_catalog_id: '4' },
],
version: 1,
scope: {
scope_id: 'o_1',
type: 'scope',
},
},
},
});
const model = store.peekRecord('target', '123abc');
await model.addHostSets(['123_abc', 'foobar']);
});
test('it has a `removeHostSets` method that targets a specific POST API endpoint and serialization', async function (assert) {
test('it has an `addHostSources` method that targets a specific POST API endpoint and serialization', async function (assert) {
assert.expect(1);
this.server.post(
'/v1/targets/123abc:remove-host-sets',
'/v1/targets/123abc:add-host-sources',
(schema, request) => {
const body = JSON.parse(request.requestBody);
assert.deepEqual(body, {
host_set_ids: ['1', '3'],
host_source_ids: ['123_abc', 'foobar'],
version: 1,
});
return { id: '123abc' };
@@ -127,9 +93,9 @@ module('Unit | Model | target', function (hooks) {
attributes: {
name: 'Target',
description: 'Description',
host_sets: [
{ host_set_id: '1', host_catalog_id: '2' },
{ host_set_id: '3', host_catalog_id: '4' },
host_sources: [
{ host_source_id: '1', host_catalog_id: '2' },
{ host_source_id: '3', host_catalog_id: '4' },
],
version: 1,
scope: {
@@ -140,17 +106,17 @@ module('Unit | Model | target', function (hooks) {
},
});
const model = store.peekRecord('target', '123abc');
await model.removeHostSets(['1', '3']);
await model.addHostSources(['123_abc', 'foobar']);
});
test('it has a `removeHostSet` method that deletes a single host set using `removeHostSets` method', async function (assert) {
test('it has a `removeHostSources` method that targets a specific POST API endpoint and serialization', async function (assert) {
assert.expect(1);
this.server.post(
'/v1/targets/123abc:remove-host-sets',
'/v1/targets/123abc:remove-host-sources',
(schema, request) => {
const body = JSON.parse(request.requestBody);
assert.deepEqual(body, {
host_set_ids: ['3'],
host_source_ids: ['1', '3'],
version: 1,
});
return { id: '123abc' };
@@ -164,9 +130,9 @@ module('Unit | Model | target', function (hooks) {
attributes: {
name: 'Target',
description: 'Description',
host_sets: [
{ host_set_id: '1', host_catalog_id: '2' },
{ host_set_id: '3', host_catalog_id: '4' },
host_sources: [
{ host_source_id: '1', host_catalog_id: '2' },
{ host_source_id: '3', host_catalog_id: '4' },
],
version: 1,
scope: {
@@ -177,7 +143,44 @@ module('Unit | Model | target', function (hooks) {
},
});
const model = store.peekRecord('target', '123abc');
await model.removeHostSet('3');
await model.removeHostSources(['1', '3']);
});
test('it has a `removeHostSource` method that deletes a single host set using `removeHostSources` method', async function (assert) {
assert.expect(1);
this.server.post(
'/v1/targets/123abc:remove-host-sources',
(schema, request) => {
const body = JSON.parse(request.requestBody);
assert.deepEqual(body, {
host_source_ids: ['3'],
version: 1,
});
return { id: '123abc' };
}
);
const store = this.owner.lookup('service:store');
store.push({
data: {
id: '123abc',
type: 'target',
attributes: {
name: 'Target',
description: 'Description',
host_sources: [
{ host_source_id: '1', host_catalog_id: '2' },
{ host_source_id: '3', host_catalog_id: '4' },
],
version: 1,
scope: {
scope_id: 'o_1',
type: 'scope',
},
},
},
});
const model = store.peekRecord('target', '123abc');
await model.removeHostSource('3');
});
test('it has a `sessions` array of session instances associated with the target (if those instances are already in the store)', function (assert) {
@@ -232,15 +235,15 @@ module('Unit | Model | target', function (hooks) {
id: '123abc',
type: 'target',
attributes: {
application_credential_library_ids: [{ value: '1' }, { value: '2' }],
application_credential_source_ids: [{ value: '1' }, { value: '2' }],
},
},
});
const target = store.peekRecord('target', '123abc');
assert.equal(
target.application_credential_library_ids.length,
target.application_credential_source_ids.length,
2,
'Target has two entires in application_credential_library_ids'
'Target has two entires in application_credential_source_ids'
);
assert.equal(
target.credentialLibraries.length,
@@ -261,17 +264,17 @@ module('Unit | Model | target', function (hooks) {
attributes: {},
},
});
// Since `credentialLibraries` is computed on `application_credential_library_ids`,
// Since `credentialLibraries` is computed on `application_credential_source_ids`,
// not the store itself, it's necessary to do this assignment to kick-off the
// computed update.
/* eslint-disable no-self-assign */
target.application_credential_library_ids =
target.application_credential_library_ids;
target.application_credential_source_ids =
target.application_credential_source_ids;
/* eslint-enable no-self-assign */
assert.equal(
target.application_credential_library_ids.length,
target.application_credential_source_ids.length,
2,
'Target has two entires in application_credential_library_ids'
'Target has two entires in application_credential_source_ids'
);
assert.equal(
target.credentialLibraries.length,
@@ -280,14 +283,14 @@ module('Unit | Model | target', function (hooks) {
);
});
test('it has an `addCredentialLibraries` method that targets a specific POST API endpoint and serialization', async function (assert) {
test('it has an `addCredentialSources` method that targets a specific POST API endpoint and serialization', async function (assert) {
assert.expect(1);
this.server.post(
'/v1/targets/123abc:add-credential-libraries',
'/v1/targets/123abc:add-credential-sources',
(schema, request) => {
const body = JSON.parse(request.requestBody);
assert.deepEqual(body, {
application_credential_library_ids: ['123_abc', 'foobar'],
application_credential_source_ids: ['123_abc', 'foobar'],
version: 1,
});
return { id: '123abc' };
@@ -301,7 +304,7 @@ module('Unit | Model | target', function (hooks) {
attributes: {
name: 'Target',
description: 'Description',
application_credential_library_ids: [{ value: '1' }, { value: '2' }],
application_credential_source_ids: [{ value: '1' }, { value: '2' }],
version: 1,
scope: {
scope_id: 'o_1',
@@ -311,17 +314,17 @@ module('Unit | Model | target', function (hooks) {
},
});
const model = store.peekRecord('target', '123abc');
await model.addCredentialLibraries(['123_abc', 'foobar']);
await model.addCredentialSources(['123_abc', 'foobar']);
});
test('it has a `removeCredentialLibraries` method that targets a specific POST API endpoint and serialization', async function (assert) {
test('it has a `removeCredentialSources` method that targets a specific POST API endpoint and serialization', async function (assert) {
assert.expect(1);
this.server.post(
'/v1/targets/123abc:remove-credential-libraries',
'/v1/targets/123abc:remove-credential-sources',
(schema, request) => {
const body = JSON.parse(request.requestBody);
assert.deepEqual(body, {
application_credential_library_ids: ['1', '2'],
application_credential_source_ids: ['1', '2'],
version: 1,
});
return { id: '123abc' };
@@ -335,7 +338,7 @@ module('Unit | Model | target', function (hooks) {
attributes: {
name: 'Target',
description: 'Description',
application_credential_library_ids: [{ value: '1' }, { value: '2' }],
application_credential_source_ids: [{ value: '1' }, { value: '2' }],
version: 1,
scope: {
scope_id: 'o_1',
@@ -345,17 +348,17 @@ module('Unit | Model | target', function (hooks) {
},
});
const model = store.peekRecord('target', '123abc');
await model.removeCredentialLibraries(['1', '2']);
await model.removeCredentialSources(['1', '2']);
});
test('it has a `removeCredentialLibrary` method that deletes a single credential library using `removeCredentialLibraries` method', async function (assert) {
test('it has a `removeCredentialSource` method that deletes a single credential library using `removeCredentialSources` method', async function (assert) {
assert.expect(1);
this.server.post(
'/v1/targets/123abc:remove-credential-libraries',
'/v1/targets/123abc:remove-credential-sources',
(schema, request) => {
const body = JSON.parse(request.requestBody);
assert.deepEqual(body, {
application_credential_library_ids: ['2'],
application_credential_source_ids: ['2'],
version: 1,
});
return { id: '123abc' };
@@ -369,7 +372,7 @@ module('Unit | Model | target', function (hooks) {
attributes: {
name: 'Target',
description: 'Description',
application_credential_library_ids: [{ value: '1' }, { value: '2' }],
application_credential_source_ids: [{ value: '1' }, { value: '2' }],
version: 1,
scope: {
scope_id: 'o_1',
@@ -379,6 +382,6 @@ module('Unit | Model | target', function (hooks) {
},
});
const model = store.peekRecord('target', '123abc');
await model.removeCredentialLibrary('2');
await model.removeCredentialSource('2');
});
});
@@ -204,8 +204,8 @@ module('Unit | Serializer | application', function (hooks) {
authorized_actions: [],
name: 'Target 1',
scope: { scope_id: 'o_123' },
host_sets: [],
application_credential_library_ids: [],
host_sources: [],
application_credential_source_ids: [],
},
relationships: {},
},
@@ -1,27 +1,27 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import FragmentHostSet from 'api/models/fragment-host-set';
import FragmentHostSource from 'api/models/fragment-host-source';
module('Unit | Serializer | fragment host set', function (hooks) {
module('Unit | Serializer | fragment host source', function (hooks) {
setupTest(hooks);
test('it normalizes `id` into `host_set_id`', function (assert) {
test('it normalizes `id` into `host_source_id`', function (assert) {
assert.expect(1);
const store = this.owner.lookup('service:store');
const serializer = store.serializerFor('fragment-host-set');
const normalized = serializer.normalize(FragmentHostSet, {
const serializer = store.serializerFor('fragment-host-source');
const normalized = serializer.normalize(FragmentHostSource, {
id: '2',
host_catalog_id: '1',
});
assert.deepEqual(normalized, {
data: {
attributes: {
host_set_id: '2',
host_source_id: '2',
host_catalog_id: '1',
},
id: null,
relationships: {},
type: 'fragment-host-set',
type: 'fragment-host-source',
},
});
});
@@ -11,11 +11,11 @@ module('Unit | Serializer | target', function (hooks) {
const record = store.createRecord('target', {
name: 'User',
description: 'Description',
host_sets: [
{ host_set_id: '1', host_catalog_id: '2' },
{ host_set_id: '3', host_catalog_id: '4' },
host_sources: [
{ host_source_id: '1', host_catalog_id: '2' },
{ host_source_id: '3', host_catalog_id: '4' },
],
application_credential_library_ids: [{ value: '1' }, { value: '2' }],
application_credential_source_ids: [{ value: '1' }, { value: '2' }],
scope: {
scope_id: 'org_1',
type: 'org',
@@ -40,16 +40,16 @@ module('Unit | Serializer | target', function (hooks) {
});
});
test('it serializes only host sets and version when an `adapterOptions.hostSetIDs` array is passed', function (assert) {
test('it serializes only host sources and version when an `adapterOptions.hostSetIDs` array is passed', function (assert) {
assert.expect(1);
const store = this.owner.lookup('service:store');
const serializer = store.serializerFor('target');
const record = store.createRecord('target', {
name: 'User',
description: 'Description',
host_sets: [
{ host_set_id: '1', host_catalog_id: '2' },
{ host_set_id: '3', host_catalog_id: '4' },
host_sources: [
{ host_source_id: '1', host_catalog_id: '2' },
{ host_source_id: '3', host_catalog_id: '4' },
],
version: 1,
});
@@ -59,19 +59,19 @@ module('Unit | Serializer | target', function (hooks) {
};
const serializedRecord = serializer.serialize(snapshot);
assert.deepEqual(serializedRecord, {
host_set_ids: ['4', '5'],
host_source_ids: ['4', '5'],
version: 1,
});
});
test('it serializes only credential libraries and version when an `adapterOptions.credentialLibraryIDs` array is passed', function (assert) {
test('it serializes only credential sources and version when an `adapterOptions.credentialLibraryIDs` array is passed', function (assert) {
assert.expect(1);
const store = this.owner.lookup('service:store');
const serializer = store.serializerFor('target');
const record = store.createRecord('target', {
name: 'User',
description: 'Description',
application_credential_library_ids: [{ value: '1' }, { value: '2' }],
application_credential_source_ids: [{ value: '1' }, { value: '2' }],
version: 1,
});
const snapshot = record._createSnapshot();
@@ -80,7 +80,7 @@ module('Unit | Serializer | target', function (hooks) {
};
const serializedRecord = serializer.serialize(snapshot);
assert.deepEqual(serializedRecord, {
application_credential_library_ids: ['4', '5'],
application_credential_source_ids: ['4', '5'],
version: 1,
});
});
@@ -93,11 +93,11 @@ module('Unit | Serializer | target', function (hooks) {
const payload = {
id: '1',
name: 'Target 1',
host_sets: [
{ host_set_id: '1', host_catalog_id: '2' },
{ host_set_id: '3', host_catalog_id: '4' },
host_sources: [
{ host_source_id: '1', host_catalog_id: '2' },
{ host_source_id: '3', host_catalog_id: '4' },
],
application_credential_library_ids: ['1'],
application_credential_source_ids: ['1'],
};
const normalized = serializer.normalizeSingleResponse(
store,
@@ -112,18 +112,18 @@ module('Unit | Serializer | target', function (hooks) {
attributes: {
authorized_actions: [],
name: 'Target 1',
host_sets: [
{ host_set_id: '1', host_catalog_id: '2' },
{ host_set_id: '3', host_catalog_id: '4' },
host_sources: [
{ host_source_id: '1', host_catalog_id: '2' },
{ host_source_id: '3', host_catalog_id: '4' },
],
application_credential_library_ids: [{ value: '1' }],
application_credential_source_ids: [{ value: '1' }],
},
relationships: {},
},
});
});
test('it normalizes missing host_sets and credential libraries to empty array', function (assert) {
test('it normalizes missing host_sources and application_credential_source_ids to empty array', function (assert) {
assert.expect(1);
const store = this.owner.lookup('service:store');
const serializer = store.serializerFor('target');
@@ -147,8 +147,8 @@ module('Unit | Serializer | target', function (hooks) {
authorized_actions: [],
name: 'Target 1',
scope: { scope_id: 'o_123' },
host_sets: [],
application_credential_library_ids: [],
host_sources: [],
application_credential_source_ids: [],
},
relationships: {},
},
@@ -23,7 +23,6 @@ choose-org: Choose Scope
choose-different-org: Choose a different scope
add-host-set: Create Host Set
add-host: Create Host
add-host-sets: Add Host Sets
add-principals: Add Principals
add-members: Add Members
add-hosts: Add Hosts
@@ -253,11 +253,11 @@ target:
actions:
create: New Target
delete: Delete Target
add-host-sets: Add Host Sources
add-credential-libraries: Add Credential Sources
add-host-sources: Add Host Sources
add-credential-sources: Add Credential Sources
types:
tcp: TCP
host-set:
host-source:
title: Host Source
title_plural: Host Sources
messages:
@@ -270,7 +270,7 @@ target:
add:
title: Add Host Sources
description: Select host sources to assign to this target.
credential-library:
credential-source:
title: Credential Source
title_plural: Credential Sources
messages:
@@ -8,7 +8,7 @@
as |form|
>
<form.actions
@submitText={{t 'resources.target.actions.add-credential-libraries'}}
@submitText={{t 'resources.target.actions.add-credential-sources'}}
@cancelText={{t 'actions.cancel'}}
/>
@@ -48,13 +48,13 @@
{{#unless this.hasAvailableCredentialLibraries}}
<Rose::Layout::Centered>
<Rose::Message
@title={{t 'resources.target.credential-library.messages.none.title'}}
@title={{t 'resources.target.credential-source.messages.none.title'}}
as |message|
>
<message.description>
{{t 'resources.target.credential-library.messages.none.description'}}
{{t 'resources.target.credential-source.messages.none.description'}}
</message.description>
<message.link @route='scopes.scope.targets.target.credential-libraries'>
<message.link @route='scopes.scope.targets.target.credential-sources'>
<Rose::Icon @name='flight-icons/svg/chevron-left-16' />
{{t 'actions.back'}}
</message.link>
@@ -26,13 +26,13 @@ export default class FormTargetAddCredentialLibrariesIndexComponent extends Comp
* @type {[CredentialLibraryModel]}
*/
@computed(
'args.{credentialLibraries.[],model.application_credential_library_ids.[]}'
'args.{credentialLibraries.[],model.application_credential_source_ids.[]}'
)
get filteredCredentialLibraries() {
// Get IDs for credential libraries already added to the current target
const currentCredentialLibraryIDs =
this.args.model.application_credential_library_ids.map(
(credentialLibrary) => credentialLibrary.value
this.args.model.application_credential_source_ids.map(
(source) => source.value
);
const notAddedCredentialLibraries = this.args.credentialLibraries.filter(
({ id }) => !currentCredentialLibraryIDs.includes(id)
@@ -9,7 +9,7 @@
>
<form.actions
@submitText={{t 'resources.target.actions.add-host-sets'}}
@submitText={{t 'resources.target.actions.add-host-sources'}}
@cancelText={{t 'actions.cancel'}}
/>
@@ -52,13 +52,13 @@
{{#unless this.hasAvailableHostSets}}
<Rose::Layout::Centered>
<Rose::Message
@title={{t 'resources.target.host-set.messages.none.title'}}
@title={{t 'resources.target.host-source.messages.none.title'}}
as |message|
>
<message.description>
{{t 'resources.target.host-set.messages.none.description'}}
{{t 'resources.target.host-source.messages.none.description'}}
</message.description>
<message.link @route='scopes.scope.targets.target.host-sets'>
<message.link @route='scopes.scope.targets.target.host-sources'>
<Rose::Icon @name='flight-icons/svg/chevron-left-16' />
{{t 'actions.back'}}
</message.link>
@@ -25,11 +25,11 @@ export default class FormTargetAddHostSetsComponent extends Component {
* Host sets not already added to the target.
* @type {[HostSetModel]}
*/
@computed('args.{hostSets.[],model.host_sets.[]}')
@computed('args.{hostSets.[],model.host_sources.[]}')
get filteredHostSets() {
// Get IDs for host sets already added to the current target
const alreadyAddedHostSetIDs = this.args.model.host_sets.map(
({ host_set_id }) => host_set_id
const alreadyAddedHostSetIDs = this.args.model.host_sources.map(
({ host_source_id }) => host_source_id
);
const notAddedHostSets = this.args.hostSets.filter(
({ id }) => !alreadyAddedHostSetIDs.includes(id)
@@ -1,7 +1,7 @@
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
export default class ScopesScopeTargetsTargetHostSetsController extends Controller {
export default class ScopesScopeTargetsTargetAddHostSourcesController extends Controller {
// =services
@service intl;
@@ -13,6 +13,6 @@ export default class ScopesScopeTargetsTargetHostSetsController extends Controll
* @type {string}
*/
get breadCrumb() {
return this.intl.t('resources.host-set.title_plural');
return this.intl.t('resources.target.actions.add-host-sources');
}
}
@@ -1,7 +1,7 @@
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
export default class ScopesScopeTargetsTargetCredentialLibrariesController extends Controller {
export default class ScopesScopeTargetsTargetCredentialSourcesController extends Controller {
// =services
@service intl;
@@ -13,6 +13,6 @@ export default class ScopesScopeTargetsTargetCredentialLibrariesController exten
* @type {string}
*/
get breadCrumb() {
return this.intl.t('resources.credential-library.title_plural');
return this.intl.t('resources.target.credential-source.title_plural');
}
}
@@ -1,7 +1,7 @@
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
export default class ScopesScopeTargetsTargetAddHostSetsController extends Controller {
export default class ScopesScopeTargetsTargetHostSourcesController extends Controller {
// =services
@service intl;
@@ -13,6 +13,6 @@ export default class ScopesScopeTargetsTargetAddHostSetsController extends Contr
* @type {string}
*/
get breadCrumb() {
return this.intl.t('resources.target.actions.add-host-sets');
return this.intl.t('resources.target.host-source.title_plural');
}
}
+4 -4
View File
@@ -63,10 +63,10 @@ Router.map(function () {
this.route('targets', function () {
this.route('target', { path: ':target_id' }, function () {
this.route('host-sets', function () {});
this.route('add-host-sets');
this.route('credential-libraries');
this.route('add-credential-libraries');
this.route('host-sources', function () {});
this.route('add-host-sources');
this.route('credential-sources');
this.route('add-credential-sources');
});
this.route('new');
});
@@ -5,7 +5,7 @@ import { action } from '@ember/object';
import loading from 'ember-loading/decorator';
import { notifySuccess, notifyError } from 'core/decorators/notify';
export default class ScopesScopeTargetsTargetAddCredentialLibrariesRoute extends Route {
export default class ScopesScopeTargetsTargetAddCredentialSourcesRoute extends Route {
// =services
@service intl;
@@ -49,13 +49,10 @@ export default class ScopesScopeTargetsTargetAddCredentialLibrariesRoute extends
renderTemplate() {
super.renderTemplate(...arguments);
this.render(
'scopes/scope/targets/target/add-credential-libraries/-header',
{
into: 'scopes/scope/targets/target',
outlet: 'header',
}
);
this.render('scopes/scope/targets/target/add-credential-sources/-header', {
into: 'scopes/scope/targets/target',
outlet: 'header',
});
this.render('-empty', {
into: 'scopes/scope/targets/target',
@@ -80,15 +77,15 @@ export default class ScopesScopeTargetsTargetAddCredentialLibrariesRoute extends
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.add-success')
async save(target, credentialLibraryIDs) {
await target.addCredentialLibraries(credentialLibraryIDs);
this.replaceWith('scopes.scope.targets.target.credential-libraries');
await target.addCredentialSources(credentialLibraryIDs);
this.replaceWith('scopes.scope.targets.target.credential-sources');
}
/**
* Redirect to target credential libraries as if nothing ever happened.
* Redirect to target credential sources as if nothing ever happened.
*/
@action
cancel() {
this.replaceWith('scopes.scope.targets.target.credential-libraries');
this.replaceWith('scopes.scope.targets.target.credential-sources');
}
}
@@ -5,7 +5,7 @@ import { all } from 'rsvp';
import loading from 'ember-loading/decorator';
import { notifySuccess, notifyError } from 'core/decorators/notify';
export default class ScopesScopeTargetsTargetAddHostSetsRoute extends Route {
export default class ScopesScopeTargetsTargetAddHostSourcesRoute extends Route {
// =services
@service intl;
@@ -42,13 +42,13 @@ export default class ScopesScopeTargetsTargetAddHostSetsRoute extends Route {
}
/**
* Renders the add-host-sets-specific header template.
* Renders the add-host-sources-specific header template.
* @override
*/
renderTemplate() {
super.renderTemplate(...arguments);
this.render('scopes/scope/targets/target/add-host-sets/-header', {
this.render('scopes/scope/targets/target/add-host-sources/-header', {
into: 'scopes/scope/targets/target',
outlet: 'header',
});
@@ -71,15 +71,15 @@ export default class ScopesScopeTargetsTargetAddHostSetsRoute extends Route {
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.add-success')
async save(target, hostSetIDs) {
await target.addHostSets(hostSetIDs);
this.replaceWith('scopes.scope.targets.target.host-sets');
await target.addHostSources(hostSetIDs);
this.replaceWith('scopes.scope.targets.target.host-sources');
}
/**
* Redirect to target host sets as if nothing ever happened.
* Redirect to target host sources as if nothing ever happened.
*/
@action
cancel() {
this.replaceWith('scopes.scope.targets.target.host-sets');
this.replaceWith('scopes.scope.targets.target.host-sources');
}
}
@@ -5,7 +5,7 @@ import loading from 'ember-loading/decorator';
import { confirm } from 'core/decorators/confirm';
import { notifySuccess, notifyError } from 'core/decorators/notify';
export default class ScopesScopeTargetsTargetCredentialLibrariesRoute extends Route {
export default class ScopesScopeTargetsTargetCredentialSourcesRoute extends Route {
// =methods
/**
@@ -13,7 +13,7 @@ export default class ScopesScopeTargetsTargetCredentialLibrariesRoute extends Ro
* @return {Promise{[CredentialLibraryModel]}}
*/
beforeModel() {
const { application_credential_library_ids: credential_libraries } =
const { application_credential_source_ids: credential_libraries } =
this.modelFor('scopes.scope.targets.target');
return all(
credential_libraries.map((credential_library) =>
@@ -44,8 +44,8 @@ export default class ScopesScopeTargetsTargetCredentialLibrariesRoute extends Ro
@confirm('questions.remove-confirm')
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.remove-success')
async removeCredentialLibrary(target, credentialLibrary) {
await target.removeCredentialLibrary(credentialLibrary.id);
async removeCredentialSource(target, credentialLibrary) {
await target.removeCredentialSource(credentialLibrary.id);
this.refresh();
}
}
@@ -6,7 +6,7 @@ import loading from 'ember-loading/decorator';
import { confirm } from 'core/decorators/confirm';
import { notifySuccess, notifyError } from 'core/decorators/notify';
export default class ScopesScopeTargetsTargetHostSetsRoute extends Route {
export default class ScopesScopeTargetsTargetHostSourcesRoute extends Route {
// =services
@service intl;
@@ -20,9 +20,11 @@ export default class ScopesScopeTargetsTargetHostSetsRoute extends Route {
* @return {Promise{[HostSetModel, HostCatalogModel]}}
*/
beforeModel() {
const { scopeID, host_sets } = this.modelFor('scopes.scope.targets.target');
const promises = host_sets.map(
({ host_set_id, host_catalog_id: hostCatalogID }) =>
const { scopeID, host_sources } = this.modelFor(
'scopes.scope.targets.target'
);
const promises = host_sources.map(
({ host_source_id, host_catalog_id: hostCatalogID }) =>
hash({
// TODO: multiple host sets may belong to the same catalog,
// resulting in the catalog being loaded multiple times.
@@ -30,7 +32,7 @@ export default class ScopesScopeTargetsTargetHostSetsRoute extends Route {
hostCatalog: this.store.findRecord('host-catalog', hostCatalogID, {
adapterOptions: { scopeID },
}),
hostSet: this.store.findRecord('host-set', host_set_id, {
hostSet: this.store.findRecord('host-set', host_source_id, {
adapterOptions: { scopeID, hostCatalogID },
}),
})
@@ -58,8 +60,8 @@ export default class ScopesScopeTargetsTargetHostSetsRoute extends Route {
@confirm('questions.remove-confirm')
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.remove-success')
async removeHostSet(target, hostSet) {
await target.removeHostSet(hostSet.id);
async removeHostSource(target, hostSet) {
await target.removeHostSource(hostSet.id);
this.refresh();
}
}
@@ -3,14 +3,12 @@
@dropdownRight={{true}}
as |dropdown|
>
<dropdown.link @route='scopes.scope.targets.target.add-host-sets'>
{{t 'resources.target.actions.add-host-sets'}}
<dropdown.link @route='scopes.scope.targets.target.add-host-sources'>
{{t 'resources.target.actions.add-host-sources'}}
</dropdown.link>
{{#if (feature-flag 'credential-store')}}
<dropdown.link
@route='scopes.scope.targets.target.add-credential-libraries'
>
{{t 'resources.target.actions.add-credential-libraries'}}
<dropdown.link @route='scopes.scope.targets.target.add-credential-sources'>
{{t 'resources.target.actions.add-credential-sources'}}
</dropdown.link>
{{/if}}
{{#if (can 'delete model' @model)}}
@@ -2,12 +2,12 @@
<nav.link @route='scopes.scope.targets.target.index'>
{{t 'titles.details'}}
</nav.link>
<nav.link @route='scopes.scope.targets.target.host-sets'>
{{t 'resources.target.host-set.title_plural'}}
<nav.link @route='scopes.scope.targets.target.host-sources'>
{{t 'resources.target.host-source.title_plural'}}
</nav.link>
{{#if (feature-flag 'credential-store')}}
<nav.link @route='scopes.scope.targets.target.credential-libraries'>
{{t 'resources.target.credential-library.title_plural'}}
<nav.link @route='scopes.scope.targets.target.credential-sources'>
{{t 'resources.target.credential-source.title_plural'}}
</nav.link>
{{/if}}
</Rose::Nav::Tabs>
@@ -1,4 +0,0 @@
<h2>
{{t 'resources.target.credential-library.messages.add.title'}}
</h2>
<p>{{t 'resources.target.credential-library.messages.add.description'}}</p>
@@ -1,4 +1,4 @@
{{page-title (t 'resources.target.actions.add-credential-libraries')}}
{{page-title (t 'resources.target.actions.add-credential-sources')}}
{{#if @model.credentialLibraries}}
<Form::Target::AddCredentialLibraries
@@ -12,13 +12,13 @@
{{#unless @model.credentialLibraries}}
<Rose::Layout::Centered>
<Rose::Message
@title={{t 'resources.target.credential-library.messages.none.title'}}
@title={{t 'resources.target.credential-source.messages.none.title'}}
as |message|
>
<message.description>
{{t 'resources.target.credential-library.messages.none.description'}}
{{t 'resources.target.credential-source.messages.none.description'}}
</message.description>
<message.link @route='scopes.scope.targets.target.credential-libraries'>
<message.link @route='scopes.scope.targets.target.credential-sources'>
<Rose::Icon @name='flight-icons/svg/chevron-left-16' />
{{t 'actions.back'}}
</message.link>
@@ -0,0 +1,4 @@
<h2>
{{t 'resources.target.credential-source.messages.add.title'}}
</h2>
<p>{{t 'resources.target.credential-source.messages.add.description'}}</p>
@@ -1,5 +0,0 @@
<h2>
{{t 'resources.target.host-set.messages.add.title'}}
<DocLink @doc='target.add-host-sets' @iconSize='large' />
</h2>
<p>{{t 'resources.target.host-set.messages.add.description'}}</p>
@@ -1,4 +1,4 @@
{{page-title (t 'resources.target.actions.add-host-sets')}}
{{page-title (t 'resources.target.actions.add-host-sources')}}
{{#if @model.hostSets}}
<Form::Target::AddHostSets
@@ -13,13 +13,13 @@
{{#unless @model.hostSets}}
<Rose::Layout::Centered>
<Rose::Message
@title={{t 'resources.target.host-set.messages.none.title'}}
@title={{t 'resources.target.host-source.messages.none.title'}}
as |message|
>
<message.description>
{{t 'resources.target.host-set.messages.none.description'}}
{{t 'resources.target.host-source.messages.none.description'}}
</message.description>
<message.link @route='scopes.scope.targets.target.host-sets'>
<message.link @route='scopes.scope.targets.target.host-sources'>
<Rose::Icon @name='flight-icons/svg/chevron-left-16' />
{{t 'actions.back'}}
</message.link>
@@ -0,0 +1,5 @@
<h2>
{{t 'resources.target.host-source.messages.add.title'}}
<DocLink @doc='target.add-host-sources' @iconSize='large' />
</h2>
<p>{{t 'resources.target.host-source.messages.add.description'}}</p>
@@ -1,4 +1,4 @@
{{page-title (t 'resources.target.credential-library.title_plural')}}
{{page-title (t 'resources.target.credential-source.title_plural')}}
{{#if @model.credentialLibraries}}
@@ -56,7 +56,7 @@
{{on
'click'
(route-action
'removeCredentialLibrary' @model credentialLibrary
'removeCredentialSource' @model credentialLibrary
)
}}
>
@@ -73,17 +73,15 @@
<Rose::Layout::Centered>
<Rose::Message
@title={{t 'resources.target.credential-library.messages.welcome.title'}}
@title={{t 'resources.target.credential-source.messages.welcome.title'}}
as |message|
>
<message.description>
{{t 'resources.target.credential-library.messages.welcome.description'}}
{{t 'resources.target.credential-source.messages.welcome.description'}}
</message.description>
<message.link
@route='scopes.scope.targets.target.add-credential-libraries'
>
<message.link @route='scopes.scope.targets.target.add-credential-sources'>
<Rose::Icon @name='flight-icons/svg/plus-circle-16' />
{{t 'resources.target.actions.add-credential-libraries'}}
{{t 'resources.target.actions.add-credential-sources'}}
</message.link>
</Rose::Message>
</Rose::Layout::Centered>
@@ -1,4 +1,4 @@
{{page-title (t 'resources.target.host-set.title_plural')}}
{{page-title (t 'resources.target.host-source.title_plural')}}
{{#if @model.hostSets}}
@@ -45,7 +45,7 @@
@style='danger'
{{on
'click'
(route-action 'removeHostSet' @model hostSet.model)
(route-action 'removeHostSource' @model hostSet.model)
}}
>
{{t 'actions.remove'}}
@@ -61,15 +61,15 @@
<Rose::Layout::Centered>
<Rose::Message
@title={{t 'resources.target.host-set.messages.welcome.title'}}
@title={{t 'resources.target.host-source.messages.welcome.title'}}
as |message|
>
<message.description>
{{t 'resources.target.host-set.messages.welcome.description'}}
{{t 'resources.target.host-source.messages.welcome.description'}}
</message.description>
<message.link @route='scopes.scope.targets.target.add-host-sets'>
<message.link @route='scopes.scope.targets.target.add-host-sources'>
<Rose::Icon @name='flight-icons/svg/plus-circle-16' />
{{t 'resources.target.actions.add-host-sets'}}
{{t 'resources.target.actions.add-host-sources'}}
</message.link>
</Rose::Message>
</Rose::Layout::Centered>
+1 -1
View File
@@ -64,7 +64,7 @@ module.exports = function (environment) {
session: '/sessions',
target: '/targets',
'target.new': '/targets/new',
'target.add-host-sets': '/targets/add-host-sets',
'target.add-host-sources': '/targets/add-host-sets',
user: '/users',
},
},
@@ -35,7 +35,7 @@ module('Acceptance | targets | credential-libraries', function (hooks) {
target: null,
credentialLibraries: null,
credentialLibrary: null,
addCredentialLibraries: null,
addCredentialSources: null,
};
hooks.beforeEach(function () {
@@ -72,65 +72,65 @@ module('Acceptance | targets | credential-libraries', function (hooks) {
urls.projectScope = `/scopes/${instances.scopes.project.id}`;
urls.targets = `${urls.projectScope}/targets`;
urls.target = `${urls.targets}/${instances.target.id}`;
urls.credentialLibraries = `${urls.target}/credential-libraries`;
urls.credentialSources = `${urls.target}/credential-sources`;
urls.credentialLibrary = `${urls.projectScope}/credential-stores/${instances.credentialLibrary.credentialStoreId}/credential-libraries/${instances.credentialLibrary.id}`;
urls.addCredentialLibraries = `${urls.target}/add-credential-libraries`;
urls.addCredentialSources = `${urls.target}/add-credential-sources`;
// Generate resource counter
getCredentialLibraryCount = () =>
this.server.schema.credentialLibraries.all().models.length;
authenticateSession({});
});
test('visiting target credential libraries', async function (assert) {
test('visiting target credential sources', async function (assert) {
assert.expect(2);
await visit(urls.credentialLibraries);
await visit(urls.credentialSources);
await a11yAudit();
assert.equal(currentURL(), urls.credentialLibraries);
assert.equal(currentURL(), urls.credentialSources);
assert.equal(findAll('tbody tr').length, getCredentialLibraryCount());
});
test('can navigate to a credential library', async function (assert) {
assert.expect(1);
await visit(urls.credentialLibraries);
await visit(urls.credentialSources);
await click('main tbody .rose-table-header-cell:nth-child(1) a');
await a11yAudit();
assert.equal(currentURL(), urls.credentialLibrary);
});
test('visiting add credential libraries', async function (assert) {
test('visiting add credential sources', async function (assert) {
assert.expect(1);
await visit(urls.addCredentialLibraries);
await visit(urls.addCredentialSources);
await a11yAudit();
assert.equal(currentURL(), urls.addCredentialLibraries);
assert.equal(currentURL(), urls.addCredentialSources);
});
test('can select and save credential libraries to add', async function (assert) {
test('can select and save credential sources to add', async function (assert) {
assert.expect(4);
instances.target.update({ credentialLibraries: [] });
await visit(urls.credentialLibraries);
await visit(urls.credentialSources);
assert.equal(findAll('tbody tr').length, 0);
await visit(urls.addCredentialLibraries);
await visit(urls.addCredentialSources);
assert.equal(findAll('tbody tr').length, getCredentialLibraryCount());
await click('tbody label');
await click('form [type="submit"]');
assert.equal(currentURL(), urls.credentialLibraries);
assert.equal(currentURL(), urls.credentialSources);
assert.equal(findAll('tbody tr').length, 1);
});
test('can select and cancel credential libraries to add', async function (assert) {
test('can select and cancel credential sources to add', async function (assert) {
assert.expect(4);
instances.target.update({ credentialLibraries: [] });
await visit(urls.credentialLibraries);
await visit(urls.credentialSources);
assert.equal(findAll('tbody tr').length, 0);
await visit(urls.addCredentialLibraries);
await visit(urls.addCredentialSources);
assert.equal(findAll('tbody tr').length, getCredentialLibraryCount());
await click('tbody label');
await click('form [type="button"]');
assert.equal(currentURL(), urls.credentialLibraries);
assert.equal(currentURL(), urls.credentialSources);
assert.equal(findAll('tbody tr').length, 0);
});
test('adding credential libraries which errors displays error message', async function (assert) {
test('adding credential sources which errors displays error message', async function (assert) {
assert.expect(1);
this.server.post('/targets/:idMethod', () => {
return new Response(
@@ -145,7 +145,7 @@ module('Acceptance | targets | credential-libraries', function (hooks) {
);
});
instances.target.update({ credentialLibraries: [] });
await visit(urls.addCredentialLibraries);
await visit(urls.addCredentialSources);
await click('tbody label');
await click('form [type="submit"]');
assert.ok(find('[role="alert"]'));
@@ -154,7 +154,7 @@ module('Acceptance | targets | credential-libraries', function (hooks) {
test('can remove a credential library', async function (assert) {
assert.expect(2);
const count = getCredentialLibraryCount();
await visit(urls.credentialLibraries);
await visit(urls.credentialSources);
assert.equal(findAll('tbody tr').length, count);
await click('tbody tr .rose-dropdown-button-danger');
assert.equal(findAll('tbody tr').length, count - 1);
@@ -175,7 +175,7 @@ module('Acceptance | targets | credential-libraries', function (hooks) {
);
});
const count = getCredentialLibraryCount();
await visit(urls.credentialLibraries);
await visit(urls.credentialSources);
assert.equal(findAll('tbody tr').length, count);
await click('tbody tr .rose-dropdown-button-danger');
assert.ok(find('[role="alert"]'));
@@ -11,7 +11,7 @@ import {
//invalidateSession,
} from 'ember-simple-auth/test-support';
module('Acceptance | targets | host-sets', function (hooks) {
module('Acceptance | targets | host-sources', function (hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
@@ -60,17 +60,17 @@ module('Acceptance | targets | host-sets', function (hooks) {
urls.projectScope = `/scopes/${instances.scopes.project.id}`;
urls.targets = `/scopes/${instances.scopes.project.id}/targets`;
urls.target = `${urls.targets}/${instances.target.id}`;
urls.targetHostSets = `${urls.target}/host-sets`;
urls.targetAddHostSets = `${urls.target}/add-host-sets`;
urls.targetHostSources = `${urls.target}/host-sources`;
urls.targetAddHostSources = `${urls.target}/add-host-sources`;
authenticateSession({});
});
test('visiting target host sets', async function (assert) {
test('visiting target host sources', async function (assert) {
assert.expect(3);
const targetHostSetCount = instances.target.hostSets.length;
await visit(urls.targetHostSets);
await visit(urls.targetHostSources);
await a11yAudit();
assert.equal(currentURL(), urls.targetHostSets);
assert.equal(currentURL(), urls.targetHostSources);
assert.ok(targetHostSetCount);
assert.equal(findAll('tbody tr').length, targetHostSetCount);
});
@@ -78,7 +78,7 @@ module('Acceptance | targets | host-sets', function (hooks) {
test('can remove a host sets', async function (assert) {
assert.expect(2);
const targetHostSetCount = instances.target.hostSets.length;
await visit(urls.targetHostSets);
await visit(urls.targetHostSources);
assert.equal(findAll('tbody tr').length, targetHostSetCount);
await click('tbody tr .rose-dropdown-button-danger');
assert.equal(findAll('tbody tr').length, targetHostSetCount - 1);
@@ -99,7 +99,7 @@ module('Acceptance | targets | host-sets', function (hooks) {
);
});
const targetHostSetCount = instances.target.hostSets.length;
await visit(urls.targetHostSets);
await visit(urls.targetHostSources);
assert.equal(findAll('tbody tr').length, targetHostSetCount);
await click('tbody tr .rose-dropdown-button-danger');
assert.ok(find('[role="alert"]'));
@@ -108,32 +108,32 @@ module('Acceptance | targets | host-sets', function (hooks) {
test('select and save host sets to add', async function (assert) {
assert.expect(3);
instances.target.update({ hostSetIds: [] });
await visit(urls.targetHostSets);
await visit(urls.targetHostSources);
assert.equal(findAll('tbody tr').length, 0);
await click('.rose-layout-page-actions a');
assert.equal(currentURL(), urls.targetAddHostSets);
assert.equal(currentURL(), urls.targetAddHostSources);
// Click three times to select, unselect, then reselect (for coverage)
await click('tbody label');
await click('tbody label');
await click('tbody label');
await click('form [type="submit"]');
await visit(urls.targetHostSets);
await visit(urls.targetHostSources);
assert.equal(findAll('tbody tr').length, 1);
});
test('select and cancel host sets to add', async function (assert) {
assert.expect(4);
const targetHostSetCount = instances.target.hostSets.length;
await visit(urls.targetHostSets);
await visit(urls.targetHostSources);
assert.equal(findAll('tbody tr').length, targetHostSetCount);
// first, remove a target host set (otherwise none would be available to add)
await click('tbody tr .rose-dropdown-button-danger');
assert.equal(findAll('tbody tr').length, targetHostSetCount - 1);
await click('.rose-layout-page-actions a');
assert.equal(currentURL(), urls.targetAddHostSets);
assert.equal(currentURL(), urls.targetAddHostSources);
await click('tbody label');
await click('form [type="button"]');
await visit(urls.targetHostSets);
await visit(urls.targetHostSources);
assert.equal(findAll('tbody tr').length, targetHostSetCount - 1);
});
@@ -152,12 +152,12 @@ module('Acceptance | targets | host-sets', function (hooks) {
);
});
instances.target.update({ hostSetIds: [] });
await visit(urls.targetAddHostSets);
await visit(urls.targetAddHostSources);
assert.equal(instances.target.hostSets.length, 0);
assert.equal(currentURL(), urls.targetAddHostSets);
assert.equal(currentURL(), urls.targetAddHostSources);
await click('tbody label');
await click('form [type="submit"]');
assert.equal(currentURL(), urls.targetAddHostSets);
assert.equal(currentURL(), urls.targetAddHostSources);
assert.equal(instances.target.hostSets.length, 0);
});
});
@@ -2,14 +2,14 @@ import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module(
'Unit | Controller | scopes/scope/targets/target/add-host-sets',
'Unit | Controller | scopes/scope/targets/target/add-host-sources',
function (hooks) {
setupTest(hooks);
// TODO: Replace this with your real tests.
test('it exists', function (assert) {
let controller = this.owner.lookup(
'controller:scopes/scope/targets/target/add-host-sets'
'controller:scopes/scope/targets/target/add-host-sources'
);
assert.ok(controller);
});
@@ -2,14 +2,14 @@ import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module(
'Unit | Controller | scopes/scope/targets/target/credential-libraries',
'Unit | Controller | scopes/scope/targets/target/credential-sources',
function (hooks) {
setupTest(hooks);
// TODO: Replace this with your real tests.
test('it exists', function (assert) {
let controller = this.owner.lookup(
'controller:scopes/scope/targets/target/credential-libraries'
'controller:scopes/scope/targets/target/credential-sources'
);
assert.ok(controller);
});
@@ -2,14 +2,14 @@ import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module(
'Unit | Controller | scopes/scope/targets/target/host-sets',
'Unit | Controller | scopes/scope/targets/target/host-sources',
function (hooks) {
setupTest(hooks);
// TODO: Replace this with your real tests.
test('it exists', function (assert) {
let controller = this.owner.lookup(
'controller:scopes/scope/targets/target/host-sets'
'controller:scopes/scope/targets/target/host-sources'
);
assert.ok(controller);
});
@@ -2,13 +2,13 @@ import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module(
'Unit | Route | scopes/scope/targets/target/add-credential-libraries',
'Unit | Route | scopes/scope/targets/target/add-credential-sources',
function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let route = this.owner.lookup(
'route:scopes/scope/targets/target/add-credential-libraries'
'route:scopes/scope/targets/target/add-credential-sources'
);
assert.ok(route);
});
@@ -2,13 +2,13 @@ import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module(
'Unit | Route | scopes/scope/targets/target/add-host-sets',
'Unit | Route | scopes/scope/targets/target/add-host-sources',
function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let route = this.owner.lookup(
'route:scopes/scope/targets/target/add-host-sets'
'route:scopes/scope/targets/target/add-host-sources'
);
assert.ok(route);
});
@@ -2,13 +2,13 @@ import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module(
'Unit | Route | scopes/scope/targets/target/credential-libraries',
'Unit | Route | scopes/scope/targets/target/credential-sources',
function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let route = this.owner.lookup(
'route:scopes/scope/targets/target/credential-libraries'
'route:scopes/scope/targets/target/credential-sources'
);
assert.ok(route);
});
@@ -2,13 +2,13 @@ import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module(
'Unit | Route | scopes/scope/targets/target/host-sets',
'Unit | Route | scopes/scope/targets/target/host-sources',
function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let route = this.owner.lookup(
'route:scopes/scope/targets/target/host-sets'
'route:scopes/scope/targets/target/host-sources'
);
assert.ok(route);
});
@@ -21,8 +21,8 @@ export default class ScopesScopeProjectsTargetsTargetHostsRoute extends Route {
const target = this.modelFor('scopes.scope.projects.targets.target');
// Load all host-sets
const hostSets = await all(
target.host_sets.map(({ host_set_id }) =>
this.store.findRecord('host-set', host_set_id)
target.host_sources.map(({ host_source_id }) =>
this.store.findRecord('host-set', host_source_id)
)
);