'use strict';
const start = require('./common');
const Query = require('../lib/query');
const assert = require('assert');
const mongoose = start.mongoose;
const Schema = mongoose.Schema;
describe('Query:', function() {
let Comment;
let Product;
describe('toConstructor', function() {
let db;
before(function() {
db = start();
});
after(async function() {
await db.close();
});
before(function() {
Comment = new Schema({
text: String
});
Product = new Schema({
tags: {},
array: Array,
ids: [Schema.ObjectId],
strings: [String],
numbers: [Number],
comments: [Comment],
title: String
});
Product = db.model('Product', Product);
});
it('creates a query', function() {
const prodQ = Product.find({ title: /test/ }).toConstructor();
assert.ok(prodQ() instanceof Query);
});
it('copies all the right values', function() {
const prodQ = Product.updateOne({ title: /test/ }, { title: 'blah' });
const prodC = prodQ.toConstructor();
assert.deepEqual(prodQ._conditions, prodC()._conditions);
assert.deepEqual(prodQ._fields, prodC()._fields);
assert.deepEqual(prodQ._update, prodC()._update);
assert.equal(prodQ._path, prodC()._path);
assert.equal(prodQ._distinct, prodC()._distinct);
assert.deepEqual(prodQ._collection, prodC()._collection);
assert.deepEqual(prodQ.model, prodC().model);
assert.deepEqual(prodQ.mongooseCollection, prodC().mongooseCollection);
assert.deepEqual(prodQ._mongooseOptions, prodC()._mongooseOptions);
});
it('gets expected results', async function() {
const p = await Product.create({ title: 'this is a test' });
const prodC = Product.find({ title: /test/ }).toConstructor();
const results = await prodC().exec();
assert.equal(results.length, 1);
assert.equal(p.title, results[0].title);
});
it('can be re-used multiple times', async function() {
const prods = await Product.create([{ title: 'moar thing' }, { title: 'second thing' }]);
assert.equal(prods.length, 2);
const prod = prods[0];
const prodC = Product.find({ title: /thing/ }).toConstructor();
const results = await prodC().exec();
assert.equal(results.length, 2);
let res = await prodC().find({ _id: prod.id }).exec();
assert.equal(res.length, 1);
res = await prodC().exec();
assert.equal(res.length, 2);
});
it('options get merged properly', function() {
let prodC = Product.find({ title: /blah/ }).setOptions({ sort: 'title', lean: true });
prodC = prodC.toConstructor();
const nq = prodC(null, { limit: 3 });
assert.deepEqual(nq._mongooseOptions, { lean: true, limit: 3 });
assert.deepEqual(nq.options, {
sort: { title: 1 },
limit: 3
});
});
it('options get cloned (gh-3176)', function() {
let prodC = Product.find({ title: /blah/ }).setOptions({ sort: 'title', lean: true });
prodC = prodC.toConstructor();
const nq = prodC(null, { limit: 3 });
assert.deepEqual(nq._mongooseOptions, { lean: true, limit: 3 });
assert.deepEqual(nq.options, {
sort: { title: 1 },
limit: 3
});
const nq2 = prodC(null, { limit: 5 });
assert.deepEqual(nq._mongooseOptions, { lean: true, limit: 3 });
assert.deepEqual(nq2._mongooseOptions, { lean: true, limit: 5 });
});
it('creates subclasses of mquery', function() {
const opts = { w: 'majority', readPreference: 'p' };
const match = { title: 'test', count: { $gt: 101 } };
const select = { name: 1, count: 0 };
const update = { $set: { title: 'thing' } };
const path = 'title';
const q = Product.updateOne(match, update);
q.select(select);
q.where(path);
q.setOptions(opts);
q.find();
const M = q.toConstructor();
const m = M();
assert.ok(m instanceof Query);
assert.deepEqual(opts, m.options);
assert.deepEqual(match, m._conditions);
assert.deepEqual(select, m._fields);
assert.deepEqual(update, m._update);
assert.equal(path, m._path);
assert.equal('find', m.op);
});
it('with findOneAndUpdate (gh-4318)', async function() {
const Q = Product.where({ title: 'test' }).toConstructor();
const query = { 'tags.test': 1 };
const update = {
strings: ['123'],
numbers: [1, 2, 3]
};
await Q().findOneAndUpdate(query, update);
});
it('gets middleware from model (gh-6455)', async function() {
let called = 0;
const schema = new Schema({
name: String
});
schema.pre('findOne', function logHook() {
called++;
});
const Test = db.model('Test', schema);
await Test.init();
await Test.deleteMany({});
const test = new Test({ name: 'Romero' });
const Q = Test.findOne({}).toConstructor();
await test.save();
const doc = await Q();
assert.strictEqual(doc.name, 'Romero');
assert.strictEqual(called, 1);
});
it('works with entries-style sort() syntax (gh-8159)', function() {
mongoose.deleteModel(/Test/);
const Model = mongoose.model('Test', Schema({ name: String }));
const query = Model.find().sort([['name', 1]]);
const Query = query.toConstructor();
const q = new Query();
assert.deepEqual(q.options.sort, { name: 1 });
});
});
});