diff options
| author | Jules Laplace <jules@okfoc.us> | 2012-09-24 16:22:07 -0400 |
|---|---|---|
| committer | Jules Laplace <jules@okfoc.us> | 2012-09-24 16:22:07 -0400 |
| commit | 686106d544ecc3b6ffd4db2b665d3bc879a58d8c (patch) | |
| tree | a5b5e50237cef70e12f0745371896e96f5f6d578 /node_modules/mongoose/test/model.ref.test.js | |
ok
Diffstat (limited to 'node_modules/mongoose/test/model.ref.test.js')
| -rw-r--r-- | node_modules/mongoose/test/model.ref.test.js | 1528 |
1 files changed, 1528 insertions, 0 deletions
diff --git a/node_modules/mongoose/test/model.ref.test.js b/node_modules/mongoose/test/model.ref.test.js new file mode 100644 index 0000000..967b6e4 --- /dev/null +++ b/node_modules/mongoose/test/model.ref.test.js @@ -0,0 +1,1528 @@ + +/** + * Test dependencies. + */ + +var start = require('./common') + , should = require('should') + , mongoose = start.mongoose + , random = require('../lib/utils').random + , Schema = mongoose.Schema + , ObjectId = Schema.ObjectId + , DocObjectId = mongoose.Types.ObjectId + +/** + * Setup. + */ + +/** + * User schema. + */ + +var User = new Schema({ + name : String + , email : String + , gender : { type: String, enum: ['male', 'female'], default: 'male' } + , age : { type: Number, default: 21 } + , blogposts : [{ type: ObjectId, ref: 'RefBlogPost' }] +}); + +/** + * Comment subdocument schema. + */ + +var Comment = new Schema({ + _creator : { type: ObjectId, ref: 'RefUser' } + , content : String +}); + +/** + * Blog post schema. + */ + +var BlogPost = new Schema({ + _creator : { type: ObjectId, ref: 'RefUser' } + , title : String + , comments : [Comment] + , fans : [{ type: ObjectId, ref: 'RefUser' }] +}); + +var posts = 'blogposts_' + random() + , users = 'users_' + random(); + +mongoose.model('RefBlogPost', BlogPost); +mongoose.model('RefUser', User); + +/** + * Tests. + */ + +module.exports = { + + 'test populating a single reference': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users) + + User.create({ + name : 'Guillermo' + , email : 'rauchg@gmail.com' + }, function (err, creator) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'woot' + , _creator : creator + }, function (err, post) { + should.strictEqual(err, null); + + BlogPost + .findById(post._id) + .populate('_creator') + .run(function (err, post) { + db.close(); + should.strictEqual(err, null); + + post._creator.should.be.an.instanceof(User); + post._creator.name.should.equal('Guillermo'); + post._creator.email.should.equal('rauchg@gmail.com'); + }); + }); + }); + }, + + 'test an error in single reference population propagates': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts + '1') + , User = db.model('RefUser', users + '1'); + + User.create({ + name: 'Guillermo' + , email: 'rauchg@gmail.com' + }, function (err, creator) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'woot' + , _creator : creator + }, function (err, post) { + should.strictEqual(err, null); + + var origFind = User.findOne; + + // mock an error + User.findOne = function () { + var args = Array.prototype.map.call(arguments, function (arg) { + return 'function' == typeof arg ? function () { + arg(new Error('woot')); + } : arg; + }); + return origFind.apply(this, args); + }; + + BlogPost + .findById(post._id) + .populate('_creator') + .run(function (err, post) { + db.close(); + err.should.be.an.instanceof(Error); + err.message.should.equal('woot'); + }); + }); + }); + }, + + 'test populating with partial fields selection': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users); + + User.create({ + name : 'Guillermo' + , email : 'rauchg@gmail.com' + }, function (err, creator) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'woot' + , _creator : creator + }, function (err, post) { + should.strictEqual(err, null); + + BlogPost + .findById(post._id) + .populate('_creator', ['email']) + .run(function (err, post) { + db.close(); + should.strictEqual(err, null); + + post._creator.should.be.an.instanceof(User); + post._creator.isInit('name').should.be.false; + post._creator.email.should.equal('rauchg@gmail.com'); + }); + }); + }); + }, + + 'populating single oid with partial field selection and filter': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users); + + User.create({ + name : 'Banana' + , email : 'cats@example.com' + }, function (err, creator) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'woot' + , _creator : creator + }, function (err, post) { + should.strictEqual(err, null); + + BlogPost + .findById(post._id) + .populate('_creator', 'email', { name: 'Peanut' }) + .run(function (err, post) { + should.strictEqual(err, null); + should.strictEqual(post._creator, null); + + BlogPost + .findById(post._id) + .populate('_creator', 'email', { name: 'Banana' }) + .run(function (err, post) { + db.close(); + should.strictEqual(err, null); + post._creator.should.be.an.instanceof(User); + post._creator.isInit('name').should.be.false; + post._creator.email.should.equal('cats@example.com'); + }); + }); + }); + }); + }, + + 'test populating and changing a reference': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users); + + User.create({ + name : 'Guillermo' + , email : 'rauchg@gmail.com' + }, function (err, creator) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'woot' + , _creator : creator + }, function (err, post) { + should.strictEqual(err, null); + + BlogPost + .findById(post._id) + .populate('_creator') + .run(function (err, post) { + should.strictEqual(err, null); + + post._creator.should.be.an.instanceof(User); + post._creator.name.should.equal('Guillermo'); + post._creator.email.should.equal('rauchg@gmail.com'); + + User.create({ + name : 'Aaron' + , email : 'aaron@learnboost.com' + }, function (err, newCreator) { + should.strictEqual(err, null); + + post._creator = newCreator._id; + post.save(function (err) { + should.strictEqual(err, null); + + BlogPost + .findById(post._id) + .populate('_creator') + .run(function (err, post) { + db.close(); + should.strictEqual(err, null); + + post._creator.name.should.equal('Aaron'); + post._creator.email.should.equal('aaron@learnboost.com'); + }); + }); + }); + }); + }); + }); + }, + + 'test populating with partial fields selection and changing ref': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users); + + User.create({ + name : 'Guillermo' + , email : 'rauchg@gmail.com' + }, function (err, creator) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'woot' + , _creator : creator + }, function (err, post) { + should.strictEqual(err, null); + + BlogPost + .findById(post._id) + .populate('_creator', {'name': 1}) + .run(function (err, post) { + should.strictEqual(err, null); + + post._creator.should.be.an.instanceof(User); + post._creator.name.should.equal('Guillermo'); + + User.create({ + name : 'Aaron' + , email : 'aaron@learnboost.com' + }, function (err, newCreator) { + should.strictEqual(err, null); + + post._creator = newCreator._id; + post.save(function (err) { + should.strictEqual(err, null); + + BlogPost + .findById(post._id) + .populate('_creator', {email: 0}) + .run(function (err, post) { + db.close(); + should.strictEqual(err, null); + + post._creator.name.should.equal('Aaron'); + should.not.exist(post._creator.email); + }); + }); + }); + }); + }); + }); + }, + + 'test populating an array of references and fetching many': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users); + + User.create({ + name : 'Fan 1' + , email : 'fan1@learnboost.com' + }, function (err, fan1) { + should.strictEqual(err, null); + + User.create({ + name : 'Fan 2' + , email : 'fan2@learnboost.com' + }, function (err, fan2) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'Woot' + , fans : [fan1, fan2] + }, function (err, post1) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'Woot' + , fans : [fan2, fan1] + }, function (err, post2) { + should.strictEqual(err, null); + + BlogPost + .find({ _id: { $in: [post1._id, post2._id ] } }) + .populate('fans') + .run(function (err, blogposts) { + db.close(); + should.strictEqual(err, null); + + blogposts[0].fans[0].name.should.equal('Fan 1'); + blogposts[0].fans[0].email.should.equal('fan1@learnboost.com'); + blogposts[0].fans[1].name.should.equal('Fan 2'); + blogposts[0].fans[1].email.should.equal('fan2@learnboost.com'); + + blogposts[1].fans[0].name.should.equal('Fan 2'); + blogposts[1].fans[0].email.should.equal('fan2@learnboost.com'); + blogposts[1].fans[1].name.should.equal('Fan 1'); + blogposts[1].fans[1].email.should.equal('fan1@learnboost.com'); + + }); + }); + }); + }); + }); + }, + + 'test an error in array reference population propagates': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts + '2') + , User = db.model('RefUser', users + '2'); + + User.create({ + name : 'Fan 1' + , email : 'fan1@learnboost.com' + }, function (err, fan1) { + should.strictEqual(err, null); + + User.create({ + name : 'Fan 2' + , email : 'fan2@learnboost.com' + }, function (err, fan2) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'Woot' + , fans : [fan1, fan2] + }, function (err, post1) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'Woot' + , fans : [fan2, fan1] + }, function (err, post2) { + should.strictEqual(err, null); + + // mock an error + var origFind = User.find; + User.find = function () { + var args = Array.prototype.map.call(arguments, function (arg) { + return 'function' == typeof arg ? function () { + arg(new Error('woot 2')); + } : arg; + }); + return origFind.apply(this, args); + }; + + BlogPost + .find({ $or: [{ _id: post1._id }, { _id: post2._id }] }) + .populate('fans') + .run(function (err, blogposts) { + db.close(); + err.should.be.an.instanceof(Error); + err.message.should.equal('woot 2'); + }); + }); + }); + }); + }); + }, + + 'test populating an array of references with fields selection': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users); + + User.create({ + name : 'Fan 1' + , email : 'fan1@learnboost.com' + }, function (err, fan1) { + should.strictEqual(err, null); + + User.create({ + name : 'Fan 2' + , email : 'fan2@learnboost.com' + }, function (err, fan2) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'Woot' + , fans : [fan1, fan2] + }, function (err, post1) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'Woot' + , fans : [fan2, fan1] + }, function (err, post2) { + should.strictEqual(err, null); + + BlogPost + .find({ _id: { $in: [post1._id, post2._id ] } }) + .populate('fans', 'name') + .run(function (err, blogposts) { + db.close(); + should.strictEqual(err, null); + + blogposts[0].fans[0].name.should.equal('Fan 1'); + blogposts[0].fans[0].isInit('email').should.be.false; + blogposts[0].fans[1].name.should.equal('Fan 2'); + blogposts[0].fans[1].isInit('email').should.be.false; + should.strictEqual(blogposts[0].fans[1].email, undefined); + + blogposts[1].fans[0].name.should.equal('Fan 2'); + blogposts[1].fans[0].isInit('email').should.be.false; + blogposts[1].fans[1].name.should.equal('Fan 1'); + blogposts[1].fans[1].isInit('email').should.be.false; + }); + }); + }); + }); + }); + }, + + 'test populating an array of references and filtering': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users); + + User.create({ + name : 'Fan 1' + , email : 'fan1@learnboost.com' + }, function (err, fan1) { + should.strictEqual(err, null); + + User.create({ + name : 'Fan 2' + , email : 'fan2@learnboost.com' + , gender : 'female' + }, function (err, fan2) { + should.strictEqual(err, null); + + User.create({ + name : 'Fan 3' + , email : 'fan3@learnboost.com' + , gender : 'female' + }, function (err, fan3) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'Woot' + , fans : [fan1, fan2, fan3] + }, function (err, post1) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'Woot' + , fans : [fan3, fan2, fan1] + }, function (err, post2) { + should.strictEqual(err, null); + + BlogPost + .find({ _id: { $in: [post1._id, post2._id ] } }) + .populate('fans', '', { gender: 'female', _id: { $in: [fan2] }}) + .run(function (err, blogposts) { + should.strictEqual(err, null); + + blogposts[0].fans.length.should.equal(1); + blogposts[0].fans[0].gender.should.equal('female'); + blogposts[0].fans[0].name.should.equal('Fan 2'); + blogposts[0].fans[0].email.should.equal('fan2@learnboost.com'); + + blogposts[1].fans.length.should.equal(1); + blogposts[1].fans[0].gender.should.equal('female'); + blogposts[1].fans[0].name.should.equal('Fan 2'); + blogposts[1].fans[0].email.should.equal('fan2@learnboost.com'); + + BlogPost + .find({ _id: { $in: [post1._id, post2._id ] } }) + .populate('fans', false, { gender: 'female' }) + .run(function (err, blogposts) { + db.close(); + should.strictEqual(err, null); + + should.strictEqual(blogposts[0].fans.length, 2); + blogposts[0].fans[0].gender.should.equal('female'); + blogposts[0].fans[0].name.should.equal('Fan 2'); + blogposts[0].fans[0].email.should.equal('fan2@learnboost.com'); + blogposts[0].fans[1].gender.should.equal('female'); + blogposts[0].fans[1].name.should.equal('Fan 3'); + blogposts[0].fans[1].email.should.equal('fan3@learnboost.com'); + + should.strictEqual(blogposts[1].fans.length, 2); + blogposts[1].fans[0].gender.should.equal('female'); + blogposts[1].fans[0].name.should.equal('Fan 3'); + blogposts[1].fans[0].email.should.equal('fan3@learnboost.com'); + blogposts[1].fans[1].gender.should.equal('female'); + blogposts[1].fans[1].name.should.equal('Fan 2'); + blogposts[1].fans[1].email.should.equal('fan2@learnboost.com'); + }); + + }); + }); + }); + }); + }); + }); + }, + + 'test populating an array of references and multi-filtering': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users); + + User.create({ + name : 'Fan 1' + , email : 'fan1@learnboost.com' + }, function (err, fan1) { + should.strictEqual(err, null); + + User.create({ + name : 'Fan 2' + , email : 'fan2@learnboost.com' + , gender : 'female' + }, function (err, fan2) { + should.strictEqual(err, null); + + User.create({ + name : 'Fan 3' + , email : 'fan3@learnboost.com' + , gender : 'female' + , age : 25 + }, function (err, fan3) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'Woot' + , fans : [fan1, fan2, fan3] + }, function (err, post1) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'Woot' + , fans : [fan3, fan2, fan1] + }, function (err, post2) { + should.strictEqual(err, null); + + BlogPost + .find({ _id: { $in: [post1._id, post2._id ] } }) + .populate('fans', undefined, { _id: fan3 }) + .run(function (err, blogposts) { + should.strictEqual(err, null); + + blogposts[0].fans.length.should.equal(1); + blogposts[0].fans[0].gender.should.equal('female'); + blogposts[0].fans[0].name.should.equal('Fan 3'); + blogposts[0].fans[0].email.should.equal('fan3@learnboost.com'); + should.equal(blogposts[0].fans[0].age, 25); + + blogposts[1].fans.length.should.equal(1); + blogposts[1].fans[0].gender.should.equal('female'); + blogposts[1].fans[0].name.should.equal('Fan 3'); + blogposts[1].fans[0].email.should.equal('fan3@learnboost.com'); + should.equal(blogposts[1].fans[0].age, 25); + + BlogPost + .find({ _id: { $in: [post1._id, post2._id ] } }) + .populate('fans', 0, { gender: 'female' }) + .run(function (err, blogposts) { + db.close(); + should.strictEqual(err, null); + + blogposts[0].fans.length.should.equal(2); + blogposts[0].fans[0].gender.should.equal('female'); + blogposts[0].fans[0].name.should.equal('Fan 2'); + blogposts[0].fans[0].email.should.equal('fan2@learnboost.com'); + blogposts[0].fans[1].gender.should.equal('female'); + blogposts[0].fans[1].name.should.equal('Fan 3'); + blogposts[0].fans[1].email.should.equal('fan3@learnboost.com'); + should.equal(blogposts[0].fans[1].age, 25); + + blogposts[1].fans.length.should.equal(2); + blogposts[1].fans[0].gender.should.equal('female'); + blogposts[1].fans[0].name.should.equal('Fan 3'); + blogposts[1].fans[0].email.should.equal('fan3@learnboost.com'); + should.equal(blogposts[1].fans[0].age, 25); + blogposts[1].fans[1].gender.should.equal('female'); + blogposts[1].fans[1].name.should.equal('Fan 2'); + blogposts[1].fans[1].email.should.equal('fan2@learnboost.com'); + }); + }); + }); + }); + }); + }); + }); + }, + + 'test populating an array of references and multi-filtering with field selection': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users); + + User.create({ + name : 'Fan 1' + , email : 'fan1@learnboost.com' + }, function (err, fan1) { + should.strictEqual(err, null); + + User.create({ + name : 'Fan 2' + , email : 'fan2@learnboost.com' + , gender : 'female' + }, function (err, fan2) { + should.strictEqual(err, null); + + User.create({ + name : 'Fan 3' + , email : 'fan3@learnboost.com' + , gender : 'female' + , age : 25 + }, function (err, fan3) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'Woot' + , fans : [fan1, fan2, fan3] + }, function (err, post1) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'Woot' + , fans : [fan3, fan2, fan1] + }, function (err, post2) { + should.strictEqual(err, null); + + BlogPost + .find({ _id: { $in: [post1._id, post2._id ] } }) + .populate('fans', 'name email', { gender: 'female', age: 25 }) + .run(function (err, blogposts) { + db.close(); + should.strictEqual(err, null); + + should.strictEqual(blogposts[0].fans.length, 1); + blogposts[0].fans[0].name.should.equal('Fan 3'); + blogposts[0].fans[0].email.should.equal('fan3@learnboost.com'); + blogposts[0].fans[0].isInit('email').should.be.true; + blogposts[0].fans[0].isInit('gender').should.be.false; + blogposts[0].fans[0].isInit('age').should.be.false; + + should.strictEqual(blogposts[1].fans.length, 1); + blogposts[1].fans[0].name.should.equal('Fan 3'); + blogposts[1].fans[0].email.should.equal('fan3@learnboost.com'); + blogposts[1].fans[0].isInit('email').should.be.true; + blogposts[1].fans[0].isInit('gender').should.be.false; + blogposts[1].fans[0].isInit('age').should.be.false; + }); + }); + }); + }); + }); + }); + }, + + 'test populating an array of refs, changing one, and removing one': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users); + + User.create({ + name : 'Fan 1' + , email : 'fan1@learnboost.com' + }, { + name : 'Fan 2' + , email : 'fan2@learnboost.com' + }, { + name : 'Fan 3' + , email : 'fan3@learnboost.com' + }, { + name : 'Fan 4' + , email : 'fan4@learnboost.com' + }, function (err, fan1, fan2, fan3, fan4) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'Woot' + , fans : [fan1, fan2] + }, { + title : 'Woot' + , fans : [fan2, fan1] + }, function (err, post1, post2) { + should.strictEqual(err, null); + + BlogPost + .find({ _id: { $in: [post1._id, post2._id ] } }) + .populate('fans', ['name']) + .run(function (err, blogposts) { + should.strictEqual(err, null); + + blogposts[0].fans[0].name.should.equal('Fan 1'); + blogposts[0].fans[0].isInit('email').should.be.false; + blogposts[0].fans[1].name.should.equal('Fan 2'); + blogposts[0].fans[1].isInit('email').should.be.false; + + blogposts[1].fans[0].name.should.equal('Fan 2'); + blogposts[1].fans[0].isInit('email').should.be.false; + blogposts[1].fans[1].name.should.equal('Fan 1'); + blogposts[1].fans[1].isInit('email').should.be.false; + + blogposts[1].fans = [fan3, fan4]; + + blogposts[1].save(function (err) { + should.strictEqual(err, null); + + BlogPost + .findById(blogposts[1]._id, [], { populate: ['fans'] }) + .run(function (err, post) { + should.strictEqual(err, null); + + post.fans[0].name.should.equal('Fan 3'); + post.fans[1].name.should.equal('Fan 4'); + + post.fans.splice(0, 1); + post.save(function (err) { + should.strictEqual(err, null); + + BlogPost + .findById(post._id) + .populate('fans') + .run(function (err, post) { + db.close(); + should.strictEqual(err, null); + post.fans.length.should.equal(1); + post.fans[0].name.should.equal('Fan 4'); + }); + }); + }); + }); + }); + }); + }); + }, + + 'test populating subdocuments': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users); + + User.create({ name: 'User 1' }, function (err, user1) { + should.strictEqual(err, null); + + User.create({ name: 'User 2' }, function (err, user2) { + should.strictEqual(err, null); + + BlogPost.create({ + title: 'Woot' + , _creator: user1._id + , comments: [ + { _creator: user1._id, content: 'Woot woot' } + , { _creator: user2._id, content: 'Wha wha' } + ] + }, function (err, post) { + should.strictEqual(err, null); + + BlogPost + .findById(post._id) + .populate('_creator') + .populate('comments._creator') + .run(function (err, post) { + db.close(); + should.strictEqual(err, null); + + post._creator.name.should.equal('User 1'); + post.comments[0]._creator.name.should.equal('User 1'); + post.comments[1]._creator.name.should.equal('User 2'); + }); + }); + }); + }); + }, + + 'test populating subdocuments partially': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users); + + User.create({ + name : 'User 1' + , email : 'user1@learnboost.com' + }, function (err, user1) { + should.strictEqual(err, null); + + User.create({ + name : 'User 2' + , email : 'user2@learnboost.com' + }, function (err, user2) { + should.strictEqual(err, null); + + var post = BlogPost.create({ + title: 'Woot' + , comments: [ + { _creator: user1, content: 'Woot woot' } + , { _creator: user2, content: 'Wha wha' } + ] + }, function (err, post) { + should.strictEqual(err, null); + + BlogPost + .findById(post._id) + .populate('comments._creator', ['email']) + .run(function (err, post) { + db.close(); + should.strictEqual(err, null); + + post.comments[0]._creator.email.should.equal('user1@learnboost.com'); + post.comments[0]._creator.isInit('name').should.be.false; + post.comments[1]._creator.email.should.equal('user2@learnboost.com'); + post.comments[1]._creator.isInit('name').should.be.false; + }); + }); + }); + }); + }, + + 'test populating subdocuments partially with conditions': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users); + + User.create({ + name : 'User 1' + , email : 'user1@learnboost.com' + }, function (err, user1) { + should.strictEqual(err, null); + + User.create({ + name : 'User 2' + , email : 'user2@learnboost.com' + }, function (err, user2) { + should.strictEqual(err, null); + + var post = BlogPost.create({ + title: 'Woot' + , comments: [ + { _creator: user1, content: 'Woot woot' } + , { _creator: user2, content: 'Wha wha' } + ] + }, function (err, post) { + should.strictEqual(err, null); + + BlogPost + .findById(post._id) + .populate('comments._creator', {'email': 1}, { name: /User/ }) + .run(function (err, post) { + db.close(); + should.strictEqual(err, null); + + post.comments[0]._creator.email.should.equal('user1@learnboost.com'); + post.comments[0]._creator.isInit('name').should.be.false; + post.comments[1]._creator.email.should.equal('user2@learnboost.com'); + post.comments[1]._creator.isInit('name').should.be.false; + }); + }); + }); + }); + }, + + 'populating subdocs with invalid/missing subproperties': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users); + + User.create({ + name : 'T-100' + , email : 'terminator100@learnboost.com' + }, function (err, user1) { + should.strictEqual(err, null); + + User.create({ + name : 'T-1000' + , email : 'terminator1000@learnboost.com' + }, function (err, user2) { + should.strictEqual(err, null); + + var post = BlogPost.create({ + title: 'Woot' + , comments: [ + { _creator: null, content: 'Woot woot' } + , { _creator: user2, content: 'Wha wha' } + ] + }, function (err, post) { + should.strictEqual(err, null); + + // invalid subprop + BlogPost + .findById(post._id) + .populate('comments._idontexist', 'email') + .run(function (err, post) { + should.strictEqual(err, null); + should.exist(post); + post.comments.length.should.equal(2); + should.strictEqual(post.comments[0]._creator, null); + post.comments[1]._creator.toString().should.equal(user2.id); + + // subprop is null in a doc + BlogPost + .findById(post._id) + .populate('comments._creator', 'email') + .run(function (err, post) { + db.close(); + should.strictEqual(err, null); + + should.exist(post); + post.comments.length.should.equal(2); + should.strictEqual(post.comments[0]._creator, null); + should.strictEqual(post.comments[0].content, 'Woot woot'); + post.comments[1]._creator.email.should.equal('terminator1000@learnboost.com'); + post.comments[1]._creator.isInit('name').should.be.false; + post.comments[1].content.should.equal('Wha wha'); + }); + }); + }); + }); + }); + }, + + // gh-481 + 'test populating subdocuments partially with empty array': function (beforeExit) { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , worked = false; + + var post = BlogPost.create({ + title: 'Woot' + , comments: [] // EMPTY ARRAY + }, function (err, post) { + should.strictEqual(err, null); + + BlogPost + .findById(post._id) + .populate('comments._creator', ['email']) + .run(function (err, returned) { + db.close(); + worked = true; + should.strictEqual(err, null); + returned.id.should.equal(post.id); + }); + }); + + beforeExit(function () { + worked.should.be.true; + }); + }, + + 'populating subdocuments with array including nulls': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users) + + var user = new User({ name: 'hans zimmer' }); + user.save(function (err) { + should.strictEqual(err, null); + + var post = BlogPost.create({ + title: 'Woot' + , fans: [] + }, function (err, post) { + should.strictEqual(err, null); + + // shove some uncasted vals + BlogPost.collection.update({ _id: post._id }, { $set: { fans: [null, undefined, user.id, null] } }, function (err) { + should.strictEqual(err, undefined); + + BlogPost + .findById(post._id) + .populate('fans', ['name']) + .run(function (err, returned) { + db.close(); + should.strictEqual(err, null); + returned.id.should.equal(post.id); + returned.fans.length.should.equal(1); + }); + }) + }); + }); + }, + + 'populating more than one array at a time': function () { + var db = start() + , User = db.model('RefUser', users) + , M = db.model('PopMultiSubDocs', new Schema({ + users: [{ type: ObjectId, ref: 'RefUser' }] + , fans: [{ type: ObjectId, ref: 'RefUser' }] + , comments: [Comment] + })) + + User.create({ + email : 'fan1@learnboost.com' + }, { + name : 'Fan 2' + , email : 'fan2@learnboost.com' + , gender : 'female' + }, { + name: 'Fan 3' + }, function (err, fan1, fan2, fan3) { + should.strictEqual(err, null); + + M.create({ + users: [fan3] + , fans: [fan1] + , comments: [ + { _creator: fan1, content: 'bejeah!' } + , { _creator: fan2, content: 'chickfila' } + ] + }, { + users: [fan1] + , fans: [fan2] + , comments: [ + { _creator: fan3, content: 'hello' } + , { _creator: fan1, content: 'world' } + ] + }, function (err, post1, post2) { + should.strictEqual(err, null); + + M.where('_id').in([post1, post2]) + .populate('fans', 'name', { gender: 'female' }) + .populate('users', 'name', { gender: 'male' }) + .populate('comments._creator', ['email'], { name: null }) + .run(function (err, posts) { + db.close(); + should.strictEqual(err, null); + + should.exist(posts); + posts.length.should.equal(2); + var p1 = posts[0]; + var p2 = posts[1]; + should.strictEqual(p1.fans.length, 0); + should.strictEqual(p2.fans.length, 1); + p2.fans[0].name.should.equal('Fan 2'); + p2.fans[0].isInit('email').should.be.false; + p2.fans[0].isInit('gender').should.be.false; + p1.comments.length.should.equal(2); + p2.comments.length.should.equal(2); + should.exist(p1.comments[0]._creator.email); + should.not.exist(p2.comments[0]._creator); + p1.comments[0]._creator.email.should.equal('fan1@learnboost.com'); + p2.comments[1]._creator.email.should.equal('fan1@learnboost.com'); + p1.comments[0]._creator.isInit('name').should.be.false; + p2.comments[1]._creator.isInit('name').should.be.false; + p1.comments[0].content.should.equal('bejeah!'); + p2.comments[1].content.should.equal('world'); + should.not.exist(p1.comments[1]._creator); + should.not.exist(p2.comments[0]._creator); + p1.comments[1].content.should.equal('chickfila'); + p2.comments[0].content.should.equal('hello'); + }); + }); + }); + }, + + 'populating multiple children of a sub-array at a time': function () { + var db = start() + , User = db.model('RefUser', users) + , BlogPost = db.model('RefBlogPost', posts) + , Inner = new Schema({ + user: { type: ObjectId, ref: 'RefUser' } + , post: { type: ObjectId, ref: 'RefBlogPost' } + }) + , I = db.model('PopMultiChildrenOfSubDocInner', Inner) + var M = db.model('PopMultiChildrenOfSubDoc', new Schema({ + kids: [Inner] + })) + + User.create({ + name : 'Fan 1' + , email : 'fan1@learnboost.com' + , gender : 'male' + }, { + name : 'Fan 2' + , email : 'fan2@learnboost.com' + , gender : 'female' + }, function (err, fan1, fan2) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'woot' + }, { + title : 'yay' + }, function (err, post1, post2) { + should.strictEqual(err, null); + M.create({ + kids: [ + { user: fan1, post: post1, y: 5 } + , { user: fan2, post: post2, y: 8 } + ] + , x: 4 + }, function (err, m1) { + should.strictEqual(err, null); + + M.findById(m1) + .populate('kids.user', ["name"]) + .populate('kids.post', ["title"], { title: "woot" }) + .run(function (err, o) { + db.close(); + should.strictEqual(err, null); + should.strictEqual(o.kids.length, 2); + var k1 = o.kids[0]; + var k2 = o.kids[1]; + should.strictEqual(true, !k2.post); + should.strictEqual(k1.user.name, "Fan 1"); + should.strictEqual(k1.user.email, undefined); + should.strictEqual(k1.post.title, "woot"); + should.strictEqual(k2.user.name, "Fan 2"); + }); + }); + }); + }); + }, + + 'passing sort options to the populate method': function () { + var db = start() + , P = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users); + + User.create({ name: 'aaron', age: 10 }, { name: 'fan2', age: 8 }, { name: 'someone else', age: 3 }, + function (err, fan1, fan2, fan3) { + should.strictEqual(err, null); + + P.create({ fans: [fan2, fan3, fan1] }, function (err, post) { + should.strictEqual(err, null); + + P.findById(post) + .populate('fans', null, null, { sort: 'name' }) + .run(function (err, post) { + should.strictEqual(err, null); + + post.fans.length.should.equal(3); + post.fans[0].name.should.equal('aaron'); + post.fans[1].name.should.equal('fan2'); + post.fans[2].name.should.equal('someone else'); + + P.findById(post) + .populate('fans', 'name', null, { sort: [['name', -1]] }) + .run(function (err, post) { + should.strictEqual(err, null); + + post.fans.length.should.equal(3); + post.fans[2].name.should.equal('aaron'); + should.strictEqual(undefined, post.fans[2].age) + post.fans[1].name.should.equal('fan2'); + should.strictEqual(undefined, post.fans[1].age) + post.fans[0].name.should.equal('someone else'); + should.strictEqual(undefined, post.fans[0].age) + + P.findById(post) + .populate('fans', 'age', { age: { $gt: 3 }}, { sort: [['name', 'desc']] }) + .run(function (err, post) { + db.close(); + should.strictEqual(err, null); + + post.fans.length.should.equal(2); + post.fans[1].age.valueOf().should.equal(10); + post.fans[0].age.valueOf().should.equal(8); + }); + }); + }); + }); + }); + }, + + 'refs should cast to ObjectId from hexstrings': function () { + var BP = mongoose.model('RefBlogPost', BlogPost); + var bp = new BP; + bp._creator = new DocObjectId().toString(); + bp._creator.should.be.an.instanceof(DocObjectId); + bp.set('_creator', new DocObjectId().toString()); + bp._creator.should.be.an.instanceof(DocObjectId); + }, + + 'populate should work on String _ids': function () { + var db = start(); + + var UserSchema = new Schema({ + _id: String + , name: String + }) + + var NoteSchema = new Schema({ + author: { type: String, ref: 'UserWithStringId' } + , body: String + }) + + var User = db.model('UserWithStringId', UserSchema, random()) + var Note = db.model('NoteWithStringId', NoteSchema, random()) + + var alice = new User({_id: 'alice', name: "Alice"}) + + alice.save(function (err) { + should.strictEqual(err, null); + + var note = new Note({author: 'alice', body: "Buy Milk"}); + note.save(function (err) { + should.strictEqual(err, null); + + Note.findById(note.id).populate('author').run(function (err, note) { + db.close(); + should.strictEqual(err, null); + note.body.should.equal('Buy Milk'); + should.exist(note.author); + note.author.name.should.equal('Alice'); + }); + }); + }) + }, + + 'populate should work on Number _ids': function () { + var db = start(); + + var UserSchema = new Schema({ + _id: Number + , name: String + }) + + var NoteSchema = new Schema({ + author: { type: Number, ref: 'UserWithNumberId' } + , body: String + }) + + var User = db.model('UserWithNumberId', UserSchema, random()) + var Note = db.model('NoteWithNumberId', NoteSchema, random()) + + var alice = new User({_id: 2359, name: "Alice"}) + + alice.save(function (err) { + should.strictEqual(err, null); + + var note = new Note({author: 2359, body: "Buy Milk"}); + note.save(function (err) { + should.strictEqual(err, null); + + Note.findById(note.id).populate('author').run(function (err, note) { + db.close(); + should.strictEqual(err, null); + note.body.should.equal('Buy Milk'); + should.exist(note.author); + note.author.name.should.equal('Alice'); + }); + }); + }) + }, + + // gh-577 + 'required works on ref fields': function () { + var db = start(); + + var userSchema = new Schema({ + email: {type: String, required: true} + }); + var User = db.model('ObjectIdRefRequiredField', userSchema, random()); + + var numSchema = new Schema({ _id: Number, val: Number }); + var Num = db.model('NumberRefRequired', numSchema, random()); + + var strSchema = new Schema({ _id: String, val: String }); + var Str = db.model('StringRefRequired', strSchema, random()); + + var commentSchema = new Schema({ + user: {type: ObjectId, ref: 'ObjectIdRefRequiredField', required: true} + , num: {type: Number, ref: 'NumberRefRequired', required: true} + , str: {type: String, ref: 'StringRefRequired', required: true} + , text: String + }); + var Comment = db.model('CommentWithRequiredField', commentSchema); + + var pending = 3; + + var string = new Str({ _id: 'my string', val: 'hello' }); + var number = new Num({ _id: 1995, val: 234 }); + var user = new User({ email: 'test' }); + + string.save(next); + number.save(next); + user.save(next); + + function next (err) { + should.strictEqual(null, err); + if (--pending) return; + + var comment = new Comment({ + text: 'test' + }); + + comment.save(function (err) { + should.equal('Validation failed', err && err.message); + err.errors.should.have.property('num'); + err.errors.should.have.property('str'); + err.errors.should.have.property('user'); + err.errors.num.type.should.equal('required'); + err.errors.str.type.should.equal('required'); + err.errors.user.type.should.equal('required'); + + comment.user = user; + comment.num = 1995; + comment.str = 'my string'; + + comment.save(function (err, comment) { + should.strictEqual(null, err); + + Comment + .findById(comment.id) + .populate('user') + .populate('num') + .populate('str') + .run(function (err, comment) { + should.strictEqual(err, null); + + comment.set({text: 'test2'}); + + comment.save(function (err, comment) { + db.close(); + should.strictEqual(err, null); + }); + }); + }); + }); + } + }, + + 'populate works with schemas with both id and _id defined': function () { + var db =start() + , S1 = new Schema({ id: String }) + , S2 = new Schema({ things: [{ type: ObjectId, ref: '_idAndid' }]}) + + var M1 = db.model('_idAndid', S1); + var M2 = db.model('populateWorksWith_idAndidSchemas', S2); + + M1.create( + { id: "The Tiger That Isn't" } + , { id: "Users Guide To The Universe" } + , function (err, a, b) { + should.strictEqual(null, err); + + var m2 = new M2({ things: [a, b]}); + m2.save(function (err) { + should.strictEqual(null, err); + M2.findById(m2).populate('things').run(function (err, doc) { + db.close(); + should.strictEqual(null, err); + doc.things.length.should.equal(2); + doc.things[0].id.should.equal("The Tiger That Isn't"); + doc.things[1].id.should.equal("Users Guide To The Universe"); + }) + }); + }) + }, + + // gh-602 + 'Update works with populated arrays': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users) + + var user1 = new User({ name: 'aphex' }); + var user2 = new User({ name: 'twin' }); + + User.create({name:'aphex'},{name:'twin'}, function (err, u1, u2) { + should.strictEqual(err, null); + + var post = BlogPost.create({ + title: 'Woot' + , fans: [] + }, function (err, post) { + should.strictEqual(err, null); + + var update = { fans: [u1, u2] }; + BlogPost.update({ _id: post }, update, function (err) { + should.strictEqual(err, null); + + // the original update doc should not be modified + ;('fans' in update).should.be.true; + ;('$set' in update).should.be.false; + update.fans[0].should.be.instanceof(mongoose.Document); + update.fans[1].should.be.instanceof(mongoose.Document); + + BlogPost.findById(post, function (err, post) { + db.close(); + should.strictEqual(err, null); + post.fans.length.should.equal(2); + post.fans[0].should.be.instanceof(DocObjectId); + post.fans[1].should.be.instanceof(DocObjectId); + }); + }); + }); + }); + }, + + // gh-675 + 'toJSON should also be called for refs': function () { + var db = start() + , BlogPost = db.model('RefBlogPost', posts) + , User = db.model('RefUser', users) + + User.prototype._toJSON = User.prototype.toJSON; + User.prototype.toJSON = function() { + var res = this._toJSON(); + res.was_in_to_json = true; + return res; + } + + BlogPost.prototype._toJSON = BlogPost.prototype.toJSON; + BlogPost.prototype.toJSON = function() { + var res = this._toJSON(); + res.was_in_to_json = true; + return res; + } + + User.create({ + name : 'Jerem' + , email : 'jerem@jolicloud.com' + }, function (err, creator) { + should.strictEqual(err, null); + + BlogPost.create({ + title : 'Ping Pong' + , _creator : creator + }, function (err, post) { + should.strictEqual(err, null); + + BlogPost + .findById(post._id) + .populate('_creator') + .run(function (err, post) { + db.close(); + should.strictEqual(err, null); + + var json = post.toJSON(); + json.was_in_to_json.should.equal(true); + json._creator.was_in_to_json.should.equal(true); + }); + }); + }); + }, + + // gh-686 + 'populate should work on Buffer _ids': function () { + var db = start(); + + var UserSchema = new Schema({ + _id: Buffer + , name: String + }) + + var NoteSchema = new Schema({ + author: { type: Buffer, ref: 'UserWithBufferId' } + , body: String + }) + + var User = db.model('UserWithBufferId', UserSchema, random()) + var Note = db.model('NoteWithBufferId', NoteSchema, random()) + + var alice = new User({_id: new mongoose.Types.Buffer('YWxpY2U=', 'base64'), name: "Alice"}) + + alice.save(function (err) { + should.strictEqual(err, null); + + var note = new Note({author: 'alice', body: "Buy Milk"}); + note.save(function (err) { + should.strictEqual(err, null); + + Note.findById(note.id).populate('author').run(function (err, note) { + db.close(); + should.strictEqual(err, null); + note.body.should.equal('Buy Milk'); + should.exist(note.author); + note.author.name.should.equal('Alice'); + }); + }); + }) + } +};
\ No newline at end of file |
