UNPKG

lbg-mongoose-utils

Version:

a collection of plugins used in my projects for mongoose

221 lines (204 loc) 7.52 kB
//dependencies var assert = require('assert'); var async = require('async'); var mongoose = require('mongoose'); //mongoose.set('debug', true); var ancestorTree = require('../lib/ancestorTree'); var common = require('./utils/common'); var db = common.db; var Schema = mongoose.Schema; var ObjectId = Schema.ObjectId; describe('ancestorTree', function () { var MockSchema = new Schema(); describe('#default()', function() { MockSchema.plugin(ancestorTree); var MockModel = db.model('ancestorMock', MockSchema); var parent = new MockModel({parent:''}); var child = new MockModel({parent: parent._id}); var subChild = new MockModel({parent: child._id}); before(function() { MockModel.remove(function(err) { assert.strictEqual(err, null); }); }); it('should have custom properties set', function (done) { assert.strictEqual(typeof MockSchema.paths.parent, 'object'); assert.strictEqual(typeof MockSchema.paths.ancestors, 'object'); done(); }); it('should save and set hierarchy where aplicable', function (done) { async.waterfall([ function(cb){ parent.save(function(err, doc){ assert.strictEqual(typeof doc.parent, 'undefined', 'parent should be not set'); assert.strictEqual(typeof doc.ancestors, 'object', 'ancestors should be array'); assert.strictEqual(doc.parent, undefined, 'no parent should be set'); assert.strictEqual(doc.ancestors.length, 0, 'ancestors array should be empty'); cb(err); }); }, function(cb){ child.save(function(err,doc){ assert.strictEqual(err, null, 'No errors while saving'); assert.strictEqual(typeof doc.parent, 'object'); assert.strictEqual(doc.parent, parent._id); assert.strictEqual(typeof doc.ancestors, 'object'); assert.strictEqual(doc.ancestors.length, 1, 'the node is a children.'); assert.strictEqual(doc.ancestors[0], parent._id); cb(err); }); }, function(cb){ subChild.save(function(err, doc){ assert.strictEqual(doc.ancestors.length, 2, 'should be length of 2'); assert.strictEqual(doc.ancestors[1], child._id, 'second item should be last added'); cb(err); }); } ], function(err){ assert.strictEqual(err, null, 'should be no errors thrown'); done(); }); }); }); describe('#update()', function(){ MockSchema.plugin(ancestorTree); var MockModel = db.model('ancestorMock', MockSchema); var p = new MockModel({}); var c = new MockModel({parent: p._id}); var sc = new MockModel({parent: c._id}); var ap = new MockModel({}); var ac = new MockModel({parent: ap._id}); var asc = new MockModel({parent: ac._id}); before(function() { MockModel.remove(function(err) { assert.strictEqual(err, null); }); }); it ('should save and update ancestors.', function (done) { async.waterfall([ function(cb) { p.save(function(err,doc) { cb(err); }); }, function(cb) { c.save(function(err,doc) { cb(err); }); }, function(cb) { sc.save(function(err,doc) { cb(err); }); }, function(cb) { ap.save(function(err,doc) { cb(err); }); }, function(cb) { ac.save(function(err,doc) { cb(err); }); }, function(cb) { asc.save(function(err,doc) { cb(err); }); }, function(cb){ ac.parent = c; ac.save(function(err,doc){ MockModel.findOne({_id: asc._id}, function(err, doc){ assert.strictEqual(doc.ancestors[0].toString(), p._id.toString(), 'hierarchy should be updated to the new tree'); assert.strictEqual(doc.ancestors[1].toString(), c._id.toString(), 'hierarchy should be updated in children'); assert.strictEqual(doc.ancestors.length, 3, 'there should be 3 ancestors'); cb(err); }); }); }, function(cb){ c.parent = undefined; c.save(function(err,doc){ MockModel.findOne({_id: sc._id}, function(err, doc){ assert.strictEqual(doc.ancestors.length, 1, 'there should be only one ancestor left'); assert.strictEqual(c._id.toString(), doc.ancestors[0].toString(), 'ancestores are being changed correctly'); cb(err); }); }); } ], function(err){ assert.strictEqual(err, null, 'should be no errors'); done(); }); }); it('should retrieve children.', function(done){ MockModel.findOne({_id: c._id}, function(err, doc){ async.waterfall([ function(cb) { doc.findDirectChildren({fields:{_id:1}}, function(err, children){ assert.strictEqual(children.length, 2, 'there should be 2 direct children'); cb(err); }); }, function(cb) { doc.findChildren({fields:{_id:1}}, function(err, children){ assert.strictEqual(children.length, 3, 'there should be 3 children'); assert.strictEqual(children[0]._id.toString(), sc._id.toString()); assert.strictEqual(children[1]._id.toString(), ac._id.toString()); assert.strictEqual(children[2]._id.toString(), asc._id.toString()); cb(err); }); }, function(cb) { doc.findChildren(function(err, children){ assert.strictEqual(err, null, 'should work with one argument only.'); cb(err); }); } ], function(err){ assert.strictEqual(err, null, 'should be no errors'); done(); }); }); }); it('should retrieve ancestors.', function(done){ MockModel.findOne({_id: asc._id}, function(err, doc){ doc.getAncestors({fields:'_id'}, function(err, ancestors) { assert.strictEqual(ancestors.length, 2, 'asc is 2 levels deep'); assert.strictEqual(ancestors[0]._id.toString(), c._id.toString()); assert.strictEqual(ancestors[1]._id.toString(), ac._id.toString()); done(); }); }); }); it('should not delete items with children.', function(done){ MockModel.findOne({_id: c._id}, function(err, doc){ doc.remove(function(err, res){ assert.strictEqual('Please delete/move all children before proceeding', err.message); MockModel.count({_id: c._id}, function(err, count){ assert.strictEqual(err, null); assert.strictEqual(count, 1); done(); }); }); }); }); it('should Delete items without children.', function(done){ MockModel.findOne({_id: asc._id}, function(err, doc){ doc.remove( function(err, res){ assert.strictEqual(err, null); MockModel.count({_id: asc._id}, function(err, count){ assert.strictEqual(err, null); assert.strictEqual(count, 0); done(); }); }); }); }); }); });