loopback-datasource-juggler/test/scope.test.js

446 lines
12 KiB
JavaScript
Raw Normal View History

2019-05-08 15:45:37 +00:00
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
2016-04-01 22:25:16 +00:00
// Node module: loopback-datasource-juggler
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
2013-04-11 23:56:51 +00:00
// This test written in mocha+should.js
2016-08-22 19:55:22 +00:00
'use strict';
/* global getSchema:false */
2018-12-07 14:54:29 +00:00
const should = require('./init.js');
2013-04-11 23:56:51 +00:00
2018-12-07 14:54:29 +00:00
let db, Railway, Station;
2013-04-11 23:56:51 +00:00
2016-04-01 11:48:17 +00:00
describe('scope', function() {
before(function() {
2014-01-24 17:09:53 +00:00
db = getSchema();
Railway = db.define('Railway', {
2016-08-19 17:46:59 +00:00
URID: {type: String, index: true},
}, {
scopes: {
highSpeed: {
where: {
2016-04-01 11:48:17 +00:00
highSpeed: true,
},
},
},
2013-04-11 23:56:51 +00:00
});
2014-01-24 17:09:53 +00:00
Station = db.define('Station', {
2016-08-19 17:46:59 +00:00
USID: {type: String, index: true},
capacity: {type: Number, index: true},
thoughput: {type: Number, index: true},
isActive: {type: Boolean, index: true},
isUndeground: {type: Boolean, index: true},
2013-04-11 23:56:51 +00:00
});
2014-01-24 17:09:53 +00:00
});
2013-04-11 23:56:51 +00:00
2016-04-01 11:48:17 +00:00
beforeEach(function(done) {
Railway.destroyAll(function() {
2014-01-24 17:09:53 +00:00
Station.destroyAll(done);
2013-04-11 23:56:51 +00:00
});
2014-01-24 17:09:53 +00:00
});
2016-04-01 11:48:17 +00:00
it('should define scope using options.scopes', function() {
Railway.scopes.should.have.property('highSpeed');
Railway.highSpeed.should.be.function;
});
2013-04-11 23:56:51 +00:00
2016-04-01 11:48:17 +00:00
it('should define scope with query', function(done) {
2016-08-19 17:46:59 +00:00
Station.scope('active', {where: {isActive: true}});
Station.scopes.should.have.property('active');
2016-04-01 11:48:17 +00:00
Station.active.create(function(err, station) {
if (err) return done(err);
2014-01-24 17:09:53 +00:00
should.exist(station);
should.exist(station.isActive);
station.isActive.should.be.true;
done();
2013-04-11 23:56:51 +00:00
});
2014-01-24 17:09:53 +00:00
});
2016-04-01 11:48:17 +00:00
it('should allow scope chaining', function(done) {
2016-08-19 17:46:59 +00:00
Station.scope('active', {where: {isActive: true}});
Station.scope('subway', {where: {isUndeground: true}});
2016-04-01 11:48:17 +00:00
Station.active.subway.create(function(err, station) {
if (err) return done(err);
2014-01-24 17:09:53 +00:00
should.exist(station);
station.isActive.should.be.true;
station.isUndeground.should.be.true;
done();
2016-04-01 11:48:17 +00:00
});
2014-01-24 17:09:53 +00:00
});
2013-04-11 23:56:51 +00:00
2016-04-01 11:48:17 +00:00
it('should query all', function(done) {
2016-08-19 17:46:59 +00:00
Station.scope('active', {where: {isActive: true}});
Station.scope('inactive', {where: {isActive: false}});
Station.scope('ground', {where: {isUndeground: true}});
2016-04-01 11:48:17 +00:00
Station.active.ground.create(function() {
Station.inactive.ground.create(function() {
Station.ground.inactive(function(err, ss) {
if (err) return done(err);
2014-01-24 17:09:53 +00:00
ss.should.have.lengthOf(1);
done();
2013-04-11 23:56:51 +00:00
});
2014-01-24 17:09:53 +00:00
});
2013-04-11 23:56:51 +00:00
});
2014-01-24 17:09:53 +00:00
});
2016-04-01 11:48:17 +00:00
it('should not cache any results', function(done) {
2016-08-19 17:46:59 +00:00
Station.scope('active', {where: {isActive: true}});
2016-04-01 11:48:17 +00:00
Station.active.create(function(err, s) {
if (err) return done(err);
s.isActive.should.be.true;
Station.active(function(err, ss) {
if (err) return done(err);
ss.should.have.lengthOf(1);
ss[0].id.should.eql(s.id);
s.updateAttribute('isActive', false, function(err, s) {
if (err) return done(err);
s.isActive.should.be.false;
Station.active(function(err, ss) {
if (err) return done(err);
ss.should.have.lengthOf(0);
done();
});
});
});
});
});
2013-04-11 23:56:51 +00:00
});
2016-04-01 11:48:17 +00:00
describe('scope - order', function() {
before(function() {
db = getSchema();
Station = db.define('Station', {
2016-08-19 17:46:59 +00:00
name: {type: String, index: true},
order: {type: Number, index: true},
});
2016-08-19 17:46:59 +00:00
Station.scope('reverse', {order: 'order DESC'});
});
2016-04-01 11:48:17 +00:00
beforeEach(function(done) {
Station.destroyAll(done);
});
2016-04-01 11:48:17 +00:00
beforeEach(function(done) {
2016-08-19 17:46:59 +00:00
Station.create({name: 'a', order: 1}, done);
});
2016-04-01 11:48:17 +00:00
beforeEach(function(done) {
2016-08-19 17:46:59 +00:00
Station.create({name: 'b', order: 2}, done);
});
2016-04-01 11:48:17 +00:00
beforeEach(function(done) {
2016-08-19 17:46:59 +00:00
Station.create({name: 'c', order: 3}, done);
});
2016-04-01 11:48:17 +00:00
it('should define scope with default order', function(done) {
Station.reverse(function(err, stations) {
if (err) return done(err);
stations[0].name.should.equal('c');
stations[0].order.should.equal(3);
stations[1].name.should.equal('b');
stations[1].order.should.equal(2);
stations[2].name.should.equal('a');
stations[2].order.should.equal(1);
done();
});
});
2016-04-01 11:48:17 +00:00
it('should override default scope order', function(done) {
2016-08-19 17:46:59 +00:00
Station.reverse({order: 'order ASC'}, function(err, stations) {
if (err) return done(err);
stations[0].name.should.equal('a');
stations[0].order.should.equal(1);
stations[1].name.should.equal('b');
stations[1].order.should.equal(2);
stations[2].name.should.equal('c');
stations[2].order.should.equal(3);
done();
});
});
});
2016-04-01 11:48:17 +00:00
describe('scope - filtered count, updateAll and destroyAll', function() {
2018-12-07 14:54:29 +00:00
let stationA;
2015-03-20 15:37:46 +00:00
2016-04-01 11:48:17 +00:00
before(function() {
db = getSchema();
Station = db.define('Station', {
2016-08-19 17:46:59 +00:00
name: {type: String, index: true},
order: {type: Number, index: true},
active: {type: Boolean, index: true, default: true},
flagged: {type: Boolean, index: true, default: false},
});
2016-08-19 17:46:59 +00:00
Station.scope('ordered', {order: 'order'});
Station.scope('active', {where: {active: true}});
Station.scope('inactive', {where: {active: false}});
Station.scope('flagged', {where: {flagged: true}});
});
2016-04-01 11:48:17 +00:00
beforeEach(function(done) {
Station.destroyAll(done);
});
2016-04-01 11:48:17 +00:00
beforeEach(function(done) {
2016-08-19 17:46:59 +00:00
Station.create({name: 'b', order: 2, active: false}, done);
});
2016-04-01 11:48:17 +00:00
beforeEach(function(done) {
2016-08-19 17:46:59 +00:00
Station.create({name: 'a', order: 1}, function(err, inst) {
if (err) return done(err);
2015-03-20 15:37:46 +00:00
stationA = inst;
done();
});
});
2016-04-01 11:48:17 +00:00
beforeEach(function(done) {
2016-08-19 17:46:59 +00:00
Station.create({name: 'd', order: 4, active: false}, done);
});
2016-04-01 11:48:17 +00:00
beforeEach(function(done) {
2016-08-19 17:46:59 +00:00
Station.create({name: 'c', order: 3}, done);
});
it('should find all - verify', function(done) {
Station.ordered(function(err, stations) {
if (err) return done(err);
2016-04-01 11:48:17 +00:00
stations.should.have.length(4);
stations[0].name.should.equal('a');
stations[1].name.should.equal('b');
stations[2].name.should.equal('c');
stations[3].name.should.equal('d');
done();
});
});
2015-03-21 12:44:06 +00:00
it('should find one', function(done) {
Station.active.findOne(function(err, station) {
if (err) return done(err);
2016-04-01 11:48:17 +00:00
station.name.should.equal('a');
done();
2015-03-21 12:44:06 +00:00
});
});
2015-03-21 12:44:06 +00:00
it('should find one - with filter', function(done) {
2016-08-19 17:46:59 +00:00
Station.active.findOne({where: {name: 'c'}}, function(err, station) {
if (err) return done(err);
2016-04-01 11:48:17 +00:00
station.name.should.equal('c');
done();
2015-03-21 12:44:06 +00:00
});
});
2015-03-20 15:37:46 +00:00
it('should find by id - match', function(done) {
Station.active.findById(stationA.id, function(err, station) {
if (err) return done(err);
2016-04-01 11:48:17 +00:00
station.name.should.equal('a');
done();
2015-03-20 15:37:46 +00:00
});
});
2015-03-20 15:37:46 +00:00
it('should find by id - no match', function(done) {
Station.inactive.findById(stationA.id, function(err, station) {
if (err) return done(err);
2016-04-01 11:48:17 +00:00
should.not.exist(station);
done();
2015-03-20 15:37:46 +00:00
});
});
it('should count all in scope - active', function(done) {
Station.active.count(function(err, count) {
if (err) return done(err);
2016-04-01 11:48:17 +00:00
count.should.equal(2);
done();
});
});
it('should count all in scope - inactive', function(done) {
Station.inactive.count(function(err, count) {
if (err) return done(err);
2016-04-01 11:48:17 +00:00
count.should.equal(2);
done();
});
});
it('should count filtered - active', function(done) {
2016-08-19 17:46:59 +00:00
Station.active.count({order: {gt: 1}}, function(err, count) {
if (err) return done(err);
2016-04-01 11:48:17 +00:00
count.should.equal(1);
done();
});
});
it('should count filtered - inactive', function(done) {
2016-08-19 17:46:59 +00:00
Station.inactive.count({order: 2}, function(err, count) {
if (err) return done(err);
2016-04-01 11:48:17 +00:00
count.should.equal(1);
done();
});
});
2015-03-28 20:25:24 +00:00
it('should allow updateAll', function(done) {
2016-08-19 17:46:59 +00:00
Station.inactive.updateAll({flagged: true}, function(err, result) {
if (err) return done(err);
2016-04-01 11:48:17 +00:00
result.count.should.equal(2);
verify();
2015-03-28 20:25:24 +00:00
});
2018-12-07 15:22:36 +00:00
function verify() {
2015-03-28 20:25:24 +00:00
Station.flagged.count(function(err, count) {
if (err) return done(err);
2015-03-28 20:25:24 +00:00
count.should.equal(2);
done();
});
2018-12-07 14:54:29 +00:00
}
2015-03-28 20:25:24 +00:00
});
it('should allow filtered updateAll', function(done) {
2016-08-19 17:46:59 +00:00
Station.ordered.updateAll({active: true}, {flagged: true}, function(err, result) {
if (err) return done(err);
2016-04-01 11:48:17 +00:00
result.count.should.equal(2);
verify();
2015-03-28 20:25:24 +00:00
});
2018-12-07 15:22:36 +00:00
function verify() {
2015-03-28 20:25:24 +00:00
Station.flagged.count(function(err, count) {
if (err) return done(err);
2015-03-28 20:25:24 +00:00
count.should.equal(2);
done();
});
2018-12-07 14:54:29 +00:00
}
2015-03-28 20:25:24 +00:00
});
it('should allow filtered destroyAll', function(done) {
2016-08-19 17:46:59 +00:00
Station.ordered.destroyAll({active: false}, function(err) {
if (err) return done(err);
2016-04-01 11:48:17 +00:00
verify();
});
2018-12-07 15:22:36 +00:00
function verify() {
Station.ordered.count(function(err, count) {
if (err) return done(err);
count.should.equal(2);
Station.inactive.count(function(err, count) {
if (err) return done(err);
2016-04-01 11:48:17 +00:00
count.should.equal(0);
done();
});
});
2018-12-07 14:54:29 +00:00
}
});
});
2016-04-01 11:48:17 +00:00
describe('scope - dynamic target class', function() {
2018-12-07 14:54:29 +00:00
let Collection, Image, Video;
2016-04-01 11:48:17 +00:00
before(function() {
db = getSchema();
2016-08-19 17:46:59 +00:00
Image = db.define('Image', {name: String});
Video = db.define('Video', {name: String});
2016-08-19 17:46:59 +00:00
Collection = db.define('Collection', {name: String, modelName: String});
2014-08-30 19:08:23 +00:00
Collection.scope('items', function() {
return {}; // could return a scope based on `this` (receiver)
2016-08-19 17:46:59 +00:00
}, null, {}, {isStatic: false, modelTo: function(receiver) {
return db.models[receiver.modelName];
2016-08-19 17:46:59 +00:00
}});
});
2016-04-01 11:48:17 +00:00
beforeEach(function(done) {
Collection.destroyAll(function() {
Image.destroyAll(function() {
Video.destroyAll(done);
2016-04-01 11:48:17 +00:00
});
});
});
2016-04-01 11:48:17 +00:00
beforeEach(function(done) {
2016-08-19 17:46:59 +00:00
Collection.create({name: 'Images', modelName: 'Image'}, done);
});
2016-04-01 11:48:17 +00:00
beforeEach(function(done) {
2016-08-19 17:46:59 +00:00
Collection.create({name: 'Videos', modelName: 'Video'}, done);
});
2016-04-01 11:48:17 +00:00
beforeEach(function(done) {
2016-08-19 17:46:59 +00:00
Collection.create({name: 'Things', modelName: 'Unknown'}, done);
});
2016-04-01 11:48:17 +00:00
beforeEach(function(done) {
2016-08-19 17:46:59 +00:00
Image.create({name: 'Image A'}, done);
});
2016-04-01 11:48:17 +00:00
beforeEach(function(done) {
2016-08-19 17:46:59 +00:00
Video.create({name: 'Video A'}, done);
});
it('should deduce modelTo at runtime - Image', function(done) {
2016-08-19 17:46:59 +00:00
Collection.findOne({where: {modelName: 'Image'}}, function(err, coll) {
if (err) return done(err);
coll.name.should.equal('Images');
coll.items(function(err, items) {
if (err) return done(err);
items.length.should.equal(1);
items[0].name.should.equal('Image A');
items[0].should.be.instanceof(Image);
done();
});
});
});
it('should deduce modelTo at runtime - Video', function(done) {
2016-08-19 17:46:59 +00:00
Collection.findOne({where: {modelName: 'Video'}}, function(err, coll) {
if (err) return done(err);
coll.name.should.equal('Videos');
coll.items(function(err, items) {
if (err) return done(err);
items.length.should.equal(1);
items[0].name.should.equal('Video A');
items[0].should.be.instanceof(Video);
done();
});
});
});
it('should throw if modelTo is invalid', function(done) {
2016-08-19 17:46:59 +00:00
Collection.findOne({where: {name: 'Things'}}, function(err, coll) {
if (err) return done(err);
coll.modelName.should.equal('Unknown');
2016-04-01 11:48:17 +00:00
(function() {
coll.items(function(err, items) {});
}).should.throw();
done();
});
});
});
2016-04-01 11:48:17 +00:00
describe('scope - dynamic function', function() {
2018-12-07 14:54:29 +00:00
let Item, seed = 0;
2016-04-01 11:48:17 +00:00
before(function() {
db = getSchema();
2016-08-19 17:46:59 +00:00
Item = db.define('Item', {title: Number, creator: Number});
2016-04-01 11:48:17 +00:00
Item.scope('dynamicQuery', function() {
seed++;
2016-08-19 17:46:59 +00:00
return {where: {creator: seed}};
2016-04-01 11:48:17 +00:00
});
});
2016-04-01 11:48:17 +00:00
beforeEach(function(done) {
2016-08-19 17:46:59 +00:00
Item.create({title: 1, creator: 1}, function() {
Item.create({title: 2, creator: 2}, done);
2016-04-01 11:48:17 +00:00
});
});
2016-04-01 11:48:17 +00:00
it('should deduce item by runtime creator', function(done) {
Item.dynamicQuery.findOne(function(err, firstQuery) {
if (err) return done(err);
firstQuery.title.should.equal(1);
2016-04-01 11:48:17 +00:00
Item.dynamicQuery.findOne(function(err, secondQuery) {
if (err) return done(err);
secondQuery.title.should.equal(2);
done();
2016-04-01 11:48:17 +00:00
});
});
});
2014-08-30 19:08:23 +00:00
});