fix: normalize embedded scope IDs and ensure scope resources do not receive scope-prefixed URLs like other resources do

This commit is contained in:
Randall Morey committed 2020-07-23 10:34:31 -04:00
1 parent c743cc1716
commit b7996f6271
4 files changed
+47 -12

No files matched your search

+10 -4
View File
@@ -71,10 +71,16 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
*/
urlPrefix(path, parentURL, modelName, id, snapshot={}) {
const prefix = super.urlPrefix(...arguments);
let scopePath = getWithDefault(snapshot, 'adapterOptions.scopeID', '');
// Ensure a slash is added between prefix + scope path if needed.
if (scopePath && prefix.charAt(prefix.length - 1) !== '/') {
scopePath = `/scopes/${scopePath}`;
const isScope = modelName === 'scope';
let scopePath = '';
// Only non-scope resources need a scope path, since scope resources
// aren't technically "scoped" the same way.
if (!isScope) {
scopePath = getWithDefault(snapshot, 'adapterOptions.scopeID', '');
// Ensure a slash is added between prefix + scope path if needed.
if (scopePath && prefix.charAt(prefix.length - 1) !== '/') {
scopePath = `/scopes/${scopePath}`;
}
}
return `${prefix}${scopePath}`;
}
+19 -1
View File
@@ -1,5 +1,6 @@
import RESTSerializer from '@ember-data/serializer/rest';
import { underscore } from '@ember/string';
import { get } from '@ember/object';
import { copy } from 'ember-copy';
/**
@@ -117,7 +118,7 @@ export default class ApplicationSerializer extends RESTSerializer {
primaryModelClass.modelName
);
// Copy the unrooted payload under the expected root key name.
transformedPayload[payloadKey] = copy(payload);
transformedPayload[payloadKey] = copy(payload, true);
// Return the result of normalizing the transformed payload.
return super.normalizeSingleResponse(
store,
@@ -128,4 +129,21 @@ export default class ApplicationSerializer extends RESTSerializer {
);
}
/**
* One consequence of using model fragments to represent the embedded scope
* is that they cannot have `id` fields. We still need to know scope IDs,
* so we copy the `scope.id` value into the `scope.scope_id` field.
* @override
* @see FragmentScope
* @param {Model} typeClass
* @param {Object} hash
* @return {Object}
*/
normalize(typeClass, hash) {
const normalizedHash = copy(hash, true);
const scopeID = get(normalizedHash, 'scope.id');
if (scopeID) normalizedHash.scope.scope_id = scopeID;
return super.normalize(typeClass, normalizedHash);
}
}
@@ -35,6 +35,16 @@ module('Unit | Adapter | application', function (hooks) {
assert.equal(prefix, `v1/scopes/${scopeID}`);
});
test('it does not prefixes URLs with `scopeID` for scope resources', function (assert) {
assert.expect(1);
const scopeID = 'global';
const adapter = this.owner.lookup('adapter:application');
const prefix = adapter.urlPrefix(null, null, 'scope', null, {
adapterOptions: {scopeID}
});
assert.equal(prefix, `v1`);
});
test('it generates correct default URL suffixes', function (assert) {
assert.expect(1);
const adapter = this.owner.lookup('adapter:application');
@@ -36,9 +36,9 @@ module('Unit | Serializer | application', function (hooks) {
const userModelClass = store.createRecord('user').constructor;
const payload = {
items: [
{ id: 1, name: 'User 1' },
{ id: 2, name: 'User 2' },
{ id: 3, name: 'User 3' },
{ id: 1, name: 'User 1', scope: { id: 'o_123' } },
{ id: 2, name: 'User 2', scope: { id: 'o_123' } },
{ id: 3, name: 'User 3', scope: { id: 'o_123' } },
],
};
const normalizedArray = serializer.normalizeArrayResponse(
@@ -52,19 +52,19 @@ module('Unit | Serializer | application', function (hooks) {
{
id: '1',
type: 'user',
attributes: { name: 'User 1' },
attributes: { name: 'User 1', scope: { scope_id: 'o_123' } },
relationships: {},
},
{
id: '2',
type: 'user',
attributes: { name: 'User 2' },
attributes: { name: 'User 2', scope: { scope_id: 'o_123' } },
relationships: {},
},
{
id: '3',
type: 'user',
attributes: { name: 'User 3' },
attributes: { name: 'User 3', scope: { scope_id: 'o_123' } },
relationships: {},
},
],
@@ -79,6 +79,7 @@ module('Unit | Serializer | application', function (hooks) {
const payload = {
id: '1',
name: 'User 1',
scope: { id: 'o_123' }
};
const normalized = serializer.normalizeSingleResponse(
store,
@@ -90,7 +91,7 @@ module('Unit | Serializer | application', function (hooks) {
data: {
id: '1',
type: 'user',
attributes: { name: 'User 1' },
attributes: { name: 'User 1', scope: { scope_id: 'o_123' } },
relationships: {},
},
});