diff --git a/packages/activemodel-adapter/lib/system/active-model-adapter.js b/packages/activemodel-adapter/lib/system/active-model-adapter.js index 3a3d206964b..c22518945ff 100644 --- a/packages/activemodel-adapter/lib/system/active-model-adapter.js +++ b/packages/activemodel-adapter/lib/system/active-model-adapter.js @@ -1,17 +1,21 @@ -import {RESTAdapter} from "ember-data/adapters"; -import {pluralize} from "ember-inflector"; +import Ember from 'ember'; import { InvalidError, errorsHashToArray -} from "ember-data/adapters/errors"; +} from 'ember-data/adapters/errors'; +import RESTAdapter from 'ember-data/adapters/rest-adapter'; + +import { pluralize } from 'ember-inflector'; + +const { + decamelize, + underscore +} = Ember.String; /** @module ember-data */ -var decamelize = Ember.String.decamelize; -var underscore = Ember.String.underscore; - /** The ActiveModelAdapter is a subclass of the RESTAdapter designed to integrate with a JSON API that uses an underscored naming convention instead of camelCasing. @@ -103,7 +107,7 @@ var underscore = Ember.String.underscore; @extends DS.RESTAdapter **/ -var ActiveModelAdapter = RESTAdapter.extend({ +const ActiveModelAdapter = RESTAdapter.extend({ defaultSerializer: '-active-model', /** The ActiveModelAdapter overrides the `pathForType` method to build diff --git a/packages/activemodel-adapter/lib/system/active-model-serializer.js b/packages/activemodel-adapter/lib/system/active-model-serializer.js index 674556cf260..3d2bf5cc512 100644 --- a/packages/activemodel-adapter/lib/system/active-model-serializer.js +++ b/packages/activemodel-adapter/lib/system/active-model-serializer.js @@ -1,15 +1,18 @@ -import { singularize } from "ember-inflector"; -import RESTSerializer from "ember-data/serializers/rest-serializer"; -import normalizeModelName from "ember-data/system/normalize-model-name"; +import Ember from 'ember'; +import RESTSerializer from 'ember-data/serializers/rest-serializer'; +import normalizeModelName from 'ember-data/system/normalize-model-name'; + /** @module ember-data -*/ + */ -var forEach = Ember.ArrayPolyfills.forEach; -var camelize = Ember.String.camelize; -var classify = Ember.String.classify; -var decamelize = Ember.String.decamelize; -var underscore = Ember.String.underscore; +const { + singularize, + classify, + decamelize, + camelize, + underscore +} = Ember.String; /** The ActiveModelSerializer is a subclass of the RESTSerializer designed to integrate @@ -177,9 +180,7 @@ var ActiveModelSerializer = RESTSerializer.extend({ if (Ember.isNone(belongsTo)) { json[jsonKey] = null; } else { - json[jsonKey] = classify(belongsTo.modelName).replace(/(\/)([a-z])/g, function(match, separator, chr) { - return match.toUpperCase(); - }).replace('/', '::'); + json[jsonKey] = classify(belongsTo.modelName).replace('/', '::'); } }, @@ -279,10 +280,7 @@ var ActiveModelSerializer = RESTSerializer.extend({ if (payload && payload.type) { payload.type = this.modelNameFromPayloadKey(payload.type); } else if (payload && relationship.kind === "hasMany") { - var self = this; - forEach.call(payload, function(single) { - single.type = self.modelNameFromPayloadKey(single.type); - }); + payload.forEach((single) => single.type = this.modelNameFromPayloadKey(single.type)); } } else { payloadKey = this.keyForRelationship(key, relationship.kind, "deserialize"); @@ -298,12 +296,62 @@ var ActiveModelSerializer = RESTSerializer.extend({ }, this); } }, + + extractRelationships: function(modelClass, resourceHash) { + modelClass.eachRelationship(function (key, relationshipMeta) { + var relationshipKey = this.keyForRelationship(key, relationshipMeta.kind, "deserialize"); + + // prefer the format the AMS gem expects, e.g.: + // relationship: {id: id, type: type} + if (relationshipMeta.options.polymorphic) { + extractPolymorphicRelationships(key, relationshipMeta, resourceHash, relationshipKey); + } + // If the preferred format is not found, use {relationship_name_id, relationship_name_type} + if (resourceHash.hasOwnProperty(relationshipKey) && typeof resourceHash[relationshipKey] !== 'object') { + var polymorphicTypeKey = this.keyForRelationship(key) + '_type'; + if (resourceHash[polymorphicTypeKey] && relationshipMeta.options.polymorphic) { + let id = resourceHash[relationshipKey]; + let type = resourceHash[polymorphicTypeKey]; + delete resourceHash[polymorphicTypeKey]; + delete resourceHash[relationshipKey]; + resourceHash[relationshipKey] = { id: id, type: type }; + } + } + }, this); + return this._super.apply(this, arguments); + }, + modelNameFromPayloadKey: function(key) { - var convertedFromRubyModule = camelize(singularize(key)).replace(/(^|\:)([A-Z])/g, function(match, separator, chr) { - return match.toLowerCase(); - }).replace('::', '/'); + var convertedFromRubyModule = singularize(key.replace('::', '/')); return normalizeModelName(convertedFromRubyModule); } }); +function extractPolymorphicRelationships(key, relationshipMeta, resourceHash, relationshipKey) { + let polymorphicKey = decamelize(key); + if (polymorphicKey in resourceHash && typeof resourceHash[polymorphicKey] === 'object') { + if (relationshipMeta.kind === 'belongsTo') { + let hash = resourceHash[polymorphicKey]; + let {id, type} = hash; + resourceHash[relationshipKey] = { id, type }; + // otherwise hasMany + } else { + let hashes = resourceHash[polymorphicKey]; + + if (!hashes) { + return; + } + + // TODO: replace this with map when ActiveModelAdapter branches for Ember Data 2.0 + var array = []; + for (let i = 0, length = hashes.length; i < length; i++) { + let hash = hashes[i]; + let {id, type} = hash; + array.push({ id, type }); + } + resourceHash[relationshipKey] = array; + } + } +} + export default ActiveModelSerializer; diff --git a/packages/activemodel-adapter/tests/integration/active-model-adapter-serializer-test.js b/packages/activemodel-adapter/tests/integration/active-model-adapter-serializer-test.js index 58a6f7c475d..9388173b880 100644 --- a/packages/activemodel-adapter/tests/integration/active-model-adapter-serializer-test.js +++ b/packages/activemodel-adapter/tests/integration/active-model-adapter-serializer-test.js @@ -1,5 +1,7 @@ var env, store, adapter, User; + var originalAjax; +const {ActiveModelAdapter} = DS; module("integration/active_model_adapter_serializer - AMS Adapter and Serializer", { setup: function() { @@ -11,7 +13,7 @@ module("integration/active_model_adapter_serializer - AMS Adapter and Serializer env = setupStore({ user: User, - adapter: DS.ActiveModelAdapter + adapter: ActiveModelAdapter }); store = env.store; @@ -25,7 +27,7 @@ module("integration/active_model_adapter_serializer - AMS Adapter and Serializer } }); -test('errors are camelCased and are expected under the `errors` property of the payload', function() { +test('errors are camelCased and are expected under the `errors` property of the payload', function(assert) { var jqXHR = { status: 422, getAllResponseHeaders: function() { return ''; }, @@ -48,8 +50,8 @@ test('errors are camelCased and are expected under the `errors` property of the Ember.run(function() { user.save().then(null, function() { var errors = user.get('errors'); - ok(errors.has('firstName'), "there are errors for the firstName attribute"); - deepEqual(errors.errorsFor('firstName').getEach('message'), ['firstName error']); + assert.ok(errors.has('firstName'), "there are errors for the firstName attribute"); + assert.deepEqual(errors.errorsFor('firstName').getEach('message'), ['firstName error']); }); }); }); diff --git a/packages/activemodel-adapter/tests/integration/active-model-adapter-test.js b/packages/activemodel-adapter/tests/integration/active-model-adapter-test.js index 7df6b666e62..a662b864208 100644 --- a/packages/activemodel-adapter/tests/integration/active-model-adapter-test.js +++ b/packages/activemodel-adapter/tests/integration/active-model-adapter-test.js @@ -1,3 +1,5 @@ +const {ActiveModelAdapter} = DS; + var env, store, adapter, SuperUser; var passedUrl, passedVerb, passedHash; module("integration/active_model_adapter - AMS Adapter", { @@ -6,7 +8,7 @@ module("integration/active_model_adapter - AMS Adapter", { env = setupStore({ superUser: SuperUser, - adapter: DS.ActiveModelAdapter + adapter: ActiveModelAdapter }); store = env.store; @@ -16,11 +18,11 @@ module("integration/active_model_adapter - AMS Adapter", { } }); -test('buildURL - decamelizes names', function() { - equal(adapter.buildURL('superUser', 1), "/super_users/1"); +test('buildURL - decamelizes names', function(assert) { + assert.equal(adapter.buildURL('superUser', 1), "/super_users/1"); }); -test('handleResponse - returns invalid error if 422 response', function() { +test('handleResponse - returns invalid error if 422 response', function(assert) { var jqXHR = { status: 422, @@ -31,11 +33,11 @@ test('handleResponse - returns invalid error if 422 response', function() { var error = adapter.handleResponse(jqXHR.status, {}, json).errors[0]; - equal(error.detail, "can't be blank"); - equal(error.source.pointer, "data/attributes/name"); + assert.equal(error.detail, "can't be blank"); + assert.equal(error.source.pointer, "data/attributes/name"); }); -test('handleResponse - returns ajax response if not 422 response', function() { +test('handleResponse - returns ajax response if not 422 response', function(assert) { var jqXHR = { status: 500, responseText: "Something went wrong" @@ -43,5 +45,5 @@ test('handleResponse - returns ajax response if not 422 response', function() { var json = adapter.parseErrorResponse(jqXHR.responseText); - ok(adapter.handleResponse(jqXHR.status, {}, json) instanceof DS.AdapterError, 'must be a DS.AdapterError'); + assert.ok(adapter.handleResponse(jqXHR.status, {}, json) instanceof DS.AdapterError, 'must be a DS.AdapterError'); }); diff --git a/packages/activemodel-adapter/tests/integration/active-model-serializer-namespaced-model-name-new-test.js b/packages/activemodel-adapter/tests/integration/active-model-serializer-namespaced-model-name-new-test.js index 915ffec6bf1..387109cc55b 100644 --- a/packages/activemodel-adapter/tests/integration/active-model-serializer-namespaced-model-name-new-test.js +++ b/packages/activemodel-adapter/tests/integration/active-model-serializer-namespaced-model-name-new-test.js @@ -1,3 +1,5 @@ +const {ActiveModelSerializer} = DS; + var SuperVillain, EvilMinion, YellowMinion, DoomsdayDevice, MediocreVillain, TestSerializer, env; var run = Ember.run; @@ -22,7 +24,7 @@ module("integration/active_model - AMS-namespaced-model-names (new API)", { name: DS.attr('string'), evilMinions: DS.hasMany('evilMinion', { polymorphic: true }) }); - TestSerializer = DS.ActiveModelSerializer.extend({ + TestSerializer = ActiveModelSerializer.extend({ isNewSerializerAPI: true }); env = setupStore({ @@ -49,74 +51,78 @@ module("integration/active_model - AMS-namespaced-model-names (new API)", { } }); -test("extractPolymorphic hasMany", function() { - var json_hash = { - mediocre_villain: { id: 1, name: "Dr Horrible", evil_minion_ids: [{ type: "EvilMinions::YellowMinion", id: 12 }] }, - "evil-minions/yellow-minion": [{ id: 12, name: "Alex", doomsday_device_ids: [1] }] - }; - var json; +if (Ember.FEATURES.isEnabled('ds-new-serializer-api')) { - run(function() { - json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json_hash, '1', 'findRecord'); - }); + test("extractPolymorphic hasMany", function(assert) { + var json_hash = { + mediocre_villain: { id: 1, name: "Dr Horrible", evil_minion_ids: [{ type: "EvilMinions::YellowMinion", id: 12 }] }, + "evil-minions/yellow-minion": [{ id: 12, name: "Alex", doomsday_device_ids: [1] }] + }; + var json; - deepEqual(json, { - "data": { - "id": "1", - "type": "mediocre-villain", - "attributes": { - "name": "Dr Horrible" - }, - "relationships": { - "evilMinions": { - "data": [ - { "id": "12", "type": "evil-minions/yellow-minion" } - ] + run(function() { + json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json_hash, '1', 'find'); + }); + + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "mediocre-villain", + "attributes": { + "name": "Dr Horrible" + }, + "relationships": { + "evilMinions": { + "data": [ + { "id": "12", "type": "evil-minions/yellow-minion" } + ] + } } - } - }, - "included": [{ - "id": "12", - "type": "evil-minions/yellow-minion", - "attributes": { - "name": "Alex" }, - "relationships": {} - }] + "included": [{ + "id": "12", + "type": "evil-minions/yellow-minion", + "attributes": { + "name": "Alex" + }, + "relationships": {} + }] + }); }); -}); -test("extractPolymorphic belongsTo", function() { - var json_hash = { - doomsday_device: { id: 1, name: "DeathRay", evil_minion_id: { type: "EvilMinions::YellowMinion", id: 12 } }, - "evil-minions/yellow-minion": [{ id: 12, name: "Alex", doomsday_device_ids: [1] }] - }; - var json; + test("extractPolymorphic belongsTo", function(assert) { + var json_hash = { + doomsday_device: { id: 1, name: "DeathRay", evil_minion_id: { type: "EvilMinions::YellowMinion", id: 12 } }, + "evil-minions/yellow-minion": [{ id: 12, name: "Alex", doomsday_device_ids: [1] }] + }; + var json; - run(function() { - json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'findRecord'); - }); + run(function() { + json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'find'); + }); - deepEqual(json, { - "data": { - "id": "1", - "type": "doomsday-device", - "attributes": { - "name": "DeathRay" - }, - "relationships": { - "evilMinion": { - "data": { "id": "12", "type": "evil-minions/yellow-minion" } + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "doomsday-device", + "attributes": { + "name": "DeathRay" + }, + "relationships": { + "evilMinion": { + "data": { "id": "12", "type": "evil-minions/yellow-minion" } + } } - } - }, - "included": [{ - "id": "12", - "type": "evil-minions/yellow-minion", - "attributes": { - "name": "Alex" }, - "relationships": {} - }] + "included": [{ + "id": "12", + "type": "evil-minions/yellow-minion", + "attributes": { + "name": "Alex" + }, + "relationships": {} + }] + }); }); -}); + +} diff --git a/packages/activemodel-adapter/tests/integration/active-model-serializer-namespaced-model-name-test.js b/packages/activemodel-adapter/tests/integration/active-model-serializer-namespaced-model-name-test.js index 958281d5ac3..f4ba7675c33 100644 --- a/packages/activemodel-adapter/tests/integration/active-model-serializer-namespaced-model-name-test.js +++ b/packages/activemodel-adapter/tests/integration/active-model-serializer-namespaced-model-name-test.js @@ -1,5 +1,7 @@ +const {ActiveModelAdapter, ActiveModelSerializer} = DS; + var SuperVillain, EvilMinion, YellowMinion, DoomsdayDevice, MediocreVillain, env; -var run = Ember.run; +const {run} = Ember; module("integration/active_model - AMS-namespaced-model-names", { setup: function() { @@ -35,9 +37,9 @@ module("integration/active_model - AMS-namespaced-model-names", { env.store.modelFor('evil-minions/yellow-minion'); env.store.modelFor('doomsday-device'); env.store.modelFor('mediocre-villain'); - env.registry.register('serializer:application', DS.ActiveModelSerializer); - env.registry.register('serializer:-active-model', DS.ActiveModelSerializer); - env.registry.register('adapter:-active-model', DS.ActiveModelAdapter); + env.registry.register('serializer:application', ActiveModelSerializer.extend({ isNewSerializerAPI: true })); + env.registry.register('serializer:-active-model', ActiveModelSerializer.extend({ isNewSerializerAPI: true })); + env.registry.register('adapter:-active-model', ActiveModelAdapter); env.amsSerializer = env.container.lookup("serializer:-active-model"); env.amsAdapter = env.container.lookup("adapter:-active-model"); }, @@ -47,7 +49,7 @@ module("integration/active_model - AMS-namespaced-model-names", { } }); -test("serialize polymorphic", function() { +test("serialize polymorphic", function(assert) { var tom, ray; run(function() { tom = env.store.createRecord('evil-minions/yellow-minion', { name: "Alex", id: "124" }); @@ -56,14 +58,14 @@ test("serialize polymorphic", function() { var json = env.amsSerializer.serialize(ray._createSnapshot()); - deepEqual(json, { + assert.deepEqual(json, { name: "DeathRay", evil_minion_type: "EvilMinions::YellowMinion", evil_minion_id: "124" }); }); -test("serialize polymorphic when type key is not camelized", function() { +test("serialize polymorphic when type key is not camelized", function(assert) { YellowMinion.modelName = 'evil-minions/yellow-minion'; var tom, ray; run(function() { @@ -73,47 +75,77 @@ test("serialize polymorphic when type key is not camelized", function() { var json = env.amsSerializer.serialize(ray._createSnapshot()); - deepEqual(json["evil_minion_type"], "EvilMinions::YellowMinion"); + assert.deepEqual(json["evil_minion_type"], "EvilMinions::YellowMinion"); }); -test("extractPolymorphic hasMany", function() { +test("extractPolymorphic hasMany", function(assert) { var json_hash = { - mediocre_villain: { id: 1, name: "Dr Horrible", evil_minions: [{ type: "EvilMinions::YellowMinion", id: 12 }] }, - evil_minions: [{ id: 12, name: "Alex", doomsday_device_ids: [1] }] + mediocre_villain: { id: 1, name: "Dr Horrible", evil_minion_ids: [{ type: "EvilMinions::YellowMinion", id: 12 }] }, + "evil-minions/yellow-minion": [{ id: 12, name: "Alex", doomsday_device_ids: [1] }] }; var json; run(function() { - json = env.amsSerializer.extractSingle(env.store, MediocreVillain, json_hash); + json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json_hash, '1', 'findRecord'); }); - deepEqual(json, { - "id": 1, - "name": "Dr Horrible", - "evilMinions": [{ - type: "evil-minions/yellow-minion", - id: 12 + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "mediocre-villain", + "attributes": { + "name": "Dr Horrible" + }, + "relationships": { + "evilMinions": { + "data": [ + { "id": "12", "type": "evil-minions/yellow-minion" } + ] + } + } + }, + "included": [{ + "id": "12", + "type": "evil-minions/yellow-minion", + "attributes": { + "name": "Alex" + }, + "relationships": {} }] }); }); -test("extractPolymorphic", function() { +test("extractPolymorphic belongsTo", function(assert) { var json_hash = { - doomsday_device: { id: 1, name: "DeathRay", evil_minion: { type: "EvilMinions::YellowMinion", id: 12 } }, - evil_minions: [{ id: 12, name: "Alex", doomsday_device_ids: [1] }] + doomsday_device: { id: 1, name: "DeathRay", evil_minion_id: { type: "EvilMinions::YellowMinion", id: 12 } }, + "evil-minions/yellow-minion": [{ id: 12, name: "Alex", doomsday_device_ids: [1] }] }; var json; run(function() { - json = env.amsSerializer.extractSingle(env.store, DoomsdayDevice, json_hash); + json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'findRecord'); }); - deepEqual(json, { - "id": 1, - "name": "DeathRay", - "evilMinion": { - type: "evil-minions/yellow-minion", - id: 12 - } + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "doomsday-device", + "attributes": { + "name": "DeathRay" + }, + "relationships": { + "evilMinion": { + "data": { "id": "12", "type": "evil-minions/yellow-minion" } + } + } + }, + "included": [{ + "id": "12", + "type": "evil-minions/yellow-minion", + "attributes": { + "name": "Alex" + }, + "relationships": {} + }] }); }); diff --git a/packages/activemodel-adapter/tests/integration/active-model-serializer-new-test.js b/packages/activemodel-adapter/tests/integration/active-model-serializer-new-test.js index 68ffb2d67db..b7b123fc000 100644 --- a/packages/activemodel-adapter/tests/integration/active-model-serializer-new-test.js +++ b/packages/activemodel-adapter/tests/integration/active-model-serializer-new-test.js @@ -1,3 +1,5 @@ +const {ActiveModelAdapter, ActiveModelSerializer} = DS; + var HomePlanet, SuperVillain, EvilMinion, YellowMinion, DoomsdayDevice, MediocreVillain, TestSerializer, env; var run = Ember.run; @@ -26,7 +28,7 @@ module("integration/active_model - ActiveModelSerializer (new API)", { name: DS.attr('string'), evilMinions: DS.hasMany('evilMinion', { polymorphic: true }) }); - TestSerializer = DS.ActiveModelSerializer.extend({ + TestSerializer = ActiveModelSerializer.extend({ isNewSerializerAPI: true }); env = setupStore({ @@ -45,7 +47,7 @@ module("integration/active_model - ActiveModelSerializer (new API)", { env.store.modelFor('mediocreVillain'); env.registry.register('serializer:application', TestSerializer); env.registry.register('serializer:-active-model', TestSerializer); - env.registry.register('adapter:-active-model', DS.ActiveModelAdapter); + env.registry.register('adapter:-active-model', ActiveModelAdapter); env.amsSerializer = env.container.lookup("serializer:-active-model"); env.amsAdapter = env.container.lookup("adapter:-active-model"); }, @@ -55,303 +57,307 @@ module("integration/active_model - ActiveModelSerializer (new API)", { } }); -test("normalize", function() { - SuperVillain.reopen({ - yellowMinion: DS.belongsTo('yellowMinion') - }); +if (Ember.FEATURES.isEnabled('ds-new-serializer-api')) { - var superVillain_hash = { - id: "1", - first_name: "Tom", - last_name: "Dale", - home_planet_id: "123", - evil_minion_ids: [1, 2] - }; - - var json = env.amsSerializer.normalize(SuperVillain, superVillain_hash, "superVillain"); - - deepEqual(json, { - "data": { - "id": "1", - "type": "super-villain", - "attributes": { - "firstName": "Tom", - "lastName": "Dale" - }, - "relationships": { - "evilMinions": { - "data": [ - { "id": "1", "type": "evil-minion" }, - { "id": "2", "type": "evil-minion" } - ] + test("normalize", function(assert) { + SuperVillain.reopen({ + yellowMinion: DS.belongsTo('yellowMinion') + }); + + var superVillain_hash = { + id: "1", + first_name: "Tom", + last_name: "Dale", + home_planet_id: "123", + evil_minion_ids: [1, 2] + }; + + var json = env.amsSerializer.normalize(SuperVillain, superVillain_hash, "superVillain"); + + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "super-villain", + "attributes": { + "firstName": "Tom", + "lastName": "Dale" }, - "homePlanet": { - "data": { "id": "123", "type": "home-planet" } + "relationships": { + "evilMinions": { + "data": [ + { "id": "1", "type": "evil-minion" }, + { "id": "2", "type": "evil-minion" } + ] + }, + "homePlanet": { + "data": { "id": "123", "type": "home-planet" } + } } } - } + }); }); -}); -test("normalize links", function() { - var home_planet = { - id: "1", - name: "Umber", - links: { super_villains: "/api/super_villians/1" } - }; - - var json = env.amsSerializer.normalize(HomePlanet, home_planet, "homePlanet"); - - equal(json.data.relationships.superVillains.links.related, "/api/super_villians/1", "normalize links"); -}); - -test("normalizeSingleResponse", function() { - env.registry.register('adapter:superVillain', DS.ActiveModelAdapter); - - var json_hash = { - home_planet: { id: "1", name: "Umber", super_villain_ids: [1] }, - super_villains: [{ + test("normalize links", function(assert) { + var home_planet = { id: "1", - first_name: "Tom", - last_name: "Dale", - home_planet_id: "1" - }] - }; + name: "Umber", + links: { super_villains: "/api/super_villians/1" } + }; - var json; - run(function() { - json = env.amsSerializer.normalizeSingleResponse(env.store, HomePlanet, json_hash, '1', 'findRecord'); + var json = env.amsSerializer.normalize(HomePlanet, home_planet, "homePlanet"); + + assert.equal(json.data.relationships.superVillains.links.related, "/api/super_villians/1", "normalize links"); }); - deepEqual(json, { - "data": { - "id": "1", - "type": "home-planet", - "attributes": { - "name": "Umber" - }, - "relationships": { - "superVillains": { - "data": [ - { "id": "1", "type": "super-villain" } - ] + test("normalizeSingleResponse", function(assert) { + env.registry.register('adapter:superVillain', ActiveModelAdapter); + + var json_hash = { + home_planet: { id: "1", name: "Umber", super_villain_ids: [1] }, + super_villains: [{ + id: "1", + first_name: "Tom", + last_name: "Dale", + home_planet_id: "1" + }] + }; + + var json; + run(function() { + json = env.amsSerializer.normalizeSingleResponse(env.store, HomePlanet, json_hash, '1', 'find'); + }); + + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "home-planet", + "attributes": { + "name": "Umber" + }, + "relationships": { + "superVillains": { + "data": [ + { "id": "1", "type": "super-villain" } + ] + } } - } - }, - "included": [{ - "id": "1", - "type": "super-villain", - "attributes": { - "firstName": "Tom", - "lastName": "Dale" }, - "relationships": { - "homePlanet": { - "data": { "id": "1", "type": "home-planet" } + "included": [{ + "id": "1", + "type": "super-villain", + "attributes": { + "firstName": "Tom", + "lastName": "Dale" + }, + "relationships": { + "homePlanet": { + "data": { "id": "1", "type": "home-planet" } + } } - } - }] + }] + }); }); -}); -test("normalizeArrayResponse", function() { - env.registry.register('adapter:superVillain', DS.ActiveModelAdapter); - var array; + test("normalizeArrayResponse", function(assert) { + env.registry.register('adapter:superVillain', ActiveModelAdapter); + var array; - var json_hash = { - home_planets: [{ id: "1", name: "Umber", super_villain_ids: [1] }], - super_villains: [{ id: "1", first_name: "Tom", last_name: "Dale", home_planet_id: "1" }] - }; + var json_hash = { + home_planets: [{ id: "1", name: "Umber", super_villain_ids: [1] }], + super_villains: [{ id: "1", first_name: "Tom", last_name: "Dale", home_planet_id: "1" }] + }; - run(function() { - array = env.amsSerializer.normalizeArrayResponse(env.store, HomePlanet, json_hash, null, 'findAll'); - }); + run(function() { + array = env.amsSerializer.normalizeArrayResponse(env.store, HomePlanet, json_hash, null, 'findAll'); + }); - deepEqual(array, { - "data": [{ - "id": "1", - "type": "home-planet", - "attributes": { - "name": "Umber" - }, - "relationships": { - "superVillains": { - "data": [ - { "id": "1", "type": "super-villain" } - ] + assert.deepEqual(array, { + "data": [{ + "id": "1", + "type": "home-planet", + "attributes": { + "name": "Umber" + }, + "relationships": { + "superVillains": { + "data": [ + { "id": "1", "type": "super-villain" } + ] + } } - } - }], - "included": [{ - "id": "1", - "type": "super-villain", - "attributes": { - "firstName": "Tom", - "lastName": "Dale" - }, - "relationships": { - "homePlanet": { - "data": { "id": "1", "type": "home-planet" } + }], + "included": [{ + "id": "1", + "type": "super-villain", + "attributes": { + "firstName": "Tom", + "lastName": "Dale" + }, + "relationships": { + "homePlanet": { + "data": { "id": "1", "type": "home-planet" } + } } - } - }] + }] + }); }); -}); -test("extractPolymorphic hasMany", function() { - env.registry.register('adapter:yellowMinion', DS.ActiveModelAdapter); - MediocreVillain.toString = function() { return "MediocreVillain"; }; - YellowMinion.toString = function() { return "YellowMinion"; }; + test("extractPolymorphic hasMany", function(assert) { + env.registry.register('adapter:yellowMinion', ActiveModelAdapter); + MediocreVillain.toString = function() { return "MediocreVillain"; }; + YellowMinion.toString = function() { return "YellowMinion"; }; - var json_hash = { - mediocre_villain: { id: 1, name: "Dr Horrible", evil_minion_ids: [{ type: "yellow_minion", id: 12 }] }, - yellow_minions: [{ id: 12, name: "Alex" }] - }; - var json; + var json_hash = { + mediocre_villain: { id: 1, name: "Dr Horrible", evil_minion_ids: [{ type: "yellow_minion", id: 12 }] }, + yellow_minions: [{ id: 12, name: "Alex" }] + }; + var json; - run(function() { - json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json_hash, '1', 'findRecord'); - }); + run(function() { + json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json_hash, '1', 'find'); + }); - deepEqual(json, { - "data": { - "id": "1", - "type": "mediocre-villain", - "attributes": { - "name": "Dr Horrible" - }, - "relationships": { - "evilMinions": { - "data": [ - { "id": "12", "type": "yellow-minion" } - ] + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "mediocre-villain", + "attributes": { + "name": "Dr Horrible" + }, + "relationships": { + "evilMinions": { + "data": [ + { "id": "12", "type": "yellow-minion" } + ] + } } - } - }, - "included": [{ - "id": "12", - "type": "yellow-minion", - "attributes": { - "name": "Alex" }, - "relationships": {} - }] + "included": [{ + "id": "12", + "type": "yellow-minion", + "attributes": { + "name": "Alex" + }, + "relationships": {} + }] + }); }); -}); -test("extractPolymorphic belongsTo", function() { - env.registry.register('adapter:yellowMinion', DS.ActiveModelAdapter); - EvilMinion.toString = function() { return "EvilMinion"; }; - YellowMinion.toString = function() { return "YellowMinion"; }; + test("extractPolymorphic belongsTo", function(assert) { + env.registry.register('adapter:yellowMinion', ActiveModelAdapter); + EvilMinion.toString = function() { return "EvilMinion"; }; + YellowMinion.toString = function() { return "YellowMinion"; }; - var json_hash = { - doomsday_device: { id: 1, name: "DeathRay", evil_minion_id: { type: "yellow_minion", id: 12 } }, - yellow_minions: [{ id: 12, name: "Alex", doomsday_device_ids: [1] }] - }; - var json; + var json_hash = { + doomsday_device: { id: 1, name: "DeathRay", evil_minion_id: { type: "yellow_minion", id: 12 } }, + yellow_minions: [{ id: 12, name: "Alex", doomsday_device_ids: [1] }] + }; + var json; - run(function() { - json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'findRecord'); - }); + run(function() { + json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'find'); + }); - deepEqual(json, { - "data": { - "id": "1", - "type": "doomsday-device", - "attributes": { - "name": "DeathRay" - }, - "relationships": { - "evilMinion": { - "data": { "id": "12", "type": "yellow-minion" } + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "doomsday-device", + "attributes": { + "name": "DeathRay" + }, + "relationships": { + "evilMinion": { + "data": { "id": "12", "type": "yellow-minion" } + } } - } - }, - "included": [{ - "id": "12", - "type": "yellow-minion", - "attributes": { - "name": "Alex" }, - "relationships": {} - }] + "included": [{ + "id": "12", + "type": "yellow-minion", + "attributes": { + "name": "Alex" + }, + "relationships": {} + }] + }); }); -}); -test("extractPolymorphic when the related data is not specified", function() { - var json = { - doomsday_device: { id: 1, name: "DeathRay" }, - evil_minions: [{ id: 12, name: "Alex", doomsday_device_ids: [1] }] - }; + test("extractPolymorphic when the related data is not specified", function(assert) { + var json = { + doomsday_device: { id: 1, name: "DeathRay" }, + evil_minions: [{ id: 12, name: "Alex", doomsday_device_ids: [1] }] + }; - run(function() { - json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json, '1', 'findRecord'); - }); + run(function() { + json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json, '1', 'find'); + }); - deepEqual(json, { - "data": { - "id": "1", - "type": "doomsday-device", - "attributes": { - "name": "DeathRay" - }, - "relationships": {} - }, - "included": [{ - "id": "12", - "type": "evil-minion", - "attributes": { - "name": "Alex" + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "doomsday-device", + "attributes": { + "name": "DeathRay" + }, + "relationships": {} }, - "relationships": {} - }] + "included": [{ + "id": "12", + "type": "evil-minion", + "attributes": { + "name": "Alex" + }, + "relationships": {} + }] + }); }); -}); -test("extractPolymorphic hasMany when the related data is not specified", function() { - var json = { - mediocre_villain: { id: 1, name: "Dr Horrible" } - }; + test("extractPolymorphic hasMany when the related data is not specified", function(assert) { + var json = { + mediocre_villain: { id: 1, name: "Dr Horrible" } + }; - run(function() { - json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json, '1', 'findRecord'); - }); + run(function() { + json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json, '1', 'find'); + }); - deepEqual(json, { - "data": { - "id": "1", - "type": "mediocre-villain", - "attributes": { - "name": "Dr Horrible" + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "mediocre-villain", + "attributes": { + "name": "Dr Horrible" + }, + "relationships": {} }, - "relationships": {} - }, - "included": [] + "included": [] + }); }); -}); -test("extractPolymorphic does not break hasMany relationships", function() { - var json = { - mediocre_villain: { id: 1, name: "Dr. Evil", evil_minion_ids: [] } - }; + test("extractPolymorphic does not break hasMany relationships", function(assert) { + var json = { + mediocre_villain: { id: 1, name: "Dr. Evil", evil_minion_ids: [] } + }; - run(function () { - json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json, '1', 'findRecord'); - }); + run(function () { + json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json, '1', 'find'); + }); - deepEqual(json, { - "data": { - "id": "1", - "type": "mediocre-villain", - "attributes": { - "name": "Dr. Evil" - }, - "relationships": { - "evilMinions": { - "data": [] + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "mediocre-villain", + "attributes": { + "name": "Dr. Evil" + }, + "relationships": { + "evilMinions": { + "data": [] + } } - } - }, - "included": [] + }, + "included": [] + }); }); -}); + +} diff --git a/packages/activemodel-adapter/tests/integration/active-model-serializer-test.js b/packages/activemodel-adapter/tests/integration/active-model-serializer-test.js index 26e1f5964b2..15e78240e94 100644 --- a/packages/activemodel-adapter/tests/integration/active-model-serializer-test.js +++ b/packages/activemodel-adapter/tests/integration/active-model-serializer-test.js @@ -1,3 +1,5 @@ +const {ActiveModelAdapter, ActiveModelSerializer} = DS; + var get = Ember.get; var HomePlanet, league, SuperVillain, EvilMinion, YellowMinion, DoomsdayDevice, MediocreVillain, env; var run = Ember.run; @@ -41,9 +43,9 @@ module("integration/active_model - ActiveModelSerializer", { env.store.modelFor('yellow-minion'); env.store.modelFor('doomsday-device'); env.store.modelFor('mediocre-villain'); - env.registry.register('serializer:application', DS.ActiveModelSerializer); - env.registry.register('serializer:-active-model', DS.ActiveModelSerializer); - env.registry.register('adapter:-active-model', DS.ActiveModelAdapter); + env.registry.register('serializer:application', ActiveModelSerializer.extend({ isNewSerializerAPI: true })); + env.registry.register('serializer:-active-model', ActiveModelSerializer.extend({ isNewSerializerAPI: true })); + env.registry.register('adapter:-active-model', ActiveModelAdapter); env.amsSerializer = env.container.lookup("serializer:-active-model"); env.amsAdapter = env.container.lookup("adapter:-active-model"); }, @@ -53,7 +55,7 @@ module("integration/active_model - ActiveModelSerializer", { } }); -test("serialize", function() { +test("serialize", function(assert) { var tom; run(function() { league = env.store.createRecord('home-planet', { name: "Villain League", id: "123" }); @@ -62,14 +64,14 @@ test("serialize", function() { var json = env.amsSerializer.serialize(tom._createSnapshot()); - deepEqual(json, { + assert.deepEqual(json, { first_name: "Tom", last_name: "Dale", home_planet_id: get(league, "id") }); }); -test("serializeIntoHash", function() { +test("serializeIntoHash", function(assert) { run(function() { league = env.store.createRecord('home-planet', { name: "Umber", id: "123" }); }); @@ -77,14 +79,14 @@ test("serializeIntoHash", function() { env.amsSerializer.serializeIntoHash(json, HomePlanet, league._createSnapshot()); - deepEqual(json, { + assert.deepEqual(json, { home_planet: { name: "Umber" } }); }); -test("serializeIntoHash with decamelized types", function() { +test("serializeIntoHash with decamelized types", function(assert) { HomePlanet.modelName = 'home-planet'; run(function() { league = env.store.createRecord('home-planet', { name: "Umber", id: "123" }); @@ -93,7 +95,7 @@ test("serializeIntoHash with decamelized types", function() { env.amsSerializer.serializeIntoHash(json, HomePlanet, league._createSnapshot()); - deepEqual(json, { + assert.deepEqual(json, { home_planet: { name: "Umber" } @@ -101,38 +103,58 @@ test("serializeIntoHash with decamelized types", function() { }); -test("normalize", function() { +test("normalize", function(assert) { SuperVillain.reopen({ - yellowMinion: DS.belongsTo('yellow-minion') + yellowMinion: DS.belongsTo('yellowMinion') }); - var superVillain_hash = { first_name: "Tom", last_name: "Dale", home_planet_id: "123", evil_minion_ids: [1,2] }; + var superVillain_hash = { + id: "1", + first_name: "Tom", + last_name: "Dale", + home_planet_id: "123", + evil_minion_ids: [1, 2] + }; var json = env.amsSerializer.normalize(SuperVillain, superVillain_hash, "superVillain"); - deepEqual(json, { - firstName: "Tom", - lastName: "Dale", - homePlanet: "123", - evilMinions: [1,2] + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "super-villain", + "attributes": { + "firstName": "Tom", + "lastName": "Dale" + }, + "relationships": { + "evilMinions": { + "data": [ + { "id": "1", "type": "evil-minion" }, + { "id": "2", "type": "evil-minion" } + ] + }, + "homePlanet": { + "data": { "id": "123", "type": "home-planet" } + } + } + } }); }); -test("normalize links", function() { +test("normalize links", function(assert) { var home_planet = { id: "1", name: "Umber", links: { super_villains: "/api/super_villians/1" } }; - var json = env.amsSerializer.normalize(HomePlanet, home_planet, "homePlanet"); - equal(json.links.superVillains, "/api/super_villians/1", "normalize links"); + assert.equal(json.data.relationships.superVillains.links.related, "/api/super_villians/1", "normalize links"); }); -test("extractSingle", function() { - env.registry.register('adapter:superVillain', DS.ActiveModelAdapter); +test("normalizeResponse", function(assert) { + env.registry.register('adapter:superVillain', ActiveModelAdapter); var json_hash = { home_planet: { id: "1", name: "Umber", super_villain_ids: [1] }, @@ -146,24 +168,42 @@ test("extractSingle", function() { var json; run(function() { - json = env.amsSerializer.extractSingle(env.store, HomePlanet, json_hash); - }); - - deepEqual(json, { - "id": "1", - "name": "Umber", - "superVillains": [1] + json = env.amsSerializer.normalizeResponse(env.store, HomePlanet, json_hash, '1', 'findRecord'); }); - run(function() { - env.store.findRecord('super-villain', 1).then(function(minion) { - equal(minion.get('firstName'), "Tom"); - }); + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "home-planet", + "attributes": { + "name": "Umber" + }, + "relationships": { + "superVillains": { + "data": [ + { "id": "1", "type": "super-villain" } + ] + } + } + }, + "included": [{ + "id": "1", + "type": "super-villain", + "attributes": { + "firstName": "Tom", + "lastName": "Dale" + }, + "relationships": { + "homePlanet": { + "data": { "id": "1", "type": "home-planet" } + } + } + }] }); }); -test("extractArray", function() { - env.registry.register('adapter:superVillain', DS.ActiveModelAdapter); +test("normalizeResponse", function(assert) { + env.registry.register('adapter:superVillain', ActiveModelAdapter); var array; var json_hash = { @@ -172,23 +212,41 @@ test("extractArray", function() { }; run(function() { - array = env.amsSerializer.extractArray(env.store, HomePlanet, json_hash); + array = env.amsSerializer.normalizeResponse(env.store, HomePlanet, json_hash, null, 'findAll'); }); - deepEqual(array, [{ - "id": "1", - "name": "Umber", - "superVillains": [1] - }]); - - run(function() { - env.store.findRecord('super-villain', 1).then(function(minion) { - equal(minion.get('firstName'), "Tom"); - }); + assert.deepEqual(array, { + "data": [{ + "id": "1", + "type": "home-planet", + "attributes": { + "name": "Umber" + }, + "relationships": { + "superVillains": { + "data": [ + { "id": "1", "type": "super-villain" } + ] + } + } + }], + "included": [{ + "id": "1", + "type": "super-villain", + "attributes": { + "firstName": "Tom", + "lastName": "Dale" + }, + "relationships": { + "homePlanet": { + "data": { "id": "1", "type": "home-planet" } + } + } + }] }); }); -test("serialize polymorphic", function() { +test("serialize polymorphic", function(assert) { var tom, ray; run(function() { tom = env.store.createRecord('yellow-minion', { name: "Alex", id: "124" }); @@ -197,14 +255,14 @@ test("serialize polymorphic", function() { var json = env.amsSerializer.serialize(ray._createSnapshot()); - deepEqual(json, { + assert.deepEqual(json, { name: "DeathRay", evil_minion_type: "YellowMinion", evil_minion_id: "124" }); }); -test("serialize polymorphic when type key is not camelized", function() { +test("serialize polymorphic when type key is not camelized", function(assert) { YellowMinion.modelName = 'yellow-minion'; var tom, ray; run(function() { @@ -214,119 +272,272 @@ test("serialize polymorphic when type key is not camelized", function() { var json = env.amsSerializer.serialize(ray._createSnapshot()); - deepEqual(json["evil_minion_type"], "YellowMinion"); + assert.deepEqual(json["evil_minion_type"], "YellowMinion"); }); -test("serialize polymorphic when associated object is null", function() { +test("serialize polymorphic when associated object is null", function(assert) { var ray, json; run(function() { ray = env.store.createRecord('doomsday-device', { name: "DeathRay" }); json = env.amsSerializer.serialize(ray._createSnapshot()); }); - deepEqual(json["evil_minion_type"], null); + assert.deepEqual(json["evil_minion_type"], null); }); -test("extractPolymorphic hasMany", function() { - env.registry.register('adapter:yellowMinion', DS.ActiveModelAdapter); +test("extractPolymorphic hasMany", function(assert) { + env.registry.register('adapter:yellowMinion', ActiveModelAdapter); MediocreVillain.toString = function() { return "MediocreVillain"; }; YellowMinion.toString = function() { return "YellowMinion"; }; var json_hash = { - mediocre_villain: { id: 1, name: "Dr Horrible", evil_minions: [{ type: "yellow_minion", id: 12 }] }, - evil_minions: [{ id: 12, name: "Alex", doomsday_device_ids: [1] }] + mediocre_villain: { id: 1, name: "Dr Horrible", evil_minion_ids: [{ type: "yellow_minion", id: 12 }] }, + yellow_minions: [{ id: 12, name: "Alex" }] }; var json; run(function() { - json = env.amsSerializer.extractSingle(env.store, MediocreVillain, json_hash); + json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json_hash, '1', 'findRecord'); }); - deepEqual(json, { - "id": 1, - "name": "Dr Horrible", - "evilMinions": [{ - type: "yellow-minion", - id: 12 + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "mediocre-villain", + "attributes": { + "name": "Dr Horrible" + }, + "relationships": { + "evilMinions": { + "data": [ + { "id": "12", "type": "yellow-minion" } + ] + } + } + }, + "included": [{ + "id": "12", + "type": "yellow-minion", + "attributes": { + "name": "Alex" + }, + "relationships": {} }] }); }); -test("extractPolymorphic", function() { - env.registry.register('adapter:yellowMinion', DS.ActiveModelAdapter); +test("extractPolymorphic belongsTo", function(assert) { + env.registry.register('adapter:yellowMinion', ActiveModelAdapter); EvilMinion.toString = function() { return "EvilMinion"; }; YellowMinion.toString = function() { return "YellowMinion"; }; var json_hash = { - doomsday_device: { id: 1, name: "DeathRay", evil_minion: { type: "yellow_minion", id: 12 } }, - evil_minions: [{ id: 12, name: "Alex", doomsday_device_ids: [1] }] + doomsday_device: { id: 1, name: "DeathRay", evil_minion_id: { type: "yellow_minion", id: 12 } }, + yellow_minions: [{ id: 12, name: "Alex" }] }; var json; run(function() { - json = env.amsSerializer.extractSingle(env.store, DoomsdayDevice, json_hash); + json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'findRecord'); }); - deepEqual(json, { - "id": 1, - "name": "DeathRay", - "evilMinion": { - type: "yellow-minion", - id: 12 - } + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "doomsday-device", + "attributes": { + "name": "DeathRay" + }, + "relationships": { + "evilMinion": { + "data": { "id": "12", "type": "yellow-minion" } + } + } + }, + "included": [{ + "id": "12", + "type": "yellow-minion", + "attributes": { + "name": "Alex" + }, + "relationships": {} + }] + }); +}); + +test("extractPolymorphic belongsTo (weird format)", function(assert) { + env.registry.register('adapter:yellowMinion', ActiveModelAdapter); + EvilMinion.toString = function() { return "EvilMinion"; }; + YellowMinion.toString = function() { return "YellowMinion"; }; + + var json_hash = { + doomsday_device: { + id: 1, + name: "DeathRay", + evil_minion_id: 12, + evil_minion_type: "yellow_minion" + }, + yellow_minions: [{ id: 12, name: "Alex" }] + }; + var json; + + run(function() { + json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'findRecord'); + }); + + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "doomsday-device", + "attributes": { + "name": "DeathRay" + }, + "relationships": { + "evilMinion": { + "data": { "id": "12", "type": "yellow-minion" } + } + } + }, + "included": [{ + "id": "12", + "type": "yellow-minion", + "attributes": { + "name": "Alex" + }, + "relationships": {} + }] + }); +}); + +test("belongsTo (weird format) does not screw if there is a relationshipType attribute", function(assert) { + env.registry.register('adapter:yellowMinion', ActiveModelAdapter); + EvilMinion.toString = function() { return "EvilMinion"; }; + YellowMinion.toString = function() { return "YellowMinion"; }; + DoomsdayDevice.reopen({ + evilMinionType: DS.attr() + }); + + var json_hash = { + doomsday_device: { + id: 1, + name: "DeathRay", + evil_minion_id: { + id: 12, + type: 'yellow_minion' + }, + evil_minion_type: "what a minion" }, + yellow_minions: [{ id: 12, name: "Alex" }] + }; + var json; + + run(function() { + json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'findRecord'); + }); + + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "doomsday-device", + "attributes": { + "name": "DeathRay", + "evilMinionType": "what a minion" + }, + "relationships": { + "evilMinion": { + "data": { "id": "12", "type": "yellow-minion" } + } + } + }, + "included": [{ + "id": "12", + "type": "yellow-minion", + "attributes": { + "name": "Alex" + }, + "relationships": {} + }] }); }); -test("extractPolymorphic when the related data is not specified", function() { +test("extractPolymorphic when the related data is not specified", function(assert) { var json = { doomsday_device: { id: 1, name: "DeathRay" }, - evil_minions: [{ id: 12, name: "Alex", doomsday_device_ids: [1] }] + evil_minions: [{ id: 12, name: "Alex" }] }; run(function() { - json = env.amsSerializer.extractSingle(env.store, DoomsdayDevice, json); + json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json, '1', 'findRecord'); }); - deepEqual(json, { - "id": 1, - "name": "DeathRay", - "evilMinion": undefined + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "doomsday-device", + "attributes": { + "name": "DeathRay" + }, + "relationships": {} + }, + "included": [{ + "id": "12", + "type": "evil-minion", + "attributes": { + "name": "Alex" + }, + "relationships": {} + }] }); }); -test("extractPolymorphic hasMany when the related data is not specified", function() { +test("extractPolymorphic hasMany when the related data is not specified", function(assert) { var json = { mediocre_villain: { id: 1, name: "Dr Horrible" } }; run(function() { - json = env.amsSerializer.extractSingle(env.store, MediocreVillain, json); + json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json, '1', 'findRecord'); }); - deepEqual(json, { - "id": 1, - "name": "Dr Horrible", - "evilMinions": undefined + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "mediocre-villain", + "attributes": { + "name": "Dr Horrible" + }, + "relationships": {} + }, + "included": [] }); }); -test("extractPolymorphic does not break hasMany relationships", function() { +test("extractPolymorphic does not break hasMany relationships", function(assert) { var json = { - mediocre_villain: { id: 1, name: "Dr. Evil", evil_minions: [] } + mediocre_villain: { id: 1, name: "Dr. Evil", evil_minion_ids: [] } }; run(function () { - json = env.amsSerializer.extractSingle(env.store, MediocreVillain, json); + json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json, '1', 'findRecord'); }); - deepEqual(json, { - "id": 1, - "name": "Dr. Evil", - "evilMinions": [] + assert.deepEqual(json, { + "data": { + "id": "1", + "type": "mediocre-villain", + "attributes": { + "name": "Dr. Evil" + }, + "relationships": { + "evilMinions": { + "data": [] + } + } + }, + "included": [] }); }); -test("extractErrors camelizes keys", function() { +test("extractErrors camelizes keys", function(assert) { var error = { errors: [ { @@ -344,7 +555,64 @@ test("extractErrors camelizes keys", function() { payload = env.amsSerializer.extractErrors(env.store, SuperVillain, error); }); - deepEqual(payload, { + assert.deepEqual(payload, { firstName: ["firstName not evil enough"] }); }); + +test('supports the default format for polymorphic belongsTo', function(assert) { + var payload = { + doomsday_devices: [ + { + id: 1, + evil_minion: { + id: 1, + type: 'yellow_minion' + } + } + ], + yellow_minions: [ + { + id: 1, + name: 'Sally' + } + ] + }; + var json, minion; + + run(() => { + json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, payload, '1', 'findRecord'); + env.store.push(json); + minion = env.store.findRecord('doomsday-device', 1); + }); + + assert.equal(minion.get('evilMinion.name'), 'Sally'); +}); + +test('supports the default format for polymorphic hasMany', function(assert) { + var payload = { + mediocre_villain: { + id: 1, + evil_minions: [{ + id: 1, + type: 'evil_minion' + }] + }, + evil_minions: [ + { + id: 1, + name: 'Harry' + } + ] + }; + + var json, villain; + + run(() => { + json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, payload, '1', 'findRecord'); + env.store.push(json); + villain = env.store.findRecord('mediocre-villain', '1'); + }); + + assert.equal(villain.get('evilMinions.firstObject.name'), 'Harry'); +});