UNPKG

jsonapi-serializer

Version:

A Node.js framework agnostic library for serializing your data to JSON API

933 lines (843 loc) 27.2 kB
'use strict'; /* global describe, it */ var expect = require('chai').expect; var JsonApiSerializer = require('../lib/serializer'); describe('Options', function () { describe('id', function () { it('should override the id field', function (done) { var dataSet = [{ _id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', }, { _id: '5490143e69e49d0c8f9fc6bc', firstName: 'Lawrence', lastName: 'Bennett' }]; new JsonApiSerializer('users', dataSet, { apiEndpoint: 'http://localhost:3000/api', id: '_id', attributes: ['firstName', 'lastName'] }).then(function (json) { expect(json.data[0].id).equal('54735750e16638ba1eee59cb'); done(null, json); }); }); }); describe('ref', function () { it('should returns the result of the passed function', function (done) { var dataSet = [{ id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', address: { addressLine1: '406 Madison Court', zipCode: '49426', country: 'USA' }, }, { id: '5490143e69e49d0c8f9fc6bc', firstName: 'Lawrence', lastName: 'Bennett', address: { addressLine1: '361 Shady Lane', zipCode: '23185', country: 'USA' } }]; new JsonApiSerializer('users', dataSet, { apiEndpoint: 'http://localhost:3000/api', id: 'id', attributes: ['firstName', 'lastName', 'address'], address: { ref: function (collection, field) { return collection.id + field.country + field.zipCode; }, attributes: ['addressLine1', 'country', 'zipCode'] } }).then(function (json) { expect(json).to.have.property('data').with.length(2); expect(json.data[0]).to.have.property('relationships'); expect(json.data[0].relationships).to.be.an('object').eql({ address: { data: { id: '54735750e16638ba1eee59cbUSA49426', type: 'addresses' } } }); expect(json).to.have.property('included').to.be.an('array').with .length(2); expect(json.included[0]).to.be.an('object').eql({ id: '54735750e16638ba1eee59cbUSA49426', type: 'addresses', attributes: { 'address-line1': '406 Madison Court', country: 'USA', 'zip-code': '49426' } }); done(null, json); }); }); }); }); describe('JSON API Serializer', function () { describe('Flat data collection', function () { it('should be set into the `data.attributes`', function (done) { var dataSet = [{ id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', }, { id: '5490212e69e49d0c4f9fc6b4', firstName: 'Lawrence', lastName: 'Bennett' }]; new JsonApiSerializer('users', dataSet, { apiEndpoint: 'http://localhost:3000/api', attributes: ['firstName', 'lastName'], }).then(function (json) { expect(json).to.have.property('data').with.length(2); expect(json.data[0]).to.have.property('id') .equal('54735750e16638ba1eee59cb'); expect(json.data[0]).to.have.property('type').equal('users'); expect(json.data[0]).to.have.property('attributes').that.is .an('object') .eql({ 'first-name': 'Sandro', 'last-name': 'Munda', }); done(null, json); }); }); }); describe('Flat data resource', function () { it('should be set into the `data.attributes`', function (done) { var resource = { id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', }; new JsonApiSerializer('users', resource, { apiEndpoint: 'http://localhost:3000/api', attributes: ['firstName', 'lastName'], }).then(function (json) { expect(json).to.have.property('data').and.to.be.instanceof(Object); expect(json.data).to.have.property('id') .equal('54735750e16638ba1eee59cb'); expect(json.data).to.have.property('type').equal('users'); expect(json.data).to.have.property('attributes').that.is .an('object') .eql({ 'first-name': 'Sandro', 'last-name': 'Munda', }); done(null, json); }); }); }); describe('Nested document', function () { it('should be set into the `data.attributes`', function (done) { var dataSet = [{ id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', address: { addressLine1: '406 Madison Court', zipCode: '49426', country: 'USA' }, }, { id: '5490212e69e49d0c4f9fc6b4', firstName: 'Lawrence', lastName: 'Bennett', address: { addressLine1: '361 Shady Lane', zipCode: '23185', country: 'USA' } }]; new JsonApiSerializer('users', dataSet, { apiEndpoint: 'http://localhost:3000/api', attributes: ['firstName', 'lastName', 'address'], address: { attributes: ['addressLine1', 'zipCode', 'country'] } }).then(function (json) { expect(json.data[0].attributes).to.have.property('address') .that.is.an('object') .eql({ addressLine1: '406 Madison Court', zipCode: '49426', country: 'USA' }); done(null, json); }); }); }); describe('Nested documents', function () { it('should be set into the `data.attributes`', function (done) { var dataSet = [{ id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', books: [{ title: 'Tesla, SpaceX, and the Quest for a Fantastic Future', isbn: '978-0062301239' }, { title: 'Steve Jobs', isbn: '978-1451648546' }] }, { id: '5490143e69e49d0c8f9fc6bc', firstName: 'Lawrence', lastName: 'Bennett', books: [{ title: 'Zero to One: Notes on Startups, or How to Build the Future', isbn: '978-0804139298' }, { title: 'Einstein: His Life and Universe', isbn: '978-0743264747' }] }]; new JsonApiSerializer('users', dataSet, { apiEndpoint: 'http://localhost:3000/api', attributes: ['firstName', 'lastName', 'books'], books: { attributes: ['title', 'isbn'] } }).then(function (json) { expect(json.data[0].attributes).to.have.property('books') .that.is.an('array') .eql([{ title: 'Tesla, SpaceX, and the Quest for a Fantastic Future', isbn: '978-0062301239' }, { title: 'Steve Jobs', isbn: '978-1451648546' }]); done(null, json); }); }); }); describe('Compound document', function () { it('should be set into the `data.relationships` and `included`', function (done) { var dataSet = [{ id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', address: { id: '54735722e16620ba1eee36af', addressLine1: '406 Madison Court', zipCode: '49426', country: 'USA' }, }, { id: '5490143e69e49d0c8f9fc6bc', firstName: 'Lawrence', lastName: 'Bennett', address: { id: '54735697e16624ba1eee36bf', addressLine1: '361 Shady Lane', zipCode: '23185', country: 'USA' } }]; new JsonApiSerializer('users', dataSet, { apiEndpoint: 'http://localhost:3000/api', attributes: ['firstName', 'lastName', 'address'], address: { ref: 'id', attributes: ['addressLine1', 'addressLine2', 'zipCode', 'country'] } }).then(function (json) { expect(json.included).to.have.length(2); expect(json.included[0]).to.have.property('id') .equal('54735722e16620ba1eee36af'); expect(json.included[0]).to.have.property('type').equal('addresses'); expect(json.included[0]).to.have.property('attributes').to.be .an('object').eql({ 'address-line1': '406 Madison Court', 'zip-code': '49426', 'country': 'USA' }); expect(json.data[0].relationships).to.have.property('address').that.is .an('object'); expect(json.data[0].relationships.address.data).eql({ id: '54735722e16620ba1eee36af', type: 'addresses' }); done(null, json); }); }); }); describe('Compound documents', function () { it('should be set into the `data.relationships` and `included`', function (done) { var dataSet = [{ id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', books: [{ id: '52735730e16632ba1eee62dd', title: 'Tesla, SpaceX, and the Quest for a Fantastic Future', isbn: '978-0062301239' }, { id: '52735780e16610ba1eee15cd', title: 'Steve Jobs', isbn: '978-1451648546' }] }, { id: '5490143e69e49d0c8f9fc6bc', firstName: 'Lawrence', lastName: 'Bennett', books: [{ id: '52735718e16610ba1eee15cd', title: 'Zero to One: Notes on Startups, or How to Build the Future', isbn: '978-0804139298' }, { id: '52735671e16610ba1eee15ff', title: 'Einstein: His Life and Universe', isbn: '978-0743264747' }] }]; new JsonApiSerializer('users', dataSet, { apiEndpoint: 'http://localhost:3000/api', attributes: ['firstName', 'lastName', 'books'], books: { ref: 'id', attributes: ['title', 'isbn'] } }).then(function (json) { expect(json.included[0]).to.have.property('id') .equal('52735730e16632ba1eee62dd'); expect(json.included[0]).to.have.property('type').equal('books'); expect(json.included[0].attributes).to.be.eql({ title: 'Tesla, SpaceX, and the Quest for a Fantastic Future', isbn: '978-0062301239' }); expect(json.included[1]).to.have.property('id') .equal('52735780e16610ba1eee15cd'); expect(json.included[1]).to.have.property('type').equal('books'); expect(json.included[1].attributes).to.be.eql({ title: 'Steve Jobs', isbn: '978-1451648546' }); expect(json.data[0].relationships).to.have.property('books').that.is .an('object'); expect(json.data[0].relationships.books.data).to.be.an('array') .eql([{ type: 'books', 'id': '52735730e16632ba1eee62dd' }, { type: 'books', 'id': '52735780e16610ba1eee15cd' }]); done(null, json); }); }); }); describe('Multiple compound documents (array -> object)', function () { it('should be set into the `data.relationships` and `included`', function (done) { var dataSet = [{ id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', books: [{ id: '52735730e16632ba1eee62dd', title: 'Tesla, SpaceX, and the Quest for a Fantastic Future', isbn: '978-0062301239', author: { id: '2934f384bb824a7cb7b238b8dc194a22', firstName: 'Ashlee', lastName: 'Vance' } }, { id: '52735780e16610ba1eee15cd', title: 'Steve Jobs', isbn: '978-1451648546', author: { id: '5ed95269a8334d8a970a2bd9fa599288', firstName: 'Walter', lastName: 'Isaacson' } }] }]; new JsonApiSerializer('users', dataSet, { apiEndpoint: 'http://localhost:3000/api', attributes: ['firstName', 'lastName', 'books'], books: { ref: 'id', attributes: ['title', 'isbn', 'author'], author: { ref: 'id', attributes: ['firstName', 'lastName'] } } }).then(function (json) { expect(json.included).to.include({ type: 'books', id: '52735730e16632ba1eee62dd', attributes: { title: 'Tesla, SpaceX, and the Quest for a Fantastic Future', isbn: '978-0062301239' }, relationships: { author: { data: { id: '2934f384bb824a7cb7b238b8dc194a22', type: 'authors' } } } }); expect(json.included).to.include({ type: 'books', id: '52735780e16610ba1eee15cd', attributes: { title: 'Steve Jobs', isbn: '978-1451648546' }, relationships: { author: { data: { id: '5ed95269a8334d8a970a2bd9fa599288', type: 'authors' } } } }); expect(json.included).to.include({ id: '2934f384bb824a7cb7b238b8dc194a22', type: 'authors', attributes: { 'first-name': 'Ashlee', 'last-name': 'Vance' } }); expect(json.included).to.include({ id: '5ed95269a8334d8a970a2bd9fa599288', type: 'authors', attributes: { 'first-name': 'Walter', 'last-name': 'Isaacson' } }); done(null, json); }); }); }); describe('Multiple compound documents (array -> array)', function () { it('should be set into the `data.relationships` and `included`', function (done) { var dataSet = [{ id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', books: [{ id: '52735730e16632ba1eee62dd', title: 'Tesla, SpaceX, and the Quest for a Fantastic Future', isbn: '978-0062301239', authors: [{ id: '2934f384bb824a7cb7b238b8dc194a22', firstName: 'Ashlee', lastName: 'Vance' }, { id: '5ed95269a8334d8a970a2bd9fa599288', firstName: 'Walter', lastName: 'Isaacson' }] }] }]; new JsonApiSerializer('users', dataSet, { apiEndpoint: 'http://localhost:3000/api', attributes: ['firstName', 'lastName', 'books'], books: { ref: 'id', attributes: ['title', 'isbn', 'authors'], authors: { ref: 'id', attributes: ['firstName', 'lastName'] } } }).then(function (json) { expect(json.included).to.include({ type: 'books', id: '52735730e16632ba1eee62dd', attributes: { title: 'Tesla, SpaceX, and the Quest for a Fantastic Future', isbn: '978-0062301239' }, relationships: { authors: { data: [ { id: '2934f384bb824a7cb7b238b8dc194a22', type: 'authors' }, { id: '5ed95269a8334d8a970a2bd9fa599288', type: 'authors' }, ] } } }); expect(json.included).to.include({ id: '2934f384bb824a7cb7b238b8dc194a22', type: 'authors', attributes: { 'first-name': 'Ashlee', 'last-name': 'Vance' } }); expect(json.included).to.include({ id: '5ed95269a8334d8a970a2bd9fa599288', type: 'authors', attributes: { 'first-name': 'Walter', 'last-name': 'Isaacson' } }); done(null, json); }); }); }); describe('Multiple compound documents (object -> array)', function () { it('should be set into the `data.relationships` and `included`', function (done) { var dataSet = [{ id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', address: { id: '5cd95269a8334d8a970a2bd9fa599278', addressLine1: '406 Madison Court', zipCode: '49426', country: 'USA', neighbours: [{ id: '5490143e69e49d0c8f9fc6bc', firstName: 'Lawrence', lastName: 'Bennett' }] } }]; new JsonApiSerializer('users', dataSet, { apiEndpoint: 'http://localhost:3000/api', attributes: ['firstName', 'lastName', 'address'], address: { ref: 'id', attributes: ['addressLine1', 'zipCode', 'country', 'neighbours'], neighbours: { ref: 'id', attributes: ['firstName', 'lastName'], } } }).then(function (json) { expect(json.included).to.include({ id: '5cd95269a8334d8a970a2bd9fa599278', type: 'addresses', attributes: { 'address-line1': '406 Madison Court', 'zip-code': '49426', country: 'USA' }, relationships: { neighbours: { data: [{ type: 'neighbours', id: '5490143e69e49d0c8f9fc6bc' }] } } }); expect(json.included).to.include({ type: 'neighbours', id: '5490143e69e49d0c8f9fc6bc', attributes: { 'first-name': 'Lawrence', 'last-name': 'Bennett' } }); done(null, json); }); }); }); describe('Top level links', function () { it('should be set', function (done) { var dataSet = [{ id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', }]; new JsonApiSerializer('users', dataSet, { topLevellinks: { self: 'http://localhost:3000/api/users' }, attributes: ['firstName', 'lastName'], }).then(function (json) { expect(json).to.have.property('links').eql({ self: 'http://localhost:3000/api/users' }); done(null, json); }); }); }); describe('Top level links (Function)', function () { it('should be set', function (done) { var dataSet = [{ id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', }]; new JsonApiSerializer('users', dataSet, { topLevellinks: { self: function (users) { return 'http://localhost:3000/api/users/' + users[0].firstName; } }, attributes: ['firstName', 'lastName'], }).then(function (json) { expect(json).to.have.property('links').eql({ self: 'http://localhost:3000/api/users/Sandro' }); done(null, json); }); }); }); describe('Links inside data', function () { it('should be set', function (done) { var dataSet = [{ id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', }, { id: '5490212e69e49d0c4f9fc6b4', firstName: 'Lawrence', lastName: 'Bennett' }]; new JsonApiSerializer('users', dataSet, { topLevellinks: { self: 'http://localhost:3000/api/users' }, links: { self: 'http://localhost:3000/api/datalinks' }, attributes: ['firstName', 'lastName'], }).then(function (json) { expect(json.data).to.include({ type: 'users', id: '54735750e16638ba1eee59cb', attributes: { 'first-name': 'Sandro', 'last-name': 'Munda' }, links: { self: 'http://localhost:3000/api/datalinks' } }); expect(json.data).to.include({ type: 'users', id: '5490212e69e49d0c4f9fc6b4', attributes: { 'first-name': 'Lawrence', 'last-name': 'Bennett' }, links: { self: 'http://localhost:3000/api/datalinks' } }); done(null, json); }); }); }); describe('Links (Function) inside data', function () { it('should be set', function (done) { var dataSet = [{ id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', }, { id: '5490212e69e49d0c4f9fc6b4', firstName: 'Lawrence', lastName: 'Bennett' }]; new JsonApiSerializer('users', dataSet, { topLevellinks: { self: 'http://localhost:3000/api/users' }, links: { self: function (user) { return 'http://localhost:3000/api/datalinks/' + user.id; } }, attributes: ['firstName', 'lastName'], }).then(function (json) { expect(json.data).to.include({ type: 'users', id: '54735750e16638ba1eee59cb', attributes: { 'first-name': 'Sandro', 'last-name': 'Munda' }, links: { self: 'http://localhost:3000/api/datalinks/54735750e16638ba1eee59cb' } }); expect(json.data).to.include({ type: 'users', id: '5490212e69e49d0c4f9fc6b4', attributes: { 'first-name': 'Lawrence', 'last-name': 'Bennett' }, links: { self: 'http://localhost:3000/api/datalinks/5490212e69e49d0c4f9fc6b4' } }); done(null, json); }); }); }); describe('Links inside an array compound document', function () { it('should be set', function (done) { var dataSet = [{ id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', addresses: [{ addressLine1: '406 Madison Court', zipCode: '49426', country: 'USA' }], }, { id: '5490143e69e49d0c8f9fc6bc', firstName: 'Lawrence', lastName: 'Bennett', addresses: [{ addressLine1: '361 Shady Lane', zipCode: '23185', country: 'USA' }] }]; new JsonApiSerializer('users', dataSet, { topLevellinks: { self: 'http://localhost:3000/api/users' }, attributes: ['firstName', 'lastName', 'addresses'], addresses: { ref: 'zipCode', attributes: ['addressLine1', 'country'], links: { self: 'http://localhost:4000/users/1/relationships/addresses', related: 'http://localhost:4000/users/1/addresses' } } }).then(function (json) { expect(json.included[0]).to.have.property('links'); expect(json.included[0].links).eql({ self: 'http://localhost:4000/users/1/relationships/addresses', related: 'http://localhost:4000/users/1/addresses' }); done(null, json); }); }); }); describe('Links (Function) inside an array compound document', function () { it('should be set', function (done) { var dataSet = [{ id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', addresses: [{ addressLine1: '406 Madison Court', zipCode: '49426', country: 'USA' }], }, { id: '5490143e69e49d0c8f9fc6bc', firstName: 'Lawrence', lastName: 'Bennett', addresses: [{ addressLine1: '361 Shady Lane', zipCode: '23185', country: 'USA' }] }]; new JsonApiSerializer('users', dataSet, { topLevellinks: { self: 'http://localhost:3000/api/users' }, attributes: ['firstName', 'lastName', 'addresses'], addresses: { ref: 'zipCode', attributes: ['addressLine1', 'country'], links: { self: function (object) { return 'http://localhost:4000/addresses/' + object.zipCode; } } } }).then(function (json) { expect(json.included[0]).to.have.property('links'); expect(json.included[0].links).eql({ self: 'http://localhost:4000/addresses/49426' }); done(null, json); }); }); }); describe('Links inside an object compound document', function () { it('should be set', function (done) { var dataSet = [{ id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', address: { addressLine1: '406 Madison Court', zipCode: '49426', country: 'USA' }, }, { id: '5490143e69e49d0c8f9fc6bc', firstName: 'Lawrence', lastName: 'Bennett', address: { addressLine1: '361 Shady Lane', zipCode: '23185', country: 'USA' } }]; new JsonApiSerializer('users', dataSet, { topLevellinks: { self: 'http://localhost:3000/api/users' }, attributes: ['firstName', 'lastName', 'address'], address: { ref: 'zipCode', attributes: ['addressLine1', 'country'], links: { self: 'http://localhost:4000/users/1/relationships/addresses', related: 'http://localhost:4000/users/1/addresses' } } }).then(function (json) { expect(json.included[0]).to.have.property('links'); expect(json.included[0].links).eql({ self: 'http://localhost:4000/users/1/relationships/addresses', related: 'http://localhost:4000/users/1/addresses' }); done(null, json); }); }); }); describe('Links (Function) inside an object compound document', function () { it('should be set', function (done) { var dataSet = [{ id: '54735750e16638ba1eee59cb', firstName: 'Sandro', lastName: 'Munda', address: { addressLine1: '406 Madison Court', zipCode: '49426', country: 'USA' }, }, { id: '5490143e69e49d0c8f9fc6bc', firstName: 'Lawrence', lastName: 'Bennett', address: { addressLine1: '361 Shady Lane', zipCode: '23185', country: 'USA' } }]; new JsonApiSerializer('users', dataSet, { topLevellinks: { self: 'http://localhost:3000/api/users' }, attributes: ['firstName', 'lastName', 'address'], address: { ref: 'zipCode', attributes: ['addressLine1', 'country'], links: { self: function (object) { return 'http://localhost:4000/addresses/' + object.zipCode; } } } }).then(function (json) { expect(json.included[0]).to.have.property('links'); expect(json.included[0].links).eql({ self: 'http://localhost:4000/addresses/49426' }); done(null, json); }); }); }); });