UNPKG

thinky-rest

Version:

Create REST resources and controllers with thinky and Express or Restify

424 lines (372 loc) 13.8 kB
'use strict'; var Promise = require('bluebird'), TestFixture = require('./test-fixture'), request = require('request'), expect = require('chai').expect, _ = require('lodash'), rest = require('../lib'), schemas = require('./schemas'); function parseAndRemoveFields(data, fields) { return JSON.parse(data).map(function(r) { return _.omit(r, fields); }); } var test = new TestFixture(); describe('Resource(sort)', function() { before(function() { return test.initializeDatabase() .then(function() { test.models.User = test.db.createModel('users', schemas.User); test.models.UserWithIndex = test.db.createModel('usersWithIndex', schemas.User); test.models.UserWithIndex.ensureIndex('email'); test.userlist = [ { username: 'arthur', email: 'arthur@gmail.com', other: { data: 'a' }, array: [ { data: 'f' } ] }, { username: 'james', email: 'james@gmail.com', other: { data: 'b' }, array: [ { data: 'e' } ] }, { username: 'henry', email: 'henry@gmail.com', other: { data: 'c' }, array: [ { data: 'd' } ] }, { username: 'william', email: 'william@gmail.com', other: { data: 'd' }, array: [ { data: 'c' } ] }, { username: 'edward', email: 'edward@gmail.com', other: { data: 'e' }, array: [ { data: 'b' } ] }, { username: 'arthur', email: 'aaaaarthur@gmail.com', other: { data: 'f' }, array: [ { data: 'a' } ] } ]; return Promise.all([ test.models.User.tableReady(), test.models.UserWithIndex.tableReady() ]); }); }); after(function() { return test.dropDatabase(); }); beforeEach(function() { return test.initializeServer() .then(function() { return Promise.all([ test.models.User.ready(), test.models.UserWithIndex.ready() ]); }) .then(function() { return Promise.all([ test.models.User.save(_.cloneDeep(test.userlist)), test.models.UserWithIndex.save(_.cloneDeep(test.userlist)) ]); }) .then(function() { rest.initialize({ app: test.app, thinky: test.db }); }); }); afterEach(function(done) { test.clearDatabase() .then(function() { test.server.close(done); }); }); ////// it('should sort with default options', function(done) { rest.resource({ model: test.models.User, endpoints: ['/users', '/users/:id'] }); request.get({ url: test.baseUrl + '/users?sort=email' }, function(err, response, body) { expect(response.statusCode).to.equal(200); var records = parseAndRemoveFields(body, ['id']); expect(records).to.eql(_.sortBy(test.userlist, ['email'])); done(); }); }); it('should sort with custom param', function(done) { rest.resource({ model: test.models.User, endpoints: ['/users', '/users/:id'], sort: { param: 'orderby' } }); request.get({ url: test.baseUrl + '/users?orderby=email' }, function(err, response, body) { expect(response.statusCode).to.equal(200); var records = parseAndRemoveFields(body, ['id']); expect(records).to.eql(_.sortBy(test.userlist, ['email'])); done(); }); }); it('should sort with restricted attributes', function(done) { rest.resource({ model: test.models.User, endpoints: ['/users', '/users/:id'], sort: { attributes: ['email'] } }); request.get({ url: test.baseUrl + '/users?sort=email' }, function(err, response, body) { expect(response.statusCode).to.equal(200); var records = parseAndRemoveFields(body, ['id']); expect(records).to.eql(_.sortBy(test.userlist, ['email'])); done(); }); }); it('should sort with default sort criteria', function(done) { rest.resource({ model: test.models.User, endpoints: ['/users', '/users/:id'], sort: { default: "email" } }); request.get({ url: test.baseUrl + '/users' }, function(err, response, body) { expect(response.statusCode).to.equal(200); var records = parseAndRemoveFields(body, ['id']); expect(records).to.eql(_.sortBy(test.userlist, ['email'])); done(); }); }); it('should sort with query overriding default sort criteria', function(done) { rest.resource({ model: test.models.User, endpoints: ['/users', '/users/:id'], sort: { default: "-username" } }); request.get({ url: test.baseUrl + '/users?sort=email' }, function(err, response, body) { expect(response.statusCode).to.equal(200); var records = parseAndRemoveFields(body, ['id']); expect(records).to.eql(_.sortBy(test.userlist, ['email'])); done(); }); }); it('should sort by deep criteria', function(done) { rest.resource({ model: test.models.User, endpoints: ['/users', '/users/:id'] }); request.get({ url: test.baseUrl + '/users?sort=other.data' }, function(err, response, body) { expect(response.statusCode).to.equal(200); var records = parseAndRemoveFields(body, ['id']); expect(records).to.eql(_.sortBy(test.userlist, ['other.data'])); done(); }); }); it('should sort by deep criteria with an array', function(done) { rest.resource({ model: test.models.User, endpoints: ['/users', '/users/:id'] }); request.get({ url: test.baseUrl + '/users?sort=array[0].data' }, function(err, response, body) { expect(response.statusCode).to.equal(200); var records = parseAndRemoveFields(body, ['id']); expect(records).to.eql(_.sortBy(test.userlist, ['array[0].data'])); done(); }); }); it('should sort by deep criteria with an array descending', function(done) { rest.resource({ model: test.models.User, endpoints: ['/users', '/users/:id'] }); request.get({ url: test.baseUrl + '/users?sort=-array[0].data' }, function(err, response, body) { expect(response.statusCode).to.equal(200); var records = parseAndRemoveFields(body, ['id']); expect(records).to.eql(_.sortBy(test.userlist, ['array[0].data']).reverse()); done(); }); }); it('should sort by deep criteria in descending', function(done) { rest.resource({ model: test.models.User, endpoints: ['/users', '/users/:id'] }); request.get({ url: test.baseUrl + '/users?sort=-other.data' }, function(err, response, body) { expect(response.statusCode).to.equal(200); var records = parseAndRemoveFields(body, ['id']); expect(records).to.eql(_.sortBy(test.userlist, ['other.data']).reverse()); done(); }); }); it('should sort by a single field ascending', function(done) { rest.resource({ model: test.models.User, endpoints: ['/users', '/users/:id'] }); request.get({ url: test.baseUrl + '/users?sort=email' }, function(err, response, body) { expect(response.statusCode).to.equal(200); var records = parseAndRemoveFields(body, ['id', 'other', 'array']); expect(records).to.eql([ { username: 'arthur', email: 'aaaaarthur@gmail.com' }, { username: 'arthur', email: 'arthur@gmail.com' }, { username: 'edward', email: 'edward@gmail.com' }, { username: 'henry', email: 'henry@gmail.com' }, { username: 'james', email: 'james@gmail.com' }, { username: 'william', email: 'william@gmail.com' } ]); done(); }); }); it('should sort by a single field descending', function(done) { rest.resource({ model: test.models.User, endpoints: ['/users', '/users/:id'] }); request.get({ url: test.baseUrl + '/users?sort=-email' }, function(err, response, body) { expect(response.statusCode).to.equal(200); var records = parseAndRemoveFields(body, ['id', 'other', 'array']); expect(records).to.eql([ { username: 'william', email: 'william@gmail.com' }, { username: 'james', email: 'james@gmail.com' }, { username: 'henry', email: 'henry@gmail.com' }, { username: 'edward', email: 'edward@gmail.com' }, { username: 'arthur', email: 'arthur@gmail.com' }, { username: 'arthur', email: 'aaaaarthur@gmail.com' } ]); done(); }); }); it('should sort by multiple fields', function(done) { rest.resource({ model: test.models.User, endpoints: ['/users', '/users/:id'] }); request.get({ url: test.baseUrl + '/users?sort=username,email' }, function(err, response, body) { expect(response.statusCode).to.equal(200); var records = parseAndRemoveFields(body, ['id', 'other', 'array']); expect(records).to.eql([ { username: 'arthur', email: 'aaaaarthur@gmail.com' }, { username: 'arthur', email: 'arthur@gmail.com' }, { username: 'edward', email: 'edward@gmail.com' }, { username: 'henry', email: 'henry@gmail.com' }, { username: 'james', email: 'james@gmail.com' }, { username: 'william', email: 'william@gmail.com' } ]); done(); }); }); it('should sort by multiple fields ascending/descending', function(done) { rest.resource({ model: test.models.User, endpoints: ['/users', '/users/:id'] }); request.get({ url: test.baseUrl + '/users?sort=username,-email' }, function(err, response, body) { expect(response.statusCode).to.equal(200); var records = parseAndRemoveFields(body, ['id', 'other', 'array']); expect(records).to.eql([ { username: 'arthur', email: 'arthur@gmail.com' }, { username: 'arthur', email: 'aaaaarthur@gmail.com' }, { username: 'edward', email: 'edward@gmail.com' }, { username: 'henry', email: 'henry@gmail.com' }, { username: 'james', email: 'james@gmail.com' }, { username: 'william', email: 'william@gmail.com' } ]); done(); }); }); it('should sort by multiple fields (multiple query items)', function(done) { rest.resource({ model: test.models.User, endpoints: ['/users', '/users/:id'] }); request.get({ url: test.baseUrl + '/users?sort=username&sort=email' }, function(err, response, body) { expect(response.statusCode).to.equal(200); var records = parseAndRemoveFields(body, ['id', 'other', 'array']); expect(records).to.eql([ { username: 'arthur', email: 'aaaaarthur@gmail.com' }, { username: 'arthur', email: 'arthur@gmail.com' }, { username: 'edward', email: 'edward@gmail.com' }, { username: 'henry', email: 'henry@gmail.com' }, { username: 'james', email: 'james@gmail.com' }, { username: 'william', email: 'william@gmail.com' } ]); done(); }); }); it('should sort using a secondary index if available', function(done) { var resource = rest.resource({ model: test.models.UserWithIndex, endpoints: ['/users', '/users/:id'] }); resource.list.fetch.before(function(req, res, context) { context.debug = true; return context.continue; }); resource.list.send.after(function(req, res, context) { expect(context.query._query._query[1][0][2]).to.eql({ index: 'email' }); done(); }); request.get({ url: test.baseUrl + '/users?sort=email' }, function(err, response, body) { expect(response.statusCode).to.equal(200); var records = parseAndRemoveFields(body, ['id']); expect(records).to.eql(_.sortBy(test.userlist, ['email'])); }); }); it('should sort with secondary index, filter and limit', function(done) { var resource = rest.resource({ model: test.models.UserWithIndex, endpoints: ['/users', '/users/:id'] }); request.get({ url: test.baseUrl + '/users?sort=email&offset=0&count=10&username=-arthur,-henry' }, function(err, response, body) { expect(response.statusCode).to.equal(200); var records = parseAndRemoveFields(body, ['id']); expect(records).to.eql([ { username: 'edward', email: 'edward@gmail.com', other: { data: 'e' }, array: [ { data: 'b' } ] }, { username: 'james', email: 'james@gmail.com', other: { data: 'b' }, array: [ { data: 'e' } ] }, { username: 'william', email: 'william@gmail.com', other: { data: 'd' }, array: [ { data: 'c' } ] }, ]); done(); }); }); // it('should fail sorting with a restricted attribute', function(done) { // rest.resource({ // model: test.models.User, // endpoints: ['/users', '/users/:id'], // sort: { // attributes: ['email'] // } // }); // request.get({ // url: test.baseUrl + '/users?sort=username' // }, function(err, response, body) { // expect(response.statusCode).to.equal(400); // var result = JSON.parse(body); // expect(result.message).to.contain('Sorting not allowed'); // expect(result.errors).to.eql(['username']); // done(); // }); // }); // it('should fail sorting with multiple restricted attributes', function(done) { // rest.resource({ // model: test.models.User, // endpoints: ['/users', '/users/:id'], // sort: { // attributes: ['email'] // } // }); // request.get({ // url: test.baseUrl + '/users?sort=username,-invalid' // }, function(err, response, body) { // expect(response.statusCode).to.equal(400); // var result = JSON.parse(body); // expect(result.message).to.contain('Sorting not allowed'); // expect(result.errors).to.eql(['username','invalid']); // done(); // }); // }); });