From 7846398135d28b45fefb7dbf1bb0cf16c4b4ab49 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Tue, 25 Aug 2020 11:54:36 -0400 Subject: [PATCH 01/11] chore: Update target mirage config to include hostsets --- ui/core/mirage/config.js | 20 ++++++++++++++++++++ ui/core/mirage/factories/target.js | 13 ++++++++++++- ui/core/mirage/models/host-set.js | 1 + ui/core/mirage/scenarios/default.js | 4 ++-- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/ui/core/mirage/config.js b/ui/core/mirage/config.js index 56ebd68d0..68ef3f031 100644 --- a/ui/core/mirage/config.js +++ b/ui/core/mirage/config.js @@ -131,6 +131,26 @@ export default function() { this.patch('/scopes/:scope_id/targets/:id'); this.del('/scopes/:scope_id/targets/:id'); + // host-set in a target + this.get('/scopes/:scope_id/targets/:targetId/host-sets', function ({ hostSets }, { params: { targetId } }) { + return hostSets.where({ targetId }); + }); + this.post('/scopes/:scope_id/targets/:targetId/host-sets', function ({ hostSets }, { params: { targetId } }) { + const attrs = this.normalizedRequestAttrs(); + attrs.targetId = targetId; + return hostSets.create(attrs); + }); + this.get('/scopes/:scope_id/targets/:targetId/host-sets/:id'); + this.patch('/scopes/:scope_id/targets/:targetId/host-sets/:id'); + this.del('/scopes/:scope_id/targets/:targetId/host-sets/:id'); + this.post('/scopes/:scope_id/targets/:targetId/host-sets/:idMethod', function ({ hostSets }, { params: { idMethod } }) { + const attrs = this.normalizedRequestAttrs(); + const id = idMethod.split(':')[0]; + const hostSet = hostSets.find(id); + attrs.id = id; + return hostSet.update(attrs); + }); + // Uncomment the following line and the Response import above // Then change the response code to simulate error responses. // this.get('/scopes/:scope_id/projects', () => new Response(505)); diff --git a/ui/core/mirage/factories/target.js b/ui/core/mirage/factories/target.js index b664ff88a..9746158f2 100644 --- a/ui/core/mirage/factories/target.js +++ b/ui/core/mirage/factories/target.js @@ -1,3 +1,14 @@ import factory from '../generated/factories/target'; +import { trait } from 'ember-cli-mirage'; -export default factory.extend(); +export default factory.extend({ + + withChildren: trait({ + afterCreate(target, server) { + const scope = target.scope; + const hosts = server.createList('host', 10, { scope }); + server.createList('host-set', 3, { scope, target , hosts}); + } + }) + +}); diff --git a/ui/core/mirage/models/host-set.js b/ui/core/mirage/models/host-set.js index 2f78f5510..3aa8fbf7e 100644 --- a/ui/core/mirage/models/host-set.js +++ b/ui/core/mirage/models/host-set.js @@ -2,6 +2,7 @@ import { Model, belongsTo, hasMany } from 'ember-cli-mirage'; export default Model.extend({ + target: belongsTo(), hostCatalog: belongsTo(), hosts: hasMany() diff --git a/ui/core/mirage/scenarios/default.js b/ui/core/mirage/scenarios/default.js index 439b9fd01..5c835dadf 100644 --- a/ui/core/mirage/scenarios/default.js +++ b/ui/core/mirage/scenarios/default.js @@ -33,7 +33,7 @@ export default function(server) { server.db.scopes.where({type: 'project'}).forEach(({ id, type }) => { const scope = { id, type }; server.createList('host-catalog', 2, { scope }, 'withChildren'); - server.createList('target', 2, { scope }); + server.createList('target', 2, { scope }, 'withChildren'); }); - + } From 590c33f5fa953560ff45e0d7e4d7d386619123c8 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Tue, 25 Aug 2020 14:50:26 -0400 Subject: [PATCH 02/11] chore: Add host-sets route to target --- ui/core/app/router.js | 6 +++++- .../projects/project/targets/target/host-sets.js | 5 +++++ .../project/targets/target/host-sets/host-set.js | 4 ++++ .../project/targets/target/host-sets/index.js | 4 ++++ .../projects/project/targets/target/host-sets.hbs | 3 +++ .../project/targets/target/host-sets/host-set.hbs | 1 + .../project/targets/target/host-sets/index.hbs | 1 + .../scope/projects/project/targets/target/index.hbs | 3 +++ .../projects/project/targets/target/host-sets-test.js | 11 +++++++++++ .../project/targets/target/host-sets/host-set-test.js | 11 +++++++++++ .../project/targets/target/host-sets/index-test.js | 11 +++++++++++ 11 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js create mode 100644 ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets/host-set.js create mode 100644 ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets/index.js create mode 100644 ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs create mode 100644 ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets/host-set.hbs create mode 100644 ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets/index.hbs create mode 100644 ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/host-sets-test.js create mode 100644 ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/host-sets/host-set-test.js create mode 100644 ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/host-sets/index-test.js diff --git a/ui/core/app/router.js b/ui/core/app/router.js index 13e46eb06..43bc97d14 100644 --- a/ui/core/app/router.js +++ b/ui/core/app/router.js @@ -36,7 +36,11 @@ Router.map(function () { }); }); this.route('targets', function() { - this.route('target', { path: ':target_id' }, function() {}); + this.route('target', { path: ':target_id' }, function() { + this.route('host-sets', function() { + this.route('host-set'); + }); + }); this.route('new'); }); }); diff --git a/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js b/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js new file mode 100644 index 000000000..c9b491c05 --- /dev/null +++ b/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js @@ -0,0 +1,5 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeProjectsProjectTargetsTargetHostSetsRoute extends Route { + +} diff --git a/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets/host-set.js b/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets/host-set.js new file mode 100644 index 000000000..2b45938a3 --- /dev/null +++ b/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets/host-set.js @@ -0,0 +1,4 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeProjectsProjectTargetsTargetHostSetsHostSetRoute extends Route { +} diff --git a/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets/index.js b/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets/index.js new file mode 100644 index 000000000..6e14d67c1 --- /dev/null +++ b/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets/index.js @@ -0,0 +1,4 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeProjectsProjectTargetsTargetHostSetsIndexRoute extends Route { +} diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs new file mode 100644 index 000000000..49966461b --- /dev/null +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs @@ -0,0 +1,3 @@ +{{title (t "resources.host-sets")}} + +{{outlet}} \ No newline at end of file diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets/host-set.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets/host-set.hbs new file mode 100644 index 000000000..e2147cab0 --- /dev/null +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets/host-set.hbs @@ -0,0 +1 @@ +{{outlet}} \ No newline at end of file diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets/index.hbs new file mode 100644 index 000000000..262f42662 --- /dev/null +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets/index.hbs @@ -0,0 +1 @@ +Target/host-sets \ No newline at end of file diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/target/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/target/index.hbs index da4860986..ec7719f9a 100644 --- a/ui/core/app/templates/scopes/scope/projects/project/targets/target/index.hbs +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/target/index.hbs @@ -13,6 +13,9 @@ {{t 'titles.details'}} + + {{t 'titles.host-sets'}} + diff --git a/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/host-sets-test.js b/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/host-sets-test.js new file mode 100644 index 000000000..41d4cf0e3 --- /dev/null +++ b/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/host-sets-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | scopes/scope/projects/project/targets/target/host-sets', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:scopes/scope/projects/project/targets/target/host-sets'); + assert.ok(route); + }); +}); diff --git a/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/host-sets/host-set-test.js b/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/host-sets/host-set-test.js new file mode 100644 index 000000000..fb7e2480e --- /dev/null +++ b/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/host-sets/host-set-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | scopes/scope/projects/project/targets/target/host-sets/host-set', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:scopes/scope/projects/project/targets/target/host-sets/host-set'); + assert.ok(route); + }); +}); diff --git a/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/host-sets/index-test.js b/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/host-sets/index-test.js new file mode 100644 index 000000000..285fcc909 --- /dev/null +++ b/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/host-sets/index-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | scopes/scope/projects/project/targets/target/host-sets/index', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:scopes/scope/projects/project/targets/target/host-sets/index'); + assert.ok(route); + }); +}); From b166a35dd66e3c9c5ec282f459b30f8dba541984 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Tue, 25 Aug 2020 15:45:51 -0400 Subject: [PATCH 03/11] chore: add target host set mocks --- ui/core/mirage/factories/target.js | 16 ++++++++++++---- ui/core/mirage/models/target.js | 7 +++++++ ui/core/mirage/scenarios/default.js | 2 +- ui/core/mirage/serializers/target.js | 21 ++++++++++++++++++++- 4 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 ui/core/mirage/models/target.js diff --git a/ui/core/mirage/factories/target.js b/ui/core/mirage/factories/target.js index 9746158f2..7c74806a6 100644 --- a/ui/core/mirage/factories/target.js +++ b/ui/core/mirage/factories/target.js @@ -1,13 +1,21 @@ import factory from '../generated/factories/target'; import { trait } from 'ember-cli-mirage'; +const randomBoolean = (chance = 0.5) => Math.random() < chance; +const hostSetChance = 0.3; + export default factory.extend({ - withChildren: trait({ + /** + * Randomly selects existing host sets to assign to target. + */ + withRandomHostSets: trait({ afterCreate(target, server) { - const scope = target.scope; - const hosts = server.createList('host', 10, { scope }); - server.createList('host-set', 3, { scope, target , hosts}); + let randomlySelectedHostSets; + randomlySelectedHostSets = server.schema.hostSets + .where(item => item.scope.id === target.scope.id).models + .filter(() => randomBoolean(hostSetChance)); + target.update({hostSets: randomlySelectedHostSets}); } }) diff --git a/ui/core/mirage/models/target.js b/ui/core/mirage/models/target.js new file mode 100644 index 000000000..d33295663 --- /dev/null +++ b/ui/core/mirage/models/target.js @@ -0,0 +1,7 @@ +import { Model, hasMany } from 'ember-cli-mirage'; + +export default Model.extend({ + + hostSets: hasMany() + +}); diff --git a/ui/core/mirage/scenarios/default.js b/ui/core/mirage/scenarios/default.js index 5c835dadf..2b212f999 100644 --- a/ui/core/mirage/scenarios/default.js +++ b/ui/core/mirage/scenarios/default.js @@ -33,7 +33,7 @@ export default function(server) { server.db.scopes.where({type: 'project'}).forEach(({ id, type }) => { const scope = { id, type }; server.createList('host-catalog', 2, { scope }, 'withChildren'); - server.createList('target', 2, { scope }, 'withChildren'); + server.createList('target', 2, { scope }, 'withRandomHostSets'); }); } diff --git a/ui/core/mirage/serializers/target.js b/ui/core/mirage/serializers/target.js index 3d4bc5f3e..c9c6935a0 100644 --- a/ui/core/mirage/serializers/target.js +++ b/ui/core/mirage/serializers/target.js @@ -1,5 +1,24 @@ import ApplicationSerializer from './application'; +import { underscore } from '@ember/string'; export default ApplicationSerializer.extend({ - modelName: 'target' + modelName: 'target', + + keyForRelationshipIds(relationshipName) { + return `${this._container.inflector.singularize( + underscore(relationshipName) + )}_ids`; + }, + + _hashForModel(model) { + const json = ApplicationSerializer.prototype._hashForModel.apply(this, arguments); + const { hostSets } = this.schema; + json.host_sets = model.hostSetIds.map(host_set_id => { + const hostSet = hostSets.find(host_set_id); + const host_catalog_id = hostSet?.hostCatalog?.id; + return { host_set_id, host_catalog_id }; + }); + return json; + } + }); From e8cc2f5729b2f06f43f2277bc0819cdae6fa72a4 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 26 Aug 2020 12:31:55 -0400 Subject: [PATCH 04/11] chore: Add host-sets tab to in target view --- ui/core/app/router.js | 2 +- .../project/targets/target/host-sets.js | 21 +++++++++ .../scope/projects/project/targets/target.hbs | 39 ++++++++++++++- .../project/targets/target/host-sets.hbs | 32 ++++++++++++- .../projects/project/targets/target/index.hbs | 47 ++----------------- 5 files changed, 96 insertions(+), 45 deletions(-) diff --git a/ui/core/app/router.js b/ui/core/app/router.js index 43bc97d14..e5577e83a 100644 --- a/ui/core/app/router.js +++ b/ui/core/app/router.js @@ -38,7 +38,7 @@ Router.map(function () { this.route('targets', function() { this.route('target', { path: ':target_id' }, function() { this.route('host-sets', function() { - this.route('host-set'); + this.route('host-set', { path: ':host_set_id'}, function() {}); }); }); this.route('new'); diff --git a/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js b/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js index c9b491c05..1c63e3aaf 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js +++ b/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js @@ -1,5 +1,26 @@ import Route from '@ember/routing/route'; +import { all } from 'rsvp'; export default class ScopesScopeProjectsProjectTargetsTargetHostSetsRoute extends Route { + // =methods + /** + * + * Loads all host-sets under the current target and it's parent scope. + * @return {Promise{[HostSetModel]}} + */ + async model() { + const target = this.modelFor('scopes.scope.projects.project.targets.target'); + const scopeID = this.modelFor('scopes.scope.projects.project').id; + + const hostSets = target.host_sets.map((hostSet) => + this.store.findRecord( + 'host-set', + hostSet.host_set_id, + { adapterOptions : { scopeID, hostCatalogID: hostSet.host_catalog_id } } + ) + ); + + return all(hostSets); + } } diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/target.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/target.hbs index e2147cab0..50b97cd47 100644 --- a/ui/core/app/templates/scopes/scope/projects/project/targets/target.hbs +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/target.hbs @@ -1 +1,38 @@ -{{outlet}} \ No newline at end of file + + + + + + + +

{{t "resources.target"}}

+
+ + + + + {{t 'titles.details'}} + + + {{t 'titles.host-sets'}} + + + + + + + + {{t 'actions.delete-target'}} + + + + + + {{outlet}} + + +
diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs index 49966461b..f156172d3 100644 --- a/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs @@ -1,3 +1,33 @@ {{title (t "resources.host-sets")}} -{{outlet}} \ No newline at end of file + + + + {{t "form.label.name"}} + {{t "form.label.type"}} + {{t "form.label.id"}} + + + + {{#each @model as |hostSet|}} + + + + {{hostSet.displayName}} + +

{{hostSet.description}}

+
+ + {{hostSet.type}} + + + {{hostSet.id}} + +
+ {{/each}} +
+
+ diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/target/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/target/index.hbs index ec7719f9a..5c39ce009 100644 --- a/ui/core/app/templates/scopes/scope/projects/project/targets/target/index.hbs +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/target/index.hbs @@ -1,42 +1,5 @@ - - - - - - - -

{{t "resources.target"}}

-
- - - - - {{t 'titles.details'}} - - - {{t 'titles.host-sets'}} - - - - - - - - {{t 'actions.delete-target'}} - - - - - - - - -
+ \ No newline at end of file From 5025fa847e36d1665a6ac35936d8615f00dd3c26 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 26 Aug 2020 13:39:39 -0400 Subject: [PATCH 05/11] chore: Add breadcrumbs for host-sets in a target Remove unused target/host-sets/index route. Unlink host-sets in a target. --- .../project/targets/target/host-sets.js | 19 ++++++ .../project/targets/target/host-sets.hbs | 68 +++++++++++-------- .../targets/target/host-sets/index.hbs | 1 - ui/core/mirage/generated/factories/target.js | 2 +- .../project/targets/target/host-sets-test.js | 12 ++++ .../targets/target/host-sets/index-test.js | 11 --- ui/core/translations/en-us.yaml | 4 +- 7 files changed, 73 insertions(+), 44 deletions(-) create mode 100644 ui/core/app/controllers/scopes/scope/projects/project/targets/target/host-sets.js delete mode 100644 ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets/index.hbs create mode 100644 ui/core/tests/unit/controllers/scopes/scope/projects/project/targets/target/host-sets-test.js delete mode 100644 ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/host-sets/index-test.js diff --git a/ui/core/app/controllers/scopes/scope/projects/project/targets/target/host-sets.js b/ui/core/app/controllers/scopes/scope/projects/project/targets/target/host-sets.js new file mode 100644 index 000000000..a8fb5fd35 --- /dev/null +++ b/ui/core/app/controllers/scopes/scope/projects/project/targets/target/host-sets.js @@ -0,0 +1,19 @@ +import Controller from '@ember/controller'; +import { inject as service } from '@ember/service'; + +export default class ScopesScopeProjectsProjectTargetsTargetHostSetsController extends Controller { + + // =services + + @service intl; + + // =attributes + + /** + * Host sets breadcrumb + * @type {string} + */ + get breadCrumb() { + return this.intl.t('resources.host-sets'); + } +} diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs index f156172d3..8f04eb6e0 100644 --- a/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs @@ -1,33 +1,41 @@ {{title (t "resources.host-sets")}} - - - - {{t "form.label.name"}} - {{t "form.label.type"}} - {{t "form.label.id"}} - - - - {{#each @model as |hostSet|}} - - - - {{hostSet.displayName}} - -

{{hostSet.description}}

-
- - {{hostSet.type}} - - - {{hostSet.id}} - -
- {{/each}} -
-
+{{#if @model}} + + + + {{t "form.label.name"}} + {{t "form.label.type"}} + {{t "form.label.id"}} + + + + {{#each @model as |hostSet|}} + + + {{hostSet.displayName}} +

{{hostSet.description}}

+
+ + {{hostSet.type}} + + + {{hostSet.id}} + +
+ {{/each}} +
+
+ +{{else}} + + + + + {{t "descriptions.target-host-sets-welcome"}} + + + + +{{/if}} diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets/index.hbs deleted file mode 100644 index 262f42662..000000000 --- a/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets/index.hbs +++ /dev/null @@ -1 +0,0 @@ -Target/host-sets \ No newline at end of file diff --git a/ui/core/mirage/generated/factories/target.js b/ui/core/mirage/generated/factories/target.js index 134cc7c02..2fca0871d 100644 --- a/ui/core/mirage/generated/factories/target.js +++ b/ui/core/mirage/generated/factories/target.js @@ -6,7 +6,7 @@ import { random, date } from 'faker'; */ export default Factory.extend({ - protocol: 'SSH', + protocol: 'tcp', name: () => random.words(), description: () => random.words(), created_time: () => date.recent(), diff --git a/ui/core/tests/unit/controllers/scopes/scope/projects/project/targets/target/host-sets-test.js b/ui/core/tests/unit/controllers/scopes/scope/projects/project/targets/target/host-sets-test.js new file mode 100644 index 000000000..796ce6793 --- /dev/null +++ b/ui/core/tests/unit/controllers/scopes/scope/projects/project/targets/target/host-sets-test.js @@ -0,0 +1,12 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Controller | scopes/scope/projects/project/targets/target/host-sets', function(hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function(assert) { + let controller = this.owner.lookup('controller:scopes/scope/projects/project/targets/target/host-sets'); + assert.ok(controller); + }); +}); diff --git a/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/host-sets/index-test.js b/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/host-sets/index-test.js deleted file mode 100644 index 285fcc909..000000000 --- a/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/host-sets/index-test.js +++ /dev/null @@ -1,11 +0,0 @@ -import { module, test } from 'qunit'; -import { setupTest } from 'ember-qunit'; - -module('Unit | Route | scopes/scope/projects/project/targets/target/host-sets/index', function(hooks) { - setupTest(hooks); - - test('it exists', function(assert) { - let route = this.owner.lookup('route:scopes/scope/projects/project/targets/target/host-sets/index'); - assert.ok(route); - }); -}); diff --git a/ui/core/translations/en-us.yaml b/ui/core/translations/en-us.yaml index 69b41f0cc..8e2ffd179 100644 --- a/ui/core/translations/en-us.yaml +++ b/ui/core/translations/en-us.yaml @@ -36,7 +36,7 @@ host-set: static: Static target: protocols: - SSH: SSH + tcp: TCP host: types: static: Static @@ -79,6 +79,7 @@ titles: groups-welcome: Welcome to Groups auth-methods-welcome: Welcome to Auth Methods targets-welcome: Create your first Target + target-host-sets-welcome: No Host Sets Associated grants: Permissions new-grant: New Grant principals: Principals @@ -99,6 +100,7 @@ descriptions: groups-welcome: Groups are collections of users. auth-methods-welcome: Auth methods are configurations to authenticate users. targets-welcome: Targets provide Users the means to connect to and interact networked services. A Target contains a collection of Hosts and a collection of Credentials. + target-host-sets-welcome: Add Host Sets to this target to provide access. no-host-set-hosts: Before associating hosts with this host set, create hosts within the host catalog. states: info: Info From 4469ab762e0ef963e9c3e2701c6ddf58ce38a9cc Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Wed, 26 Aug 2020 13:52:54 -0400 Subject: [PATCH 06/11] add custom add/delete host set support to targets --- addons/api/addon/models/target.js | 32 +++++++++++++-- addons/api/addon/serializers/target.js | 19 ++++----- addons/api/tests/unit/models/target-test.js | 39 ++++++++++++++++-- .../api/tests/unit/serializers/target-test.js | 6 +-- ui/core/mirage/config.js | 40 +++++++++++-------- 5 files changed, 100 insertions(+), 36 deletions(-) diff --git a/addons/api/addon/models/target.js b/addons/api/addon/models/target.js index 0dad6ba7a..e9d3ac018 100644 --- a/addons/api/addon/models/target.js +++ b/addons/api/addon/models/target.js @@ -30,16 +30,40 @@ export default class TargetModel extends GeneratedTargetModel { // =methods /** - * Saves the `host_set_ids` array on the via the `set-hosts` method. + * Adds host sets via the `add-host-sets` method. * See serializer and adapter for more information. * @param {object} options * @param {object} options.adapterOptions * @return {Promise} */ - saveHostSets(options={ adapterOptions: {} }) { + addHostSets(hostSets, options={ adapterOptions: {} }) { const defaultAdapterOptions = { - method: 'set-host-sets', - serializeHostSets: true + method: 'add-host-sets', + hostSets + }; + // There is no "deep merge" in ES. + // All of this nonsense is here to ensure we get + // a decent merge of `adapterOptions`. + return this.save({ + ...options, + adapterOptions: { + ...defaultAdapterOptions, + ...options.adapterOptions + } + }); + } + + /** + * Delete host sets via the `delete-host-sets` method. + * See serializer and adapter for more information. + * @param {object} options + * @param {object} options.adapterOptions + * @return {Promise} + */ + deleteHostSets(hostSets, options={ adapterOptions: {} }) { + const defaultAdapterOptions = { + method: 'delete-host-sets', + hostSets }; // There is no "deep merge" in ES. // All of this nonsense is here to ensure we get diff --git a/addons/api/addon/serializers/target.js b/addons/api/addon/serializers/target.js index fefaf0fcb..5d45fec4d 100644 --- a/addons/api/addon/serializers/target.js +++ b/addons/api/addon/serializers/target.js @@ -5,30 +5,31 @@ export default class TargetSerializer extends ApplicationSerializer { // =methods /** - * If `adapterOptions.serializeHostSets` is true, the serialization should - * include **only host sets** and the version. Normally, host sets are not - * serialized. + * If `adapterOptions.hostSets` is set to an array of host set models, + * the resulting target serialization should include **only host sets** + * and the version. Normally, host sets are not serialized. * @override * @param {Snapshot} snapshot * @return {object} */ serialize(snapshot) { - const serializeHostSets = snapshot?.adapterOptions?.serializeHostSets; let serialized = super.serialize(...arguments); - if (serializeHostSets) serialized = this.serializeWithHostSets(snapshot); + const hostSets = snapshot?.adapterOptions?.hostSets; + if (hostSets) serialized = this.serializeWithHostSets(snapshot, hostSets); return serialized; } /** - * Returns a payload containing only the host_set_ids array. + * Returns a payload containing only the host_set_ids array using host sets + * passed into the function (rather than existing host sets on the model). * @param {Snapshot} snapshot + * @param {[HostSetModel]} hostSets * @return {object} */ - serializeWithHostSets(snapshot) { + serializeWithHostSets(snapshot, hostSets) { return { version: snapshot.attr('version'), - host_set_ids: - snapshot.attr('host_sets').map(hostSet => hostSet.attr('host_set_id')) + host_set_ids: hostSets.map(({ id }) => id) }; } diff --git a/addons/api/tests/unit/models/target-test.js b/addons/api/tests/unit/models/target-test.js index 04baf1bab..581150946 100644 --- a/addons/api/tests/unit/models/target-test.js +++ b/addons/api/tests/unit/models/target-test.js @@ -57,9 +57,42 @@ module('Unit | Model | target', function (hooks) { assert.ok(target.hostSets[0].hostCatalog, 'Host catalog is resolved'); }); - test('it has a `saveHostSets` method that targets a specific POST API endpoint and serialization', async function (assert) { + 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/scopes/o_1/targets/123abc:set-host-sets', (schema, request) => { + this.server.post('/v1/scopes/o_1/targets/123abc:add-host-sets', (schema, request) => { + const body = JSON.parse(request.requestBody); + assert.deepEqual(body, { + host_set_ids: ['123_abc', 'foobar'], + version: 1 + }); + }); + 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([{id: '123_abc'}, {id: 'foobar'}]); + }); + + test('it has a `deleteHostSets` method that targets a specific POST API endpoint and serialization', async function (assert) { + assert.expect(1); + this.server.post('/v1/scopes/o_1/targets/123abc:delete-host-sets', (schema, request) => { const body = JSON.parse(request.requestBody); assert.deepEqual(body, { host_set_ids: ['1', '3'], @@ -87,6 +120,6 @@ module('Unit | Model | target', function (hooks) { } }); const model = store.peekRecord('target', '123abc'); - await model.saveHostSets(); + await model.deleteHostSets([{id: '1'}, {id: '3'}]); }); }); diff --git a/addons/api/tests/unit/serializers/target-test.js b/addons/api/tests/unit/serializers/target-test.js index a3ca9bd69..a38737ac9 100644 --- a/addons/api/tests/unit/serializers/target-test.js +++ b/addons/api/tests/unit/serializers/target-test.js @@ -29,7 +29,7 @@ module('Unit | Serializer | target', function(hooks) { }); - test('it serializes only host sets when `adapterOptions.serializeHostSets` is true', function (assert) { + test('it serializes only host sets and version when an `adapterOptions.hostSets` array is passed', function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); const serializer = store.serializerFor('target'); @@ -44,11 +44,11 @@ module('Unit | Serializer | target', function(hooks) { }); const snapshot = record._createSnapshot(); snapshot.adapterOptions = { - serializeHostSets: true + hostSets: [{id: '4'}, {id: '5'}] }; const serializedRecord = serializer.serialize(snapshot); assert.deepEqual(serializedRecord, { - host_set_ids: ['1', '3'], + host_set_ids: ['4', '5'], version: 1 }); }); diff --git a/ui/core/mirage/config.js b/ui/core/mirage/config.js index 68ef3f031..8a3e0fdc1 100644 --- a/ui/core/mirage/config.js +++ b/ui/core/mirage/config.js @@ -130,25 +130,31 @@ export default function() { this.get('/scopes/:scope_id/targets/:id'); this.patch('/scopes/:scope_id/targets/:id'); this.del('/scopes/:scope_id/targets/:id'); - - // host-set in a target - this.get('/scopes/:scope_id/targets/:targetId/host-sets', function ({ hostSets }, { params: { targetId } }) { - return hostSets.where({ targetId }); - }); - this.post('/scopes/:scope_id/targets/:targetId/host-sets', function ({ hostSets }, { params: { targetId } }) { - const attrs = this.normalizedRequestAttrs(); - attrs.targetId = targetId; - return hostSets.create(attrs); - }); - this.get('/scopes/:scope_id/targets/:targetId/host-sets/:id'); - this.patch('/scopes/:scope_id/targets/:targetId/host-sets/:id'); - this.del('/scopes/:scope_id/targets/:targetId/host-sets/:id'); - this.post('/scopes/:scope_id/targets/:targetId/host-sets/:idMethod', function ({ hostSets }, { params: { idMethod } }) { + this.post('/scopes/:scope_id/targets/:idMethod', function ({ targets }, { params: { idMethod } }) { const attrs = this.normalizedRequestAttrs(); const id = idMethod.split(':')[0]; - const hostSet = hostSets.find(id); - attrs.id = id; - return hostSet.update(attrs); + const method = idMethod.split(':')[1]; + const target = targets.find(id); + const updatedAttrs = { + version: attrs.version, + hostSetIds: target.hostSetIds + }; + // If adding host sets, push them into the array + if (method === 'add-host-sets') { + attrs.hostSetIds.forEach(id => { + if (!updatedAttrs.hostSetIds.includes(id)) { + updatedAttrs.hostSetIds.push(id); + } + }); + } + // If deleting host sets, filter them out of the array + if (method === 'delete-host-sets') { + console.log(method, attrs); + updatedAttrs.hostSetIds = updatedAttrs.hostSetIds.filter(id => { + return !attrs.hostSetIds.includes(id); + }); + } + return target.update(updatedAttrs); }); // Uncomment the following line and the Response import above From 819079b5f7c4ef4c2361d0f8bd9c1960e2419e83 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Wed, 26 Aug 2020 14:03:43 -0400 Subject: [PATCH 07/11] chore: use IDs rather than models --- addons/api/addon/models/target.js | 10 ++++++---- addons/api/addon/serializers/target.js | 13 +++++++------ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/addons/api/addon/models/target.js b/addons/api/addon/models/target.js index e9d3ac018..99e1f3d16 100644 --- a/addons/api/addon/models/target.js +++ b/addons/api/addon/models/target.js @@ -32,14 +32,15 @@ export default class TargetModel extends GeneratedTargetModel { /** * Adds host sets via the `add-host-sets` method. * See serializer and adapter for more information. + * @param {[string]} hostSetIDs * @param {object} options * @param {object} options.adapterOptions * @return {Promise} */ - addHostSets(hostSets, options={ adapterOptions: {} }) { + addHostSets(hostSetIDs, options={ adapterOptions: {} }) { const defaultAdapterOptions = { method: 'add-host-sets', - hostSets + hostSetIDs }; // There is no "deep merge" in ES. // All of this nonsense is here to ensure we get @@ -56,14 +57,15 @@ export default class TargetModel extends GeneratedTargetModel { /** * Delete host sets via the `delete-host-sets` method. * See serializer and adapter for more information. + * @param {[string]} hostSetIDs * @param {object} options * @param {object} options.adapterOptions * @return {Promise} */ - deleteHostSets(hostSets, options={ adapterOptions: {} }) { + deleteHostSets(hostSetIDs, options={ adapterOptions: {} }) { const defaultAdapterOptions = { method: 'delete-host-sets', - hostSets + hostSetIDs }; // There is no "deep merge" in ES. // All of this nonsense is here to ensure we get diff --git a/addons/api/addon/serializers/target.js b/addons/api/addon/serializers/target.js index 5d45fec4d..7fc436df5 100644 --- a/addons/api/addon/serializers/target.js +++ b/addons/api/addon/serializers/target.js @@ -14,22 +14,23 @@ export default class TargetSerializer extends ApplicationSerializer { */ serialize(snapshot) { let serialized = super.serialize(...arguments); - const hostSets = snapshot?.adapterOptions?.hostSets; - if (hostSets) serialized = this.serializeWithHostSets(snapshot, hostSets); + const hostSets = snapshot?.adapterOptions?.hostSetIDs; + if (hostSetIDs) serialized = + this.serializeWithHostSets(snapshot, hostSetIDs); return serialized; } /** - * Returns a payload containing only the host_set_ids array using host sets + * Returns a payload containing only the host_set_ids array using IDs * passed into the function (rather than existing host sets on the model). * @param {Snapshot} snapshot - * @param {[HostSetModel]} hostSets + * @param {[string]} hostSetIDs * @return {object} */ - serializeWithHostSets(snapshot, hostSets) { + serializeWithHostSets(snapshot, hostSetIDs) { return { version: snapshot.attr('version'), - host_set_ids: hostSets.map(({ id }) => id) + host_set_ids: hostSetIDs }; } From 02c755b87da50b9ef092cc0a0029f8c419333ccf Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Wed, 26 Aug 2020 14:33:26 -0400 Subject: [PATCH 08/11] =?UTF-8?q?fix:=20=F0=9F=90=9B=20fix=20broken=20test?= =?UTF-8?q?s=20and=20linting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/addon/serializers/target.js | 2 +- addons/api/tests/unit/models/target-test.js | 4 ++-- addons/api/tests/unit/serializers/target-test.js | 4 ++-- ui/core/mirage/config.js | 1 - 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/addons/api/addon/serializers/target.js b/addons/api/addon/serializers/target.js index 7fc436df5..eae3ad5b1 100644 --- a/addons/api/addon/serializers/target.js +++ b/addons/api/addon/serializers/target.js @@ -14,7 +14,7 @@ export default class TargetSerializer extends ApplicationSerializer { */ serialize(snapshot) { let serialized = super.serialize(...arguments); - const hostSets = snapshot?.adapterOptions?.hostSetIDs; + const hostSetIDs = snapshot?.adapterOptions?.hostSetIDs; if (hostSetIDs) serialized = this.serializeWithHostSets(snapshot, hostSetIDs); return serialized; diff --git a/addons/api/tests/unit/models/target-test.js b/addons/api/tests/unit/models/target-test.js index 581150946..7d3aab836 100644 --- a/addons/api/tests/unit/models/target-test.js +++ b/addons/api/tests/unit/models/target-test.js @@ -87,7 +87,7 @@ module('Unit | Model | target', function (hooks) { } }); const model = store.peekRecord('target', '123abc'); - await model.addHostSets([{id: '123_abc'}, {id: 'foobar'}]); + await model.addHostSets(['123_abc', 'foobar']); }); test('it has a `deleteHostSets` method that targets a specific POST API endpoint and serialization', async function (assert) { @@ -120,6 +120,6 @@ module('Unit | Model | target', function (hooks) { } }); const model = store.peekRecord('target', '123abc'); - await model.deleteHostSets([{id: '1'}, {id: '3'}]); + await model.deleteHostSets(['1', '3']); }); }); diff --git a/addons/api/tests/unit/serializers/target-test.js b/addons/api/tests/unit/serializers/target-test.js index a38737ac9..e37eb1de2 100644 --- a/addons/api/tests/unit/serializers/target-test.js +++ b/addons/api/tests/unit/serializers/target-test.js @@ -29,7 +29,7 @@ module('Unit | Serializer | target', function(hooks) { }); - test('it serializes only host sets and version when an `adapterOptions.hostSets` array is passed', function (assert) { + test('it serializes only host sets 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'); @@ -44,7 +44,7 @@ module('Unit | Serializer | target', function(hooks) { }); const snapshot = record._createSnapshot(); snapshot.adapterOptions = { - hostSets: [{id: '4'}, {id: '5'}] + hostSetIDs: ['4', '5'] }; const serializedRecord = serializer.serialize(snapshot); assert.deepEqual(serializedRecord, { diff --git a/ui/core/mirage/config.js b/ui/core/mirage/config.js index 8a3e0fdc1..f4bebd6cd 100644 --- a/ui/core/mirage/config.js +++ b/ui/core/mirage/config.js @@ -149,7 +149,6 @@ export default function() { } // If deleting host sets, filter them out of the array if (method === 'delete-host-sets') { - console.log(method, attrs); updatedAttrs.hostSetIds = updatedAttrs.hostSetIds.filter(id => { return !attrs.hostSetIds.includes(id); }); From 63eabb8ba188719ac3ab78f6a78d91d1bfbadf0e Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 26 Aug 2020 16:43:04 -0400 Subject: [PATCH 09/11] chore: Move target host-sets load to beforeModel --- .../project/targets/target/host-sets.js | 43 +++++++++++++------ .../project/targets/target/host-sets.hbs | 10 ++--- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js b/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js index 1c63e3aaf..0ccd3290b 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js +++ b/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js @@ -5,22 +5,41 @@ export default class ScopesScopeProjectsProjectTargetsTargetHostSetsRoute extend // =methods /** - * - * Loads all host-sets under the current target and it's parent scope. - * @return {Promise{[HostSetModel]}} + * Loads all host-sets and associated host-catalogs under the current target + * and it's parent scope. + * @return {Promise{[HostSetModel, HostCatalogModel]}} */ - async model() { + beforeModel() { + const hostSets = [], hostCatalogs = []; const target = this.modelFor('scopes.scope.projects.project.targets.target'); const scopeID = this.modelFor('scopes.scope.projects.project').id; - const hostSets = target.host_sets.map((hostSet) => - this.store.findRecord( - 'host-set', - hostSet.host_set_id, - { adapterOptions : { scopeID, hostCatalogID: hostSet.host_catalog_id } } - ) - ); + target.host_sets.map((hostSet) => { + hostSets.push( + this.store.findRecord( + 'host-set', + hostSet.host_set_id, + { adapterOptions : { scopeID, hostCatalogID: hostSet.host_catalog_id } } + ) + ); - return all(hostSets); + hostCatalogs.push( + this.store.findRecord( + 'host-catalog', + hostSet.host_catalog_id, + { adapterOptions : { scopeID } } + ) + ); + }); + + return all(hostSets.concat(hostCatalogs)); + } + + /** + * Load current target and it's associated host-sets and host-catalogs + * @return {Promise{[TargetModel]}} + */ + model() { + return this.modelFor('scopes.scope.projects.project.targets.target'); } } diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs index 8f04eb6e0..9983698ea 100644 --- a/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs @@ -11,17 +11,17 @@ - {{#each @model as |hostSet|}} + {{#each @model.hostSets as |hostSet|}} - {{hostSet.displayName}} -

{{hostSet.description}}

+ {{hostSet.model.displayName}} +

{{hostSet.model.description}}

- {{hostSet.type}} + {{hostSet.model.type}} - {{hostSet.id}} + {{hostSet.model.id}}
{{/each}} From 16f94f739e995944345acf0911a0f4af429f596f Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Thu, 27 Aug 2020 09:52:44 -0400 Subject: [PATCH 10/11] =?UTF-8?q?chore:=20=F0=9F=A4=96=20cleanup=20model?= =?UTF-8?q?=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../project/targets/target/host-sets.js | 48 +++++++++---------- ui/core/tests/acceptance/targets-test.js | 4 ++ 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js b/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js index 0ccd3290b..34418acea 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js +++ b/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js @@ -1,5 +1,5 @@ import Route from '@ember/routing/route'; -import { all } from 'rsvp'; +import { all, hash } from 'rsvp'; export default class ScopesScopeProjectsProjectTargetsTargetHostSetsRoute extends Route { // =methods @@ -10,34 +10,32 @@ export default class ScopesScopeProjectsProjectTargetsTargetHostSetsRoute extend * @return {Promise{[HostSetModel, HostCatalogModel]}} */ beforeModel() { - const hostSets = [], hostCatalogs = []; - const target = this.modelFor('scopes.scope.projects.project.targets.target'); - const scopeID = this.modelFor('scopes.scope.projects.project').id; - - target.host_sets.map((hostSet) => { - hostSets.push( - this.store.findRecord( - 'host-set', - hostSet.host_set_id, - { adapterOptions : { scopeID, hostCatalogID: hostSet.host_catalog_id } } - ) + const { scopeID, host_sets } = + this.modelFor('scopes.scope.projects.project.targets.target'); + const promises = host_sets + .map(({ host_set_id, host_catalog_id: hostCatalogID }) => + hash({ + // TODO: multiple host sets may belong to the same catalog, + // resulting in the catalog being loaded multiple times. + // An improvement would be to find the unique set of catalogs first. + hostCatalog: this.store.findRecord( + 'host-catalog', + hostCatalogID, + { adapterOptions: { scopeID } } + ), + hostSet: this.store.findRecord( + 'host-set', + host_set_id, + { adapterOptions: { scopeID, hostCatalogID } } + ) + }) ); - - hostCatalogs.push( - this.store.findRecord( - 'host-catalog', - hostSet.host_catalog_id, - { adapterOptions : { scopeID } } - ) - ); - }); - - return all(hostSets.concat(hostCatalogs)); + return all(promises); } /** - * Load current target and it's associated host-sets and host-catalogs - * @return {Promise{[TargetModel]}} + * Returns the previously loaded target instance. + * @return {TargetModel} */ model() { return this.modelFor('scopes.scope.projects.project.targets.target'); diff --git a/ui/core/tests/acceptance/targets-test.js b/ui/core/tests/acceptance/targets-test.js index 8ff26fa7f..01f73d443 100644 --- a/ui/core/tests/acceptance/targets-test.js +++ b/ui/core/tests/acceptance/targets-test.js @@ -58,4 +58,8 @@ module('Acceptance | targets', function (hooks) { test('saving an existing target with invalid fields displays error messages', async function (assert) { assert.expect(0); }); + + test('viewing target host sets', async function (assert) { + assert.expect(0); + }); }); From b74846b2c960822fd27a71a6510c83d2c26962cc Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Thu, 27 Aug 2020 10:43:32 -0400 Subject: [PATCH 11/11] fix: Check for host-sets in a target for empty message displa --- .../scopes/scope/projects/project/targets/target/host-sets.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs index 9983698ea..3effb2b0d 100644 --- a/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/target/host-sets.hbs @@ -1,6 +1,6 @@ {{title (t "resources.host-sets")}} -{{#if @model}} +{{#if @model.hostSets}}