2016-04-01 22:25:16 +00:00
|
|
|
// Copyright IBM Corp. 2013,2016. All Rights Reserved.
|
|
|
|
// Node module: loopback-datasource-juggler
|
|
|
|
// This file is licensed under the MIT License.
|
|
|
|
// License text available at https://opensource.org/licenses/MIT
|
|
|
|
|
2013-04-06 10:57:12 +00:00
|
|
|
// This test written in mocha+should.js
|
|
|
|
var should = require('./init.js');
|
2014-06-20 19:05:42 +00:00
|
|
|
var async = require('async');
|
2013-04-06 10:57:12 +00:00
|
|
|
var db, User;
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
describe('basic-querying', function() {
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
before(function(done) {
|
2014-01-24 17:09:53 +00:00
|
|
|
db = getSchema();
|
|
|
|
User = db.define('User', {
|
2016-04-01 11:48:17 +00:00
|
|
|
seq: { type: Number, index: true },
|
|
|
|
name: { type: String, index: true, sort: true },
|
|
|
|
email: { type: String, index: true },
|
|
|
|
birthday: { type: Date, index: true },
|
|
|
|
role: { type: String, index: true },
|
|
|
|
order: { type: Number, index: true, sort: true },
|
|
|
|
vip: { type: Boolean },
|
2014-01-24 17:09:53 +00:00
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2014-01-24 17:09:53 +00:00
|
|
|
db.automigrate(done);
|
2013-03-27 00:50:34 +00:00
|
|
|
|
2014-01-24 17:09:53 +00:00
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
describe('ping', function() {
|
|
|
|
it('should be able to test connections', function(done) {
|
|
|
|
db.ping(function(err) {
|
2014-08-20 23:31:23 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
describe('findById', function() {
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
before(function(done) {
|
2014-01-24 17:09:53 +00:00
|
|
|
User.destroyAll(done);
|
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should query by id: not found', function(done) {
|
|
|
|
User.findById(1, function(err, u) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.not.exist(u);
|
|
|
|
should.not.exist(err);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should query by id: found', function(done) {
|
|
|
|
User.create(function(err, u) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
should.exist(u.id);
|
2016-04-01 11:48:17 +00:00
|
|
|
User.findById(u.id, function(err, u) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.exist(u);
|
|
|
|
should.not.exist(err);
|
|
|
|
u.should.be.an.instanceOf(User);
|
|
|
|
done();
|
2013-03-26 19:33:11 +00:00
|
|
|
});
|
2014-01-24 17:09:53 +00:00
|
|
|
});
|
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2014-01-24 17:09:53 +00:00
|
|
|
});
|
2015-03-18 09:18:03 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
describe('findByIds', function() {
|
2015-02-21 05:14:41 +00:00
|
|
|
var createdUsers;
|
2014-07-29 13:01:47 +00:00
|
|
|
before(function(done) {
|
|
|
|
var people = [
|
2015-03-27 21:18:17 +00:00
|
|
|
{ name: 'a', vip: true },
|
|
|
|
{ name: 'b' },
|
|
|
|
{ name: 'c' },
|
|
|
|
{ name: 'd', vip: true },
|
|
|
|
{ name: 'e' },
|
2016-04-01 11:48:17 +00:00
|
|
|
{ name: 'f' },
|
2014-07-29 13:01:47 +00:00
|
|
|
];
|
2014-08-26 05:17:40 +00:00
|
|
|
db.automigrate(['User'], function(err) {
|
|
|
|
User.create(people, function(err, users) {
|
2015-02-21 05:14:41 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
// Users might be created in parallel and the generated ids can be
|
|
|
|
// out of sequence
|
|
|
|
createdUsers = users;
|
2014-08-26 05:17:40 +00:00
|
|
|
done();
|
|
|
|
});
|
2014-07-29 13:01:47 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2015-02-21 05:14:41 +00:00
|
|
|
it('should query by ids', function(done) {
|
|
|
|
User.findByIds(
|
|
|
|
[createdUsers[2].id, createdUsers[1].id, createdUsers[0].id],
|
|
|
|
function(err, users) {
|
|
|
|
should.exist(users);
|
|
|
|
should.not.exist(err);
|
|
|
|
var names = users.map(function(u) {
|
|
|
|
return u.name;
|
|
|
|
});
|
|
|
|
names.should.eql(
|
|
|
|
[createdUsers[2].name, createdUsers[1].name, createdUsers[0].name]);
|
|
|
|
done();
|
|
|
|
});
|
2014-07-29 13:01:47 +00:00
|
|
|
});
|
2015-02-21 05:14:41 +00:00
|
|
|
|
|
|
|
it('should query by ids and condition', function(done) {
|
|
|
|
User.findByIds([
|
2016-04-01 11:48:17 +00:00
|
|
|
createdUsers[0].id,
|
|
|
|
createdUsers[1].id,
|
|
|
|
createdUsers[2].id,
|
|
|
|
createdUsers[3].id],
|
|
|
|
{ where: { vip: true }}, function(err, users) {
|
2015-02-21 05:14:41 +00:00
|
|
|
should.exist(users);
|
|
|
|
should.not.exist(err);
|
|
|
|
var names = users.map(function(u) {
|
|
|
|
return u.name;
|
|
|
|
});
|
|
|
|
names.should.eql(createdUsers.slice(0, 4).
|
|
|
|
filter(function(u) {
|
|
|
|
return u.vip;
|
|
|
|
}).map(function(u) {
|
|
|
|
return u.name;
|
|
|
|
}));
|
|
|
|
done();
|
|
|
|
});
|
2014-07-29 13:01:47 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
describe('find', function() {
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2014-01-24 17:09:53 +00:00
|
|
|
before(seed);
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2016-03-03 08:32:40 +00:00
|
|
|
before(function setupDelayingLoadedHook() {
|
|
|
|
User.observe('loaded', nextAfterDelay);
|
|
|
|
});
|
|
|
|
|
|
|
|
after(function removeDelayingLoadHook() {
|
|
|
|
User.removeObserver('loaded', nextAfterDelay);
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should query collection', function(done) {
|
|
|
|
User.find(function(err, users) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.exists(users);
|
|
|
|
should.not.exists(err);
|
|
|
|
users.should.have.lengthOf(6);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should query limited collection', function(done) {
|
|
|
|
User.find({ limit: 3 }, function(err, users) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.exists(users);
|
|
|
|
should.not.exists(err);
|
|
|
|
users.should.have.lengthOf(3);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should query collection with skip & limit', function(done) {
|
|
|
|
User.find({ skip: 1, limit: 4, order: 'seq' }, function(err, users) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.exists(users);
|
|
|
|
should.not.exists(err);
|
2014-06-17 16:07:55 +00:00
|
|
|
users[0].seq.should.be.eql(1);
|
2014-01-24 17:09:53 +00:00
|
|
|
users.should.have.lengthOf(4);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should query collection with offset & limit', function(done) {
|
|
|
|
User.find({ offset: 2, limit: 3, order: 'seq' }, function(err, users) {
|
2014-06-17 16:07:55 +00:00
|
|
|
should.exists(users);
|
|
|
|
should.not.exists(err);
|
|
|
|
users[0].seq.should.be.eql(2);
|
|
|
|
users.should.have.lengthOf(3);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should query filtered collection', function(done) {
|
|
|
|
User.find({ where: { role: 'lead' }}, function(err, users) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.exists(users);
|
|
|
|
should.not.exists(err);
|
|
|
|
users.should.have.lengthOf(2);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should query collection sorted by numeric field', function(done) {
|
|
|
|
User.find({ order: 'order' }, function(err, users) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.exists(users);
|
|
|
|
should.not.exists(err);
|
2016-04-01 11:48:17 +00:00
|
|
|
users.forEach(function(u, i) {
|
2014-01-24 17:09:53 +00:00
|
|
|
u.order.should.eql(i + 1);
|
2013-03-26 19:33:11 +00:00
|
|
|
});
|
2014-01-24 17:09:53 +00:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should query collection desc sorted by numeric field', function(done) {
|
|
|
|
User.find({ order: 'order DESC' }, function(err, users) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.exists(users);
|
|
|
|
should.not.exists(err);
|
2016-04-01 11:48:17 +00:00
|
|
|
users.forEach(function(u, i) {
|
2014-01-24 17:09:53 +00:00
|
|
|
u.order.should.eql(users.length - i);
|
2013-03-26 19:33:11 +00:00
|
|
|
});
|
2014-01-24 17:09:53 +00:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should query collection sorted by string field', function(done) {
|
|
|
|
User.find({ order: 'name' }, function(err, users) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.exists(users);
|
|
|
|
should.not.exists(err);
|
|
|
|
users.shift().name.should.equal('George Harrison');
|
|
|
|
users.shift().name.should.equal('John Lennon');
|
|
|
|
users.pop().name.should.equal('Stuart Sutcliffe');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should query collection desc sorted by string field', function(done) {
|
|
|
|
User.find({ order: 'name DESC' }, function(err, users) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.exists(users);
|
|
|
|
should.not.exists(err);
|
|
|
|
users.pop().name.should.equal('George Harrison');
|
|
|
|
users.pop().name.should.equal('John Lennon');
|
|
|
|
users.shift().name.should.equal('Stuart Sutcliffe');
|
|
|
|
done();
|
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
});
|
|
|
|
|
2016-03-03 08:32:40 +00:00
|
|
|
it('should query sorted desc by order integer field even though there' +
|
|
|
|
'is an async model loaded hook', function(done) {
|
|
|
|
User.find({ order: 'order DESC' }, function(err, users) {
|
|
|
|
if (err) return done(err);
|
|
|
|
|
|
|
|
should.exists(users);
|
|
|
|
var order = users.map(function(u) { return u.order; });
|
|
|
|
order.should.eql([6, 5, 4, 3, 2, 1]);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support "and" operator that is satisfied', function(done) {
|
|
|
|
User.find({ where: { and: [
|
|
|
|
{ name: 'John Lennon' },
|
|
|
|
{ role: 'lead' },
|
|
|
|
] }}, function(err, users) {
|
2014-05-15 15:56:00 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 1);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support "and" operator that is not satisfied', function(done) {
|
|
|
|
User.find({ where: { and: [
|
|
|
|
{ name: 'John Lennon' },
|
|
|
|
{ role: 'member' },
|
|
|
|
] }}, function(err, users) {
|
2014-05-15 15:56:00 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 0);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support "or" that is satisfied', function(done) {
|
|
|
|
User.find({ where: { or: [
|
|
|
|
{ name: 'John Lennon' },
|
|
|
|
{ role: 'lead' },
|
|
|
|
] }}, function(err, users) {
|
2014-05-15 15:56:00 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 2);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support "or" operator that is not satisfied', function(done) {
|
|
|
|
User.find({ where: { or: [
|
|
|
|
{ name: 'XYZ' },
|
|
|
|
{ role: 'Hello1' },
|
|
|
|
] }}, function(err, users) {
|
2014-05-15 15:56:00 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 0);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support date "gte" that is satisfied', function(done) {
|
|
|
|
User.find({ order: 'seq', where: { birthday: { 'gte': new Date('1980-12-08') },
|
|
|
|
}}, function(err, users) {
|
2014-06-06 15:48:05 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 1);
|
|
|
|
users[0].name.should.equal('John Lennon');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support date "gt" that is not satisfied', function(done) {
|
|
|
|
User.find({ order: 'seq', where: { birthday: { 'gt': new Date('1980-12-08') },
|
|
|
|
}}, function(err, users) {
|
2014-06-06 15:48:05 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 0);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support date "gt" that is satisfied', function(done) {
|
|
|
|
User.find({ order: 'seq', where: { birthday: { 'gt': new Date('1980-12-07') },
|
|
|
|
}}, function(err, users) {
|
2014-06-06 15:48:05 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 1);
|
|
|
|
users[0].name.should.equal('John Lennon');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support date "lt" that is satisfied', function(done) {
|
|
|
|
User.find({ order: 'seq', where: { birthday: { 'lt': new Date('1980-12-07') },
|
|
|
|
}}, function(err, users) {
|
2014-06-06 15:48:05 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 1);
|
|
|
|
users[0].name.should.equal('Paul McCartney');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support number "gte" that is satisfied', function(done) {
|
2016-04-01 13:23:42 +00:00
|
|
|
User.find({ order: 'seq', where: { order: { 'gte': 3 },
|
2016-04-01 11:48:17 +00:00
|
|
|
}}, function(err, users) {
|
2014-06-06 15:48:05 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 4);
|
|
|
|
users[0].name.should.equal('George Harrison');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support number "gt" that is not satisfied', function(done) {
|
|
|
|
User.find({ order: 'seq', where: { order: { 'gt': 6 },
|
|
|
|
}}, function(err, users) {
|
2014-06-06 15:48:05 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 0);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support number "gt" that is satisfied', function(done) {
|
|
|
|
User.find({ order: 'seq', where: { order: { 'gt': 5 },
|
|
|
|
}}, function(err, users) {
|
2014-06-06 15:48:05 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 1);
|
|
|
|
users[0].name.should.equal('Ringo Starr');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support number "lt" that is satisfied', function(done) {
|
|
|
|
User.find({ order: 'seq', where: { order: { 'lt': 2 },
|
|
|
|
}}, function(err, users) {
|
2014-06-06 15:48:05 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 1);
|
|
|
|
users[0].name.should.equal('Paul McCartney');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support number "gt" that is satisfied by null value', function(done) {
|
|
|
|
User.find({ order: 'seq', where: { order: { 'gt': null },
|
|
|
|
}}, function(err, users) {
|
2014-06-10 23:11:50 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 0);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support number "lt" that is not satisfied by null value', function(done) {
|
|
|
|
User.find({ order: 'seq', where: { order: { 'lt': null },
|
|
|
|
}}, function(err, users) {
|
2014-06-10 23:11:50 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 0);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support string "gte" that is satisfied by null value', function(done) {
|
2016-04-01 13:23:42 +00:00
|
|
|
User.find({ order: 'seq', where: { name: { 'gte': null },
|
2016-04-01 11:48:17 +00:00
|
|
|
}}, function(err, users) {
|
2014-06-10 23:11:50 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 0);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support string "gte" that is satisfied', function(done) {
|
2016-04-01 13:23:42 +00:00
|
|
|
User.find({ order: 'seq', where: { name: { 'gte': 'Paul McCartney' },
|
2016-04-01 11:48:17 +00:00
|
|
|
}}, function(err, users) {
|
2014-06-06 15:48:05 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 4);
|
|
|
|
users[0].name.should.equal('Paul McCartney');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support string "gt" that is not satisfied', function(done) {
|
|
|
|
User.find({ order: 'seq', where: { name: { 'gt': 'xyz' },
|
|
|
|
}}, function(err, users) {
|
2014-06-06 15:48:05 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 0);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support string "gt" that is satisfied', function(done) {
|
|
|
|
User.find({ order: 'seq', where: { name: { 'gt': 'Paul McCartney' },
|
|
|
|
}}, function(err, users) {
|
2014-06-06 15:48:05 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 3);
|
|
|
|
users[0].name.should.equal('Ringo Starr');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support string "lt" that is satisfied', function(done) {
|
|
|
|
User.find({ order: 'seq', where: { name: { 'lt': 'Paul McCartney' },
|
|
|
|
}}, function(err, users) {
|
2014-06-06 15:48:05 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 2);
|
|
|
|
users[0].name.should.equal('John Lennon');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support boolean "gte" that is satisfied', function(done) {
|
2016-04-01 13:23:42 +00:00
|
|
|
User.find({ order: 'seq', where: { vip: { 'gte': true },
|
2016-04-01 11:48:17 +00:00
|
|
|
}}, function(err, users) {
|
2014-06-06 16:28:08 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 3);
|
|
|
|
users[0].name.should.equal('John Lennon');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support boolean "gt" that is not satisfied', function(done) {
|
|
|
|
User.find({ order: 'seq', where: { vip: { 'gt': true },
|
|
|
|
}}, function(err, users) {
|
2014-06-06 16:28:08 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 0);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support boolean "gt" that is satisfied', function(done) {
|
|
|
|
User.find({ order: 'seq', where: { vip: { 'gt': false },
|
|
|
|
}}, function(err, users) {
|
2014-06-06 16:28:08 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 3);
|
|
|
|
users[0].name.should.equal('John Lennon');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should support boolean "lt" that is satisfied', function(done) {
|
|
|
|
User.find({ order: 'seq', where: { vip: { 'lt': true },
|
|
|
|
}}, function(err, users) {
|
2014-06-06 16:28:08 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
users.should.have.property('length', 2);
|
|
|
|
users[0].name.should.equal('George Harrison');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should only include fields as specified', function(done) {
|
2014-01-24 17:09:53 +00:00
|
|
|
var remaining = 0;
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2014-01-24 17:09:53 +00:00
|
|
|
function sample(fields) {
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2014-01-24 17:09:53 +00:00
|
|
|
return {
|
2016-04-01 11:48:17 +00:00
|
|
|
expect: function(arr) {
|
2014-01-24 17:09:53 +00:00
|
|
|
remaining++;
|
2016-04-01 11:48:17 +00:00
|
|
|
User.find({ fields: fields }, function(err, users) {
|
2014-01-24 17:09:53 +00:00
|
|
|
|
|
|
|
remaining--;
|
|
|
|
if (err) return done(err);
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2014-01-24 17:09:53 +00:00
|
|
|
should.exists(users);
|
|
|
|
|
|
|
|
if (remaining === 0) {
|
2013-03-26 19:33:11 +00:00
|
|
|
done();
|
2014-01-24 17:09:53 +00:00
|
|
|
}
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
users.forEach(function(user) {
|
2014-01-24 17:09:53 +00:00
|
|
|
var obj = user.toObject();
|
|
|
|
|
|
|
|
Object.keys(obj)
|
2016-04-01 11:48:17 +00:00
|
|
|
.forEach(function(key) {
|
2014-01-24 17:09:53 +00:00
|
|
|
// if the obj has an unexpected value
|
|
|
|
if (obj[key] !== undefined && arr.indexOf(key) === -1) {
|
|
|
|
console.log('Given fields:', fields);
|
|
|
|
console.log('Got:', key, obj[key]);
|
|
|
|
console.log('Expected:', arr);
|
|
|
|
throw new Error('should not include data for key: ' + key);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
});
|
2016-04-01 11:48:17 +00:00
|
|
|
},
|
|
|
|
};
|
2014-01-24 17:09:53 +00:00
|
|
|
}
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
sample({ name: true }).expect(['name']);
|
|
|
|
sample({ name: false }).expect(['id', 'seq', 'email', 'role', 'order', 'birthday', 'vip']);
|
|
|
|
sample({ name: false, id: true }).expect(['id']);
|
|
|
|
sample({ id: true }).expect(['id']);
|
2014-01-24 17:09:53 +00:00
|
|
|
sample('id').expect(['id']);
|
|
|
|
sample(['id']).expect(['id']);
|
|
|
|
sample(['email']).expect(['email']);
|
2013-03-26 19:33:11 +00:00
|
|
|
});
|
|
|
|
|
2014-01-24 17:09:53 +00:00
|
|
|
});
|
2013-03-26 20:50:13 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
describe('count', function() {
|
2013-03-26 20:50:13 +00:00
|
|
|
|
2014-01-24 17:09:53 +00:00
|
|
|
before(seed);
|
2013-03-26 20:50:13 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should query total count', function(done) {
|
|
|
|
User.count(function(err, n) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
should.exist(n);
|
|
|
|
n.should.equal(6);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
2013-03-26 20:50:13 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should query filtered count', function(done) {
|
|
|
|
User.count({ role: 'lead' }, function(err, n) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
should.exist(n);
|
|
|
|
n.should.equal(2);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2013-03-26 20:50:13 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
describe('findOne', function() {
|
2013-03-26 20:50:13 +00:00
|
|
|
|
2014-01-24 17:09:53 +00:00
|
|
|
before(seed);
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should find first record (default sort by id)', function(done) {
|
|
|
|
User.all({ order: 'id' }, function(err, users) {
|
|
|
|
User.findOne(function(e, u) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.not.exist(e);
|
|
|
|
should.exist(u);
|
|
|
|
u.id.toString().should.equal(users[0].id.toString());
|
|
|
|
done();
|
2013-03-27 17:53:07 +00:00
|
|
|
});
|
2014-01-24 17:09:53 +00:00
|
|
|
});
|
|
|
|
});
|
2013-03-27 17:53:07 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should find first record', function(done) {
|
|
|
|
User.findOne({ order: 'order' }, function(e, u) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.not.exist(e);
|
|
|
|
should.exist(u);
|
|
|
|
u.order.should.equal(1);
|
|
|
|
u.name.should.equal('Paul McCartney');
|
|
|
|
done();
|
|
|
|
});
|
2013-03-26 20:50:13 +00:00
|
|
|
});
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should find last record', function(done) {
|
|
|
|
User.findOne({ order: 'order DESC' }, function(e, u) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.not.exist(e);
|
|
|
|
should.exist(u);
|
|
|
|
u.order.should.equal(6);
|
|
|
|
u.name.should.equal('Ringo Starr');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should find last record in filtered set', function(done) {
|
2014-01-24 17:09:53 +00:00
|
|
|
User.findOne({
|
2016-04-01 11:48:17 +00:00
|
|
|
where: { role: 'lead' },
|
|
|
|
order: 'order DESC',
|
|
|
|
}, function(e, u) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.not.exist(e);
|
|
|
|
should.exist(u);
|
|
|
|
u.order.should.equal(2);
|
|
|
|
u.name.should.equal('John Lennon');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should work even when find by id', function(done) {
|
|
|
|
User.findOne(function(e, u) {
|
|
|
|
User.findOne({ where: { id: u.id }}, function(err, user) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
should.exist(user);
|
|
|
|
done();
|
2013-03-26 19:33:11 +00:00
|
|
|
});
|
2014-01-24 17:09:53 +00:00
|
|
|
});
|
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2014-01-24 17:09:53 +00:00
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
describe('exists', function() {
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2014-01-24 17:09:53 +00:00
|
|
|
before(seed);
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should check whether record exist', function(done) {
|
|
|
|
User.findOne(function(e, u) {
|
|
|
|
User.exists(u.id, function(err, exists) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
should.exist(exists);
|
|
|
|
exists.should.be.ok;
|
|
|
|
done();
|
2013-08-18 17:58:53 +00:00
|
|
|
});
|
2014-01-24 17:09:53 +00:00
|
|
|
});
|
|
|
|
});
|
2013-08-18 17:58:53 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
it('should check whether record not exist', function(done) {
|
|
|
|
User.destroyAll(function() {
|
|
|
|
User.exists(42, function(err, exists) {
|
2014-01-24 17:09:53 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
exists.should.not.be.ok;
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
2013-08-18 17:58:53 +00:00
|
|
|
});
|
2014-06-17 23:30:02 +00:00
|
|
|
});
|
2015-07-24 19:56:31 +00:00
|
|
|
|
|
|
|
context('regexp operator', function() {
|
|
|
|
var invalidDataTypes = [0, true, {}, [], Function, null];
|
|
|
|
|
|
|
|
before(seed);
|
|
|
|
|
|
|
|
it('should return an error for invalid data types', function(done) {
|
|
|
|
// `undefined` is not tested because the `removeUndefined` function
|
|
|
|
// in `lib/dao.js` removes it before coercion
|
|
|
|
invalidDataTypes.forEach(function(invalidDataType) {
|
2016-04-01 11:48:17 +00:00
|
|
|
User.find({ where: { name: { regexp: invalidDataType }}}, function(err,
|
2015-07-24 19:56:31 +00:00
|
|
|
users) {
|
|
|
|
should.exist(err);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
2013-03-26 19:33:11 +00:00
|
|
|
});
|
|
|
|
|
2015-08-26 22:23:35 +00:00
|
|
|
describe.skip('queries', function() {
|
2015-08-12 06:02:29 +00:00
|
|
|
var Todo;
|
|
|
|
|
2015-08-26 22:23:35 +00:00
|
|
|
before(function prepDb(done) {
|
2015-08-12 06:02:29 +00:00
|
|
|
var db = getSchema();
|
|
|
|
Todo = db.define('Todo', {
|
|
|
|
id: false,
|
2016-04-01 11:48:17 +00:00
|
|
|
content: { type: 'string' },
|
2015-08-12 06:02:29 +00:00
|
|
|
}, {
|
2016-04-01 11:48:17 +00:00
|
|
|
idInjection: false,
|
2015-08-12 06:02:29 +00:00
|
|
|
});
|
2015-08-27 22:59:58 +00:00
|
|
|
db.automigrate(['Todo'], done);
|
2015-08-12 06:02:29 +00:00
|
|
|
});
|
|
|
|
beforeEach(function resetFixtures(done) {
|
|
|
|
Todo.destroyAll(function() {
|
|
|
|
Todo.create([
|
2016-04-01 11:48:17 +00:00
|
|
|
{ content: 'Buy eggs' },
|
|
|
|
{ content: 'Buy milk' },
|
|
|
|
{ content: 'Buy sausages' },
|
2015-08-12 06:02:29 +00:00
|
|
|
], done);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
context('that do not require an id', function() {
|
|
|
|
it('should work for create', function(done) {
|
2016-04-01 11:48:17 +00:00
|
|
|
Todo.create({ content: 'Buy ham' }, function(err) {
|
2015-08-12 06:02:29 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should work for updateOrCreate/upsert', function(done) {
|
|
|
|
var aliases = ['updateOrCreate', 'upsert'];
|
|
|
|
async.each(aliases, function(alias, cb) {
|
2016-04-01 11:48:17 +00:00
|
|
|
Todo[alias]({ content: 'Buy ham' }, function(err) {
|
2015-08-12 06:02:29 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
cb();
|
|
|
|
});
|
|
|
|
}, done);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should work for findOrCreate', function(done) {
|
2016-04-01 11:48:17 +00:00
|
|
|
Todo.findOrCreate({ content: 'Buy ham' }, function(err) {
|
2015-08-12 06:02:29 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should work for exists', function(done) {
|
2016-04-01 11:48:17 +00:00
|
|
|
Todo.exists({ content: 'Buy ham' }, function(err) {
|
2015-08-12 06:02:29 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should work for find', function(done) {
|
|
|
|
Todo.find(function(err) {
|
|
|
|
should.not.exist(err);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should work for findOne', function(done) {
|
|
|
|
Todo.findOne(function(err) {
|
|
|
|
should.not.exist(err);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should work for deleteAll/destroyAll/remove', function(done) {
|
|
|
|
// FIXME: We should add a DAO.delete static method alias for consistency
|
|
|
|
// (DAO.prototype.delete instance method already exists)
|
|
|
|
var aliases = ['deleteAll', 'destroyAll', 'remove'];
|
|
|
|
async.each(aliases, function(alias, cb) {
|
|
|
|
Todo[alias](function(err) {
|
|
|
|
should.not.exist(err);
|
|
|
|
cb();
|
|
|
|
});
|
|
|
|
}, done);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should work for update/updateAll', function(done) {
|
2016-04-01 11:48:17 +00:00
|
|
|
Todo.update({ content: 'Buy ham' }, function(err) {
|
2015-08-12 06:02:29 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should work for count', function(done) {
|
2016-04-01 11:48:17 +00:00
|
|
|
Todo.count({ content: 'Buy eggs' }, function(err) {
|
2015-08-12 06:02:29 +00:00
|
|
|
should.not.exist(err);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
context('that require an id', function() {
|
2015-08-26 22:23:35 +00:00
|
|
|
var expectedErrMsg = 'Primary key is missing for the Todo model';
|
2015-08-12 06:02:29 +00:00
|
|
|
|
|
|
|
it('should return an error for findById', function(done) {
|
|
|
|
Todo.findById(1, function(err) {
|
|
|
|
should.exist(err);
|
|
|
|
err.message.should.equal(expectedErrMsg);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should return an error for findByIds', function(done) {
|
|
|
|
Todo.findByIds([1, 2], function(err) {
|
|
|
|
should.exist(err);
|
|
|
|
err.message.should.equal(expectedErrMsg);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should return an error for deleteById/destroyById/removeById',
|
2016-04-01 13:23:42 +00:00
|
|
|
function(done) {
|
|
|
|
var aliases = ['deleteById', 'destroyById', 'removeById'];
|
|
|
|
async.each(aliases, function(alias, cb) {
|
2015-08-12 06:02:29 +00:00
|
|
|
Todo[alias](1, function(err) {
|
|
|
|
should.exist(err);
|
|
|
|
err.message.should.equal(expectedErrMsg);
|
|
|
|
cb();
|
|
|
|
});
|
|
|
|
}, done);
|
2016-04-01 13:23:42 +00:00
|
|
|
});
|
2015-08-26 22:23:35 +00:00
|
|
|
|
|
|
|
it('should return an error for instance.save', function(done) {
|
|
|
|
var todo = new Todo();
|
|
|
|
todo.content = 'Buy ham';
|
|
|
|
todo.save(function(err) {
|
|
|
|
should.exist(err);
|
|
|
|
err.message.should.equal(expectedErrMsg);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should return an error for instance.delete', function(done) {
|
|
|
|
Todo.findOne(function(err, todo) {
|
|
|
|
todo.delete(function(err) {
|
|
|
|
should.exist(err);
|
|
|
|
err.message.should.equal(expectedErrMsg);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should return an error for instance.updateAttribute', function(done) {
|
|
|
|
Todo.findOne(function(err, todo) {
|
|
|
|
todo.updateAttribute('content', 'Buy ham', function(err) {
|
|
|
|
should.exist(err);
|
|
|
|
err.message.should.equal(expectedErrMsg);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should return an error for instance.updateAttributes', function(done) {
|
|
|
|
Todo.findOne(function(err, todo) {
|
2016-04-01 11:48:17 +00:00
|
|
|
todo.updateAttributes({ content: 'Buy ham' }, function(err) {
|
2015-08-26 22:23:35 +00:00
|
|
|
should.exist(err);
|
|
|
|
err.message.should.equal(expectedErrMsg);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2015-08-12 06:02:29 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2013-03-26 19:33:11 +00:00
|
|
|
function seed(done) {
|
2014-01-24 17:09:53 +00:00
|
|
|
var beatles = [
|
|
|
|
{
|
2014-06-06 16:09:56 +00:00
|
|
|
seq: 0,
|
2014-01-24 17:09:53 +00:00
|
|
|
name: 'John Lennon',
|
|
|
|
email: 'john@b3atl3s.co.uk',
|
|
|
|
role: 'lead',
|
2014-06-06 15:48:05 +00:00
|
|
|
birthday: new Date('1980-12-08'),
|
2014-06-06 16:28:08 +00:00
|
|
|
order: 2,
|
2016-04-01 11:48:17 +00:00
|
|
|
vip: true,
|
2014-01-24 17:09:53 +00:00
|
|
|
},
|
|
|
|
{
|
2014-06-06 16:09:56 +00:00
|
|
|
seq: 1,
|
2014-01-24 17:09:53 +00:00
|
|
|
name: 'Paul McCartney',
|
|
|
|
email: 'paul@b3atl3s.co.uk',
|
|
|
|
role: 'lead',
|
2014-06-06 15:48:05 +00:00
|
|
|
birthday: new Date('1942-06-18'),
|
2014-06-06 16:28:08 +00:00
|
|
|
order: 1,
|
2016-04-01 11:48:17 +00:00
|
|
|
vip: true,
|
2014-01-24 17:09:53 +00:00
|
|
|
},
|
2016-04-01 11:48:17 +00:00
|
|
|
{ seq: 2, name: 'George Harrison', order: 5, vip: false },
|
|
|
|
{ seq: 3, name: 'Ringo Starr', order: 6, vip: false },
|
|
|
|
{ seq: 4, name: 'Pete Best', order: 4 },
|
|
|
|
{ seq: 5, name: 'Stuart Sutcliffe', order: 3, vip: true },
|
2014-01-24 17:09:53 +00:00
|
|
|
];
|
2013-03-26 19:33:11 +00:00
|
|
|
|
2014-06-20 19:05:42 +00:00
|
|
|
async.series([
|
|
|
|
User.destroyAll.bind(User),
|
|
|
|
function(cb) {
|
|
|
|
async.each(beatles, User.create.bind(User), cb);
|
2016-04-01 11:48:17 +00:00
|
|
|
},
|
2014-06-20 19:05:42 +00:00
|
|
|
], done);
|
2013-03-26 19:33:11 +00:00
|
|
|
}
|
2016-03-03 08:32:40 +00:00
|
|
|
|
|
|
|
function nextAfterDelay(ctx, next) {
|
|
|
|
var randomTimeoutTrigger = Math.floor(Math.random() * 100);
|
|
|
|
setTimeout(function() { process.nextTick(next); }, randomTimeoutTrigger);
|
|
|
|
}
|