test('Serializer should map `attrs` attributes directly when keyForAttribute also has a transform', function(assert) { Post = DS.Model.extend({ authorName: DS.attr('string'), }); env = setupStore({ post: Post, }); env.owner.register( 'serializer:post', DS.JSONSerializer.extend({ keyForAttribute: underscore, attrs: { authorName: 'author_name_key', }, }) ); var jsonHash = { id: '1', author_name_key: 'DHH', }; var post = env.store .serializerFor('post') .normalizeResponse(env.store, Post, jsonHash, '1', 'findRecord'); assert.equal(post.data.attributes.authorName, 'DHH'); });
test('serializePolymorphicType async', function(assert) { assert.expect(1); Comment.reopen({ post: DS.belongsTo('post', { async: true }), }); env.owner.register( 'serializer:comment', DS.JSONSerializer.extend({ serializePolymorphicType(record, json, relationship) { assert.ok( true, 'serializePolymorphicType is called when serialize a polymorphic belongsTo' ); }, }) ); let post = env.store.createRecord('post', { title: 'Rails is omakase', id: 1 }); let comment = env.store.createRecord('comment', { body: 'Omakase is delicious', post: post }); env.store .serializerFor('comment') .serializeBelongsTo( comment._createSnapshot(), {}, { key: 'post', options: { async: true, polymorphic: true } } ); });
test('Serializer should respect the attrs hash when extracting records', function(assert) { env.owner.register( 'serializer:post', DS.JSONSerializer.extend({ attrs: { title: 'title_payload_key', comments: { key: 'my_comments' }, }, }) ); var jsonHash = { id: '1', title_payload_key: 'Rails is omakase', my_comments: [1, 2], }; var post = env.store .serializerFor('post') .normalizeResponse(env.store, Post, jsonHash, '1', 'findRecord'); assert.equal(post.data.attributes.title, 'Rails is omakase'); assert.deepEqual(post.data.relationships.comments.data, [ { id: '1', type: 'comment' }, { id: '2', type: 'comment' }, ]); });
test('serializeHasMany respects keyForRelationship', function(assert) { env.owner.register( 'serializer:post', DS.JSONSerializer.extend({ keyForRelationship(key, type) { return key.toUpperCase(); }, }) ); let post = env.store.createRecord('post', { title: 'Rails is omakase', id: '1' }); let comment = env.store.createRecord('comment', { body: 'Omakase is delicious', post: post, id: '1', }); run(function() { post.get('comments').pushObject(comment); }); let json = {}; env.store .serializerFor('post') .serializeHasMany(post._createSnapshot(), json, { key: 'comments', options: {} }); assert.deepEqual(json, { COMMENTS: ['1'], }); });
test('Serializer should respect the attrs hash in links', function(assert) { env.owner.register( 'serializer:post', DS.JSONSerializer.extend({ attrs: { title: 'title_payload_key', comments: { key: 'my_comments' }, }, }) ); var jsonHash = { title_payload_key: 'Rails is omakase', links: { my_comments: 'posts/1/comments', }, }; var post = env.container .lookup('serializer:post') .normalizeSingleResponse(env.store, Post, jsonHash); assert.equal(post.data.attributes.title, 'Rails is omakase'); assert.equal(post.data.relationships.comments.links.related, 'posts/1/comments'); });
QUnit.begin(function(){ Ember.RSVP.configure('onerror', function(reason) { // only print error messages if they're exceptions; // otherwise, let a future turn of the event loop // handle the error. if (reason && reason instanceof Error) { Ember.Logger.log(reason, reason.stack); throw reason; } }); var transforms = { 'boolean': DS.BooleanTransform.create(), 'date': DS.DateTransform.create(), 'number': DS.NumberTransform.create(), 'string': DS.StringTransform.create() }; // Prevent all tests involving serialization to require a container DS.JSONSerializer.reopen({ transformFor: function(attributeType) { return this._super(attributeType, true) || transforms[attributeType]; } }); });
test('Serializer should respect the attrs hash when serializing records', function(assert) { Post.reopen({ parentPost: DS.belongsTo('post', { inverse: null, async: true }), }); env.owner.register( 'serializer:post', DS.JSONSerializer.extend({ attrs: { title: 'title_payload_key', parentPost: { key: 'my_parent' }, }, }) ); let parentPost = run(() => env.store.push({ data: { type: 'post', id: '2', attributes: { title: 'Rails is omakase', }, }, }) ); let post = env.store.createRecord('post', { title: 'Rails is omakase', parentPost: parentPost }); let payload = env.store.serializerFor('post').serialize(post._createSnapshot()); assert.equal(payload.title_payload_key, 'Rails is omakase'); assert.equal(payload.my_parent, '2'); });
test("Find with query calls the correct normalizeResponse", function(assert) { var passedQuery = { page: 1 }; var Person = DS.Model.extend({ name: DS.attr('string') }); var adapter = TestAdapter.extend({ query(store, type, query) { return Ember.RSVP.resolve([]); } }); var callCount = 0; var ApplicationSerializer = DS.JSONSerializer.extend({ normalizeQueryResponse() { callCount++; return this._super(...arguments); } }); var env = setupStore({ adapter: adapter, person: Person }); var store = env.store; env.registry.register('serializer:application', ApplicationSerializer); run(function() { store.query('person', passedQuery); }); assert.equal(callCount, 1, 'normalizeQueryResponse was called'); });
test('Find with query calls the correct normalizeResponse', function(assert) { let passedQuery = { page: 1 }; const Person = DS.Model.extend({ name: DS.attr('string') }); const Adapter = TestAdapter.extend({ query(store, type, query) { return resolve([]); } }); let callCount = 0; const ApplicationSerializer = DS.JSONSerializer.extend({ normalizeQueryResponse() { callCount++; return this._super(...arguments); } }); let env = setupStore({ adapter: Adapter, person: Person }); let { store } = env; env.registry.register('serializer:application', ApplicationSerializer); run(() => store.query('person', passedQuery)); assert.equal(callCount, 1, 'normalizeQueryResponse was called'); });
test('Serializer should respect the attrs hash when serializing records', function(assert) { Post.reopen({ parentPost: DS.belongsTo('post', { inverse: null, async: true }) }); env.registry.register("serializer:post", DS.JSONSerializer.extend({ attrs: { title: "title_payload_key", parentPost: { key: "my_parent" } } })); var parentPost; run(function() { env.store.push({ data: { type: 'post', id: '2', attributes: { title: "Rails is omakase" } } }); parentPost = env.store.peekRecord('post', 2); post = env.store.createRecord('post', { title: "Rails is omakase", parentPost: parentPost }); }); var payload = env.store.serializerFor("post").serialize(post._createSnapshot()); assert.equal(payload.title_payload_key, "Rails is omakase"); assert.equal(payload.my_parent, '2'); });
test('Serializer respects if embedded model has an attribute named "type" - #3726', function(assert) { env.registry.register("serializer:parent", DS.JSONSerializer.extend(DS.EmbeddedRecordsMixin, { attrs: { child: { embedded: 'always' } } })); env.registry.register("model:parent", DS.Model.extend({ child: DS.belongsTo('child') })); env.registry.register("model:child", DS.Model.extend({ type: DS.attr() })); var jsonHash = { id: 1, child: { id: 1, type: 'first_type' } }; var Parent = env.store.modelFor('parent'); var payload = env.store.serializerFor('parent').normalizeResponse(env.store, Parent, jsonHash, '1', 'findRecord'); assert.deepEqual(payload.included, [ { id: '1', type: 'child', attributes: { type: 'first_type' }, relationships: {} } ]); });
test('extractErrors respects custom key mappings', function(assert) { env.registry.register('serializer:post', DS.JSONSerializer.extend({ attrs: { title: 'le_title', comments: { key: 'my_comments' } } })); var payload = { errors: [ { source: { pointer: 'data/attributes/le_title' }, detail: "title errors" }, { source: { pointer: 'data/attributes/my_comments' }, detail: "comments errors" } ] }; var errors = env.store.serializerFor('post').extractErrors(env.store, Post, payload); assert.deepEqual(errors, { title: ["title errors"], comments: ["comments errors"] }); });
test("serializeHasMany respects keyForRelationship", function(assert) { env.registry.register('serializer:post', DS.JSONSerializer.extend({ keyForRelationship(key, type) { return key.toUpperCase(); } })); run(function() { post = env.store.createRecord('post', { title: "Rails is omakase", id: "1" }); comment = env.store.createRecord('comment', { body: "Omakase is delicious", post: post, id: "1" }); post.get('comments').pushObject(comment); }); var json = {}; env.store.serializerFor("post").serializeHasMany(post._createSnapshot(), json, { key: "comments", options: {} }); assert.deepEqual(json, { COMMENTS: ["1"] }); });
test('normalizeResponse respects `included` items (single response)', function(assert) { env.owner.register('serializer:comment', DS.JSONSerializer); env.owner.register( 'serializer:post', DS.JSONSerializer.extend(DS.EmbeddedRecordsMixin, { attrs: { comments: { embedded: 'always' }, }, }) ); var jsonHash = { id: '1', title: 'Rails is omakase', comments: [{ id: '1', body: 'comment 1' }, { id: '2', body: 'comment 2' }], }; var post = env.store .serializerFor('post') .normalizeResponse(env.store, Post, jsonHash, '1', 'findRecord'); assert.deepEqual(post.included, [ { id: '1', type: 'comment', attributes: { body: 'comment 1' }, relationships: {} }, { id: '2', type: 'comment', attributes: { body: 'comment 2' }, relationships: {} }, ]); });
test('Serializer should merge attrs from superclasses', function(assert) { assert.expect(4); Post.reopen({ description: DS.attr('string'), anotherString: DS.attr('string'), }); var BaseSerializer = DS.JSONSerializer.extend({ attrs: { title: 'title_payload_key', anotherString: 'base_another_string_key', }, }); env.owner.register( 'serializer:post', BaseSerializer.extend({ attrs: { description: 'description_payload_key', anotherString: 'overwritten_another_string_key', }, }) ); let post = env.store.createRecord('post', { title: 'Rails is omakase', description: 'Omakase is delicious', anotherString: 'yet another string', }); let payload = env.store.serializerFor('post').serialize(post._createSnapshot()); assert.equal(payload.title_payload_key, 'Rails is omakase'); assert.equal(payload.description_payload_key, 'Omakase is delicious'); assert.equal(payload.overwritten_another_string_key, 'yet another string'); assert.ok(!payload.base_another_string_key, 'overwritten key is not added'); });
test('serializer lookup order', (assert) => { resetStore(); let personSerializer = lookupSerializer('person'); assert.strictEqual(personSerializer, lookupSerializer('-rest')); resetStore(); registerSerializer('application', DS.RESTSerializer.extend()); personSerializer = lookupSerializer('person'); assert.strictEqual(personSerializer, lookupSerializer('application'), 'looks up application before default'); resetStore(); registerAdapter('person', DS.Adapter.extend({ defaultSerializer: '-rest' })); personSerializer = lookupSerializer('person'); assert.strictEqual(personSerializer, lookupSerializer('-rest'), 'uses defaultSerializer on adapterFor("model") if application not defined'); resetStore(); registerAdapter('person', DS.Adapter.extend({ defaultSerializer: '-rest' })); registerSerializer('application', DS.RESTSerializer.extend()); registerSerializer('person', DS.JSONSerializer.extend({ customThingy: true })); personSerializer = lookupSerializer('person'); assert.ok(personSerializer.get('customThingy'), 'uses the person serializer before any fallbacks if it is defined'); });
test('normalizeResponse should extract meta using extractMeta', function(assert) { env.owner.register( 'serializer:post', DS.JSONSerializer.extend({ extractMeta(store, modelClass, payload) { let meta = this._super(...arguments); meta.authors.push('Tomhuda'); return meta; }, }) ); var jsonHash = { id: '1', title_payload_key: 'Rails is omakase', my_comments: [1, 2], meta: { authors: ['Tomster'], }, }; var post = env.store .serializerFor('post') .normalizeResponse(env.store, Post, jsonHash, '1', 'findRecord'); assert.deepEqual(post.meta.authors, ['Tomster', 'Tomhuda']); });
test('normalizeResponse respects `included` items (array response)', function(assert) { env.registry.register("serializer:post", DS.JSONSerializer.extend(DS.EmbeddedRecordsMixin, { attrs: { comments: { embedded: 'always' } } })); var payload = [{ id: "1", title: "Rails is omakase", comments: [ { id: "1", body: "comment 1" } ] }, { id: "2", title: "Post 2", comments: [ { id: "2", body: "comment 2" }, { id: "3", body: "comment 3" } ] }]; var post = env.store.serializerFor("post").normalizeResponse(env.store, Post, payload, '1', 'findAll'); assert.deepEqual(post.included, [ { id: "1", type: "comment", attributes: { body: "comment 1" }, relationships: {} }, { id: "2", type: "comment", attributes: { body: "comment 2" }, relationships: {} }, { id: "3", type: "comment", attributes: { body: "comment 3" }, relationships: {} } ]); });
test("Serializer should merge attrs from superclasses", function(assert) { assert.expect(4); Post.reopen({ description: DS.attr('string'), anotherString: DS.attr('string') }); var BaseSerializer = DS.JSONSerializer.extend({ attrs: { title: "title_payload_key", anotherString: "base_another_string_key" } }); env.registry.register("serializer:post", BaseSerializer.extend({ attrs: { description: "description_payload_key", anotherString: "overwritten_another_string_key" } })); run(function() { post = env.store.createRecord("post", { title: "Rails is omakase", description: "Omakase is delicious", anotherString: "yet another string" }); }); var payload = env.store.serializerFor("post").serialize(post._createSnapshot()); assert.equal(payload.title_payload_key, "Rails is omakase"); assert.equal(payload.description_payload_key, "Omakase is delicious"); assert.equal(payload.overwritten_another_string_key, "yet another string"); assert.ok(!payload.base_another_string_key, "overwritten key is not added"); });
test("Serializer should respect the primaryKey attribute when serializing records", function(assert) { env.registry.register('serializer:post', DS.JSONSerializer.extend({ primaryKey: '_ID_' })); let post = env.store.createRecord('post', { id: "1", title: "Rails is omakase" }); let payload = env.store.serializerFor("post").serialize(post._createSnapshot(), { includeId: true }); assert.equal(payload._ID_, "1"); });
test('extractErrors leaves payload untouched if it has no errors property', function(assert) { env.registry.register('serializer:post', DS.JSONSerializer.extend()); var payload = { untouchedSinceNoErrorsSiblingPresent: ["true"] }; var errors = env.store.serializerFor('post').extractErrors(env.store, Post, payload); assert.deepEqual(errors, { untouchedSinceNoErrorsSiblingPresent: ["true"] }); });
test("Serializer should respect the primaryKey attribute when extracting records", function(assert) { env.registry.register('serializer:post', DS.JSONSerializer.extend({ primaryKey: '_ID_' })); let jsonHash = { "_ID_": 1, title: "Rails is omakase" }; let post = env.store.serializerFor("post").normalizeResponse(env.store, Post, jsonHash, '1', 'findRecord'); assert.equal(post.data.id, "1"); assert.equal(post.data.attributes.title, "Rails is omakase"); });
test('normalizeResponse returns empty `included` payload by default', function(assert) { env.registry.register("serializer:post", DS.JSONSerializer.extend()); var jsonHash = { id: "1", title: "Rails is omakase" }; var post = env.store.serializerFor("post").normalizeResponse(env.store, Post, jsonHash, '1', 'findRecord'); assert.deepEqual(post.included, []); });
test("Serializer should respect keyForRelationship when extracting records", function(assert) { env.registry.register('serializer:post', DS.JSONSerializer.extend({ keyForRelationship(key, type) { return key.toUpperCase(); } })); let jsonHash = { id: 1, title: 'Rails is omakase', COMMENTS: ['1'] }; let post = env.store.serializerFor("post").normalize(Post, jsonHash); assert.deepEqual(post.data.relationships.comments.data, [{ id: "1", type: "comment" }]); });
test('Serializer respects if embedded model has a relationship named "type" - #3726', function(assert) { env.owner.register('serializer:child', DS.JSONSerializer); env.owner.register( 'serializer:parent', DS.JSONSerializer.extend(DS.EmbeddedRecordsMixin, { attrs: { child: { embedded: 'always' }, }, }) ); env.owner.register( 'model:parent', DS.Model.extend({ child: DS.belongsTo('child'), }) ); env.owner.register( 'model:child', DS.Model.extend({ type: DS.belongsTo('le-type'), }) ); env.owner.register('model:le-type', DS.Model.extend()); var jsonHash = { id: 1, child: { id: 1, type: 'my_type_id', }, }; var Parent = env.store.modelFor('parent'); var payload = env.store .serializerFor('parent') .normalizeResponse(env.store, Parent, jsonHash, '1', 'findRecord'); assert.deepEqual(payload.included, [ { id: '1', type: 'child', attributes: {}, relationships: { type: { data: { id: 'my_type_id', type: 'le-type', }, }, }, }, ]); });
test("Serializer should respect keyForAttribute when extracting records", function(assert) { env.registry.register('serializer:post', DS.JSONSerializer.extend({ keyForAttribute(key) { return key.toUpperCase(); } })); let jsonHash = { id: 1, TITLE: 'Rails is omakase' }; let post = env.store.serializerFor("post").normalize(Post, jsonHash); assert.equal(post.data.id, "1"); assert.equal(post.data.attributes.title, "Rails is omakase"); });
test('Serializer respects `serialize: false` on the attrs hash', function(assert) { assert.expect(2); env.registry.register("serializer:post", DS.JSONSerializer.extend({ attrs: { title: { serialize: false } } })); let post = env.store.createRecord('post', { title: "Rails is omakase" }); let payload = env.store.serializerFor("post").serialize(post._createSnapshot()); assert.ok(!payload.hasOwnProperty('title'), "Does not add the key to instance"); assert.ok(!payload.hasOwnProperty('[object Object]'), "Does not add some random key like [object Object]"); });
test("serializeAttribute respects keyForAttribute", function(assert) { env.registry.register('serializer:post', DS.JSONSerializer.extend({ keyForAttribute(key) { return key.toUpperCase(); } })); let post = env.store.createRecord('post', { title: "Rails is omakase" }); let json = {}; env.store.serializerFor("post").serializeAttribute(post._createSnapshot(), json, "title", { type: "string" }); assert.deepEqual(json, { TITLE: "Rails is omakase" }); });
test('Serializer should respect the primaryKey attribute when serializing records', function(assert) { env.owner.register( 'serializer:post', DS.JSONSerializer.extend({ primaryKey: '_ID_', }) ); let post = env.store.createRecord('post', { id: '1', title: 'Rails is omakase' }); let payload = env.store .serializerFor('post') .serialize(post._createSnapshot(), { includeId: true }); assert.equal(payload._ID_, '1'); });
test('normalizeResponse returns empty `included` payload when relationship is undefined', function(assert) { env.owner.register('serializer:post', DS.JSONSerializer.extend()); var jsonHash = { id: '1', title: 'Rails is omakase', comments: null, }; var post = env.store .serializerFor('post') .normalizeResponse(env.store, Post, jsonHash, '1', 'findRecord'); assert.deepEqual(post.included, []); });