UNPKG

mongoose-paginator-simple

Version:

Pagination plugin for ORM Mongoose (easy to use, fast, no dependencies and less than 45 lines of code)

513 lines (422 loc) 17.8 kB
'use strict'; /** * Libraries. */ var mongoose = require('mongoose'); var chai = require('chai'); var expect = chai.expect; var mongoosePaginator = require('../../index'); /** * Constants. */ var MONGO_URI = 'mongodb://127.0.0.1/mongoose-paginator-test'; var QTY_MOCK_MODELS = 10; /** * Mock models. */ var User = mongoose.model('User', new mongoose.Schema({ username: String, password: String })); var CustomerSchema = new mongoose.Schema({ name: String, date: { type: Date, 'default': Date.now() }, deleted: { type: Boolean, 'default': false }, createdBy: { type: mongoose.Schema.ObjectId, ref: 'User' } }); CustomerSchema.plugin(mongoosePaginator); var Customer = mongoose.model('Customer', CustomerSchema); /** * Unit tests. */ describe('Paginator plugin for ORM Mongoose', function () { before(function (done) { mongoose.connect(MONGO_URI, done); }); before(function(done) { mongoose.connection.db.dropDatabase(done); }); before(function(done) { User.create({ username: 'test', password: '123456' }, function (err, user) { if(err) { return done(); } var customers = []; for(var i = 0; i < QTY_MOCK_MODELS; i++) { customers.push(new Customer({ name: 'Customer ' + i, deleted: i % 2 === 0, createdBy: user._id })); } Customer.create(customers, function(err, docs) { if(err) { return done(); } done(); }); }); }); describe('#paginate()', function() { it('should return an error when searching the total records', function(done) { var CustomerCountErrorSchema = new mongoose.Schema({ name: String }); CustomerCountErrorSchema.pre('count', function(next) { next(new Error('Error while running count.')); }); CustomerCountErrorSchema.plugin(mongoosePaginator); var CustomerCountError = mongoose.model('CustomerCountError', CustomerCountErrorSchema); CustomerCountError.paginate({}, function(err, result) { expect(err).to.be.ok; done(); }); }); it('should return an empty object when not found', function(done) { Customer.paginate({ name: 'not found' }, function(err, result) { expect(result).to.exist; expect(result.data).to.be.empty; expect(result.total).to.equal(0); expect(result.limit).to.equal(0); expect(result.page).to.equal(1); done(); }); }); describe('parameter [criteria]', function() { describe('when not present', function() { it('should not throw or return an error', function(done) { Customer.paginate({}, {}, function(err, result) { expect(err).to.not.be.ok; done(); }); }); it('should return all the documents', function(done) { Customer.paginate({}, {}, function(err, result) { expect(result).to.exist; expect(result.data).to.have.length(QTY_MOCK_MODELS); expect(result.total).to.equal(QTY_MOCK_MODELS); expect(result.limit).to.equal(QTY_MOCK_MODELS); expect(result.page).to.equal(1); done(); }); }); }); describe('when present', function() { it('should return the documents matching', function(done) { Customer.paginate({ name: 'Customer 5' }, {}, function(err, result) { expect(result).to.exist; expect(result.data).to.have.length(1); expect(result.total).to.equal(1); expect(result.limit).to.equal(1); expect(result.page).to.equal(1); done(); }); }); }); }); describe('parameter [options]', function() { describe('when not present', function() { it('should not throw or return an error', function(done) { Customer.paginate({ deleted: true }, undefined, function(err, result) { expect(err).to.not.be.ok; done(); }); }); it('should return the documents considering the default options', function(done) { Customer.paginate({ deleted: false }, function(err, result) { expect(result).to.exist; expect(result.data).to.have.length(5); expect(result.total).to.equal(5); expect(result.limit).to.equal(5); expect(result.page).to.equal(1); done(); }); }); }); describe('when present', function() { describe('[options.criteriaWrapper]', function() { it('should execute without problems if is a function', function(done) { var options = { criteriaWrapper: function(criteria) { criteria.deleted = false; return criteria; } }; Customer.paginate({ name: { $in: ['Customer 0', 'Customer 2', 'Customer 5', 'Customer 7', 'Customer 8' ] }}, options, function(err, result) { expect(result).to.exist; expect(result.data).to.have.length(2); done(); }); }); }); describe('[options.convertCriteria]', function() { it('should throw exception if is not a function', function(done) { // TODO done(); }); it('should convert without problems if is a function', function(done) { var options = { convertCriteria: function(criteria, schema) { if(criteria && typeof criteria === 'string') { var filters = JSON.parse(criteria); if(Array.isArray(filters)) { var filter; criteria = {}; for(var i = 0, len = filters.length; i < len; i++) { filter = filters[i]; // ignore not paths mongoose if(!schema.path(filter.property)) { continue; } if('like' === filter.operator) { criteria[filter.property] = new RegExp(filter.value, 'i'); } else { criteria[filter.property] = filter.value; } } } } return criteria; } }; Customer.paginate('[{"property":"name", "operator":"like", "value":"3"}]', options, function(err, result) { expect(result).to.exist; expect(result.data).to.have.length(1); done(); }); }); }); describe('[options.sort]', function() { it('should return the documents without ordering if property not exists', function(done) { Customer.paginate({ $or: [ { name: 'Customer 0' }, { name: 'Customer 1' }, { name: 'Customer 2' } ] }, { sort: '-xxxx' }, function(err, result) { expect(result).to.exist; expect(result.data[0].name).to.not.contain('2'); done(); }); }); it('should return the documents sorted if property exists', function(done) { Customer.paginate({}, { sort: { name: -1 } }, function(err, result) { expect(result).to.exist; expect(result.data[0].name).to.contain('9'); done(); }); }); }); describe('[options.convertSort]', function() { it('should throw exception if is not a function', function(done) { // TODO done(); }); it('should convert without problems if is a function', function(done) { var options = { sort: '[{"property": "name", "direction": "DESC"}]', convertSort: function(sort, schema) { if(sort && typeof sort === 'string') { var jsonSort = JSON.parse(sort); if(Array.isArray(jsonSort)) { sort = {}; var s; for(var i = 0, len = jsonSort.length; i < len; i++) { s = jsonSort[i]; if(s.direction === 'DESC') { sort[s.property] = -1; // desc or descending } else if(s.direction === 'ASC') { sort[s.property] = 1; // asc, or ascending } else { sort[s.property] = s.direction; } } } } return sort; } }; Customer.paginate({ name: { $not: { $in: ['Customer 9', 'Customer 8'] } } }, options, function(err, result) { expect(result).to.exist; expect(result.data[0].name).to.contain('7'); done(); }); }); }); describe('[options.select]', function() { it('should only return the id property of the documents if not exists', function(done) { Customer.paginate({ name: 'Customer 9' }, { select: 'xxxx' }, function(err, result) { expect(result).to.exist; expect(result.data[0]).to.have.all.keys('_id'); done(); }); }); it('should return the selected properties if exists', function(done) { Customer.paginate({ name: 'Customer 8' }, { select: 'name' }, function(err, result) { expect(result).to.exist; expect(result.data[0]).to.have.all.keys('_id', 'name'); done(); }); }); it('should return the selected properties if is a function', function(done) { var options = { select: function() { return 'deleted'; } }; Customer.paginate({ name: 'Customer 7' }, options, function(err, result) { expect(result).to.exist; expect(result.data[0]).to.have.all.keys('_id', 'deleted'); done(); }); }); }); describe('[options.populate]', function() { it('should return none populated property if not exists', function(done) { Customer.paginate({ name: { $in: [ 'Customer 0', 'Customer 1' ] } }, { populate: 'notexist' }, function(err, result) { expect(result).to.exist; expect(result.data[0].createdBy).to.not.contain.any.keys('username'); done(); }); }); it('should return the populated property if exists', function(done) { Customer.paginate({ name: 'Customer 3' }, { populate: { path: 'createdBy', select: 'username' } }, function(err, result) { expect(result).to.exist; expect(result.data[0].createdBy).to.contain.any.keys('username'); done(); }); }); it('should return the populated property if is a function', function(done) { var options = { populate: function() { return { path: 'createdBy', select: 'username' }; } }; Customer.paginate({ name: 'Customer 9' }, options, function(err, result) { expect(result).to.exist; expect(result.data[0].createdBy).to.contain.any.keys('username'); done(); }); }); }); describe('[options.maxLimit]', function() { it('should return the documents with limited amount', function(done) { Customer.paginate({ name: new RegExp('Cust', 'i') }, { maxLimit: 8 }, function(err, result) { expect(result).to.exist; expect(result.data).to.have.length(8); expect(result.total).to.equal(10); expect(result.limit).to.equal(8); expect(result.page).to.equal(1); done(); }); }); }); describe('[options.limit]', function() { it('should return the documents with limited amount (maxLimit undefined)', function(done) { Customer.paginate({ deleted: false }, { limit: 3 }, function(err, result) { expect(result).to.exist; expect(result.data).to.have.length(3); expect(result.total).to.equal(5); expect(result.limit).to.equal(3); expect(result.page).to.equal(1); done(); }); }); it('should return the documents with limited amount (limit <= maxLimit)', function(done) { Customer.paginate({ deleted: false }, { maxLimit: 4, limit: 2 }, function(err, result) { expect(result).to.exist; expect(result.data).to.have.length(2); expect(result.total).to.equal(5); expect(result.limit).to.equal(2); expect(result.page).to.equal(1); done(); }); }); it('should return the documents with limited amount (limit > maxLimit)', function(done) { Customer.paginate({ deleted: true }, { maxLimit: 4, limit: 5 }, function(err, result) { expect(result).to.exist; expect(result.data).to.have.length(4); expect(result.total).to.equal(5); expect(result.limit).to.equal(4); expect(result.page).to.equal(1); done(); }); }); it('should return the documents with limited amount if is a function', function(done) { Customer.paginate({ deleted: false }, { limit: function(maxLimit) { return 3; } }, function(err, result) { expect(result).to.exist; expect(result.data).to.have.length(3); expect(result.total).to.equal(5); expect(result.limit).to.equal(3); expect(result.page).to.equal(1); done(); }); }); }); describe('[options.page]', function() { it('should return the documents of the first page', function(done) { Customer.paginate({ deleted: false }, { page: 1, limit: 2, sort: 'name' }, function(err, result) { expect(result).to.exist; expect(result.data).to.have.length(2); expect(result.data[0].name).to.contain('1'); expect(result.data[1].name).to.contain('3'); expect(result.total).to.equal(5); expect(result.limit).to.equal(2); expect(result.page).to.equal(1); done(); }); }); it('should return the documents of the next page', function(done) { Customer.paginate({ deleted: false }, { page: 2, limit: 2, sort: 'name' }, function(err, result) { expect(result).to.exist; expect(result.data).to.have.length(2); expect(result.data[0].name).to.contain('5'); expect(result.data[1].name).to.contain('7'); expect(result.total).to.equal(5); expect(result.limit).to.equal(2); expect(result.page).to.equal(2); done(); }); }); it('should return the documents of the last page', function(done) { Customer.paginate({ deleted: false }, { page: 3, limit: 2, sort: 'name' }, function(err, result) { expect(result).to.exist; expect(result.data).to.have.length(1); expect(result.data[0].name).to.contain('9'); expect(result.total).to.equal(5); expect(result.limit).to.equal(2); expect(result.page).to.equal(3); done(); }); }); }); describe('[options.lean]', function() { it('should return the documents in plain object (lean<>false)', function(done) { Customer.paginate({ deleted: true }, { lean: true }, function(err, result) { expect(result).to.exist; expect(result.data[0]).to.not.be.instanceof(mongoose.Document); done(); }); }); it('should return the documents in mongoose object (lean=false)', function(done) { Customer.paginate({ deleted: false }, { lean: false }, function(err, result) { expect(result).to.exist; expect(result.data[0]).to.be.instanceof(mongoose.Document); done(); }); }); }); }); }); }); after(function(done) { mongoose.connection.db.dropDatabase(done); }); after(function (done) { mongoose.disconnect(done); }); });