Merge pull request #1594 from strongloop/upgrade-deps
Drop support for Node.js 4.x + update dependencies
This commit is contained in:
commit
751fd7b245
|
@ -1,8 +1,8 @@
|
||||||
sudo: false
|
sudo: false
|
||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- "4"
|
|
||||||
- "6"
|
- "6"
|
||||||
- "8"
|
- "8"
|
||||||
|
- "10"
|
||||||
|
|
||||||
after_success: npm run coverage
|
after_success: npm run coverage
|
||||||
|
|
|
@ -67,8 +67,8 @@ Transient.prototype.generateId = function(model, data, idName) {
|
||||||
return Math.floor(Math.random() * 10000); // max. 4 digits
|
return Math.floor(Math.random() * 10000); // max. 4 digits
|
||||||
} else {
|
} else {
|
||||||
return crypto.randomBytes(Math.ceil(24 / 2))
|
return crypto.randomBytes(Math.ceil(24 / 2))
|
||||||
.toString('hex') // convert to hexadecimal format
|
.toString('hex') // convert to hexadecimal format
|
||||||
.slice(0, 24); // return required number of characters
|
.slice(0, 24); // return required number of characters
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
28
lib/dao.js
28
lib/dao.js
|
@ -487,7 +487,7 @@ function stillConnecting(dataSource, obj, args) {
|
||||||
// promise variant
|
// promise variant
|
||||||
var promiseArgs = Array.prototype.slice.call(args);
|
var promiseArgs = Array.prototype.slice.call(args);
|
||||||
promiseArgs.callee = args.callee;
|
promiseArgs.callee = args.callee;
|
||||||
var cb = utils.createPromiseCallback();
|
var cb = utils.createPromiseCallback();
|
||||||
promiseArgs.push(cb);
|
promiseArgs.push(cb);
|
||||||
if (dataSource.ready(obj, promiseArgs)) {
|
if (dataSource.ready(obj, promiseArgs)) {
|
||||||
return cb.promise;
|
return cb.promise;
|
||||||
|
@ -801,7 +801,7 @@ DataAccessObject.upsertWithWhere = function(where, data, options, cb) {
|
||||||
function callConnector() {
|
function callConnector() {
|
||||||
try {
|
try {
|
||||||
// Support an optional where object
|
// Support an optional where object
|
||||||
var handleUndefined = Model._getSetting('normalizeUndefinedInQuery');
|
var handleUndefined = Model._getSetting('normalizeUndefinedInQuery');
|
||||||
// alter configuration of how removeUndefined handles undefined values
|
// alter configuration of how removeUndefined handles undefined values
|
||||||
ctx.where = removeUndefined(ctx.where, handleUndefined);
|
ctx.where = removeUndefined(ctx.where, handleUndefined);
|
||||||
ctx.where = Model._coerce(ctx.where, options);
|
ctx.where = Model._coerce(ctx.where, options);
|
||||||
|
@ -864,7 +864,7 @@ DataAccessObject.upsertWithWhere = function(where, data, options, cb) {
|
||||||
self.find({where: ctx.query.where}, opts, function(err, instances) {
|
self.find({where: ctx.query.where}, opts, function(err, instances) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
var modelsLength = instances.length;
|
var modelsLength = instances.length;
|
||||||
if (modelsLength === 0) {
|
if (modelsLength === 0) {
|
||||||
self.create(data, options, cb);
|
self.create(data, options, cb);
|
||||||
} else if (modelsLength === 1) {
|
} else if (modelsLength === 1) {
|
||||||
var modelInst = instances[0];
|
var modelInst = instances[0];
|
||||||
|
@ -1089,7 +1089,7 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)
|
||||||
// query will be built from data, and method will return Promise
|
// query will be built from data, and method will return Promise
|
||||||
data = query;
|
data = query;
|
||||||
query = {where: data};
|
query = {where: data};
|
||||||
} else if (options === undefined && cb === undefined) {
|
} else if (options === undefined && cb === undefined) {
|
||||||
if (typeof data === 'function') {
|
if (typeof data === 'function') {
|
||||||
// findOrCreate(data, cb);
|
// findOrCreate(data, cb);
|
||||||
// query will be built from data
|
// query will be built from data
|
||||||
|
@ -1517,7 +1517,7 @@ DataAccessObject._normalize = function(filter, options) {
|
||||||
}
|
}
|
||||||
if (isNaN(offset) || offset < 0 || Math.ceil(offset) !== offset) {
|
if (isNaN(offset) || offset < 0 || Math.ceil(offset) !== offset) {
|
||||||
err = new Error(g.f('The {{offset/skip}} parameter %j is not valid',
|
err = new Error(g.f('The {{offset/skip}} parameter %j is not valid',
|
||||||
filter.skip || filter.offset));
|
filter.skip || filter.offset));
|
||||||
err.statusCode = 400;
|
err.statusCode = 400;
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
@ -1574,7 +1574,7 @@ DataAccessObject._normalize = function(filter, options) {
|
||||||
Object.keys(this.definition.properties), this.settings.strict);
|
Object.keys(this.definition.properties), this.settings.strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
var handleUndefined = this._getSetting('normalizeUndefinedInQuery');
|
var handleUndefined = this._getSetting('normalizeUndefinedInQuery');
|
||||||
// alter configuration of how removeUndefined handles undefined values
|
// alter configuration of how removeUndefined handles undefined values
|
||||||
filter = removeUndefined(filter, handleUndefined);
|
filter = removeUndefined(filter, handleUndefined);
|
||||||
this._coerce(filter.where, options);
|
this._coerce(filter.where, options);
|
||||||
|
@ -2118,7 +2118,7 @@ DataAccessObject.find = function find(query, options, cb) {
|
||||||
if (options.notify === false) {
|
if (options.notify === false) {
|
||||||
invokeConnectorMethod(connector, 'all', self, [query], options, allCb);
|
invokeConnectorMethod(connector, 'all', self, [query], options, allCb);
|
||||||
} else {
|
} else {
|
||||||
var context = {
|
var context = {
|
||||||
Model: this,
|
Model: this,
|
||||||
query: query,
|
query: query,
|
||||||
hookState: hookState,
|
hookState: hookState,
|
||||||
|
@ -2271,7 +2271,7 @@ DataAccessObject.destroyAll = function destroyAll(where, options, cb) {
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
// Support an optional where object
|
// Support an optional where object
|
||||||
var handleUndefined = Model._getSetting('normalizeUndefinedInQuery');
|
var handleUndefined = Model._getSetting('normalizeUndefinedInQuery');
|
||||||
// alter configuration of how removeUndefined handles undefined values
|
// alter configuration of how removeUndefined handles undefined values
|
||||||
where = removeUndefined(where, handleUndefined);
|
where = removeUndefined(where, handleUndefined);
|
||||||
where = Model._coerce(where, options);
|
where = Model._coerce(where, options);
|
||||||
|
@ -2426,7 +2426,7 @@ DataAccessObject.count = function(where, options, cb) {
|
||||||
where = query.where;
|
where = query.where;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var handleUndefined = Model._getSetting('normalizeUndefinedInQuery');
|
var handleUndefined = Model._getSetting('normalizeUndefinedInQuery');
|
||||||
// alter configuration of how removeUndefined handles undefined values
|
// alter configuration of how removeUndefined handles undefined values
|
||||||
where = removeUndefined(where, handleUndefined);
|
where = removeUndefined(where, handleUndefined);
|
||||||
where = this._coerce(where, options);
|
where = this._coerce(where, options);
|
||||||
|
@ -2478,7 +2478,7 @@ DataAccessObject.prototype.save = function(options, cb) {
|
||||||
|
|
||||||
if (isPKMissing(Model, cb)) {
|
if (isPKMissing(Model, cb)) {
|
||||||
return cb.promise;
|
return cb.promise;
|
||||||
} else if (this.isNewRecord()) {
|
} else if (this.isNewRecord()) {
|
||||||
return Model.create(this, options, cb);
|
return Model.create(this, options, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2719,7 +2719,7 @@ DataAccessObject.updateAll = function(where, data, options, cb) {
|
||||||
function doUpdate(where, data) {
|
function doUpdate(where, data) {
|
||||||
try {
|
try {
|
||||||
// Support an optional where object
|
// Support an optional where object
|
||||||
var handleUndefined = Model._getSetting('normalizeUndefinedInQuery');
|
var handleUndefined = Model._getSetting('normalizeUndefinedInQuery');
|
||||||
// alter configuration of how removeUndefined handles undefined values
|
// alter configuration of how removeUndefined handles undefined values
|
||||||
where = removeUndefined(where, handleUndefined);
|
where = removeUndefined(where, handleUndefined);
|
||||||
where = Model._coerce(where, options);
|
where = Model._coerce(where, options);
|
||||||
|
@ -2982,7 +2982,7 @@ DataAccessObject.replaceById = function(id, data, options, cb) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
assert((typeof data === 'object') && (data !== null),
|
assert((typeof data === 'object') && (data !== null),
|
||||||
'The data argument must be an object');
|
'The data argument must be an object');
|
||||||
assert(typeof options === 'object', 'The options argument must be an object');
|
assert(typeof options === 'object', 'The options argument must be an object');
|
||||||
assert(typeof cb === 'function', 'The cb argument must be a function');
|
assert(typeof cb === 'function', 'The cb argument must be a function');
|
||||||
|
|
||||||
|
@ -3101,7 +3101,7 @@ DataAccessObject.replaceById = function(id, data, options, cb) {
|
||||||
Model._warned.cannotOverwritePKInLoadedHook = true;
|
Model._warned.cannotOverwritePKInLoadedHook = true;
|
||||||
g.warn('WARNING: {{id}} property cannot be changed from %s to %s for model:%s in ' +
|
g.warn('WARNING: {{id}} property cannot be changed from %s to %s for model:%s in ' +
|
||||||
'{{\'loaded\'}} operation hook',
|
'{{\'loaded\'}} operation hook',
|
||||||
id, ctx.data[pkName], Model.modelName);
|
id, ctx.data[pkName], Model.modelName);
|
||||||
}
|
}
|
||||||
|
|
||||||
inst.__persisted = true;
|
inst.__persisted = true;
|
||||||
|
@ -3208,7 +3208,7 @@ function(data, options, cb) {
|
||||||
if (data[idName] !== undefined && !idEquals(data[idName], inst[idName])) {
|
if (data[idName] !== undefined && !idEquals(data[idName], inst[idName])) {
|
||||||
var err = new Error(g.f('{{id}} cannot be updated from ' +
|
var err = new Error(g.f('{{id}} cannot be updated from ' +
|
||||||
'%s to %s when {{forceId}} is set to true',
|
'%s to %s when {{forceId}} is set to true',
|
||||||
inst[idName], data[idName]));
|
inst[idName], data[idName]));
|
||||||
err.statusCode = 400;
|
err.statusCode = 400;
|
||||||
process.nextTick(function() {
|
process.nextTick(function() {
|
||||||
cb(err);
|
cb(err);
|
||||||
|
|
|
@ -227,7 +227,7 @@ function connectorModuleNames(name) {
|
||||||
}
|
}
|
||||||
// Only try the short name if the connector is not from StrongLoop
|
// Only try the short name if the connector is not from StrongLoop
|
||||||
if (['mongodb', 'oracle', 'mysql', 'postgresql', 'mssql', 'rest', 'soap', 'db2', 'cloudant']
|
if (['mongodb', 'oracle', 'mysql', 'postgresql', 'mssql', 'rest', 'soap', 'db2', 'cloudant']
|
||||||
.indexOf(name) === -1) {
|
.indexOf(name) === -1) {
|
||||||
names.push(name);
|
names.push(name);
|
||||||
}
|
}
|
||||||
return names;
|
return names;
|
||||||
|
@ -272,7 +272,7 @@ DataSource._resolveConnector = function(name, loader) {
|
||||||
if (!connector) {
|
if (!connector) {
|
||||||
error = g.f('\nWARNING: {{LoopBack}} connector "%s" is not installed ' +
|
error = g.f('\nWARNING: {{LoopBack}} connector "%s" is not installed ' +
|
||||||
'as any of the following modules:\n\n %s\n\nTo fix, run:\n\n {{npm install %s --save}}\n',
|
'as any of the following modules:\n\n %s\n\nTo fix, run:\n\n {{npm install %s --save}}\n',
|
||||||
name, names.join('\n'), names[names.length - 1]);
|
name, names.join('\n'), names[names.length - 1]);
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
connector: connector,
|
connector: connector,
|
||||||
|
@ -498,7 +498,7 @@ DataSource.prototype.setup = function(dsName, settings) {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.message) {
|
if (err.message) {
|
||||||
err.message = 'Cannot initialize connector ' +
|
err.message = 'Cannot initialize connector ' +
|
||||||
JSON.stringify(connectorName) + ': ' +
|
JSON.stringify(connectorName) + ': ' +
|
||||||
err.message;
|
err.message;
|
||||||
}
|
}
|
||||||
throw err;
|
throw err;
|
||||||
|
@ -1101,7 +1101,7 @@ DataSource.prototype.autoupdate = function(models, cb) {
|
||||||
if (invalidModels.length) {
|
if (invalidModels.length) {
|
||||||
process.nextTick(function() {
|
process.nextTick(function() {
|
||||||
cb(new Error(g.f('Cannot migrate models not attached to this datasource: %s',
|
cb(new Error(g.f('Cannot migrate models not attached to this datasource: %s',
|
||||||
invalidModels.join(' '))));
|
invalidModels.join(' '))));
|
||||||
});
|
});
|
||||||
return cb.promise;
|
return cb.promise;
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ function deprecateHook(ctor, prefixes, capitalizedName) {
|
||||||
|
|
||||||
var hookName = candidateNames.filter(function(hook) { return !!ctor[hook]; })[0];
|
var hookName = candidateNames.filter(function(hook) { return !!ctor[hook]; })[0];
|
||||||
if (!hookName) return; // just to be sure, this should never happen
|
if (!hookName) return; // just to be sure, this should never happen
|
||||||
if (ctor.modelName) hookName = ctor.modelName + '.' + hookName;
|
if (ctor.modelName) hookName = ctor.modelName + '.' + hookName;
|
||||||
deprecated(g.f('Model hook "%s" is deprecated, ' +
|
deprecated(g.f('Model hook "%s" is deprecated, ' +
|
||||||
'use Operation hooks instead. ' +
|
'use Operation hooks instead. ' +
|
||||||
'{{http://docs.strongloop.com/display/LB/Operation+hooks}}', hookName));
|
'{{http://docs.strongloop.com/display/LB/Operation+hooks}}', hookName));
|
||||||
|
|
|
@ -575,7 +575,7 @@ function lookupModelTo(modelFrom, modelToRef, params, singularize) {
|
||||||
|
|
||||||
if (!modelTo) {
|
if (!modelTo) {
|
||||||
// lookup by modelTo name was not successful. Now looking-up by relationTo name
|
// lookup by modelTo name was not successful. Now looking-up by relationTo name
|
||||||
var relationToName = params.as || modelToRef; // modelToRef might be relationTo name
|
var relationToName = params.as || modelToRef; // modelToRef might be relationTo name
|
||||||
modelToName = (singularize ? i8n.singularize(relationToName) : relationToName).toLowerCase();
|
modelToName = (singularize ? i8n.singularize(relationToName) : relationToName).toLowerCase();
|
||||||
modelTo = lookupModel(modelFrom.dataSource.modelBuilder.models, modelToName);
|
modelTo = lookupModel(modelFrom.dataSource.modelBuilder.models, modelToName);
|
||||||
}
|
}
|
||||||
|
@ -787,7 +787,7 @@ RelationDefinition.hasMany = function hasMany(modelFrom, modelToRef, params) {
|
||||||
if (relation.type === RelationTypes.belongsTo &&
|
if (relation.type === RelationTypes.belongsTo &&
|
||||||
(relation.polymorphic && !relation.modelTo || relation.modelTo === definition.modelTo) &&
|
(relation.polymorphic && !relation.modelTo || relation.modelTo === definition.modelTo) &&
|
||||||
(relation.keyFrom === definition.keyThrough)
|
(relation.keyFrom === definition.keyThrough)
|
||||||
) {
|
) {
|
||||||
throughRelationName = relation.name;
|
throughRelationName = relation.name;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -992,7 +992,7 @@ var throughKeys = function(definition) {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
fk1 = findBelongsTo(modelThrough, definition.modelFrom,
|
fk1 = findBelongsTo(modelThrough, definition.modelFrom,
|
||||||
definition.keyFrom)[0];
|
definition.keyFrom)[0];
|
||||||
fk2 = findBelongsTo(modelThrough, definition.modelTo, pk2)[0];
|
fk2 = findBelongsTo(modelThrough, definition.modelTo, pk2)[0];
|
||||||
}
|
}
|
||||||
return [fk1, fk2];
|
return [fk1, fk2];
|
||||||
|
@ -1022,8 +1022,8 @@ HasManyThrough.prototype.findById = function(fkId, options, cb) {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
err = new Error(g.f('No relation found in %s' +
|
err = new Error(g.f('No relation found in %s' +
|
||||||
' for (%s.%s,%s.%s)',
|
' for (%s.%s,%s.%s)',
|
||||||
modelThrough.modelName, self.definition.modelFrom.modelName,
|
modelThrough.modelName, self.definition.modelFrom.modelName,
|
||||||
modelInstance[pk], modelTo.modelName, fkId));
|
modelInstance[pk], modelTo.modelName, fkId));
|
||||||
err.statusCode = 404;
|
err.statusCode = 404;
|
||||||
}
|
}
|
||||||
return cb(err);
|
return cb(err);
|
||||||
|
@ -1825,7 +1825,7 @@ HasOne.prototype.create = function(targetModelData, options, cb) {
|
||||||
} else {
|
} else {
|
||||||
cb && cb(new Error(g.f(
|
cb && cb(new Error(g.f(
|
||||||
'{{HasOne}} relation cannot create more than one instance of %s',
|
'{{HasOne}} relation cannot create more than one instance of %s',
|
||||||
modelTo.modelName)));
|
modelTo.modelName)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return cb.promise;
|
return cb.promise;
|
||||||
|
@ -2472,10 +2472,10 @@ RelationDefinition.embedsMany = function embedsMany(modelFrom, modelToRef, param
|
||||||
var opts = Object.assign(
|
var opts = Object.assign(
|
||||||
params.options && params.options.property ? params.options.property : {},
|
params.options && params.options.property ? params.options.property : {},
|
||||||
params.options && params.options.omitDefaultEmbeddedItem ? {type: [modelTo]} :
|
params.options && params.options.omitDefaultEmbeddedItem ? {type: [modelTo]} :
|
||||||
{
|
{
|
||||||
type: [modelTo],
|
type: [modelTo],
|
||||||
default: function() { return []; },
|
default: function() { return []; },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
modelFrom.dataSource.defineProperty(modelFrom.modelName, propertyName, opts);
|
modelFrom.dataSource.defineProperty(modelFrom.modelName, propertyName, opts);
|
||||||
|
@ -2785,12 +2785,12 @@ EmbedsMany.prototype.updateById = function(fkId, data, options, cb) {
|
||||||
|
|
||||||
if (typeof cb === 'function') {
|
if (typeof cb === 'function') {
|
||||||
modelInstance.updateAttribute(propertyName, embeddedList, options,
|
modelInstance.updateAttribute(propertyName, embeddedList, options,
|
||||||
function(err) {
|
function(err) {
|
||||||
if (err) return cb(err, inst);
|
if (err) return cb(err, inst);
|
||||||
modelTo.notifyObserversOf('after save', context, function(err) {
|
modelTo.notifyObserversOf('after save', context, function(err) {
|
||||||
cb(err, inst);
|
cb(err, inst);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
modelTo.notifyObserversOf('after save', context, function(err) {
|
modelTo.notifyObserversOf('after save', context, function(err) {
|
||||||
if (!err) return;
|
if (!err) return;
|
||||||
|
|
|
@ -63,7 +63,7 @@ function setScopeValuesFromWhere(data, where, targetModel) {
|
||||||
if (prop) {
|
if (prop) {
|
||||||
var val = where[i];
|
var val = where[i];
|
||||||
if (typeof val !== 'object' || val instanceof prop.type ||
|
if (typeof val !== 'object' || val instanceof prop.type ||
|
||||||
prop.type.name === 'ObjectID' || // MongoDB key
|
prop.type.name === 'ObjectID' || // MongoDB key
|
||||||
prop.type.name === 'uuidFromString') { // C*
|
prop.type.name === 'uuidFromString') { // C*
|
||||||
// Only pick the {propertyName: propertyValue}
|
// Only pick the {propertyName: propertyValue}
|
||||||
data[i] = where[i];
|
data[i] = where[i];
|
||||||
|
@ -358,7 +358,7 @@ function parseSettings(urlStr) {
|
||||||
settings.port = uri.port && Number(uri.port); // port is a string
|
settings.port = uri.port && Number(uri.port); // port is a string
|
||||||
settings.user = settings.username = uri.auth && uri.auth.split(':')[0]; // <username>:<password>
|
settings.user = settings.username = uri.auth && uri.auth.split(':')[0]; // <username>:<password>
|
||||||
settings.password = uri.auth && uri.auth.split(':')[1];
|
settings.password = uri.auth && uri.auth.split(':')[1];
|
||||||
settings.database = uri.pathname && uri.pathname.split('/')[1]; // remove the leading /
|
settings.database = uri.pathname && uri.pathname.split('/')[1]; // remove the leading /
|
||||||
settings.url = urlStr;
|
settings.url = urlStr;
|
||||||
if (uri.query) {
|
if (uri.query) {
|
||||||
var params = qs.parse(uri.query);
|
var params = qs.parse(uri.query);
|
||||||
|
|
|
@ -869,8 +869,8 @@ function ValidationError(obj) {
|
||||||
var context = obj && obj.constructor && obj.constructor.modelName;
|
var context = obj && obj.constructor && obj.constructor.modelName;
|
||||||
this.message = g.f(
|
this.message = g.f(
|
||||||
'The %s instance is not valid. Details: %s.',
|
'The %s instance is not valid. Details: %s.',
|
||||||
context ? '`' + context + '`' : 'model',
|
context ? '`' + context + '`' : 'model',
|
||||||
formatErrors(obj.errors, obj.toJSON()) || '(unknown)'
|
formatErrors(obj.errors, obj.toJSON()) || '(unknown)'
|
||||||
);
|
);
|
||||||
|
|
||||||
this.statusCode = 422;
|
this.statusCode = 422;
|
||||||
|
|
14
package.json
14
package.json
|
@ -15,7 +15,7 @@
|
||||||
"ORM"
|
"ORM"
|
||||||
],
|
],
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4.0.0"
|
"node": ">=6"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -37,12 +37,12 @@
|
||||||
"@types/node": "^10.0.8",
|
"@types/node": "^10.0.8",
|
||||||
"async-iterators": "^0.2.2",
|
"async-iterators": "^0.2.2",
|
||||||
"bson": "^1.0.4",
|
"bson": "^1.0.4",
|
||||||
"coveralls": "^2.13.1",
|
"coveralls": "^3.0.1",
|
||||||
"eslint": "^3.12.2",
|
"eslint": "^4.19.1",
|
||||||
"eslint-config-loopback": "^8.0.0",
|
"eslint-config-loopback": "^10.0.0",
|
||||||
"loopback-connector-throwing": "file:./test/fixtures/loopback-connector-throwing",
|
"loopback-connector-throwing": "file:./test/fixtures/loopback-connector-throwing",
|
||||||
"mocha": "^3.2.0",
|
"mocha": "^5.2.0",
|
||||||
"nyc": "^11.1.0",
|
"nyc": "^12.0.2",
|
||||||
"should": "^8.4.0",
|
"should": "^8.4.0",
|
||||||
"typescript": "^2.8.3"
|
"typescript": "^2.8.3"
|
||||||
},
|
},
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
"minimatch": "^3.0.3",
|
"minimatch": "^3.0.3",
|
||||||
"qs": "^6.5.0",
|
"qs": "^6.5.0",
|
||||||
"shortid": "^2.2.6",
|
"shortid": "^2.2.6",
|
||||||
"strong-globalize": "^3.1.0",
|
"strong-globalize": "^4.1.1",
|
||||||
"traverse": "^0.6.6",
|
"traverse": "^0.6.6",
|
||||||
"uuid": "^3.0.1"
|
"uuid": "^3.0.1"
|
||||||
},
|
},
|
||||||
|
|
|
@ -137,27 +137,27 @@ describe('basic-querying', function() {
|
||||||
createdUsers[1].id,
|
createdUsers[1].id,
|
||||||
createdUsers[2].id,
|
createdUsers[2].id,
|
||||||
createdUsers[3].id],
|
createdUsers[3].id],
|
||||||
{where: {vip: true}}, function(err, users) {
|
{where: {vip: true}}, function(err, users) {
|
||||||
should.exist(users);
|
should.exist(users);
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
var names = users.map(function(u) {
|
var names = users.map(function(u) {
|
||||||
return u.name;
|
return u.name;
|
||||||
});
|
|
||||||
names.should.eql(createdUsers.slice(0, 4).
|
|
||||||
filter(function(u) {
|
|
||||||
return u.vip;
|
|
||||||
}).map(function(u) {
|
|
||||||
return u.name;
|
|
||||||
}));
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
names.should.eql(createdUsers.slice(0, 4).
|
||||||
|
filter(function(u) {
|
||||||
|
return u.vip;
|
||||||
|
}).map(function(u) {
|
||||||
|
return u.name;
|
||||||
|
}));
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
bdd.itIf(connectorCapabilities.nullDataValueExists !== false,
|
bdd.itIf(connectorCapabilities.nullDataValueExists !== false,
|
||||||
'should query by ids to check null property', function(done) {
|
'should query by ids to check null property', function(done) {
|
||||||
User.findByIds([
|
User.findByIds([
|
||||||
createdUsers[0].id,
|
createdUsers[0].id,
|
||||||
createdUsers[1].id],
|
createdUsers[1].id],
|
||||||
{where: {vip: null}}, function(err, users) {
|
{where: {vip: null}}, function(err, users) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(users);
|
should.exist(users);
|
||||||
|
@ -165,7 +165,7 @@ describe('basic-querying', function() {
|
||||||
users[0].name.should.eql(createdUsers[1].name);
|
users[0].name.should.eql(createdUsers[1].name);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('find', function() {
|
describe('find', function() {
|
||||||
|
@ -334,28 +334,28 @@ describe('basic-querying', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
bdd.itIf(connectorCapabilities.nullDataValueExists !== false,
|
bdd.itIf(connectorCapabilities.nullDataValueExists !== false,
|
||||||
'should support where date "neq" null', function(done) {
|
'should support where date "neq" null', function(done) {
|
||||||
User.find({where: {birthday: {'neq': null},
|
User.find({where: {birthday: {'neq': null},
|
||||||
}}, function(err, users) {
|
}}, function(err, users) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(users);
|
should.exist(users);
|
||||||
users.should.have.property('length', 2);
|
users.should.have.property('length', 2);
|
||||||
should(users[0].name).be.oneOf('John Lennon', 'Paul McCartney');
|
should(users[0].name).be.oneOf('John Lennon', 'Paul McCartney');
|
||||||
should(users[1].name).be.oneOf('John Lennon', 'Paul McCartney');
|
should(users[1].name).be.oneOf('John Lennon', 'Paul McCartney');
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
bdd.itIf(connectorCapabilities.nullDataValueExists !== false,
|
bdd.itIf(connectorCapabilities.nullDataValueExists !== false,
|
||||||
'should support where date is null', function(done) {
|
'should support where date is null', function(done) {
|
||||||
User.find({where: {birthday: null,
|
User.find({where: {birthday: null,
|
||||||
}}, function(err, users) {
|
}}, function(err, users) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(users);
|
should.exist(users);
|
||||||
users.should.have.property('length', 4);
|
users.should.have.property('length', 4);
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('should support date "gte" that is satisfied', function(done) {
|
it('should support date "gte" that is satisfied', function(done) {
|
||||||
User.find({where: {birthday: {'gte': new Date('1980-12-08')},
|
User.find({where: {birthday: {'gte': new Date('1980-12-08')},
|
||||||
|
@ -887,13 +887,13 @@ describe('basic-querying', function() {
|
||||||
'should support nested property for order in query',
|
'should support nested property for order in query',
|
||||||
function(done) {
|
function(done) {
|
||||||
User.find({where: {'address.state': 'CA'}, order: 'address.city DESC'},
|
User.find({where: {'address.state': 'CA'}, order: 'address.city DESC'},
|
||||||
function(err, users) {
|
function(err, users) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
users.length.should.be.equal(2);
|
users.length.should.be.equal(2);
|
||||||
users[0].address.city.should.be.eql('San Mateo');
|
users[0].address.city.should.be.eql('San Mateo');
|
||||||
users[1].address.city.should.be.eql('San Jose');
|
users[1].address.city.should.be.eql('San Jose');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support multi-level nested array property in query', function(done) {
|
it('should support multi-level nested array property in query', function(done) {
|
||||||
|
@ -907,13 +907,13 @@ describe('basic-querying', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when querying with an invalid value for a type',
|
it('should fail when querying with an invalid value for a type',
|
||||||
function(done) {
|
function(done) {
|
||||||
User.find({where: {birthday: 'notadate'}}, function(err, users) {
|
User.find({where: {birthday: 'notadate'}}, function(err, users) {
|
||||||
should.exist(err);
|
should.exist(err);
|
||||||
err.message.should.equal('Invalid date: notadate');
|
err.message.should.equal('Invalid date: notadate');
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1160,16 +1160,16 @@ describe.skip('queries', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return an error for deleteById/destroyById/removeById',
|
it('should return an error for deleteById/destroyById/removeById',
|
||||||
function(done) {
|
function(done) {
|
||||||
var aliases = ['deleteById', 'destroyById', 'removeById'];
|
var aliases = ['deleteById', 'destroyById', 'removeById'];
|
||||||
async.each(aliases, function(alias, cb) {
|
async.each(aliases, function(alias, cb) {
|
||||||
Todo[alias](1, function(err) {
|
Todo[alias](1, function(err) {
|
||||||
should.exist(err);
|
should.exist(err);
|
||||||
err.message.should.equal(expectedErrMsg);
|
err.message.should.equal(expectedErrMsg);
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
}, done);
|
}, done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return an error for instance.save', function(done) {
|
it('should return an error for instance.save', function(done) {
|
||||||
var todo = new Todo();
|
var todo = new Todo();
|
||||||
|
|
|
@ -90,6 +90,7 @@ function clearAndCreate(model, data, callback) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* eslint-disable mocha/handle-done-callback */
|
||||||
function testOrm(dataSource) {
|
function testOrm(dataSource) {
|
||||||
var requestsAreCounted = dataSource.name !== 'mongodb';
|
var requestsAreCounted = dataSource.name !== 'mongodb';
|
||||||
|
|
||||||
|
@ -407,7 +408,7 @@ function testOrm(dataSource) {
|
||||||
dataSource.name !== 'memory' &&
|
dataSource.name !== 'memory' &&
|
||||||
dataSource.name !== 'neo4j' &&
|
dataSource.name !== 'neo4j' &&
|
||||||
dataSource.name !== 'cradle'
|
dataSource.name !== 'cradle'
|
||||||
)
|
)
|
||||||
it('relations key is working', function(test) {
|
it('relations key is working', function(test) {
|
||||||
test.ok(User.relations, 'Relations key should be defined');
|
test.ok(User.relations, 'Relations key should be defined');
|
||||||
test.ok(User.relations.posts, 'posts relation should exist on User');
|
test.ok(User.relations.posts, 'posts relation should exist on User');
|
||||||
|
|
|
@ -124,7 +124,7 @@ describe('DataSource', function() {
|
||||||
/**
|
/**
|
||||||
* new DataSource(dsName, connectorInstance)
|
* new DataSource(dsName, connectorInstance)
|
||||||
*/
|
*/
|
||||||
it('should accept resolved connector', function() {
|
it('should accept dsName and resolved connector', function() {
|
||||||
var mockConnector = {
|
var mockConnector = {
|
||||||
name: 'loopback-connector-mock',
|
name: 'loopback-connector-mock',
|
||||||
initialize: function(ds, cb) {
|
initialize: function(ds, cb) {
|
||||||
|
|
|
@ -156,19 +156,19 @@ describe('datatypes', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('rejects array value converted to NaN for a required property',
|
it('rejects array value converted to NaN for a required property',
|
||||||
function(done) {
|
function(done) {
|
||||||
db = getSchema();
|
db = getSchema();
|
||||||
Model = db.define('RequiredNumber', {
|
Model = db.define('RequiredNumber', {
|
||||||
num: {type: Number, required: true},
|
num: {type: Number, required: true},
|
||||||
});
|
});
|
||||||
db.automigrate(['Model'], function() {
|
db.automigrate(['Model'], function() {
|
||||||
Model.create({num: [1, 2, 3]}, function(err, inst) {
|
Model.create({num: [1, 2, 3]}, function(err, inst) {
|
||||||
should.exist(err);
|
should.exist(err);
|
||||||
err.should.have.property('name').equal('ValidationError');
|
err.should.have.property('name').equal('ValidationError');
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('handles null data', (done) => {
|
it('handles null data', (done) => {
|
||||||
db = getSchema();
|
db = getSchema();
|
||||||
|
|
|
@ -667,6 +667,7 @@ describe('default scope', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line mocha/no-identical-title
|
||||||
it('should find a scoped instance - thing', function(done) {
|
it('should find a scoped instance - thing', function(done) {
|
||||||
Product.find({where: {name: 'Product'}}, function(err, products) {
|
Product.find({where: {name: 'Product'}}, function(err, products) {
|
||||||
products.should.have.length(2);
|
products.should.have.length(2);
|
||||||
|
|
|
@ -162,20 +162,20 @@ describe('Memory connector with mocked discovery', function() {
|
||||||
function(done) {
|
function(done) {
|
||||||
ds.connector.discoverSchemas = null;
|
ds.connector.discoverSchemas = null;
|
||||||
ds.discoverSchemas('INVENTORY', {})
|
ds.discoverSchemas('INVENTORY', {})
|
||||||
.then(function(schemas) {
|
.then(function(schemas) {
|
||||||
schemas.should.have.property('STRONGLOOP.INVENTORY');
|
schemas.should.have.property('STRONGLOOP.INVENTORY');
|
||||||
|
|
||||||
var s = schemas['STRONGLOOP.INVENTORY'];
|
var s = schemas['STRONGLOOP.INVENTORY'];
|
||||||
s.name.should.be.eql('Inventory');
|
s.name.should.be.eql('Inventory');
|
||||||
|
|
||||||
Object.keys(s.properties).should.be.eql(
|
Object.keys(s.properties).should.be.eql(
|
||||||
['productId', 'locationId', 'available', 'total']
|
['productId', 'locationId', 'available', 'total']
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
.catch(function(err) {
|
.catch(function(err) {
|
||||||
done(err);
|
done(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('discoverSchema', function() {
|
describe('discoverSchema', function() {
|
||||||
|
@ -344,9 +344,9 @@ describe('discoverModelDefinitions', function() {
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
.catch(function(err) {
|
.catch(function(err) {
|
||||||
done(err);
|
done(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -430,9 +430,9 @@ describe('discoverModelProperties', function() {
|
||||||
schemas.should.be.eql(modelProperties);
|
schemas.should.be.eql(modelProperties);
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
.catch(function(err) {
|
.catch(function(err) {
|
||||||
done(err);
|
done(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -599,16 +599,16 @@ describe('discoverExportedForeignKeys', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should discover foreign key definitions using `discoverExportedForeignKeys` - promise variant',
|
it('should discover foreign key definitions using `discoverExportedForeignKeys` - promise variant',
|
||||||
function(done) {
|
function(done) {
|
||||||
ds.discoverExportedForeignKeys('INVENTORY', {})
|
ds.discoverExportedForeignKeys('INVENTORY', {})
|
||||||
.then(function(modelForeignKeys) {
|
.then(function(modelForeignKeys) {
|
||||||
modelForeignKeys.should.be.eql(exportedForeignKeys);
|
modelForeignKeys.should.be.eql(exportedForeignKeys);
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
.catch(function(err) {
|
.catch(function(err) {
|
||||||
done(err);
|
done(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Mock connector', function() {
|
describe('Mock connector', function() {
|
||||||
|
|
|
@ -19,7 +19,7 @@ describe('exclude properties ', function() {
|
||||||
var User = ds.define('User', {name: String, password: String});
|
var User = ds.define('User', {name: String, password: String});
|
||||||
var properties = User.definition.properties;
|
var properties = User.definition.properties;
|
||||||
// User should have id, name & password properties
|
// User should have id, name & password properties
|
||||||
assert(('id' in properties) && ('password' in properties) && ('name' in properties),
|
assert(('id' in properties) && ('password' in properties) && ('name' in properties),
|
||||||
'User should have id, name & password properties');
|
'User should have id, name & password properties');
|
||||||
// Create sub model Customer with vip as property. id property gets automatically created here as well.
|
// Create sub model Customer with vip as property. id property gets automatically created here as well.
|
||||||
// Customer will inherit name, password and id from base User model.
|
// Customer will inherit name, password and id from base User model.
|
||||||
|
|
1321
test/include.test.js
1321
test/include.test.js
File diff suppressed because it is too large
Load Diff
|
@ -13,8 +13,8 @@ describe('include_util', function() {
|
||||||
describe('#buildOneToOneIdentityMapWithOrigKeys', function() {
|
describe('#buildOneToOneIdentityMapWithOrigKeys', function() {
|
||||||
it('should return an object with keys', function() {
|
it('should return an object with keys', function() {
|
||||||
var objs = [
|
var objs = [
|
||||||
{id: 11, letter: 'A'},
|
{id: 11, letter: 'A'},
|
||||||
{id: 22, letter: 'B'},
|
{id: 22, letter: 'B'},
|
||||||
];
|
];
|
||||||
var result = includeUtils.buildOneToOneIdentityMapWithOrigKeys(objs, 'id');
|
var result = includeUtils.buildOneToOneIdentityMapWithOrigKeys(objs, 'id');
|
||||||
result.get(11).should.be.ok;
|
result.get(11).should.be.ok;
|
||||||
|
@ -36,19 +36,17 @@ describe('include_util', function() {
|
||||||
result.get(11)['letter'].should.equal('HA!');
|
result.get(11)['letter'].should.equal('HA!');
|
||||||
result.get(33)['letter'].should.equal('C');
|
result.get(33)['letter'].should.equal('C');
|
||||||
});
|
});
|
||||||
});
|
|
||||||
describe('#buildOneToOneIdentityMapWithOrigKeys', function() {
|
it('should return an object with no additional keys', function() {
|
||||||
it('should return an object with keys', function() {
|
|
||||||
var objs = [
|
var objs = [
|
||||||
{id: 11, letter: 'A'},
|
{id: 11, letter: 'A'},
|
||||||
{id: 22, letter: 'B'},
|
{id: 22, letter: 'B'},
|
||||||
];
|
];
|
||||||
var result = includeUtils.buildOneToOneIdentityMapWithOrigKeys(objs, 'id');
|
var result = includeUtils.buildOneToOneIdentityMapWithOrigKeys(objs, 'id');
|
||||||
result.get(11).should.be.ok;
|
result.getKeys().should.eql([11, 22]); // no additional properties
|
||||||
result.get(22).should.be.ok;
|
|
||||||
result.getKeys().should.have.lengthOf(2); // no additional properties
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#buildOneToManyIdentityMap', function() {
|
describe('#buildOneToManyIdentityMap', function() {
|
||||||
it('should return an object with keys', function() {
|
it('should return an object with keys', function() {
|
||||||
var objs = [
|
var objs = [
|
||||||
|
|
|
@ -15,7 +15,7 @@ function givenCacheItem(dataSourceFactory) {
|
||||||
};
|
};
|
||||||
|
|
||||||
function givenModel(dataSourceFactory, modelName,
|
function givenModel(dataSourceFactory, modelName,
|
||||||
modelProperties, options) {
|
modelProperties, options) {
|
||||||
const dataSource = dataSourceFactory();
|
const dataSource = dataSourceFactory();
|
||||||
const Model = dataSource.createModel(modelName, modelProperties);
|
const Model = dataSource.createModel(modelName, modelProperties);
|
||||||
const p = 'deleteAll' in dataSource.connector ?
|
const p = 'deleteAll' in dataSource.connector ?
|
||||||
|
|
|
@ -69,9 +69,9 @@ module.exports = function(dataSourceFactory, connectorCapabilities) {
|
||||||
|
|
||||||
it('honours options.ttl', function() {
|
it('honours options.ttl', function() {
|
||||||
return CacheItem.set('a-key', 'a-value', {ttl: TTL_PRECISION})
|
return CacheItem.set('a-key', 'a-value', {ttl: TTL_PRECISION})
|
||||||
.delay(2 * TTL_PRECISION)
|
.delay(2 * TTL_PRECISION)
|
||||||
.then(function() { return CacheItem.get('a-key'); })
|
.then(function() { return CacheItem.get('a-key'); })
|
||||||
.then(function(value) { should.equal(value, null); });
|
.then(function(value) { should.equal(value, null); });
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('get', function() {
|
describe('get', function() {
|
||||||
|
|
|
@ -24,25 +24,25 @@ module.exports = function(dataSourceFactory, connectorCapabilities) {
|
||||||
beforeEach(setupCacheItem);
|
beforeEach(setupCacheItem);
|
||||||
|
|
||||||
it('gets TTL when key with unexpired TTL exists - Promise API',
|
it('gets TTL when key with unexpired TTL exists - Promise API',
|
||||||
function() {
|
function() {
|
||||||
return Promise.resolve(
|
return Promise.resolve(
|
||||||
CacheItem.set('a-key', 'a-value', {ttl: INITIAL_TTL}))
|
CacheItem.set('a-key', 'a-value', {ttl: INITIAL_TTL}))
|
||||||
.delay(SMALL_DELAY)
|
.delay(SMALL_DELAY)
|
||||||
.then(function() { return CacheItem.ttl('a-key'); })
|
.then(function() { return CacheItem.ttl('a-key'); })
|
||||||
.then(function(ttl) { ttl.should.be.within(1, INITIAL_TTL); });
|
.then(function(ttl) { ttl.should.be.within(1, INITIAL_TTL); });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('gets TTL when key with unexpired TTL exists - Callback API',
|
it('gets TTL when key with unexpired TTL exists - Callback API',
|
||||||
function(done) {
|
function(done) {
|
||||||
CacheItem.set('a-key', 'a-value', {ttl: INITIAL_TTL}, function(err) {
|
CacheItem.set('a-key', 'a-value', {ttl: INITIAL_TTL}, function(err) {
|
||||||
if (err) return done(err);
|
|
||||||
CacheItem.ttl('a-key', function(err, ttl) {
|
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
ttl.should.be.within(1, INITIAL_TTL);
|
CacheItem.ttl('a-key', function(err, ttl) {
|
||||||
done();
|
if (err) return done(err);
|
||||||
|
ttl.should.be.within(1, INITIAL_TTL);
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('succeeds when key without TTL exists', function() {
|
it('succeeds when key without TTL exists', function() {
|
||||||
return CacheItem.set('a-key', 'a-value')
|
return CacheItem.set('a-key', 'a-value')
|
||||||
|
@ -52,7 +52,7 @@ module.exports = function(dataSourceFactory, connectorCapabilities) {
|
||||||
|
|
||||||
it('fails when getting TTL for a key with expired TTL', function() {
|
it('fails when getting TTL for a key with expired TTL', function() {
|
||||||
return Promise.resolve(
|
return Promise.resolve(
|
||||||
CacheItem.set('expired-key', 'a-value', {ttl: TTL_PRECISION}))
|
CacheItem.set('expired-key', 'a-value', {ttl: TTL_PRECISION}))
|
||||||
.delay(2 * TTL_PRECISION)
|
.delay(2 * TTL_PRECISION)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return CacheItem.ttl('expired-key');
|
return CacheItem.ttl('expired-key');
|
||||||
|
|
|
@ -339,7 +339,7 @@ describe('DataSource define model', function() {
|
||||||
it('supports plain model definitions', function() {
|
it('supports plain model definitions', function() {
|
||||||
var ds = new DataSource('memory');
|
var ds = new DataSource('memory');
|
||||||
|
|
||||||
// define models
|
// define models
|
||||||
var Post = ds.define('Post', {
|
var Post = ds.define('Post', {
|
||||||
title: {type: String, length: 255},
|
title: {type: String, length: 255},
|
||||||
content: {type: ModelBuilder.Text},
|
content: {type: ModelBuilder.Text},
|
||||||
|
@ -350,7 +350,7 @@ describe('DataSource define model', function() {
|
||||||
published: {type: Boolean, default: false, index: true},
|
published: {type: Boolean, default: false, index: true},
|
||||||
});
|
});
|
||||||
|
|
||||||
// simpler way to describe model
|
// simpler way to describe model
|
||||||
var User = ds.define('User', {
|
var User = ds.define('User', {
|
||||||
name: String,
|
name: String,
|
||||||
bio: ModelBuilder.Text,
|
bio: ModelBuilder.Text,
|
||||||
|
@ -362,7 +362,7 @@ describe('DataSource define model', function() {
|
||||||
var Group = ds.define('Group', {group: String});
|
var Group = ds.define('Group', {group: String});
|
||||||
User.mixin(Group);
|
User.mixin(Group);
|
||||||
|
|
||||||
// define any custom method
|
// define any custom method
|
||||||
User.prototype.getNameAndAge = function() {
|
User.prototype.getNameAndAge = function() {
|
||||||
return this.name + ', ' + this.age;
|
return this.name + ', ' + this.age;
|
||||||
};
|
};
|
||||||
|
@ -418,7 +418,7 @@ describe('DataSource define model', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// should be able to attach a data source to an existing model
|
// should be able to attach a data source to an existing model
|
||||||
var modelBuilder = new ModelBuilder();
|
var modelBuilder = new ModelBuilder();
|
||||||
|
|
||||||
var Color = modelBuilder.define('Color', {
|
var Color = modelBuilder.define('Color', {
|
||||||
|
@ -427,7 +427,7 @@ describe('DataSource define model', function() {
|
||||||
|
|
||||||
Color.should.not.have.property('create');
|
Color.should.not.have.property('create');
|
||||||
|
|
||||||
// attach
|
// attach
|
||||||
ds.attach(Color);
|
ds.attach(Color);
|
||||||
Color.should.have.property('create');
|
Color.should.have.property('create');
|
||||||
|
|
||||||
|
@ -971,7 +971,7 @@ describe('DataSource connector types', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DataSource constructor', function() {
|
describe('DataSource._resolveConnector', function() {
|
||||||
// Mocked require
|
// Mocked require
|
||||||
var loader = function(name) {
|
var loader = function(name) {
|
||||||
if (name.indexOf('./connectors/') !== -1) {
|
if (name.indexOf('./connectors/') !== -1) {
|
||||||
|
|
|
@ -228,11 +228,11 @@ describe('manipulation', function() {
|
||||||
should.exist(p);
|
should.exist(p);
|
||||||
should.not.exists(p.name);
|
should.not.exists(p.name);
|
||||||
return Person.findById(p.id)
|
return Person.findById(p.id)
|
||||||
.then(function(person) {
|
.then(function(person) {
|
||||||
person.id.should.eql(p.id);
|
person.id.should.eql(p.id);
|
||||||
should.not.exists(person.name);
|
should.not.exists(person.name);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -528,20 +528,20 @@ describe('manipulation', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have updated password hashed with updateAttribute',
|
it('should have updated password hashed with updateAttribute',
|
||||||
function(done) {
|
function(done) {
|
||||||
StubUser.create({password: 'foo'}, function(err, created) {
|
StubUser.create({password: 'foo'}, function(err, created) {
|
||||||
if (err) return done(err);
|
|
||||||
created.updateAttribute('password', 'test', function(err, created) {
|
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
created.password.should.equal('test-TEST');
|
created.updateAttribute('password', 'test', function(err, created) {
|
||||||
StubUser.findById(created.id, function(err, found) {
|
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
found.password.should.equal('test-TEST');
|
created.password.should.equal('test-TEST');
|
||||||
done();
|
StubUser.findById(created.id, function(err, found) {
|
||||||
|
if (err) return done(err);
|
||||||
|
found.password.should.equal('test-TEST');
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('should reject created StubUser with empty password', function(done) {
|
it('should reject created StubUser with empty password', function(done) {
|
||||||
StubUser.create({email: 'b@example.com', password: ''}, function(err, createdUser) {
|
StubUser.create({email: 'b@example.com', password: ''}, function(err, createdUser) {
|
||||||
|
@ -574,14 +574,14 @@ describe('manipulation', function() {
|
||||||
|
|
||||||
it('should update one attribute (promise variant)', function(done) {
|
it('should update one attribute (promise variant)', function(done) {
|
||||||
person.updateAttribute('name', 'Teddy Graham')
|
person.updateAttribute('name', 'Teddy Graham')
|
||||||
.then(function(p) {
|
.then(function(p) {
|
||||||
return Person.all()
|
return Person.all()
|
||||||
.then(function(ps) {
|
.then(function(ps) {
|
||||||
ps.should.have.lengthOf(1);
|
ps.should.have.lengthOf(1);
|
||||||
ps.pop().name.should.equal('Teddy Graham');
|
ps.pop().name.should.equal('Teddy Graham');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should ignore undefined values on updateAttributes', function(done) {
|
it('should ignore undefined values on updateAttributes', function(done) {
|
||||||
|
@ -732,10 +732,10 @@ describe('manipulation', function() {
|
||||||
it('should fail if an id value is to be changed on updateAttributes',
|
it('should fail if an id value is to be changed on updateAttributes',
|
||||||
function(done) {
|
function(done) {
|
||||||
person.updateAttributes({id: person.id + 1, name: 'John'},
|
person.updateAttributes({id: person.id + 1, name: 'John'},
|
||||||
function(err, p) {
|
function(err, p) {
|
||||||
should.exist(err);
|
should.exist(err);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has an alias "patchAttributes"', function(done) {
|
it('has an alias "patchAttributes"', function(done) {
|
||||||
|
@ -996,14 +996,14 @@ describe('manipulation', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fails when id does not exist in db & validate is false when using updateAttributes',
|
it('fails when id does not exist in db & validate is false when using updateAttributes',
|
||||||
function(done) {
|
function(done) {
|
||||||
var unknownId = uid.fromConnector(db) || 123;
|
var unknownId = uid.fromConnector(db) || 123;
|
||||||
var post = new Post({id: unknownId});
|
var post = new Post({id: unknownId});
|
||||||
post.updateAttributes({title: 'updated title', content: 'AAA'}, {validate: false}, (err) => {
|
post.updateAttributes({title: 'updated title', content: 'AAA'}, {validate: false}, (err) => {
|
||||||
should(err).have.property('statusCode', 404);
|
should(err).have.property('statusCode', 404);
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('works on create if the request does not include an id', function(done) {
|
it('works on create if the request does not include an id', function(done) {
|
||||||
var post = {title: 'a', content: 'AAA'};
|
var post = {title: 'a', content: 'AAA'};
|
||||||
|
@ -1053,45 +1053,45 @@ describe('manipulation', function() {
|
||||||
it('works without options on create (promise variant)', function(done) {
|
it('works without options on create (promise variant)', function(done) {
|
||||||
var post = {id: unknownId, title: 'a', content: 'AAA'};
|
var post = {id: unknownId, title: 'a', content: 'AAA'};
|
||||||
Post.replaceOrCreate(post)
|
Post.replaceOrCreate(post)
|
||||||
.then(function(p) {
|
|
||||||
should.exist(p);
|
|
||||||
p.should.be.instanceOf(Post);
|
|
||||||
p.id.should.eql(post.id);
|
|
||||||
p.should.not.have.property('_id');
|
|
||||||
p.title.should.equal(post.title);
|
|
||||||
p.content.should.equal(post.content);
|
|
||||||
return Post.findById(p.id)
|
|
||||||
.then(function(p) {
|
.then(function(p) {
|
||||||
|
should.exist(p);
|
||||||
|
p.should.be.instanceOf(Post);
|
||||||
p.id.should.eql(post.id);
|
p.id.should.eql(post.id);
|
||||||
p.id.should.not.have.property('_id');
|
p.should.not.have.property('_id');
|
||||||
p.title.should.equal(p.title);
|
p.title.should.equal(post.title);
|
||||||
p.content.should.equal(p.content);
|
p.content.should.equal(post.content);
|
||||||
done();
|
return Post.findById(p.id)
|
||||||
});
|
.then(function(p) {
|
||||||
})
|
p.id.should.eql(post.id);
|
||||||
.catch(done);
|
p.id.should.not.have.property('_id');
|
||||||
|
p.title.should.equal(p.title);
|
||||||
|
p.content.should.equal(p.content);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('works with options on create (promise variant)', function(done) {
|
it('works with options on create (promise variant)', function(done) {
|
||||||
var post = {id: unknownId, title: 'a', content: 'AAA'};
|
var post = {id: unknownId, title: 'a', content: 'AAA'};
|
||||||
Post.replaceOrCreate(post, {validate: false})
|
Post.replaceOrCreate(post, {validate: false})
|
||||||
.then(function(p) {
|
|
||||||
should.exist(p);
|
|
||||||
p.should.be.instanceOf(Post);
|
|
||||||
p.id.should.eql(post.id);
|
|
||||||
p.should.not.have.property('_id');
|
|
||||||
p.title.should.equal(post.title);
|
|
||||||
p.content.should.equal(post.content);
|
|
||||||
return Post.findById(p.id)
|
|
||||||
.then(function(p) {
|
.then(function(p) {
|
||||||
|
should.exist(p);
|
||||||
|
p.should.be.instanceOf(Post);
|
||||||
p.id.should.eql(post.id);
|
p.id.should.eql(post.id);
|
||||||
p.id.should.not.have.property('_id');
|
p.should.not.have.property('_id');
|
||||||
p.title.should.equal(p.title);
|
p.title.should.equal(post.title);
|
||||||
p.content.should.equal(p.content);
|
p.content.should.equal(post.content);
|
||||||
done();
|
return Post.findById(p.id)
|
||||||
});
|
.then(function(p) {
|
||||||
})
|
p.id.should.eql(post.id);
|
||||||
.catch(done);
|
p.id.should.not.have.property('_id');
|
||||||
|
p.title.should.equal(p.title);
|
||||||
|
p.content.should.equal(p.content);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('works without options on update (promise variant)', function(done) {
|
it('works without options on update (promise variant)', function(done) {
|
||||||
|
@ -1103,26 +1103,26 @@ describe('manipulation', function() {
|
||||||
delete created.content;
|
delete created.content;
|
||||||
created.title = 'b';
|
created.title = 'b';
|
||||||
return Post.replaceOrCreate(created)
|
return Post.replaceOrCreate(created)
|
||||||
.then(function(p) {
|
|
||||||
should.exist(p);
|
|
||||||
p.should.be.instanceOf(Post);
|
|
||||||
p.id.should.eql(created.id);
|
|
||||||
p.should.not.have.property('_id');
|
|
||||||
p.title.should.equal('b');
|
|
||||||
p.should.have.property('content', undefined);
|
|
||||||
p.should.have.property('comments', undefined);
|
|
||||||
|
|
||||||
return Post.findById(created.id)
|
|
||||||
.then(function(p) {
|
.then(function(p) {
|
||||||
|
should.exist(p);
|
||||||
|
p.should.be.instanceOf(Post);
|
||||||
|
p.id.should.eql(created.id);
|
||||||
p.should.not.have.property('_id');
|
p.should.not.have.property('_id');
|
||||||
p.title.should.equal('b');
|
p.title.should.equal('b');
|
||||||
should.not.exist(p.content);
|
p.should.have.property('content', undefined);
|
||||||
should.not.exist(p.comments);
|
p.should.have.property('comments', undefined);
|
||||||
done();
|
|
||||||
|
return Post.findById(created.id)
|
||||||
|
.then(function(p) {
|
||||||
|
p.should.not.have.property('_id');
|
||||||
|
p.title.should.equal('b');
|
||||||
|
should.not.exist(p.content);
|
||||||
|
should.not.exist(p.comments);
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
})
|
})
|
||||||
.catch(done);
|
.catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('works with options on update (promise variant)', function(done) {
|
it('works with options on update (promise variant)', function(done) {
|
||||||
|
@ -1134,26 +1134,26 @@ describe('manipulation', function() {
|
||||||
delete created.content;
|
delete created.content;
|
||||||
created.title = 'b';
|
created.title = 'b';
|
||||||
return Post.replaceOrCreate(created, {validate: false})
|
return Post.replaceOrCreate(created, {validate: false})
|
||||||
.then(function(p) {
|
|
||||||
should.exist(p);
|
|
||||||
p.should.be.instanceOf(Post);
|
|
||||||
p.id.should.eql(created.id);
|
|
||||||
p.should.not.have.property('_id');
|
|
||||||
p.title.should.equal('b');
|
|
||||||
p.should.have.property('content', undefined);
|
|
||||||
p.should.have.property('comments', undefined);
|
|
||||||
|
|
||||||
return Post.findById(created.id)
|
|
||||||
.then(function(p) {
|
.then(function(p) {
|
||||||
|
should.exist(p);
|
||||||
|
p.should.be.instanceOf(Post);
|
||||||
|
p.id.should.eql(created.id);
|
||||||
p.should.not.have.property('_id');
|
p.should.not.have.property('_id');
|
||||||
p.title.should.equal('b');
|
p.title.should.equal('b');
|
||||||
should.not.exist(p.content);
|
p.should.have.property('content', undefined);
|
||||||
should.not.exist(p.comments);
|
p.should.have.property('comments', undefined);
|
||||||
done();
|
|
||||||
|
return Post.findById(created.id)
|
||||||
|
.then(function(p) {
|
||||||
|
p.should.not.have.property('_id');
|
||||||
|
p.title.should.equal('b');
|
||||||
|
should.not.exist(p.content);
|
||||||
|
should.not.exist(p.comments);
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
})
|
})
|
||||||
.catch(done);
|
.catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('works without options on update (callback variant)', function(done) {
|
it('works without options on update (callback variant)', function(done) {
|
||||||
|
@ -1279,6 +1279,7 @@ describe('manipulation', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line mocha/no-identical-title
|
||||||
it('works on create if the request does not include an id', function(done) {
|
it('works on create if the request does not include an id', function(done) {
|
||||||
var post = {title: 'a', content: 'AAA'};
|
var post = {title: 'a', content: 'AAA'};
|
||||||
Post.replaceOrCreate(post, function(err, p) {
|
Post.replaceOrCreate(post, function(err, p) {
|
||||||
|
@ -1289,19 +1290,20 @@ describe('manipulation', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line mocha/no-identical-title
|
||||||
it('works on update if the request includes an existing id in db', function(done) {
|
it('works on update if the request includes an existing id in db', function(done) {
|
||||||
Post.create({title: 'a', content: 'AAA'},
|
Post.create({title: 'a', content: 'AAA'},
|
||||||
function(err, post) {
|
function(err, post) {
|
||||||
|
if (err) return done(err);
|
||||||
|
post = post.toObject();
|
||||||
|
delete post.content;
|
||||||
|
post.title = 'b';
|
||||||
|
Post.replaceOrCreate(post, function(err, p) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
post = post.toObject();
|
p.id.should.eql(post.id);
|
||||||
delete post.content;
|
done();
|
||||||
post.title = 'b';
|
|
||||||
Post.replaceOrCreate(post, function(err, p) {
|
|
||||||
if (err) return done(err);
|
|
||||||
p.id.should.eql(post.id);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1333,20 +1335,20 @@ describe('manipulation', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have updated password hashed with replaceAttributes',
|
it('should have updated password hashed with replaceAttributes',
|
||||||
function(done) {
|
function(done) {
|
||||||
StubUser.create({password: 'foo'}, function(err, created) {
|
StubUser.create({password: 'foo'}, function(err, created) {
|
||||||
if (err) return done(err);
|
|
||||||
created.replaceAttributes({password: 'test'}, function(err, created) {
|
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
created.password.should.equal('test-TEST');
|
created.replaceAttributes({password: 'test'}, function(err, created) {
|
||||||
StubUser.findById(created.id, function(err, found) {
|
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
found.password.should.equal('test-TEST');
|
created.password.should.equal('test-TEST');
|
||||||
done();
|
StubUser.findById(created.id, function(err, found) {
|
||||||
|
if (err) return done(err);
|
||||||
|
found.password.should.equal('test-TEST');
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('should reject updated empty password with replaceAttributes', function(done) {
|
it('should reject updated empty password with replaceAttributes', function(done) {
|
||||||
StubUser.create({password: 'abc123'}, function(err, createdUser) {
|
StubUser.create({password: 'abc123'}, function(err, createdUser) {
|
||||||
|
@ -1427,42 +1429,42 @@ describe('manipulation', function() {
|
||||||
|
|
||||||
it('works without options(promise variant)', function(done) {
|
it('works without options(promise variant)', function(done) {
|
||||||
Post.findById(postInstance.id)
|
Post.findById(postInstance.id)
|
||||||
.then(function(p) {
|
|
||||||
p.replaceAttributes({title: 'b'})
|
|
||||||
.then(function(p) {
|
|
||||||
should.exist(p);
|
|
||||||
p.should.be.instanceOf(Post);
|
|
||||||
p.title.should.equal('b');
|
|
||||||
p.should.have.property('content', undefined);
|
|
||||||
return Post.findById(postInstance.id)
|
|
||||||
.then(function(p) {
|
.then(function(p) {
|
||||||
p.title.should.equal('b');
|
p.replaceAttributes({title: 'b'})
|
||||||
should.not.exist(p.content);
|
.then(function(p) {
|
||||||
done();
|
should.exist(p);
|
||||||
});
|
p.should.be.instanceOf(Post);
|
||||||
});
|
p.title.should.equal('b');
|
||||||
})
|
p.should.have.property('content', undefined);
|
||||||
.catch(done);
|
return Post.findById(postInstance.id)
|
||||||
|
.then(function(p) {
|
||||||
|
p.title.should.equal('b');
|
||||||
|
should.not.exist(p.content);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('works with options(promise variant)', function(done) {
|
it('works with options(promise variant)', function(done) {
|
||||||
Post.findById(postInstance.id)
|
Post.findById(postInstance.id)
|
||||||
.then(function(p) {
|
|
||||||
p.replaceAttributes({title: 'b'}, {validate: false})
|
|
||||||
.then(function(p) {
|
|
||||||
should.exist(p);
|
|
||||||
p.should.be.instanceOf(Post);
|
|
||||||
p.title.should.equal('b');
|
|
||||||
p.should.have.property('content', undefined);
|
|
||||||
return Post.findById(postInstance.id)
|
|
||||||
.then(function(p) {
|
.then(function(p) {
|
||||||
p.title.should.equal('b');
|
p.replaceAttributes({title: 'b'}, {validate: false})
|
||||||
should.not.exist(p.content);
|
.then(function(p) {
|
||||||
done();
|
should.exist(p);
|
||||||
});
|
p.should.be.instanceOf(Post);
|
||||||
});
|
p.title.should.equal('b');
|
||||||
})
|
p.should.have.property('content', undefined);
|
||||||
.catch(done);
|
return Post.findById(postInstance.id)
|
||||||
|
.then(function(p) {
|
||||||
|
p.title.should.equal('b');
|
||||||
|
should.not.exist(p.content);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when changing id', function(done) {
|
it('should fail when changing id', function(done) {
|
||||||
|
@ -1584,18 +1586,18 @@ describe('manipulation', function() {
|
||||||
Person.findOrCreate(
|
Person.findOrCreate(
|
||||||
{where: {name: 'Jed'}},
|
{where: {name: 'Jed'}},
|
||||||
{name: 'Jed', gender: 'male'})
|
{name: 'Jed', gender: 'male'})
|
||||||
.then(function(res) {
|
.then(function(res) {
|
||||||
res.should.be.instanceOf(Array);
|
res.should.be.instanceOf(Array);
|
||||||
res.should.have.lengthOf(2);
|
res.should.have.lengthOf(2);
|
||||||
var p = res[0];
|
var p = res[0];
|
||||||
var created = res[1];
|
var created = res[1];
|
||||||
p.should.be.instanceOf(Person);
|
p.should.be.instanceOf(Person);
|
||||||
p.name.should.equal('Jed');
|
p.name.should.equal('Jed');
|
||||||
p.gender.should.equal('male');
|
p.gender.should.equal('male');
|
||||||
created.should.equal(false);
|
created.should.equal(false);
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
.catch(done);
|
.catch(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1690,47 +1692,47 @@ describe('manipulation', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should only delete instances that satisfy the where condition',
|
it('should only delete instances that satisfy the where condition',
|
||||||
function(done) {
|
function(done) {
|
||||||
Person.deleteAll({name: 'John'}, function(err, info) {
|
Person.deleteAll({name: 'John'}, function(err, info) {
|
||||||
|
if (err) return done(err);
|
||||||
|
info.should.have.property('count', 1);
|
||||||
|
Person.find({where: {name: 'John'}}, function(err, data) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
info.should.have.property('count', 1);
|
data.should.have.length(0);
|
||||||
Person.find({where: {name: 'John'}}, function(err, data) {
|
Person.find({where: {name: 'Jane'}}, function(err, data) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
data.should.have.length(0);
|
data.should.have.length(1);
|
||||||
Person.find({where: {name: 'Jane'}}, function(err, data) {
|
done();
|
||||||
if (err) return done(err);
|
|
||||||
data.should.have.length(1);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should report zero deleted instances when no matches are found',
|
it('should report zero deleted instances when no matches are found',
|
||||||
function(done) {
|
function(done) {
|
||||||
Person.deleteAll({name: 'does-not-match'}, function(err, info) {
|
Person.deleteAll({name: 'does-not-match'}, function(err, info) {
|
||||||
|
if (err) return done(err);
|
||||||
|
info.should.have.property('count', 0);
|
||||||
|
Person.count(function(err, count) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
info.should.have.property('count', 0);
|
count.should.equal(2);
|
||||||
Person.count(function(err, count) {
|
done();
|
||||||
if (err) return done(err);
|
|
||||||
count.should.equal(2);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should delete all instances when the where condition is not provided',
|
it('should delete all instances when the where condition is not provided',
|
||||||
function(done) {
|
function(done) {
|
||||||
Person.deleteAll(function(err, info) {
|
Person.deleteAll(function(err, info) {
|
||||||
|
if (err) return done(err);
|
||||||
|
info.should.have.property('count', 2);
|
||||||
|
Person.count(function(err, count) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
info.should.have.property('count', 2);
|
count.should.equal(0);
|
||||||
Person.count(function(err, count) {
|
done();
|
||||||
if (err) return done(err);
|
|
||||||
count.should.equal(0);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
bdd.describeIf(connectorCapabilities.reportDeletedCount === false &&
|
bdd.describeIf(connectorCapabilities.reportDeletedCount === false &&
|
||||||
|
@ -1757,55 +1759,59 @@ describe('manipulation', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line mocha/no-identical-title
|
||||||
it('should be defined as function', function() {
|
it('should be defined as function', function() {
|
||||||
Person.deleteAll.should.be.a.Function;
|
Person.deleteAll.should.be.a.Function;
|
||||||
Person.destroyAll.should.be.a.Function;
|
Person.destroyAll.should.be.a.Function;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line mocha/no-identical-title
|
||||||
it('should only delete instances that satisfy the where condition',
|
it('should only delete instances that satisfy the where condition',
|
||||||
function(done) {
|
function(done) {
|
||||||
Person.deleteAll({id: idJohn}, function(err, info) {
|
Person.deleteAll({id: idJohn}, function(err, info) {
|
||||||
|
if (err) return done(err);
|
||||||
|
should.not.exist(info.count);
|
||||||
|
Person.find({where: {name: 'John'}}, function(err, data) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
should.not.exist(info.count);
|
should.not.exist(data.count);
|
||||||
Person.find({where: {name: 'John'}}, function(err, data) {
|
data.should.have.length(0);
|
||||||
|
Person.find({where: {name: 'Jane'}}, function(err, data) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
should.not.exist(data.count);
|
data.should.have.length(1);
|
||||||
data.should.have.length(0);
|
done();
|
||||||
Person.find({where: {name: 'Jane'}}, function(err, data) {
|
|
||||||
if (err) return done(err);
|
|
||||||
data.should.have.length(1);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line mocha/no-identical-title
|
||||||
it('should report zero deleted instances when no matches are found',
|
it('should report zero deleted instances when no matches are found',
|
||||||
function(done) {
|
function(done) {
|
||||||
var unknownId = uid.fromConnector(db) || 1234567890;
|
var unknownId = uid.fromConnector(db) || 1234567890;
|
||||||
Person.deleteAll({id: unknownId}, function(err, info) {
|
Person.deleteAll({id: unknownId}, function(err, info) {
|
||||||
|
if (err) return done(err);
|
||||||
|
should.not.exist(info.count);
|
||||||
|
Person.count(function(err, count) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
should.not.exist(info.count);
|
count.should.equal(2);
|
||||||
Person.count(function(err, count) {
|
done();
|
||||||
if (err) return done(err);
|
|
||||||
count.should.equal(2);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line mocha/no-identical-title
|
||||||
it('should delete all instances when the where condition is not provided',
|
it('should delete all instances when the where condition is not provided',
|
||||||
function(done) {
|
function(done) {
|
||||||
Person.deleteAll(function(err, info) {
|
Person.deleteAll(function(err, info) {
|
||||||
|
if (err) return done(err);
|
||||||
|
should.not.exist(info.count);
|
||||||
|
Person.count(function(err, count) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
should.not.exist(info.count);
|
count.should.equal(0);
|
||||||
Person.count(function(err, count) {
|
done();
|
||||||
if (err) return done(err);
|
|
||||||
count.should.equal(0);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('deleteById', function() {
|
describe('deleteById', function() {
|
||||||
|
@ -1903,22 +1909,22 @@ describe('manipulation', function() {
|
||||||
|
|
||||||
bdd.itIf(connectorCapabilities.supportStrictDelete !== false, 'should allow delete(id) - ' +
|
bdd.itIf(connectorCapabilities.supportStrictDelete !== false, 'should allow delete(id) - ' +
|
||||||
'fail with error', function(done) {
|
'fail with error', function(done) {
|
||||||
Person.settings.strictDelete = true;
|
Person.settings.strictDelete = true;
|
||||||
Person.findOne(function(err, u) {
|
Person.findOne(function(err, u) {
|
||||||
|
if (err) return done(err);
|
||||||
|
u.delete(function(err, info) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
u.delete(function(err, info) {
|
info.should.have.property('count', 1);
|
||||||
if (err) return done(err);
|
u.delete(function(err) {
|
||||||
info.should.have.property('count', 1);
|
should.exist(err);
|
||||||
u.delete(function(err) {
|
err.message.should.equal('No instance with id ' + u.id + ' found for Person');
|
||||||
should.exist(err);
|
err.should.have.property('code', 'NOT_FOUND');
|
||||||
err.message.should.equal('No instance with id ' + u.id + ' found for Person');
|
err.should.have.property('statusCode', 404);
|
||||||
err.should.have.property('code', 'NOT_FOUND');
|
done();
|
||||||
err.should.have.property('statusCode', 404);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('initialize', function() {
|
describe('initialize', function() {
|
||||||
|
@ -1933,7 +1939,7 @@ describe('manipulation', function() {
|
||||||
person.isNewRecord().should.be.true;
|
person.isNewRecord().should.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Date $now function', function() {
|
describe('Date $now function (type: Date)', function() {
|
||||||
var CustomModel;
|
var CustomModel;
|
||||||
|
|
||||||
before(function(done) {
|
before(function(done) {
|
||||||
|
@ -1957,7 +1963,7 @@ describe('manipulation', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Date $now function', function() {
|
describe('Date $now function (type: String)', function() {
|
||||||
var CustomModel;
|
var CustomModel;
|
||||||
|
|
||||||
before(function(done) {
|
before(function(done) {
|
||||||
|
@ -2202,46 +2208,46 @@ describe('manipulation', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not update instances that do not satisfy the where condition',
|
it('should not update instances that do not satisfy the where condition',
|
||||||
function(done) {
|
function(done) {
|
||||||
idHarry = uid.fromConnector(db) || undefined;
|
idHarry = uid.fromConnector(db) || undefined;
|
||||||
var filter = connectorCapabilities.updateWithOtherThanId === false ?
|
var filter = connectorCapabilities.updateWithOtherThanId === false ?
|
||||||
{id: idHarry} : {name: 'Harry Hoe'};
|
{id: idHarry} : {name: 'Harry Hoe'};
|
||||||
Person.update(filter, {name: 'Marta Moe'}, function(err,
|
Person.update(filter, {name: 'Marta Moe'}, function(err,
|
||||||
info) {
|
info) {
|
||||||
|
if (err) return done(err);
|
||||||
|
if (connectorCapabilities.reportDeletedCount !== false) {
|
||||||
|
info.should.have.property('count', 0);
|
||||||
|
} else {
|
||||||
|
should.not.exist(info.count);
|
||||||
|
}
|
||||||
|
Person.find({where: {name: 'Harry Hoe'}}, function(err, people) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
if (connectorCapabilities.reportDeletedCount !== false) {
|
people.should.be.empty;
|
||||||
info.should.have.property('count', 0);
|
done();
|
||||||
} else {
|
|
||||||
should.not.exist(info.count);
|
|
||||||
}
|
|
||||||
Person.find({where: {name: 'Harry Hoe'}}, function(err, people) {
|
|
||||||
if (err) return done(err);
|
|
||||||
people.should.be.empty;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should only update instances that satisfy the where condition',
|
it('should only update instances that satisfy the where condition',
|
||||||
function(done) {
|
function(done) {
|
||||||
var filter = connectorCapabilities.deleteWithOtherThanId === false ?
|
var filter = connectorCapabilities.deleteWithOtherThanId === false ?
|
||||||
{id: idBrett} : {name: 'Brett Boe'};
|
{id: idBrett} : {name: 'Brett Boe'};
|
||||||
Person.update(filter, {name: 'Harry Hoe'}, function(err,
|
Person.update(filter, {name: 'Harry Hoe'}, function(err,
|
||||||
info) {
|
info) {
|
||||||
|
if (err) return done(err);
|
||||||
|
if (connectorCapabilities.reportDeletedCount !== false) {
|
||||||
|
info.should.have.property('count', 1);
|
||||||
|
} else {
|
||||||
|
should.not.exist(info.count);
|
||||||
|
}
|
||||||
|
Person.find({where: {age: 19}}, function(err, people) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
if (connectorCapabilities.reportDeletedCount !== false) {
|
people.should.have.length(1);
|
||||||
info.should.have.property('count', 1);
|
people[0].name.should.equal('Harry Hoe');
|
||||||
} else {
|
done();
|
||||||
should.not.exist(info.count);
|
|
||||||
}
|
|
||||||
Person.find({where: {age: 19}}, function(err, people) {
|
|
||||||
if (err) return done(err);
|
|
||||||
people.should.have.length(1);
|
|
||||||
people[0].name.should.equal('Harry Hoe');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should reject updated empty password with updateAll', function(done) {
|
it('should reject updated empty password with updateAll', function(done) {
|
||||||
StubUser.create({password: 'abc123'}, function(err, createdUser) {
|
StubUser.create({password: 'abc123'}, function(err, createdUser) {
|
||||||
|
@ -2277,16 +2283,16 @@ describe('manipulation', function() {
|
||||||
bdd.itIf(connectorCapabilities.ignoreUndefinedConditionValue !== false, 'should ignore where ' +
|
bdd.itIf(connectorCapabilities.ignoreUndefinedConditionValue !== false, 'should ignore where ' +
|
||||||
'conditions with undefined values', function(done) {
|
'conditions with undefined values', function(done) {
|
||||||
Person.update(filterBrett, {name: undefined, gender: 'male'},
|
Person.update(filterBrett, {name: undefined, gender: 'male'},
|
||||||
function(err, info) {
|
function(err, info) {
|
||||||
if (err) return done(err);
|
|
||||||
info.should.have.property('count', 1);
|
|
||||||
Person.find({where: filterBrett}, function(err, people) {
|
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
people.should.have.length(1);
|
info.should.have.property('count', 1);
|
||||||
people[0].name.should.equal('Brett Boe');
|
Person.find({where: filterBrett}, function(err, people) {
|
||||||
done();
|
if (err) return done(err);
|
||||||
|
people.should.have.length(1);
|
||||||
|
people[0].name.should.equal('Brett Boe');
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not coerce invalid values provided in where conditions', function(done) {
|
it('should not coerce invalid values provided in where conditions', function(done) {
|
||||||
|
@ -2355,16 +2361,16 @@ describe('manipulation', function() {
|
||||||
|
|
||||||
Person.upsertWithWhere({id: 10},
|
Person.upsertWithWhere({id: 10},
|
||||||
{name: 'updated name'},
|
{name: 'updated name'},
|
||||||
function(err, updated) {
|
function(err, updated) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
var result = updated.toObject();
|
var result = updated.toObject();
|
||||||
result.should.have.properties({
|
result.should.have.properties({
|
||||||
id: instance.id,
|
id: instance.id,
|
||||||
name: 'updated name',
|
name: 'updated name',
|
||||||
});
|
|
||||||
should.equal(result.city, null);
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
should.equal(result.city, null);
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -320,19 +320,19 @@ describe('Memory connector', function() {
|
||||||
|
|
||||||
it('should successfully extract 1 user (Lennon) from the db', function(done) {
|
it('should successfully extract 1 user (Lennon) from the db', function(done) {
|
||||||
User.find({where: {birthday: {between: [new Date(1970, 0), new Date(1990, 0)]}}},
|
User.find({where: {birthday: {between: [new Date(1970, 0), new Date(1990, 0)]}}},
|
||||||
function(err, users) {
|
function(err, users) {
|
||||||
should(users.length).be.equal(1);
|
should(users.length).be.equal(1);
|
||||||
should(users[0].name).be.equal('John Lennon');
|
should(users[0].name).be.equal('John Lennon');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should successfully extract 2 users from the db', function(done) {
|
it('should successfully extract 2 users from the db', function(done) {
|
||||||
User.find({where: {birthday: {between: [new Date(1940, 0), new Date(1990, 0)]}}},
|
User.find({where: {birthday: {between: [new Date(1940, 0), new Date(1990, 0)]}}},
|
||||||
function(err, users) {
|
function(err, users) {
|
||||||
should(users.length).be.equal(2);
|
should(users.length).be.equal(2);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should successfully extract 2 users using implied and', function(done) {
|
it('should successfully extract 2 users using implied and', function(done) {
|
||||||
|
@ -358,18 +358,18 @@ describe('Memory connector', function() {
|
||||||
it('should successfully extract 2 users using date range', function(done) {
|
it('should successfully extract 2 users using date range', function(done) {
|
||||||
User.find({where: {birthday: {between:
|
User.find({where: {birthday: {between:
|
||||||
[new Date(1940, 0).toISOString(), new Date(1990, 0).toISOString()]}}},
|
[new Date(1940, 0).toISOString(), new Date(1990, 0).toISOString()]}}},
|
||||||
function(err, users) {
|
function(err, users) {
|
||||||
should(users.length).be.equal(2);
|
should(users.length).be.equal(2);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should successfully extract 0 user from the db', function(done) {
|
it('should successfully extract 0 user from the db', function(done) {
|
||||||
User.find({where: {birthday: {between: [new Date(1990, 0), Date.now()]}}},
|
User.find({where: {birthday: {between: [new Date(1990, 0), Date.now()]}}},
|
||||||
function(err, users) {
|
function(err, users) {
|
||||||
should(users.length).be.equal(0);
|
should(users.length).be.equal(0);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should successfully extract 2 users matching over array values', function(done) {
|
it('should successfully extract 2 users matching over array values', function(done) {
|
||||||
|
@ -503,14 +503,14 @@ describe('Memory connector', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work when a regex is provided without the regexp operator',
|
it('should work when a regex is provided without the regexp operator',
|
||||||
function(done) {
|
function(done) {
|
||||||
User.find({where: {name: /John.*/i}}, function(err, users) {
|
User.find({where: {name: /John.*/i}}, function(err, users) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
users.length.should.equal(1);
|
users.length.should.equal(1);
|
||||||
users[0].name.should.equal('John Lennon');
|
users[0].name.should.equal('John Lennon');
|
||||||
done();
|
done();
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should support the regexp operator with regex strings', function(done) {
|
it('should support the regexp operator with regex strings', function(done) {
|
||||||
User.find({where: {name: {regexp: '^J'}}}, function(err, users) {
|
User.find({where: {name: {regexp: '^J'}}}, function(err, users) {
|
||||||
|
@ -532,7 +532,7 @@ describe('Memory connector', function() {
|
||||||
|
|
||||||
it('should support the regexp operator with regex objects', function(done) {
|
it('should support the regexp operator with regex objects', function(done) {
|
||||||
User.find({where: {name: {regexp: new RegExp(/^J/)}}}, function(err,
|
User.find({where: {name: {regexp: new RegExp(/^J/)}}}, function(err,
|
||||||
users) {
|
users) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
users.length.should.equal(1);
|
users.length.should.equal(1);
|
||||||
users[0].name.should.equal('John Lennon');
|
users[0].name.should.equal('John Lennon');
|
||||||
|
@ -568,8 +568,8 @@ describe('Memory connector', function() {
|
||||||
state: 'CA',
|
state: 'CA',
|
||||||
zipCode: '95131',
|
zipCode: '95131',
|
||||||
tags: [
|
tags: [
|
||||||
{tag: 'business'},
|
{tag: 'business'},
|
||||||
{tag: 'rent'},
|
{tag: 'rent'},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
friends: [
|
friends: [
|
||||||
|
@ -962,14 +962,6 @@ describe('Memory connector with options', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should receive options from the find method', function(done) {
|
|
||||||
var opts = {transaction: 'tx2'};
|
|
||||||
Post.find({}, opts, function(err, p) {
|
|
||||||
savedOptions.find.should.be.eql(opts);
|
|
||||||
done(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should treat first object arg as filter for find', function(done) {
|
it('should treat first object arg as filter for find', function(done) {
|
||||||
var filter = {title: 't1'};
|
var filter = {title: 't1'};
|
||||||
Post.find(filter, function(err, p) {
|
Post.find(filter, function(err, p) {
|
||||||
|
|
|
@ -76,19 +76,19 @@ describe('Model class inheritance', function() {
|
||||||
// saving original getMergePolicy method
|
// saving original getMergePolicy method
|
||||||
let originalGetMergePolicy = base.getMergePolicy;
|
let originalGetMergePolicy = base.getMergePolicy;
|
||||||
|
|
||||||
// the injected getMergePolicy method captures the provided configureModelMerge option
|
// the injected getMergePolicy method captures the provided configureModelMerge option
|
||||||
base.getMergePolicy = function(options) {
|
base.getMergePolicy = function(options) {
|
||||||
mergePolicy = options && options.configureModelMerge;
|
mergePolicy = options && options.configureModelMerge;
|
||||||
return originalGetMergePolicy(options);
|
return originalGetMergePolicy(options);
|
||||||
};
|
};
|
||||||
|
|
||||||
// calling extend() on base model calls base.getMergePolicy() internally
|
// calling extend() on base model calls base.getMergePolicy() internally
|
||||||
// child model settings are passed as 3rd parameter
|
// child model settings are passed as 3rd parameter
|
||||||
const child = base.extend('child', {}, {configureModelMerge: newMergePolicy});
|
const child = base.extend('child', {}, {configureModelMerge: newMergePolicy});
|
||||||
|
|
||||||
should.deepEqual(mergePolicy, newMergePolicy);
|
should.deepEqual(mergePolicy, newMergePolicy);
|
||||||
|
|
||||||
// restoring original getMergePolicy method
|
// restoring original getMergePolicy method
|
||||||
base.getMergePolicy = originalGetMergePolicy;
|
base.getMergePolicy = originalGetMergePolicy;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ describe('Model class inheritance', function() {
|
||||||
|
|
||||||
it('is inherited by child model', function() {
|
it('is inherited by child model', function() {
|
||||||
const child = base.extend('child', {}, {configureModelMerge: true});
|
const child = base.extend('child', {}, {configureModelMerge: true});
|
||||||
// get mergePolicy from child
|
// get mergePolicy from child
|
||||||
const mergePolicy = child.getMergePolicy({configureModelMerge: true});
|
const mergePolicy = child.getMergePolicy({configureModelMerge: true});
|
||||||
should.deepEqual(mergePolicy, recommendedMergePolicy);
|
should.deepEqual(mergePolicy, recommendedMergePolicy);
|
||||||
});
|
});
|
||||||
|
@ -128,8 +128,8 @@ describe('Model class inheritance', function() {
|
||||||
});
|
});
|
||||||
const baseChild = modelBuilder.define('baseChild');
|
const baseChild = modelBuilder.define('baseChild');
|
||||||
baseChild.attachTo(memory);
|
baseChild.attachTo(memory);
|
||||||
// the name of this must begin with a letter < b
|
// the name of this must begin with a letter < b
|
||||||
// for this test to fail
|
// for this test to fail
|
||||||
const anotherChild = baseChild.extend('anotherChild');
|
const anotherChild = baseChild.extend('anotherChild');
|
||||||
|
|
||||||
assert(anotherChild.prototype instanceof baseChild);
|
assert(anotherChild.prototype instanceof baseChild);
|
||||||
|
@ -220,23 +220,23 @@ describe('Model class inheritance', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
var Customer = User.extend('Customer',
|
var Customer = User.extend('Customer',
|
||||||
{customerId: {type: String, id: true}}, {
|
{customerId: {type: String, id: true}}, {
|
||||||
defaultPermission: 'DENY',
|
defaultPermission: 'DENY',
|
||||||
acls: [
|
acls: [
|
||||||
{
|
{
|
||||||
principalType: 'ROLE',
|
principalType: 'ROLE',
|
||||||
principalId: '$unauthenticated',
|
principalId: '$unauthenticated',
|
||||||
permission: 'DENY',
|
permission: 'DENY',
|
||||||
},
|
|
||||||
],
|
|
||||||
relations: {
|
|
||||||
orders: {
|
|
||||||
type: 'hasMany',
|
|
||||||
model: 'Order',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
],
|
||||||
);
|
relations: {
|
||||||
|
orders: {
|
||||||
|
type: 'hasMany',
|
||||||
|
model: 'Order',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
assert.deepEqual(User.settings, {
|
assert.deepEqual(User.settings, {
|
||||||
// forceId is set to 'auto' in memory if idProp.generated && forceId !== false
|
// forceId is set to 'auto' in memory if idProp.generated && forceId !== false
|
||||||
|
@ -291,8 +291,8 @@ describe('Model class inheritance', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('defines rank of ACLs according to model\'s inheritance rank', function() {
|
it('defines rank of ACLs according to model\'s inheritance rank', function() {
|
||||||
// a simple test is enough as we already fully tested option `{rank: true}`
|
// a simple test is enough as we already fully tested option `{rank: true}`
|
||||||
// in tests with flag `configureModelMerge`
|
// in tests with flag `configureModelMerge`
|
||||||
const modelBuilder = memory.modelBuilder;
|
const modelBuilder = memory.modelBuilder;
|
||||||
const base = modelBuilder.define('base', {}, {acls: [
|
const base = modelBuilder.define('base', {}, {acls: [
|
||||||
{
|
{
|
||||||
|
@ -336,7 +336,7 @@ describe('Model class inheritance', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('replaces baseClass relations with matching subClass relations', function() {
|
it('replaces baseClass relations with matching subClass relations', function() {
|
||||||
// merge policy of settings.relations is {patch: true}
|
// merge policy of settings.relations is {patch: true}
|
||||||
const modelBuilder = memory.modelBuilder;
|
const modelBuilder = memory.modelBuilder;
|
||||||
const base = modelBuilder.define('base', {}, {
|
const base = modelBuilder.define('base', {}, {
|
||||||
relations: {
|
relations: {
|
||||||
|
@ -462,7 +462,7 @@ describe('Model class inheritance', function() {
|
||||||
|
|
||||||
it('`{replace: true}` replaces base model array with sub model matching ' +
|
it('`{replace: true}` replaces base model array with sub model matching ' +
|
||||||
'array', function() {
|
'array', function() {
|
||||||
// merge policy of settings.description is {replace: true}
|
// merge policy of settings.description is {replace: true}
|
||||||
const modelBuilder = memory.modelBuilder;
|
const modelBuilder = memory.modelBuilder;
|
||||||
const base = modelBuilder.define('base', {}, {
|
const base = modelBuilder.define('base', {}, {
|
||||||
description: ['base', 'model', 'description'],
|
description: ['base', 'model', 'description'],
|
||||||
|
@ -515,7 +515,7 @@ describe('Model class inheritance', function() {
|
||||||
|
|
||||||
it('`{replace: false}` adds distinct members of matching arrays from ' +
|
it('`{replace: false}` adds distinct members of matching arrays from ' +
|
||||||
'base model and sub model', function() {
|
'base model and sub model', function() {
|
||||||
// merge policy of settings.hidden is {replace: false}
|
// merge policy of settings.hidden is {replace: false}
|
||||||
const modelBuilder = memory.modelBuilder;
|
const modelBuilder = memory.modelBuilder;
|
||||||
const base = modelBuilder.define('base', {}, {
|
const base = modelBuilder.define('base', {}, {
|
||||||
hidden: ['firstProperty', 'secondProperty'],
|
hidden: ['firstProperty', 'secondProperty'],
|
||||||
|
@ -534,7 +534,7 @@ describe('Model class inheritance', function() {
|
||||||
|
|
||||||
it('`{patch: true}` adds distinct inner properties of matching objects ' +
|
it('`{patch: true}` adds distinct inner properties of matching objects ' +
|
||||||
'from base model and sub model', function() {
|
'from base model and sub model', function() {
|
||||||
// merge policy of settings.relations is {patch: true}
|
// merge policy of settings.relations is {patch: true}
|
||||||
const modelBuilder = memory.modelBuilder;
|
const modelBuilder = memory.modelBuilder;
|
||||||
const base = modelBuilder.define('base', {}, {
|
const base = modelBuilder.define('base', {}, {
|
||||||
relations: {
|
relations: {
|
||||||
|
@ -576,7 +576,7 @@ describe('Model class inheritance', function() {
|
||||||
|
|
||||||
it('`{patch: true}` replaces baseClass inner properties with matching ' +
|
it('`{patch: true}` replaces baseClass inner properties with matching ' +
|
||||||
'subClass inner properties', function() {
|
'subClass inner properties', function() {
|
||||||
// merge policy of settings.relations is {patch: true}
|
// merge policy of settings.relations is {patch: true}
|
||||||
const modelBuilder = memory.modelBuilder;
|
const modelBuilder = memory.modelBuilder;
|
||||||
const base = modelBuilder.define('base', {}, {
|
const base = modelBuilder.define('base', {}, {
|
||||||
relations: {
|
relations: {
|
||||||
|
|
|
@ -22,9 +22,9 @@ describe('optional-validation', function() {
|
||||||
before(function(done) {
|
before(function(done) {
|
||||||
db = getSchema();
|
db = getSchema();
|
||||||
ModelWithForceId = db.createModel(
|
ModelWithForceId = db.createModel(
|
||||||
'ModelWithForceId',
|
'ModelWithForceId',
|
||||||
{name: String},
|
{name: String},
|
||||||
{forceId: true});
|
{forceId: true});
|
||||||
User = db.define('User', {
|
User = db.define('User', {
|
||||||
seq: {type: Number, index: true},
|
seq: {type: Number, index: true},
|
||||||
name: {type: String, index: true, sort: true},
|
name: {type: String, index: true, sort: true},
|
||||||
|
@ -115,26 +115,26 @@ describe('optional-validation', function() {
|
||||||
describe('forceId', function() {
|
describe('forceId', function() {
|
||||||
context('replaceAttributes', function() {
|
context('replaceAttributes', function() {
|
||||||
it('should not fail if you do not pass the Primary key in data object',
|
it('should not fail if you do not pass the Primary key in data object',
|
||||||
function(done) {
|
function(done) {
|
||||||
ModelWithForceId.create({name: 'foo'}, function(err, created) {
|
ModelWithForceId.create({name: 'foo'}, function(err, created) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
created.replaceAttributes({name: 'bar'}, function(err, data) {
|
created.replaceAttributes({name: 'bar'}, function(err, data) {
|
||||||
done(err);
|
done(err);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('should fail if you pass the Primary key in data object',
|
it('should fail if you pass the Primary key in data object',
|
||||||
function(done) {
|
function(done) {
|
||||||
ModelWithForceId.create({name: 'foo'}, function(err, created) {
|
ModelWithForceId.create({name: 'foo'}, function(err, created) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
created.replaceAttributes({name: 'bar', id: 999},
|
created.replaceAttributes({name: 'bar', id: 999},
|
||||||
function(err, data) {
|
function(err, data) {
|
||||||
should.exist(err);
|
should.exist(err);
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -167,28 +167,28 @@ describe('optional-validation', function() {
|
||||||
|
|
||||||
describe('method findOrCreate', function() {
|
describe('method findOrCreate', function() {
|
||||||
it('should throw on findOrCreate with validate:true with invalid data',
|
it('should throw on findOrCreate with validate:true with invalid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: true},
|
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: true},
|
||||||
expectValidationError(done));
|
expectValidationError(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on findOrCreate with validate:false with invalid data',
|
it('should NOT throw on findOrCreate with validate:false with invalid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: false},
|
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: false},
|
||||||
expectCreateSuccess(INVALID_DATA, done));
|
expectCreateSuccess(INVALID_DATA, done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on findOrCreate with validate:true with valid data',
|
it('should NOT throw on findOrCreate with validate:true with valid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: true},
|
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: true},
|
||||||
expectCreateSuccess(done));
|
expectCreateSuccess(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on findOrCreate with validate:false with valid data',
|
it('should NOT throw on findOrCreate with validate:false with valid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: false},
|
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: false},
|
||||||
expectCreateSuccess(done));
|
expectCreateSuccess(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw on findOrCreate with invalid data', function(done) {
|
it('should throw on findOrCreate with invalid data', function(done) {
|
||||||
User.findOrCreate(getNewWhere(), INVALID_DATA, expectValidationError(done));
|
User.findOrCreate(getNewWhere(), INVALID_DATA, expectValidationError(done));
|
||||||
|
@ -201,28 +201,28 @@ describe('optional-validation', function() {
|
||||||
|
|
||||||
describe('method updateOrCreate on existing data', function() {
|
describe('method updateOrCreate on existing data', function() {
|
||||||
it('should throw on updateOrCreate(id) with validate:true with invalid data',
|
it('should throw on updateOrCreate(id) with validate:true with invalid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
callUpdateOrCreateWithExistingUserId(null, {validate: true},
|
callUpdateOrCreateWithExistingUserId(null, {validate: true},
|
||||||
expectValidationError(done));
|
expectValidationError(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on updateOrCreate(id) with validate:false with invalid data',
|
it('should NOT throw on updateOrCreate(id) with validate:false with invalid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
callUpdateOrCreateWithExistingUserId(null, {validate: false},
|
callUpdateOrCreateWithExistingUserId(null, {validate: false},
|
||||||
expectChangeSuccess(INVALID_DATA, done));
|
expectChangeSuccess(INVALID_DATA, done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on updateOrCreate(id) with validate:true with valid data',
|
it('should NOT throw on updateOrCreate(id) with validate:true with valid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: true},
|
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: true},
|
||||||
expectChangeSuccess(done));
|
expectChangeSuccess(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on updateOrCreate(id) with validate:false with valid data',
|
it('should NOT throw on updateOrCreate(id) with validate:false with valid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: false},
|
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: false},
|
||||||
expectChangeSuccess(done));
|
expectChangeSuccess(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
// backwards compatible with validateUpsert
|
// backwards compatible with validateUpsert
|
||||||
it('should NOT throw on updateOrCreate(id) with invalid data', function(done) {
|
it('should NOT throw on updateOrCreate(id) with invalid data', function(done) {
|
||||||
|
@ -310,17 +310,17 @@ describe('optional-validation', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns an error when trying to update the id property when forceId is set to true',
|
it('returns an error when trying to update the id property when forceId is set to true',
|
||||||
function(done) {
|
function(done) {
|
||||||
ModelWithForceId.create({name: 'foo'}, function(err, model) {
|
ModelWithForceId.create({name: 'foo'}, function(err, model) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
model.updateAttributes({id: 123}, function(err) {
|
model.updateAttributes({id: 123}, function(err) {
|
||||||
err.should.be.instanceOf(Error);
|
err.should.be.instanceOf(Error);
|
||||||
err.message.should.eql('id cannot be updated from ' + model.id +
|
err.message.should.eql('id cannot be updated from ' + model.id +
|
||||||
' to 123 when forceId is set to true');
|
' to 123 when forceId is set to true');
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -358,32 +358,32 @@ describe('optional-validation', function() {
|
||||||
|
|
||||||
describe('method findOrCreate', function() {
|
describe('method findOrCreate', function() {
|
||||||
it('should throw on findOrCreate with validate:true with invalid data',
|
it('should throw on findOrCreate with validate:true with invalid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: true},
|
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: true},
|
||||||
expectValidationError(done));
|
expectValidationError(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on findOrCreate with validate:false with invalid data',
|
it('should NOT throw on findOrCreate with validate:false with invalid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: false},
|
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: false},
|
||||||
expectCreateSuccess(INVALID_DATA, done));
|
expectCreateSuccess(INVALID_DATA, done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on findOrCreate with validate:true with valid data',
|
it('should NOT throw on findOrCreate with validate:true with valid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: true},
|
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: true},
|
||||||
expectCreateSuccess(done));
|
expectCreateSuccess(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on findOrCreate with validate:false with valid data',
|
it('should NOT throw on findOrCreate with validate:false with valid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: false},
|
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: false},
|
||||||
expectCreateSuccess(done));
|
expectCreateSuccess(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on findOrCreate with invalid data', function(done) {
|
it('should NOT throw on findOrCreate with invalid data', function(done) {
|
||||||
User.findOrCreate(getNewWhere(), INVALID_DATA,
|
User.findOrCreate(getNewWhere(), INVALID_DATA,
|
||||||
expectCreateSuccess(INVALID_DATA, done));
|
expectCreateSuccess(INVALID_DATA, done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on findOrCreate with valid data', function(done) {
|
it('should NOT throw on findOrCreate with valid data', function(done) {
|
||||||
|
@ -393,28 +393,28 @@ describe('optional-validation', function() {
|
||||||
|
|
||||||
describe('method updateOrCreate on existing data', function() {
|
describe('method updateOrCreate on existing data', function() {
|
||||||
it('should throw on updateOrCreate(id) with validate:true with invalid data',
|
it('should throw on updateOrCreate(id) with validate:true with invalid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
callUpdateOrCreateWithExistingUserId(null, {validate: true},
|
callUpdateOrCreateWithExistingUserId(null, {validate: true},
|
||||||
expectValidationError(done));
|
expectValidationError(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on updateOrCreate(id) with validate:false with invalid data',
|
it('should NOT throw on updateOrCreate(id) with validate:false with invalid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
callUpdateOrCreateWithExistingUserId(null, {validate: false},
|
callUpdateOrCreateWithExistingUserId(null, {validate: false},
|
||||||
expectChangeSuccess(INVALID_DATA, done));
|
expectChangeSuccess(INVALID_DATA, done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on updateOrCreate(id) with validate:true with valid data',
|
it('should NOT throw on updateOrCreate(id) with validate:true with valid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: true},
|
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: true},
|
||||||
expectChangeSuccess(done));
|
expectChangeSuccess(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on updateOrCreate(id) with validate:false with valid data',
|
it('should NOT throw on updateOrCreate(id) with validate:false with valid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: false},
|
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: false},
|
||||||
expectChangeSuccess(done));
|
expectChangeSuccess(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on updateOrCreate(id) with invalid data', function(done) {
|
it('should NOT throw on updateOrCreate(id) with invalid data', function(done) {
|
||||||
callUpdateOrCreateWithExistingUserId(null, expectChangeSuccess(INVALID_DATA, done));
|
callUpdateOrCreateWithExistingUserId(null, expectChangeSuccess(INVALID_DATA, done));
|
||||||
|
@ -498,28 +498,28 @@ describe('optional-validation', function() {
|
||||||
|
|
||||||
describe('method findOrCreate', function() {
|
describe('method findOrCreate', function() {
|
||||||
it('should throw on findOrCreate with validate:true with invalid data',
|
it('should throw on findOrCreate with validate:true with invalid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: true},
|
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: true},
|
||||||
expectValidationError(done));
|
expectValidationError(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on findOrCreate with validate:false with invalid data',
|
it('should NOT throw on findOrCreate with validate:false with invalid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: false},
|
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: false},
|
||||||
expectCreateSuccess(INVALID_DATA, done));
|
expectCreateSuccess(INVALID_DATA, done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on findOrCreate with validate:true with valid data',
|
it('should NOT throw on findOrCreate with validate:true with valid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: true},
|
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: true},
|
||||||
expectCreateSuccess(done));
|
expectCreateSuccess(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on findOrCreate with validate:false with valid data',
|
it('should NOT throw on findOrCreate with validate:false with valid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: false},
|
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: false},
|
||||||
expectCreateSuccess(done));
|
expectCreateSuccess(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw on findOrCreate with invalid data', function(done) {
|
it('should throw on findOrCreate with invalid data', function(done) {
|
||||||
User.findOrCreate(getNewWhere(), INVALID_DATA, expectValidationError(done));
|
User.findOrCreate(getNewWhere(), INVALID_DATA, expectValidationError(done));
|
||||||
|
@ -532,28 +532,28 @@ describe('optional-validation', function() {
|
||||||
|
|
||||||
describe('method updateOrCreate on existing data', function() {
|
describe('method updateOrCreate on existing data', function() {
|
||||||
it('should throw on updateOrCreate(id) with validate:true with invalid data',
|
it('should throw on updateOrCreate(id) with validate:true with invalid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
callUpdateOrCreateWithExistingUserId(null, {validate: true},
|
callUpdateOrCreateWithExistingUserId(null, {validate: true},
|
||||||
expectValidationError(done));
|
expectValidationError(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on updateOrCreate(id) with validate:false with invalid data',
|
it('should NOT throw on updateOrCreate(id) with validate:false with invalid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
callUpdateOrCreateWithExistingUserId(null, {validate: false},
|
callUpdateOrCreateWithExistingUserId(null, {validate: false},
|
||||||
expectChangeSuccess(INVALID_DATA, done));
|
expectChangeSuccess(INVALID_DATA, done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on updateOrCreate(id) with validate:true with valid data',
|
it('should NOT throw on updateOrCreate(id) with validate:true with valid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: true},
|
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: true},
|
||||||
expectChangeSuccess(done));
|
expectChangeSuccess(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT throw on updateOrCreate(id) with validate:false with valid data',
|
it('should NOT throw on updateOrCreate(id) with validate:false with valid data',
|
||||||
function(done) {
|
function(done) {
|
||||||
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: false},
|
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: false},
|
||||||
expectChangeSuccess(done));
|
expectChangeSuccess(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw on updateOrCreate(id) with invalid data', function(done) {
|
it('should throw on updateOrCreate(id) with invalid data', function(done) {
|
||||||
callUpdateOrCreateWithExistingUserId(null, expectValidationError(done));
|
callUpdateOrCreateWithExistingUserId(null, expectValidationError(done));
|
||||||
|
|
|
@ -140,26 +140,26 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('triggers the loaded hook multiple times when multiple instances exist when near filter is used',
|
it('triggers the loaded hook multiple times when multiple instances exist when near filter is used',
|
||||||
function(done) {
|
function(done) {
|
||||||
var hookMonitorGeoModel;
|
var hookMonitorGeoModel;
|
||||||
hookMonitorGeoModel = new HookMonitor({includeModelName: false});
|
hookMonitorGeoModel = new HookMonitor({includeModelName: false});
|
||||||
|
|
||||||
function monitorHookExecutionGeoModel(hookNames) {
|
function monitorHookExecutionGeoModel(hookNames) {
|
||||||
hookMonitorGeoModel.install(GeoModel, hookNames);
|
hookMonitorGeoModel.install(GeoModel, hookNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
monitorHookExecutionGeoModel();
|
monitorHookExecutionGeoModel();
|
||||||
|
|
||||||
var query = {
|
var query = {
|
||||||
where: {location: {near: '10,5'}},
|
where: {location: {near: '10,5'}},
|
||||||
};
|
};
|
||||||
GeoModel.find(query, function(err, list) {
|
GeoModel.find(query, function(err, list) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
|
|
||||||
hookMonitorGeoModel.names.should.eql(['access', 'loaded', 'loaded']);
|
hookMonitorGeoModel.names.should.eql(['access', 'loaded', 'loaded']);
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('applies updates from `loaded` hook when near filter is used', function(done) {
|
it('applies updates from `loaded` hook when near filter is used', function(done) {
|
||||||
GeoModel.observe('loaded', function(ctx, next) {
|
GeoModel.observe('loaded', function(ctx, next) {
|
||||||
|
@ -179,23 +179,23 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('applies updates to one specific instance from `loaded` hook when near filter is used',
|
it('applies updates to one specific instance from `loaded` hook when near filter is used',
|
||||||
function(done) {
|
function(done) {
|
||||||
GeoModel.observe('loaded', function(ctx, next) {
|
GeoModel.observe('loaded', function(ctx, next) {
|
||||||
if (ctx.data.name === 'Rome')
|
if (ctx.data.name === 'Rome')
|
||||||
ctx.data.name = 'Berlin';
|
ctx.data.name = 'Berlin';
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
var query = {
|
var query = {
|
||||||
where: {location: {near: '10,5'}},
|
where: {location: {near: '10,5'}},
|
||||||
};
|
};
|
||||||
|
|
||||||
GeoModel.find(query, function(err, list) {
|
GeoModel.find(query, function(err, list) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
list.map(get('name')).should.containEql('Berlin', 'Tokyo');
|
list.map(get('name')).should.containEql('Berlin', 'Tokyo');
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('applies updates from `loaded` hook when near filter is not used', function(done) {
|
it('applies updates from `loaded` hook when near filter is not used', function(done) {
|
||||||
TestModel.observe('loaded', function(ctx, next) {
|
TestModel.observe('loaded', function(ctx, next) {
|
||||||
|
@ -211,33 +211,33 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('applies updates to one specific instance from `loaded` hook when near filter is not used',
|
it('applies updates to one specific instance from `loaded` hook when near filter is not used',
|
||||||
function(done) {
|
function(done) {
|
||||||
TestModel.observe('loaded', function(ctx, next) {
|
TestModel.observe('loaded', function(ctx, next) {
|
||||||
if (ctx.data.name === 'first')
|
if (ctx.data.name === 'first')
|
||||||
ctx.data.name = 'Paris';
|
ctx.data.name = 'Paris';
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
TestModel.find(function(err, list) {
|
TestModel.find(function(err, list) {
|
||||||
if (err) return done(err);
|
|
||||||
list.map(get('name')).should.eql(['Paris', 'second']);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not trigger hooks for geo queries, if notify is false',
|
|
||||||
function(done) {
|
|
||||||
monitorHookExecution();
|
|
||||||
|
|
||||||
TestModel.find(
|
|
||||||
{where: {geo: {near: '10,20'}}},
|
|
||||||
{notify: false},
|
|
||||||
function(err, list) {
|
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
hookMonitor.names.should.be.empty();
|
list.map(get('name')).should.eql(['Paris', 'second']);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not trigger hooks for geo queries, if notify is false',
|
||||||
|
function(done) {
|
||||||
|
monitorHookExecution();
|
||||||
|
|
||||||
|
TestModel.find(
|
||||||
|
{where: {geo: {near: '10,20'}}},
|
||||||
|
{notify: false},
|
||||||
|
function(err, list) {
|
||||||
|
if (err) return done(err);
|
||||||
|
hookMonitor.names.should.be.empty();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should apply updates from `access` hook', function(done) {
|
it('should apply updates from `access` hook', function(done) {
|
||||||
TestModel.observe('access', function(ctx, next) {
|
TestModel.observe('access', function(ctx, next) {
|
||||||
|
@ -805,12 +805,12 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
||||||
|
|
||||||
record.id.should.eql(existingInstance.id);
|
record.id.should.eql(existingInstance.id);
|
||||||
|
|
||||||
// `findOrCreate` creates a new instance of the object everytime.
|
// `findOrCreate` creates a new instance of the object everytime.
|
||||||
// So, `data.id` as well as `currentInstance.id` always matches
|
// So, `data.id` as well as `currentInstance.id` always matches
|
||||||
// the newly generated UID.
|
// the newly generated UID.
|
||||||
// Hence, the test below asserts both `data.id` and
|
// Hence, the test below asserts both `data.id` and
|
||||||
// `currentInstance.id` to match getLastGeneratedUid().
|
// `currentInstance.id` to match getLastGeneratedUid().
|
||||||
// On same lines, it also asserts `isNewInstance` to be true.
|
// On same lines, it also asserts `isNewInstance` to be true.
|
||||||
ctxRecorder.records.should.eql(aCtxForModel(TestModel, {
|
ctxRecorder.records.should.eql(aCtxForModel(TestModel, {
|
||||||
data: {
|
data: {
|
||||||
id: getLastGeneratedUid(),
|
id: getLastGeneratedUid(),
|
||||||
|
@ -952,9 +952,9 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
||||||
|
|
||||||
record.id.should.eql(existingInstance.id);
|
record.id.should.eql(existingInstance.id);
|
||||||
|
|
||||||
// After the call to `connector.findOrCreate`, since the record
|
// After the call to `connector.findOrCreate`, since the record
|
||||||
// already exists, `data.id` matches `existingInstance.id`
|
// already exists, `data.id` matches `existingInstance.id`
|
||||||
// as against the behaviour noted for `persist` hook
|
// as against the behaviour noted for `persist` hook
|
||||||
ctxRecorder.records.should.eql(aCtxForModel(TestModel, {
|
ctxRecorder.records.should.eql(aCtxForModel(TestModel, {
|
||||||
data: {
|
data: {
|
||||||
id: existingInstance.id,
|
id: existingInstance.id,
|
||||||
|
@ -2258,7 +2258,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!dataSource.connector.replaceById) {
|
if (!dataSource.connector.replaceById) {
|
||||||
describe.skip('replaceById - not implemented', function() {});
|
describe.skip('replaceOrCreate - not implemented', function() {});
|
||||||
} else {
|
} else {
|
||||||
describe('PersistedModel.replaceOrCreate', function() {
|
describe('PersistedModel.replaceOrCreate', function() {
|
||||||
it('triggers hooks in the correct order on create', function(done) {
|
it('triggers hooks in the correct order on create', function(done) {
|
||||||
|
@ -2400,19 +2400,19 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
||||||
it('triggers `before save` hookon create', function(done) {
|
it('triggers `before save` hookon create', function(done) {
|
||||||
TestModel.observe('before save', ctxRecorder.recordAndNext());
|
TestModel.observe('before save', ctxRecorder.recordAndNext());
|
||||||
TestModel.replaceOrCreate({id: existingInstance.id, name: 'new name'},
|
TestModel.replaceOrCreate({id: existingInstance.id, name: 'new name'},
|
||||||
function(err, instance) {
|
function(err, instance) {
|
||||||
if (err)
|
if (err)
|
||||||
return done(err);
|
return done(err);
|
||||||
|
|
||||||
var expectedContext = aCtxForModel(TestModel, {
|
var expectedContext = aCtxForModel(TestModel, {
|
||||||
instance: instance,
|
instance: instance,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!dataSource.connector.replaceOrCreate) {
|
||||||
|
expectedContext.isNewInstance = false;
|
||||||
|
}
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!dataSource.connector.replaceOrCreate) {
|
|
||||||
expectedContext.isNewInstance = false;
|
|
||||||
}
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('triggers `before save` hook on replace', function(done) {
|
it('triggers `before save` hook on replace', function(done) {
|
||||||
|
@ -2573,7 +2573,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
||||||
|
|
||||||
expected.isNewInstance =
|
expected.isNewInstance =
|
||||||
isNewInstanceFlag ?
|
isNewInstanceFlag ?
|
||||||
true : undefined;
|
true : undefined;
|
||||||
|
|
||||||
ctxRecorder.records.should.eql(aCtxForModel(TestModel, expected));
|
ctxRecorder.records.should.eql(aCtxForModel(TestModel, expected));
|
||||||
done();
|
done();
|
||||||
|
@ -2597,7 +2597,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
||||||
|
|
||||||
expected.isNewInstance =
|
expected.isNewInstance =
|
||||||
isNewInstanceFlag ?
|
isNewInstanceFlag ?
|
||||||
false : undefined;
|
false : undefined;
|
||||||
|
|
||||||
ctxRecorder.records.should.eql(aCtxForModel(TestModel, expected));
|
ctxRecorder.records.should.eql(aCtxForModel(TestModel, expected));
|
||||||
done();
|
done();
|
||||||
|
@ -2632,7 +2632,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
||||||
|
|
||||||
expected.isNewInstance =
|
expected.isNewInstance =
|
||||||
isNewInstanceFlag ?
|
isNewInstanceFlag ?
|
||||||
false : undefined;
|
false : undefined;
|
||||||
|
|
||||||
ctxRecorder.records.should.eql(aCtxForModel(TestModel, expected));
|
ctxRecorder.records.should.eql(aCtxForModel(TestModel, expected));
|
||||||
done();
|
done();
|
||||||
|
@ -2656,7 +2656,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
||||||
};
|
};
|
||||||
expected.isNewInstance =
|
expected.isNewInstance =
|
||||||
isNewInstanceFlag ?
|
isNewInstanceFlag ?
|
||||||
true : undefined;
|
true : undefined;
|
||||||
|
|
||||||
ctxRecorder.records.should.eql(aCtxForModel(TestModel, expected));
|
ctxRecorder.records.should.eql(aCtxForModel(TestModel, expected));
|
||||||
done();
|
done();
|
||||||
|
@ -3162,14 +3162,14 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
||||||
TestModel.observe('access', ctxRecorder.recordAndNext());
|
TestModel.observe('access', ctxRecorder.recordAndNext());
|
||||||
|
|
||||||
TestModel.upsertWithWhere({id: existingInstance.id},
|
TestModel.upsertWithWhere({id: existingInstance.id},
|
||||||
{name: 'new name', extra: 'new extra'},
|
{name: 'new name', extra: 'new extra'},
|
||||||
function(err, instance) {
|
function(err, instance) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
ctxRecorder.records.should.eql(aCtxForModel(TestModel, {query: {
|
ctxRecorder.records.should.eql(aCtxForModel(TestModel, {query: {
|
||||||
where: {id: existingInstance.id},
|
where: {id: existingInstance.id},
|
||||||
}}));
|
}}));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('triggers hooks only once', function(done) {
|
it('triggers hooks only once', function(done) {
|
||||||
|
@ -3236,27 +3236,27 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
||||||
TestModel.observe('before save', ctxRecorder.recordAndNext());
|
TestModel.observe('before save', ctxRecorder.recordAndNext());
|
||||||
|
|
||||||
TestModel.upsertWithWhere({id: existingInstance.id},
|
TestModel.upsertWithWhere({id: existingInstance.id},
|
||||||
{id: existingInstance.id, name: 'updated name'},
|
{id: existingInstance.id, name: 'updated name'},
|
||||||
function(err, instance) {
|
function(err, instance) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
var expectedContext = aCtxForModel(TestModel, {
|
var expectedContext = aCtxForModel(TestModel, {
|
||||||
where: {id: existingInstance.id},
|
where: {id: existingInstance.id},
|
||||||
data: {
|
data: {
|
||||||
id: existingInstance.id,
|
id: existingInstance.id,
|
||||||
name: 'updated name',
|
name: 'updated name',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (!dataSource.connector.upsertWithWhere) {
|
if (!dataSource.connector.upsertWithWhere) {
|
||||||
// the difference between `existingInstance` and the following
|
// the difference between `existingInstance` and the following
|
||||||
// plain-data object is `currentInstance` the missing fields are
|
// plain-data object is `currentInstance` the missing fields are
|
||||||
// null in `currentInstance`, wehere as in `existingInstance` they
|
// null in `currentInstance`, wehere as in `existingInstance` they
|
||||||
// are undefined; please see other tests for example see:
|
// are undefined; please see other tests for example see:
|
||||||
// test for "PersistedModel.create triggers `persist` hook"
|
// test for "PersistedModel.create triggers `persist` hook"
|
||||||
expectedContext.currentInstance = {id: existingInstance.id, name: 'first', extra: null};
|
expectedContext.currentInstance = {id: existingInstance.id, name: 'first', extra: null};
|
||||||
}
|
}
|
||||||
ctxRecorder.records.should.eql(expectedContext);
|
ctxRecorder.records.should.eql(expectedContext);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('triggers `before save` hook on create', function(done) {
|
it('triggers `before save` hook on create', function(done) {
|
||||||
|
@ -3287,12 +3287,12 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
||||||
});
|
});
|
||||||
|
|
||||||
TestModel.upsertWithWhere({id: existingInstance.id},
|
TestModel.upsertWithWhere({id: existingInstance.id},
|
||||||
{name: 'updated name'},
|
{name: 'updated name'},
|
||||||
function(err, instance) {
|
function(err, instance) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
instance.name.should.equal('hooked');
|
instance.name.should.equal('hooked');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('applies updates from `before save` hook on create', function(done) {
|
it('applies updates from `before save` hook on create', function(done) {
|
||||||
|
@ -3429,11 +3429,11 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
||||||
it('emits error when `loaded` hook fails', function(done) {
|
it('emits error when `loaded` hook fails', function(done) {
|
||||||
TestModel.observe('loaded', nextWithError(expectedError));
|
TestModel.observe('loaded', nextWithError(expectedError));
|
||||||
TestModel.upsertWithWhere({id: 'new-id'},
|
TestModel.upsertWithWhere({id: 'new-id'},
|
||||||
{id: 'new-id', name: 'a name'},
|
{id: 'new-id', name: 'a name'},
|
||||||
function(err, instance) {
|
function(err, instance) {
|
||||||
[err].should.eql([expectedError]);
|
[err].should.eql([expectedError]);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('triggers `after save` hook on update', function(done) {
|
it('triggers `after save` hook on update', function(done) {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -127,7 +127,7 @@ describe('util.parseSettings', function() {
|
||||||
should.equal(settings.url, 'mysql://127.0.0.1:3306/mydb?x[a]=1&x[b]=2&engine=InnoDB');
|
should.equal(settings.url, 'mysql://127.0.0.1:3306/mydb?x[a]=1&x[b]=2&engine=InnoDB');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Parse a url without auth into a settings object', function() {
|
it('Parse a Memory url without auth into a settings object', function() {
|
||||||
var url = 'memory://?x=1';
|
var url = 'memory://?x=1';
|
||||||
var settings = utils.parseSettings(url);
|
var settings = utils.parseSettings(url);
|
||||||
should.equal(settings.hostname, '');
|
should.equal(settings.hostname, '');
|
||||||
|
@ -145,7 +145,7 @@ describe('util.deepMerge', function() {
|
||||||
var extras = {base: 'User',
|
var extras = {base: 'User',
|
||||||
relations: {accessTokens: {model: 'accessToken', type: 'hasMany',
|
relations: {accessTokens: {model: 'accessToken', type: 'hasMany',
|
||||||
foreignKey: 'userId'},
|
foreignKey: 'userId'},
|
||||||
account: {model: 'account', type: 'belongsTo'}},
|
account: {model: 'account', type: 'belongsTo'}},
|
||||||
acls: [
|
acls: [
|
||||||
{accessType: '*',
|
{accessType: '*',
|
||||||
permission: 'DENY',
|
permission: 'DENY',
|
||||||
|
@ -206,7 +206,7 @@ describe('util.deepMerge', function() {
|
||||||
base: 'User',
|
base: 'User',
|
||||||
relations: {accessTokens: {model: 'accessToken', type: 'hasMany',
|
relations: {accessTokens: {model: 'accessToken', type: 'hasMany',
|
||||||
foreignKey: 'userId'},
|
foreignKey: 'userId'},
|
||||||
account: {model: 'account', type: 'belongsTo'}}};
|
account: {model: 'account', type: 'belongsTo'}}};
|
||||||
|
|
||||||
should.deepEqual(merged, expected, 'Merged objects should match the expectation');
|
should.deepEqual(merged, expected, 'Merged objects should match the expectation');
|
||||||
});
|
});
|
||||||
|
@ -495,19 +495,19 @@ describe('util.toRegExp', function() {
|
||||||
|
|
||||||
context('with a regex string', function() {
|
context('with a regex string', function() {
|
||||||
it('should return a RegExp object when no regex flags are provided',
|
it('should return a RegExp object when no regex flags are provided',
|
||||||
function() {
|
function() {
|
||||||
utils.toRegExp('^regex$').should.be.an.instanceOf(RegExp);
|
utils.toRegExp('^regex$').should.be.an.instanceOf(RegExp);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error when invalid regex flags are provided',
|
it('should throw an error when invalid regex flags are provided',
|
||||||
function() {
|
function() {
|
||||||
utils.toRegExp('^regex$/abc').should.be.an.Error;
|
utils.toRegExp('^regex$/abc').should.be.an.Error;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return a RegExp object when valid flags are provided',
|
it('should return a RegExp object when valid flags are provided',
|
||||||
function() {
|
function() {
|
||||||
utils.toRegExp('regex/igm').should.be.an.instanceOf(RegExp);
|
utils.toRegExp('regex/igm').should.be.an.instanceOf(RegExp);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('with a regex literal', function() {
|
context('with a regex literal', function() {
|
||||||
|
|
Loading…
Reference in New Issue