不要怂,就是干,撸起袖子干!

Commit efc4649d by Jan Aagaard Meier

test(scopes) Test for scopes between associated models. 🎨 Slight changes to …

…model.scope and conform options
1 parent fe5a85b0
...@@ -310,10 +310,7 @@ module.exports = (function() { ...@@ -310,10 +310,7 @@ module.exports = (function() {
, throughWhere; , throughWhere;
if (association.scope) { if (association.scope) {
scopeWhere = {}; scopeWhere = _.clone(association.scope);
Object.keys(association.scope).forEach(function (attribute) {
scopeWhere[attribute] = association.scope[attribute];
}.bind(this));
} }
options.where = { options.where = {
......
...@@ -193,6 +193,12 @@ module.exports = (function() { ...@@ -193,6 +193,12 @@ module.exports = (function() {
this.__scope = _.isPlainObject(this.options.defaultScope) ? this.options.defaultScope : {}; this.__scope = _.isPlainObject(this.options.defaultScope) ? this.options.defaultScope : {};
_.each(this.options.scopes, function (scope) {
if (_.isPlainObject(scope) && scope.include) {
conformOptions(scope);
}
});
// Instance prototype // Instance prototype
this.Instance = this.DAO = function() { this.Instance = this.DAO = function() {
Instance.apply(this, arguments); Instance.apply(this, arguments);
...@@ -556,7 +562,7 @@ module.exports = (function() { ...@@ -556,7 +562,7 @@ module.exports = (function() {
scope = option; scope = option;
} }
} else { } else {
if (option === 'defaultScope') { if (option === 'defaultScope' && _.isPlainObject(self.options.defaultScope)) {
scope = self.options.defaultScope; scope = self.options.defaultScope;
} else { } else {
scopeName = option; scopeName = option;
...@@ -569,12 +575,14 @@ module.exports = (function() { ...@@ -569,12 +575,14 @@ module.exports = (function() {
} }
if (!!scope) { if (!!scope) {
_.assign(self.__scope, scope, function scopeCustomizer(a, b, key) { _.assign(self.__scope, scope, function scopeCustomizer(objectValue, sourceValue, key) {
if (key === 'where') { if (key === 'where') {
return _.assign(a || {}, b); return _.assign(objectValue || {}, sourceValue);
} else if (key === 'include' && Array.isArray(objectValue) && Array.isArray(sourceValue)) {
return objectValue.concat(sourceValue);
} }
return a ? a : b; return objectValue ? objectValue : sourceValue;
}); });
} else { } else {
throw new Error('Invalid scope ' + scopeName + ' called.'); throw new Error('Invalid scope ' + scopeName + ' called.');
...@@ -680,10 +688,10 @@ module.exports = (function() { ...@@ -680,10 +688,10 @@ module.exports = (function() {
_.defaults(options, { hooks: true }); _.defaults(options, { hooks: true });
_.assign(options, queryOptions); _.assign(options, queryOptions);
this.__injectScope(options);
return Promise.bind(this).then(function() { return Promise.bind(this).then(function() {
conformOptions(options, this); conformOptions(options, this);
this.__injectScope(options);
if (options.hooks) { if (options.hooks) {
return this.runHooks('beforeFind', options); return this.runHooks('beforeFind', options);
...@@ -1771,9 +1779,20 @@ module.exports = (function() { ...@@ -1771,9 +1779,20 @@ module.exports = (function() {
} }
}; };
// Inject current scope into options. Includes should have been conformed (conformOptions) before calling this
Model.prototype.__injectScope = function (options) { Model.prototype.__injectScope = function (options) {
_.defaults(options, this.__scope); _.defaults(options, this.__scope);
_.defaults(options.where, this.__scope.where); _.defaults(options.where, this.__scope.where);
if (options.include && this.__scope.include) {
this.__scope.include.forEach(function (scopeInclude) {
if (!_.any(options.include, function (optionInclude) {
return optionInclude.model.name === scopeInclude.model.name;
})) {
options.include.push(scopeInclude);
}
});
}
}; };
// private // private
...@@ -1928,6 +1947,10 @@ module.exports = (function() { ...@@ -1928,6 +1947,10 @@ module.exports = (function() {
} else { } else {
model = include.association.target; model = include.association.target;
} }
if (!include.model) {
include.model = model;
}
} else { } else {
model = include.model; model = include.model;
} }
......
...@@ -315,7 +315,7 @@ if (dialect.match(/^postgres/)) { ...@@ -315,7 +315,7 @@ if (dialect.match(/^postgres/)) {
) )
}; };
}], }],
expectation: 'SELECT * FROM "myTable" WHERE ("myTable"."archived" IS NULL AND COALESCE("place_type_codename", "announcement_type_codename") IN (\'Lost\',\'Found\'));', expectation: 'SELECT * FROM "myTable" WHERE ("myTable"."archived" IS NULL AND COALESCE("place_type_codename", "announcement_type_codename") IN (\'Lost\', \'Found\'));',
context: QueryGenerator, context: QueryGenerator,
needsSequelize: true needsSequelize: true
}, { }, {
...@@ -939,47 +939,6 @@ if (dialect.match(/^postgres/)) { ...@@ -939,47 +939,6 @@ if (dialect.match(/^postgres/)) {
expectation: 'DROP INDEX IF EXISTS mySchema.user_foo_bar', expectation: 'DROP INDEX IF EXISTS mySchema.user_foo_bar',
context: {options: {quoteIdentifiers: false}} context: {options: {quoteIdentifiers: false}}
} }
],
hashToWhereConditions: [
{
arguments: [{ id: [1, 2, 3] }],
expectation: '\"id\" IN (1,2,3)'
},
{
arguments: [{ id: [] }],
expectation: '\"id\" IN (NULL)'
},
{
arguments: [{id: {not: [1, 2, 3] }}],
expectation: '\"id\" NOT IN (1,2,3)'
},
{
arguments: [{id: {not: [] }}],
expectation: '\"id\" NOT IN (NULL)'
},
// Variants when quoteIdentifiers is false
{
arguments: [{ id: [1, 2, 3] }],
expectation: 'id IN (1,2,3)',
context: {options: {quoteIdentifiers: false}}
},
{
arguments: [{ id: [] }],
expectation: 'id IN (NULL)',
context: {options: {quoteIdentifiers: false}}
},
{
arguments: [{ id: {not: [1, 2, 3] }}],
expectation: 'id NOT IN (1,2,3)',
context: {options: {quoteIdentifiers: false}}
},
{
arguments: [{ id: {not: [] }}],
expectation: 'id NOT IN (NULL)',
context: {options: {quoteIdentifiers: false}}
}
] ]
}; };
......
...@@ -27,40 +27,16 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -27,40 +27,16 @@ describe(Support.getTestDialectTeaser('Model'), function() {
} }
}, },
scopes: { scopes: {
highValue: {
where: {
other_value: {
gte: 10
}
}
},
isTony: { isTony: {
where: { where: {
username: 'tony' username: 'tony'
} }
}, },
actualValue: function(value) {
return {
where: {
other_value: value
}
};
},
lowAccess: {
where: {
access_level: {
lte: 5
}
}
},
escape: {
where: {
username: "escape'd"
}
}
} }
}); });
this.Project = this.sequelize.define('project');
this.Company = this.sequelize.define('company', { this.Company = this.sequelize.define('company', {
active: Sequelize.BOOLEAN active: Sequelize.BOOLEAN
}, { }, {
...@@ -73,35 +49,46 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -73,35 +49,46 @@ describe(Support.getTestDialectTeaser('Model'), function() {
active: false active: false
} }
}, },
users: {
include: [
{ model: this.ScopeMe.unscoped(), as: 'users'}
]
},
reversed: { reversed: {
order: [['id', 'DESC']] order: [['id', 'DESC']]
} }
} }
}); });
this.Project = this.sequelize.define('Project'); this.Profile = this.sequelize.define('profile', {
active: Sequelize.BOOLEAN
}, {
defaultScope: {
where: { active: true }
},
scopes: {
notActive: {
where: {
active: false
}
},
}
});
this.Project.belongsToMany(this.Company, { through: 'CompanyProjects' }); this.Project.belongsToMany(this.Company, { through: 'CompanyProjects' });
this.Company.belongsToMany(this.Project, { through: 'CompanyProjects' }); this.Company.belongsToMany(this.Project, { through: 'CompanyProjects' });
this.ScopeMe.hasOne(this.Profile, { foreignKey: 'userId' });
this.ScopeMe.belongsTo(this.Company); this.ScopeMe.belongsTo(this.Company);
this.UserAssociation = this.Company.hasMany(this.ScopeMe, { as: 'users'}); this.UserAssociation = this.Company.hasMany(this.ScopeMe, { as: 'users'});
return this.sequelize.sync({force: true}).bind(this).then(function() { return this.sequelize.sync({force: true}).bind(this).then(function() {
return Promise.all([ return Promise.all([
this.ScopeMe.create({username: 'dan', email: 'dan@sequelizejs.com', access_level: 5, other_value: 10, parent_id: 1}), this.ScopeMe.create({ id: 1, username: 'dan', email: 'dan@sequelizejs.com', access_level: 5, other_value: 10, parent_id: 1}),
this.ScopeMe.create({username: 'tobi', email: 'tobi@fakeemail.com', access_level: 10, other_value: 11, parent_id: 2}), this.ScopeMe.create({ id: 2, username: 'tobi', email: 'tobi@fakeemail.com', access_level: 10, other_value: 11, parent_id: 2}),
this.ScopeMe.create({username: 'tony', email: 'tony@sequelizejs.com', access_level: 3, other_value: 7, parent_id: 1}), this.ScopeMe.create({ id: 3, username: 'tony', email: 'tony@sequelizejs.com', access_level: 3, other_value: 7, parent_id: 1}),
this.ScopeMe.create({username: 'fred', email: 'fred@foobar.com', access_level: 3, other_value: 7, parent_id: 1}), this.ScopeMe.create({ id: 4, username: 'fred', email: 'fred@foobar.com', access_level: 3, other_value: 7, parent_id: 1}),
this.Company.create({active:true}), this.Company.create({ id: 1, active: true}),
this.Company.create({active:false}), this.Company.create({ id: 2, active: false}),
this.ScopeMe.create({username: 'bob', email: 'bob@foobar.com', access_level: 1, other_value: 9, parent_id: 5}), this.ScopeMe.create({ id: 5, username: 'bob', email: 'bob@foobar.com', access_level: 1, other_value: 9, parent_id: 5}),
]); ]);
}).spread(function (u1, u2, u3, u4, c1, c2, u5) { }).spread(function (u1, u2, u3, u4, c1, c2, u5, proj1, prof1) {
return Promise.all([ return Promise.all([
c1.setUsers([u1, u2, u3, u4]), c1.setUsers([u1, u2, u3, u4]),
c2.setUsers([u5]) c2.setUsers([u5])
...@@ -110,61 +97,36 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -110,61 +97,36 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}); });
describe('include', function () { describe('include', function () {
describe('target', function () { it('should scope columns properly', function () {
it('should scope columns properly', function () { // Will error with ambigous column if id is not scoped properly to `Company`.`id`
// Will error with ambigous column if id is not scoped properly to `Company`.`id` return expect(this.Company.findAll({
return expect(this.Company.findAll({ where: { id: 1 },
where: { id: 1}, include: [this.UserAssociation]
include: [this.UserAssociation] })).not.to.be.rejected;
})).to.be.resolved;
});
it('should apply default scope when including an associations', function () {
return this.Company.findAll({
include: [this.UserAssociation]
}).get(0).then(function (company) {
expect(company.users).to.have.length(2);
});
});
it('should apply default scope when including a model', function () {
return this.Company.findAll({
include: [{ model: this.ScopeMe, as: 'users'}]
}).get(0).then(function (company) {
expect(company.users).to.have.length(2);
});
});
it('should be able to include a scoped model', function () {
return this.Company.findAll({
include: [{ model: this.ScopeMe.scope('isTony'), as: 'users'}]
}).get(0).then(function (company) {
expect(company.users).to.have.length(1);
expect(company.users[0].get('username')).to.equal('tony');
});
});
}); });
describe('source', function () { it('should apply default scope when including an associations', function () {
it('should include model with scope', function () { return this.Company.findAll({
return this.Company.scope('users').findAll({ where: { id: 1 } }).get(0).then(function (company) { include: [this.UserAssociation]
expect(company.users).to.have.length(4); }).get(0).then(function (company) {
}); expect(company.users).to.have.length(2);
}); });
});
it('should be able to override scoped include', function () { it('should apply default scope when including a model', function () {
return this.Company.scope('users').findAll({ return this.Company.findAll({
include: [ include: [{ model: this.ScopeMe, as: 'users'}]
{ association: this.UserAssociation, where: { username: 'dan'} } }).get(0).then(function (company) {
] expect(company.users).to.have.length(2);
}).get(0).then(function (company) {
expect(company.users).to.have.length(1);
expect(company.users[0].get('username')).to.equal('dan');
});
}); });
});
it('should be able to append to includes', function () { it('should be able to include a scoped model', function () {
// ? or should it return this.Company.findAll({
include: [{ model: this.ScopeMe.scope('isTony'), as: 'users'}]
}).get(0).then(function (company) {
expect(company.users).to.have.length(1);
expect(company.users[0].get('username')).to.equal('tony');
}); });
}); });
}); });
...@@ -189,7 +151,16 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -189,7 +151,16 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}); });
it('hasOne', function () { it('hasOne', function () {
return this.Profile.create({
active: false,
userId: 1
}).bind(this).then(function () {
return this.ScopeMe.find(1);
}).then(function (user) {
return user.getProfile({ scope: false });
}).then(function (project) {
expect(project).to.be.ok;
});
}); });
it('belongsTo', function () { it('belongsTo', function () {
...@@ -219,13 +190,18 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -219,13 +190,18 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}); });
it('hasOne', function () { it('hasOne', function () {
return this.Profile.create({
active: false,
userId: 1
}).bind(this).then(function () {
return this.ScopeMe.find(1);
}).then(function (user) {
return user.getProfile();
}).then(function (project) {
expect(project).not.to.be.ok;
});
}); });
it('hasMany double', function () {
// Do we need to - it's deprecated?
})
it('belongsTo', function () { it('belongsTo', function () {
return this.ScopeMe.unscoped().find({ where: { username: 'bob' }}).then(function (user) { return this.ScopeMe.unscoped().find({ where: { username: 'bob' }}).then(function (user) {
return user.getCompany(); return user.getCompany();
...@@ -255,7 +231,16 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -255,7 +231,16 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}); });
it('hasOne', function () { it('hasOne', function () {
return this.Profile.create({
active: true,
userId: 1
}).bind(this).then(function () {
return this.ScopeMe.find(1);
}).then(function (user) {
return user.getProfile({ scope: 'notActive' });
}).then(function (project) {
expect(project).not.to.be.ok;
});
}); });
it('belongsTo', function () { it('belongsTo', function () {
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
var chai = require('chai') var chai = require('chai')
, Sequelize = require('../../../../index') , Sequelize = require('../../../../index')
, expect = chai.expect , expect = chai.expect
, Promise = Sequelize.Promise
, Support = require(__dirname + '/../../support'); , Support = require(__dirname + '/../../support');
describe(Support.getTestDialectTeaser('Model'), function() { describe(Support.getTestDialectTeaser('Model'), function() {
...@@ -26,12 +25,6 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -26,12 +25,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
} }
}, },
scopes: { scopes: {
orderScope: {
order: 'access_level DESC'
},
limitScope: {
limit: 2
},
highValue: { highValue: {
where: { where: {
other_value: { other_value: {
...@@ -39,54 +32,6 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -39,54 +32,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
} }
} }
}, },
isTony: {
where: {
username: 'tony'
}
},
sequelizeTeam: {
where: {
email: {
like: '%@sequelizejs.com'
}
}
},
noArgs: function () {
// This does not make much sense, since it does not actually need to be in a function,
// In reality it could be used to do for example new Date or random in the scope - but we want it deterministic
return {
where: {
other_value: 7
}
};
},
actualValue: function(value) {
return {
where: {
other_value: value
}
};
},
complexFunction: function(username, accessLevel) {
return {
where: {
username: {
like: username
},
access_level: {
gte: accessLevel
}
}
};
},
lowAccess: {
where: {
access_level: {
lte: 5
}
}
},
andScope: { andScope: {
where: { where: {
$and: [ $and: [
...@@ -138,49 +83,6 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -138,49 +83,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}); });
}); });
it('should be able to amend the default scope with a find object', function() {
return this.ScopeMe.findAll({where: {username: 'dan'}}).then(function(users) {
expect(users).to.have.length(1);
expect(users[0].username).to.equal('dan');
});
});
it('should be able to override the default scope', function() {
return this.ScopeMe.scope('sequelizeTeam').findAll().then(function(users) {
expect(users).to.have.length(2);
expect(users[0].username).to.equal('tony');
expect(users[1].username).to.equal('dan');
});
});
it('should be able to combine two scopes', function() {
return this.ScopeMe.scope(['sequelizeTeam', 'highValue']).findAll().then(function(users) {
expect(users).to.have.length(1);
expect(users[0].username).to.equal('dan');
});
});
it('should be able to combine default with another scope', function () {
return this.ScopeMe.scope(['defaultScope', {method: ['actualValue', 11]}]).findAll().then(function(users) {
expect(users).to.have.length(1);
expect(users[0].username).to.equal('tobi');
});
});
it("should be able to call a scope that's a function", function() {
return this.ScopeMe.scope({method: ['actualValue', 11]}).findAll().then(function(users) {
expect(users).to.have.length(1);
expect(users[0].username).to.equal('tobi');
});
});
it('should be able to handle multiple function scopes', function() {
return this.ScopeMe.scope([{method: ['actualValue', 10]}, {method: ['complexFunction', 'dan', '5']}]).findAll().then(function(users) {
expect(users).to.have.length(1);
expect(users[0].username).to.equal('dan');
});
});
it('should be able to handle $and in scopes', function () { it('should be able to handle $and in scopes', function () {
return this.ScopeMe.scope('andScope').findAll().then(function(users) { return this.ScopeMe.scope('andScope').findAll().then(function(users) {
expect(users).to.have.length(1); expect(users).to.have.length(1);
...@@ -188,13 +90,6 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -188,13 +90,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}); });
}); });
it('should be able to merge scopes', function() {
return this.ScopeMe.scope(['highValue', 'isTony', {merge: true, method: ['actualValue', 7]}]).findAll().then(function(users) {
expect(users).to.have.length(1);
expect(users[0].username).to.equal('tony');
});
});
describe('should not overwrite', function() { describe('should not overwrite', function() {
it('default scope with values from previous finds', function() { it('default scope with values from previous finds', function() {
return this.ScopeMe.findAll({ where: { other_value: 10 }}).bind(this).then(function(users) { return this.ScopeMe.findAll({ where: { other_value: 10 }}).bind(this).then(function(users) {
...@@ -218,44 +113,6 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -218,44 +113,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(users).to.have.length(2); expect(users).to.have.length(2);
}); });
}); });
it('function scopes', function() {
return Promise.all([
this.ScopeMe.scope({method: ['actualValue', 11]}).findAll(),
this.ScopeMe.scope({method: ['actualValue', 10]}).findAll(),
this.ScopeMe.scope('noArgs').findAll()
]).spread(function (users1, users2, users3) {
expect(users1).to.have.length(1);
expect(users1[0].other_value).to.equal(11);
expect(users2).to.have.length(1);
expect(users2[0].other_value).to.equal(10);
expect(users3).to.have.length(2);
expect(users3[0].other_value).to.equal(7);
expect(users3[1].other_value).to.equal(7);
});
});
});
it('should give us the correct order if we declare an order in our scope', function() {
return this.ScopeMe.scope('sequelizeTeam', 'orderScope').findAll().then(function(users) {
expect(users).to.have.length(2);
expect(users[0].username).to.equal('dan');
expect(users[1].username).to.equal('tony');
});
});
it('should give us the correct order as well as a limit if we declare such in our scope', function() {
return this.ScopeMe.scope(['orderScope', 'limitScope']).findAll().then(function(users) {
expect(users).to.have.length(2);
expect(users[0].username).to.equal('tobi');
expect(users[1].username).to.equal('dan');
});
});
it('should be able to remove all scopes', function() {
return expect(this.ScopeMe.scope(null).findAll()).to.eventually.have.length(4);
}); });
it('should have no problem performing findOrCreate', function() { it('should have no problem performing findOrCreate', function() {
...@@ -263,25 +120,5 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -263,25 +120,5 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(user.username).to.equal('fake'); expect(user.username).to.equal('fake');
}); });
}); });
it('should be able to hold multiple scope objects', function() {
var sequelizeTeam = this.ScopeMe.scope('sequelizeTeam', 'orderScope')
, tobi = this.ScopeMe.scope({method: ['actualValue', 11]});
return sequelizeTeam.all().then(function(team) {
return tobi.all().then(function(t) {
expect(team).to.have.length(2);
expect(team[0].username).to.equal('dan');
expect(team[1].username).to.equal('tony');
expect(t).to.have.length(1);
expect(t[0].username).to.equal('tobi');
});
});
});
it("should emit an error for scopes that don't exist", function() {
expect(this.ScopeMe.scope.bind(this.ScopeMe, 'doesntexist', {silent: false})).to.throw('Invalid scope doesntexist called.');
});
}); });
}); });
'use strict';
/* jshint -W030 */
var chai = require('chai')
, expect = chai.expect
, Support = require(__dirname + '/../support')
, current = Support.sequelize;
describe(Support.getTestDialectTeaser('Model'), function() {
var Project = current.define('project')
, User = current.define('user')
, Company;
var scopes = {
somethingTrue: {
where: {
something: true,
somethingElse: 42
},
limit: 5
},
somethingFalse: {
where: {
something: false
}
},
users: {
include: [
{ model: User }
]
},
alsoUsers: {
include: [
{ model: User, where: { something: 42}}
]
},
projects: {
include: [Project]
},
noArgs: function () {
// This does not make much sense, since it does not actually need to be in a function,
// In reality it could be used to do for example new Date or random in the scope - but we want it deterministic
return {
where: {
other_value: 7
}
};
},
actualValue: function(value) {
return {
where: {
other_value: value
}
};
},
};
Company = current.define('company', {}, {
defaultScope: {
where: { active: true }
},
scopes: scopes
});
describe('.scope', function () {
it('should apply default scope', function () {
expect(Company.$scope).to.deep.equal({ where: { active: true }});
});
it('should be able to unscope', function () {
expect(Company.scope(null).$scope).to.be.empty;
expect(Company.unscoped().$scope).to.be.empty;
});
it('should be able to merge scopes', function() {
expect(Company.scope('somethingTrue', 'somethingFalse').$scope).to.deep.equal({
where: {
something: false,
somethingElse: 'cat'
},
limit: 5
});
});
it('should support multiple, coexistent scoped models', function () {
var scoped1 = Company.scope('somethingTrue')
, scoped2 = Company.scope('somethingFalse');
expect(scoped1.$scope).to.deep.equal(scopes.somethingTrue);
expect(scoped2.$scope).to.deep.equal(scopes.somethingFalse);
});
it('should work with function scopes', function () {
expect(Company.scope({method: ['actualValue', 11]}).$scope).to.deep.equal({
where: {
other_value: 11
}
});
expect(Company.scope('noArgs').$scope).to.deep.equal({
where: {
other_value: 7
}
});
});
it('should be able to merge two scoped includes', function () {
expect(Company.scope('users', 'projects').$scope).to.deep.equal({
include: [
{ model: User },
{ model: Project }
]
});
});
it('should be able to override the default scope', function() {
expect(Company.scope('somethingTrue').$scope).to.deep.equal(scopes.somethingTrue);
});
it('should be able to combine default with another scope', function () {
expect(Company.scope(['defaultScope', {method: ['actualValue', 11]}]).$scope).to.deep.equal({
where: {
active: true,
other_value: 11
}
});
});
it('should emit an error for scopes that dont exist', function() {
expect(function () {
Company.scope('doesntexist');
}).to.throw('Invalid scope doesntexist called.');
});
});
describe('$injectScope', function () {
it('should be able to merge scope and where', function () {
var scope = {
where: {
something: true,
somethingElse: 42
},
limit: 15,
offset: 3
};
var options = {
where: {
something: false
},
limit: 9
};
current.Model.$injectScope(scope, options);
expect(options).to.deep.equal({
where: {
something: false,
somethingElse: 42
},
limit: 9,
offset: 3
});
});
it('should be able to overwrite multiple scopes with the same include', function () {
var scope = {
include: [
{ model: Project, where: { something: false }},
{ model: Project, where: { something: true }}
]
};
var options = {};
current.Model.$injectScope(scope, options);
expect(options.include).to.have.length(1);
expect(options.include[0]).to.deep.equal({ model: Project, where: { something: true }});
});
it('should be able to override scoped include', function () {
var scope = {
include: [{ model: Project, where: { something: false }}]
};
var options = {
include: [{ model: Project, where: { something: true }}]
};
current.Model.$injectScope(scope, options);
expect(options.include).to.have.length(1);
expect(options.include[0]).to.deep.equal({ model: Project, where: { something: true }});
});
it('should be able to merge scoped include with include in find', function () {
var scope = {
include: [
{ model: Project, where: { something: false }}
]
};
var options = {
include: [
{ model: User, where: { something: true }}
]
};
current.Model.$injectScope(scope, options);
expect(options.include).to.have.length(2);
expect(options.include[0]).to.deep.equal({ model: User, where: { something: true }});
expect(options.include[1]).to.deep.equal({ model: Project, where: { something: false }});
});
});
});
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!