fix: normalize embedded scope IDs and ensure scope resources do not receive scope-prefixed URLs like other resources do
This commit is contained in:
4 files changed
+47
-12
No files matched your search
@@ -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}`;
|
||||
}
|
||||
|
||||
@@ -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: {},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user