UNPKG

bookshelf-jsonapi-params

Version:

Automatically applies relations, filters, and more from the JSON API spec to your Bookshelf.js results

695 lines (591 loc) 24.4 kB
import Bookshelf from 'bookshelf'; import Knex from 'knex'; import Promise from 'bluebird'; import JsonApiParams from '../src/index'; // Use Chai.expect import Chai from 'chai'; const expect = Chai.expect; Chai.use(expect); describe('bookshelf-jsonapi-params with postgresql', () => { // Connect Bookshelf to the database const dbConfig = { client: 'pg', connection: { host: 'localhost', user: 'postgres', database: 'bookshelf_jsonapi_test', charset: 'utf8', port: 5432 } }; const repository = Bookshelf(Knex(dbConfig)); require('./test-helpers/common')(repository, dbConfig.client); // Add postgres specific unit tests describe('test null value/string', () => { before((done) => { repository.plugin(JsonApiParams, { nullString: '_null_' }); done(); }); it('should return results with null values', (done) => { repository.Models.MovieModel .forge() .fetchJsonApi({ filter: { 'extra:time': '_null_' } }) .then((result) => { expect(result.models).to.have.length(1); expect(result.models[0].get('name')).to.equal('Scary Movie'); done(); }); }); it('should return results with null values', (done) => { repository.Models.MovieModel .forge() .fetchJsonApi({ filter: { 'extra:time': null } }) .then((result) => { expect(result.models).to.have.length(1); expect(result.models[0].get('name')).to.equal('Scary Movie'); done(); }); }); it('should not return value null while passing not _null_', (done) => { repository.Models.MovieModel .forge() .fetchJsonApi({ filter: { not: { 'extra:time': '_null_' } }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(2); expect(result.models[0].get('name')).to.equal('Spider'); expect(result.models[1].get('name')).to.equal('Go'); done(); }); }); after((done) => { repository.plugin(JsonApiParams, {}); done(); }); }); describe('passing in jsonb filtering', () => { it('should return results for json equality filter', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { 'style:species': 'dog' }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(3); expect(result.models[0].get('name')).to.equal('Patches'); expect(result.models[1].get('name')).to.equal('Grover'); expect(result.models[2].get('name')).to.equal('Benny "The Terror" Terrier'); done(); }); }); it('should return results for comma separated json equality filter, sorted reverse alphabetically', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { 'style:species': 'bird,reptile' }, sort: ['-style:species'] }) .then((result) => { expect(result.models).to.have.length(2); expect(result.models[0].get('name')).to.equal('Godzilla'); expect(result.models[1].get('name')).to.equal('Big Bird'); done(); }); }); it('should return results for comma separated json equality filter, sorted alphabetically', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { 'style:species': 'bird,reptile' }, sort: ['style:species'] }) .then((result) => { expect(result.models).to.have.length(2); expect(result.models[0].get('name')).to.equal('Big Bird'); expect(result.models[1].get('name')).to.equal('Godzilla'); done(); }); }); it('should return results for comma separated json equality filter, sorted reverse alphabetically, with only the desired fields', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { 'style:species': 'bird,reptile' }, sort: ['-style:species'], fields: { pet: ['style:species', 'name'] } }) .then((result) => { expect(result.models).to.have.length(2); expect(result.models[0].attributes).to.have.all.keys('name', 'species'); expect(result.models[0].attributes).to.not.have.all.keys('id', 'pet_owner_id', 'style'); expect(result.models[0].attributes).to.eql({ name: 'Godzilla', species: 'reptile' }); expect(result.models[1].attributes).to.eql({ name: 'Big Bird', species: 'bird' }); done(); }); }); it('should return results for json equality filter in nested objects', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { 'style:looks.height': 'short' }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(3); expect(result.models[0].get('name')).to.equal('Patches'); expect(result.models[1].get('name')).to.equal('Grover'); expect(result.models[2].get('name')).to.equal('Benny "The Terror" Terrier'); done(); }); }); it('should return fields selected from nested json column', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { 'style:looks.height': 'short' }, fields: { pet: ['style:looks.tail'] }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(3); expect(result.models[0].get('tail')).to.equal(null); expect(result.models[1].get('tail')).to.equal('long'); expect(result.models[2].get('tail')).to.equal('short'); done(); }); }); it('should return fields selected from json column in nested objects', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ fields: { pet: ['style:looks.color', 'id'] }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(5); expect(result.models[0].attributes).to.have.all.keys('color', 'id'); expect(result.models[0].attributes).to.not.have.all.keys('name', 'pet_owner_id', 'style'); expect(result.models[0].get('color')).to.equal('yellow'); expect(result.models[4].get('color')).to.equal('brown/white'); done(); }); }); it('should return single distinct field for json equality filter in nested objects', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ fields: { '': ['style:looks.color'] }, sort: ['style:looks.color'] }) .then((result) => { expect(result.models).to.have.length(4); expect(result.models[0].attributes).to.have.all.keys('color'); expect(result.models[0].attributes).to.not.have.all.keys('id', 'name', 'pet_owner_id', 'style'); expect(result.models[0].get('color')).to.equal('black'); expect(result.models[1].get('color')).to.equal('brown'); expect(result.models[2].get('color')).to.equal('brown/white'); expect(result.models[3].get('color')).to.equal('yellow'); done(); }); }); it('should return results for json contains filter', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { like: { 'style:looks.color': 'brown' } }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(3); expect(result.models[0].get('name')).to.equal('Patches'); expect(result.models[1].get('name')).to.equal('Grover'); expect(result.models[2].get('name')).to.equal('Benny "The Terror" Terrier'); done(); }); }); it('should return results for comma separated json contains filter', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { like: { 'style:looks.color': 'yel,bl' } }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(2); expect(result.models[0].get('name')).to.equal('Big Bird'); expect(result.models[1].get('name')).to.equal('Godzilla'); done(); }); }); it('should return results for comma separated json equality filter', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { 'style:looks.color': 'brown,yellow' }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(3); expect(result.models[0].get('name')).to.equal('Big Bird'); expect(result.models[1].get('name')).to.equal('Patches'); expect(result.models[2].get('name')).to.equal('Grover'); done(); }); }); it('should return results for array of strings json equality filter', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { 'style:looks.color': ['brown', 'yellow'] }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(3); expect(result.models[0].get('name')).to.equal('Big Bird'); expect(result.models[1].get('name')).to.equal('Patches'); expect(result.models[2].get('name')).to.equal('Grover'); done(); }); }); it('should return results for json less than filter on integer', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { lt: { 'style:age:numeric': 8 } }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(1); expect(result.models[0].get('name')).to.equal('Patches'); done(); }); }); it('should return results for json less than or equal filter on integer', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { lte: { 'style:age:numeric': 8 } }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(2); expect(result.models[0].get('name')).to.equal('Patches'); expect(result.models[1].get('name')).to.equal('Benny "The Terror" Terrier'); done(); }); }); it('should return results for json greater than filter on integer', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { gt: { 'style:age:numeric': 42 } }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(1); expect(result.models[0].get('name')).to.equal('Godzilla'); done(); }); }); it('should return results for json greater than or equal filter on integer', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { gte: { 'style:age:numeric': 42 } }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(2); expect(result.models[0].get('name')).to.equal('Big Bird'); expect(result.models[1].get('name')).to.equal('Godzilla'); done(); }); }); it('should return results for json less than filter on timestamp', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { lt: { 'style:birthday:timestamp': (new Date('January 1, 1979 01:00:00')).toISOString() } }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(1); expect(result.models[0].get('name')).to.equal('Big Bird'); done(); }); }); it('should return results for json less than or equal filter on timestamp', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { lte: { 'style:birthday:timestamp': (new Date('January 1, 1979 01:00:00')).toISOString() } }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(2); expect(result.models[0].get('name')).to.equal('Big Bird'); expect(result.models[1].get('name')).to.equal('Godzilla'); done(); }); }); it('should return results for json greater than filter on timestamp', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { gt: { 'style:birthday:timestamp': (new Date('July 1, 2016 17:00:41')).toISOString() } }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(1); expect(result.models[0].get('name')).to.equal('Grover'); done(); }); }); it('should return results for json greater than or equal filter on timestamp', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { gte: { 'style:birthday:timestamp': (new Date('July 1, 2016 17:00:41')).toISOString() } }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(2); expect(result.models[0].get('name')).to.equal('Patches'); expect(result.models[1].get('name')).to.equal('Grover'); done(); }); }); it('should return results for json null filter', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { 'style:looks.tail': null }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(1); expect(result.models[0].get('name')).to.equal('Patches'); done(); }); }); it('should return results for json null and equality filter', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { 'style:looks.tail': 'null,enourmous' }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(2); expect(result.models[0].get('name')).to.equal('Godzilla'); expect(result.models[1].get('name')).to.equal('Patches'); done(); }); }); it('should return results for json not null filter', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { not: { 'style:looks.tail': null } }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(4); expect(result.models[0].get('name')).to.equal('Big Bird'); expect(result.models[1].get('name')).to.equal('Godzilla'); expect(result.models[2].get('name')).to.equal('Grover'); expect(result.models[3].get('name')).to.equal('Benny "The Terror" Terrier'); done(); }); }); it('should return results for json not equal filter', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { not: { 'style:looks.height': 'short' } }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(2); expect(result.models[0].get('name')).to.equal('Big Bird'); expect(result.models[1].get('name')).to.equal('Godzilla'); done(); }); }); it('should return results for json equality filter through a relationship', (done) => { repository.Models.PersonModel .forge() .fetchJsonApi({ filter: { 'pet.style:looks.color': 'black,yellow' }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(2); expect(result.models[0].get('firstName')).to.equal('Barney'); expect(result.models[1].get('firstName')).to.equal('Baby Bop'); done(); }); }); it('should return results for combined json contains and equality filter', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { like: { 'style:looks.color': 'yel' }, 'style:looks.color': 'brown/white' }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(2); expect(result.models[0].get('name')).to.equal('Big Bird'); expect(result.models[1].get('name')).to.equal('Benny "The Terror" Terrier'); done(); }); }); }); describe('passing in "or" filtering with json filters', () => { it('should return results for json filters combined with "or"', (done) => { repository.Models.PetModel .forge() .fetchJsonApi({ filter: { or: [ { like: { 'style:looks.color': 'yel' }, 'style:looks.tail': 'small' }, { lte: { 'style:age:numeric': 8 }, 'style:looks.height': 'short' } ] }, sort: ['id'] }) .then((result) => { expect(result.models).to.have.length(3); expect(result.models[0].get('name')).to.equal('Big Bird'); expect(result.models[1].get('name')).to.equal('Patches'); expect(result.models[2].get('name')).to.equal('Benny "The Terror" Terrier'); done(); }); }); }); after((done) => { // Drop the tables when tests are complete Promise.join( repository.knex.schema.dropTableIfExists('person'), repository.knex.schema.dropTableIfExists('pet'), repository.knex.schema.dropTableIfExists('toy') ) .then(() => done()); }); });