From bce27df1f4801ec32a0af82c38aa2225173c4bda Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Thu, 3 Sep 2020 14:35:05 -0400 Subject: [PATCH] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20update=20to=20unpref?= =?UTF-8?q?ixed=20target=20pathing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/addon/adapters/application.js | 9 +++++++- addons/api/addon/adapters/target.js | 13 ++++++++++++ addons/api/addon/serializers/application.js | 21 +++++++++++++++++++ addons/api/addon/serializers/target.js | 8 +++++++ addons/api/app/adapters/target.js | 1 + addons/api/tests/unit/adapters/target-test.js | 12 +++++++++++ addons/api/tests/unit/models/target-test.js | 6 +++--- .../scopes/scope/projects/project/targets.js | 4 ++-- ui/core/mirage/config.js | 19 +++++++++++------ 9 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 addons/api/addon/adapters/target.js create mode 100644 addons/api/app/adapters/target.js create mode 100644 addons/api/tests/unit/adapters/target-test.js diff --git a/addons/api/addon/adapters/application.js b/addons/api/addon/adapters/application.js index 187c94ad1..93f0c3925 100644 --- a/addons/api/addon/adapters/application.js +++ b/addons/api/addon/adapters/application.js @@ -41,6 +41,7 @@ function prenormalizeArrayResponse(response) { export default class ApplicationAdapter extends RESTAdapter.extend( AdapterBuildURLMixin ) { + // =attributes /** @@ -57,6 +58,12 @@ export default class ApplicationAdapter extends RESTAdapter.extend( */ namespace = get(config, 'api.namespace'); + /** + * Whether or not to prefix the URL with the resource scope. + * @type {boolean} + */ + hasScopePrefix = true; + // =methods /** @@ -80,7 +87,7 @@ export default class ApplicationAdapter extends RESTAdapter.extend( const isScope = modelName === 'scope'; let scopePath = ''; let scopeID = ''; - if (snapshot) { + if (snapshot && this.hasScopePrefix) { // Not all snapshots have `attr` (such as array snapshots), // so we do this sort of ugly check. if (snapshot.attr) { diff --git a/addons/api/addon/adapters/target.js b/addons/api/addon/adapters/target.js new file mode 100644 index 000000000..9d853cc7d --- /dev/null +++ b/addons/api/addon/adapters/target.js @@ -0,0 +1,13 @@ +import ApplicationAdapter from './application'; + +export default class TargetAdapter extends ApplicationAdapter { + + // =attributes + + /** + * Targets use the new, unprefixed pathing style. + * @override + */ + hasScopePrefix = false; + +} diff --git a/addons/api/addon/serializers/application.js b/addons/api/addon/serializers/application.js index bfe422161..cea8c06a0 100644 --- a/addons/api/addon/serializers/application.js +++ b/addons/api/addon/serializers/application.js @@ -14,6 +14,12 @@ export default class ApplicationSerializer extends RESTSerializer { scope: { serialize: false } }; + /** + * Whether or not to serialize the scope ID into scope_id. + * @type {boolean} + */ + serializeScopeID = false; + // =methods /** @@ -67,6 +73,21 @@ export default class ApplicationSerializer extends RESTSerializer { Object.assign(hash, serialized); } + /** + * Optionally serializes the scope ID into `scope_id`. + * @override + * @param {Snapshot} snapshot + * @return {object} + */ + serialize(snapshot) { + const serialized = super.serialize(...arguments); + if (this.serializeScopeID) { + const scope_id = snapshot?.attr('scope')?.attr('scope_id'); + if (scope_id) serialized.scope_id = scope_id; + } + return serialized; + } + /** * In our API, array payloads are always rooted under the same key `items`. * Ember Data normally expects them to be rooted under their model name, diff --git a/addons/api/addon/serializers/target.js b/addons/api/addon/serializers/target.js index eae3ad5b1..eb7fa1155 100644 --- a/addons/api/addon/serializers/target.js +++ b/addons/api/addon/serializers/target.js @@ -2,6 +2,14 @@ import ApplicationSerializer from './application'; export default class TargetSerializer extends ApplicationSerializer { + // =attributes + + /** + * Serialized the scope ID into the `scope_id` field. + * @type {boolean} + */ + serializeScopeID = true; + // =methods /** diff --git a/addons/api/app/adapters/target.js b/addons/api/app/adapters/target.js new file mode 100644 index 000000000..4cb45ecc3 --- /dev/null +++ b/addons/api/app/adapters/target.js @@ -0,0 +1 @@ +export { default } from 'api/adapters/target'; diff --git a/addons/api/tests/unit/adapters/target-test.js b/addons/api/tests/unit/adapters/target-test.js new file mode 100644 index 000000000..bed673821 --- /dev/null +++ b/addons/api/tests/unit/adapters/target-test.js @@ -0,0 +1,12 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Adapter | target', function(hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function(assert) { + let adapter = this.owner.lookup('adapter:target'); + assert.ok(adapter); + }); +}); diff --git a/addons/api/tests/unit/models/target-test.js b/addons/api/tests/unit/models/target-test.js index 11f0d83a4..2652fcce7 100644 --- a/addons/api/tests/unit/models/target-test.js +++ b/addons/api/tests/unit/models/target-test.js @@ -59,7 +59,7 @@ module('Unit | Model | target', function (hooks) { 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:add-host-sets', (schema, request) => { + 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'], @@ -92,7 +92,7 @@ module('Unit | Model | target', function (hooks) { test('it has a `removeHostSets` 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:remove-host-sets', (schema, request) => { + this.server.post('/v1/targets/123abc:remove-host-sets', (schema, request) => { const body = JSON.parse(request.requestBody); assert.deepEqual(body, { host_set_ids: ['1', '3'], @@ -125,7 +125,7 @@ module('Unit | Model | target', function (hooks) { test('it has a `removeHostSet` method that deletes a single host set using `removeHostSets` method', async function (assert) { assert.expect(1); - this.server.post('/v1/scopes/o_1/targets/123abc:remove-host-sets', (schema, request) => { + this.server.post('/v1/targets/123abc:remove-host-sets', (schema, request) => { const body = JSON.parse(request.requestBody); assert.deepEqual(body, { host_set_ids: ['3'], diff --git a/ui/core/app/routes/scopes/scope/projects/project/targets.js b/ui/core/app/routes/scopes/scope/projects/project/targets.js index acb1e07cc..e91f0480e 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/targets.js +++ b/ui/core/app/routes/scopes/scope/projects/project/targets.js @@ -16,8 +16,8 @@ export default class ScopesScopeProjectsProjectTargetsRoute extends Route { * @return {Promise{[TargetModel]}} */ async model() { - const scopeID = this.modelFor('scopes.scope.projects.project').id; - return this.store.findAll('target', { adapterOptions: { scopeID } }); + const { id: scope_id } = this.modelFor('scopes.scope.projects.project'); + return this.store.query('target', { scope_id }); } // =actions diff --git a/ui/core/mirage/config.js b/ui/core/mirage/config.js index 8bc387276..a74e8fe30 100644 --- a/ui/core/mirage/config.js +++ b/ui/core/mirage/config.js @@ -182,12 +182,19 @@ export default function() { // target - this.get('/scopes/:scope_id/targets'); - this.post('/scopes/:scope_id/targets'); - this.get('/scopes/:scope_id/targets/:id'); - this.patch('/scopes/:scope_id/targets/:id'); - this.del('/scopes/:scope_id/targets/:id'); - this.post('/scopes/:scope_id/targets/:idMethod', function ({ targets }, { params: { idMethod } }) { + this.get('/targets', function ({ targets }, { queryParams: { scope_id } }) { + return targets.where(target => target.scope?.id === scope_id); + }); + this.post('/targets', function ({ targets, scopes }) { + const attrs = this.normalizedRequestAttrs(); + const scope = scopes.findBy(scope => scope.id === attrs.scopeId); + attrs.scope = { id: scope.id, type: scope.type }; + return targets.create(attrs); + }); + this.get('/targets/:id'); + this.patch('/targets/:id'); + this.del('/targets/:id'); + this.post('/targets/:idMethod', function ({ targets }, { params: { idMethod } }) { const attrs = this.normalizedRequestAttrs(); const id = idMethod.split(':')[0]; const method = idMethod.split(':')[1];