From 41f5bc25d847e33260ea238d44add57fa3a1ad77 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Wed, 15 Jul 2020 16:47:02 -0400 Subject: [PATCH] add support to model save method for scope_id and custom methods --- addons/api/addon/models/base.js | 29 +++++++++++ addons/api/tests/unit/models/base-test.js | 60 +++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/addons/api/addon/models/base.js b/addons/api/addon/models/base.js index e9a773d7c..9b2820a06 100644 --- a/addons/api/addon/models/base.js +++ b/addons/api/addon/models/base.js @@ -39,4 +39,33 @@ export default class BaseModel extends Model { get cannotSave() { return !this.canSave; } + + // =methods + + /** + * If this model instance has a related scope, the scope's ID will be passed + * via `adapterOptions.scope_id` automatically. End users may optionally + * pass a custom scope ID to override. + * + * @example + * model.save(); // passes the model's current scope ID + * model.save({adapterOptions: {scope_id: 'global'}}); // override scope ID + * + * End users may specify a _custom method_ via `adapterOptions.method`. + * Custom methods are appended to the record's URL by the adapter. + * + * @example + * // Results in a URL: `/v1/model-name/id:my-custom-method` + * model.save({adapterOptions: {method: 'my-custom-method'}}); + * + * @return {Promise} + */ + save(options={adapterOptions: {}}) { + const scopeID = this.belongsTo('scope').id(); + if (scopeID && !options.adapterOptions.scope_id) { + options.adapterOptions.scope_id = scopeID; + } + return super.save(options); + } + } diff --git a/addons/api/tests/unit/models/base-test.js b/addons/api/tests/unit/models/base-test.js index 0a48639a9..7b463859f 100644 --- a/addons/api/tests/unit/models/base-test.js +++ b/addons/api/tests/unit/models/base-test.js @@ -1,8 +1,10 @@ import { module, test } from 'qunit'; import { setupTest } from 'ember-qunit'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; module('Unit | Model | base', function (hooks) { setupTest(hooks); + setupMirage(hooks); // Replace this with your real tests. test('it exists', function (assert) { @@ -82,4 +84,62 @@ module('Unit | Model | base', function (hooks) { assert.equal(model.cannotSave, true); model.transitionTo('loaded'); }); + + test('it saves records to a scoped URL', async function (assert) { + assert.expect(3); + const store = this.owner.lookup('service:store'); + const scope = store.createRecord('scope', {id: 'o_123'}); + const model = store.createRecord('user', { scope }); + this.server.post('/v1/o_123/users', () => { + assert.ok(true, 'Correctly scoped create record URL was requested.') + return {}; + }); + await model.save(); + this.server.patch('/v1/o_123/users', () => { + assert.ok(true, 'Correctly scoped update record URL was requested.') + return {}; + }); + await model.save(); + this.server.delete('/v1/o_123/users', () => { + assert.ok(true, 'Correctly scoped delete record URL was requested.') + return {}; + }); + await model.destroyRecord(); + }); + + test('it saves to a custom scoped URL if requested', async function (assert) { + assert.expect(3); + const store = this.owner.lookup('service:store'); + const customScopeID = 'global'; + const scope = store.createRecord('scope', {id: 'o_123'}); + const model = store.createRecord('user', { scope }); + this.server.post('/v1/global/users', () => { + assert.ok(true, 'Correctly scoped create record URL was requested.') + return {}; + }); + await model.save({adapterOptions: {scope_id: customScopeID}}); + this.server.patch('/v1/global/users', () => { + assert.ok(true, 'Correctly scoped update record URL was requested.') + return {}; + }); + await model.save({adapterOptions: {scope_id: customScopeID}}); + this.server.delete('/v1/global/users', () => { + assert.ok(true, 'Correctly scoped delete record URL was requested.') + return {}; + }); + await model.destroyRecord({adapterOptions: {scope_id: customScopeID}}); + }); + + test('it saves records to a URL with a custom method if requested', async function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const method = 'my-custom-method'; + const scope = store.createRecord('scope', {id: 'o_123'}); + const model = store.createRecord('user', { scope }); + this.server.post(`/v1/o_123/users:${method}`, () => { + assert.ok(true, 'Correctly scoped create record URL was requested.') + return {}; + }); + await model.save({adapterOptions: {method}}); + }); });