test: extract hook-monitor helper
This commit is contained in:
parent
616a81b496
commit
09f4c7d026
|
@ -0,0 +1,30 @@
|
|||
// Copyright IBM Corp. 2016. All Rights Reserved.
|
||||
// Node module: loopback-datasource-juggler
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
module.exports = HookMonitor;
|
||||
|
||||
function HookMonitor(opts) {
|
||||
if (!(this instanceof HookMonitor)) {
|
||||
return new HookMonitor();
|
||||
}
|
||||
|
||||
this.options = opts || {};
|
||||
this.names = [];
|
||||
};
|
||||
|
||||
HookMonitor.prototype.install = function(ObservedModel, hookNames) {
|
||||
var monitor = this;
|
||||
this.names = [];
|
||||
ObservedModel._notify = ObservedModel.notifyObserversOf;
|
||||
ObservedModel.notifyObserversOf = function(operation, context, callback) {
|
||||
if (!Array.isArray(hookNames) || hookNames.indexOf(operation) !== -1) {
|
||||
var item = monitor.options.includeModelName ?
|
||||
ObservedModel.modelName + ':' + operation :
|
||||
operation;
|
||||
monitor.names.push(item);
|
||||
}
|
||||
this._notify.apply(this, arguments);
|
||||
};
|
||||
};
|
|
@ -13,6 +13,8 @@ var aCtxForModel = contextTestHelpers.aCtxForModel;
|
|||
var uid = require('./helpers/uid-generator');
|
||||
var getLastGeneratedUid = uid.last;
|
||||
|
||||
var HookMonitor = require('./helpers/hook-monitor');
|
||||
|
||||
module.exports = function(dataSource, should, connectorCapabilities) {
|
||||
if (!connectorCapabilities) connectorCapabilities = {};
|
||||
if (connectorCapabilities.replaceOrCreateReportsNewInstance === undefined) {
|
||||
|
@ -20,17 +22,16 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
' replaceOrCreateReportsNewInstance');
|
||||
}
|
||||
describe('Persistence hooks', function() {
|
||||
var ctxRecorder, expectedError, observersCalled;
|
||||
var ctxRecorder, hookMonitor, expectedError;
|
||||
var TestModel, existingInstance;
|
||||
var migrated = false;
|
||||
var triggered;
|
||||
|
||||
var undefinedValue = undefined;
|
||||
|
||||
beforeEach(function setupDatabase(done) {
|
||||
ctxRecorder = new ContextRecorder('hook not called');
|
||||
hookMonitor = new HookMonitor({ includeModelName: false });
|
||||
expectedError = new Error('test error');
|
||||
observersCalled = [];
|
||||
|
||||
TestModel = dataSource.createModel('TestModel', {
|
||||
// Set id.generated to false to honor client side values
|
||||
|
@ -77,7 +78,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
function(err, list) {
|
||||
if (err) return done(err);
|
||||
|
||||
triggered.should.eql([
|
||||
hookMonitor.names.should.eql([
|
||||
'access',
|
||||
'loaded',
|
||||
]);
|
||||
|
@ -189,7 +190,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
function(err, record, created) {
|
||||
if (err) return done(err);
|
||||
|
||||
triggered.should.eql([
|
||||
hookMonitor.names.should.eql([
|
||||
'before save',
|
||||
'persist',
|
||||
'loaded',
|
||||
|
@ -555,7 +556,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
{ name: 'new-record' },
|
||||
function(err, record, created) {
|
||||
if (err) return done(err);
|
||||
triggered.should.eql([
|
||||
hookMonitor.names.should.eql([
|
||||
'access',
|
||||
'before save',
|
||||
'persist',
|
||||
|
@ -576,14 +577,14 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
if (err) return done(err);
|
||||
|
||||
if (dataSource.connector.findOrCreate) {
|
||||
triggered.should.eql([
|
||||
hookMonitor.names.should.eql([
|
||||
'access',
|
||||
'before save',
|
||||
'persist',
|
||||
'loaded',
|
||||
]);
|
||||
} else {
|
||||
triggered.should.eql([
|
||||
hookMonitor.names.should.eql([
|
||||
'access',
|
||||
'loaded',
|
||||
]);
|
||||
|
@ -934,7 +935,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
existingInstance.save(
|
||||
function(err, record, created) {
|
||||
if (err) return done(err);
|
||||
triggered.should.eql([
|
||||
hookMonitor.names.should.eql([
|
||||
'before save',
|
||||
'persist',
|
||||
'loaded',
|
||||
|
@ -1146,7 +1147,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
{ name: 'changed' },
|
||||
function(err, record, created) {
|
||||
if (err) return done(err);
|
||||
triggered.should.eql([
|
||||
hookMonitor.names.should.eql([
|
||||
'before save',
|
||||
'persist',
|
||||
'loaded',
|
||||
|
@ -1402,7 +1403,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
{ name: 'replaced' },
|
||||
function(err, record, created) {
|
||||
if (err) return done(err);
|
||||
triggered.should.eql([
|
||||
hookMonitor.names.should.eql([
|
||||
'before save',
|
||||
'persist',
|
||||
'loaded',
|
||||
|
@ -1645,7 +1646,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
{ id: 'not-found', name: 'not found' },
|
||||
function(err, record, created) {
|
||||
if (err) return done(err);
|
||||
triggered.should.eql([
|
||||
hookMonitor.names.should.eql([
|
||||
'access',
|
||||
'before save',
|
||||
'persist',
|
||||
|
@ -1664,7 +1665,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
function(err, record, created) {
|
||||
if (err) return done(err);
|
||||
if (dataSource.connector.updateOrCreate) {
|
||||
triggered.should.eql([
|
||||
hookMonitor.names.should.eql([
|
||||
'access',
|
||||
'before save',
|
||||
'persist',
|
||||
|
@ -1672,7 +1673,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
'after save',
|
||||
]);
|
||||
} else {
|
||||
triggered.should.eql([
|
||||
hookMonitor.names.should.eql([
|
||||
'access',
|
||||
'loaded',
|
||||
'before save',
|
||||
|
@ -1769,8 +1770,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
});
|
||||
|
||||
it('triggers hooks only once', function(done) {
|
||||
TestModel.observe('access', pushNameAndNext('access'));
|
||||
TestModel.observe('before save', pushNameAndNext('before save'));
|
||||
monitorHookExecution(['access', 'before save']);
|
||||
|
||||
TestModel.observe('access', function(ctx, next) {
|
||||
ctx.query = { where: { id: { neq: existingInstance.id }}};
|
||||
|
@ -1781,7 +1781,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
{ id: 'ignored', name: 'new name' },
|
||||
function(err, instance) {
|
||||
if (err) return done(err);
|
||||
observersCalled.should.eql(['access', 'before save']);
|
||||
hookMonitor.names.should.eql(['access', 'before save']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -2101,7 +2101,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
{ id: 'not-found', name: 'not found' },
|
||||
function(err, record, created) {
|
||||
if (err) return done(err);
|
||||
triggered.should.eql([
|
||||
hookMonitor.names.should.eql([
|
||||
'access',
|
||||
'before save',
|
||||
'persist',
|
||||
|
@ -2120,7 +2120,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
function(err, record, created) {
|
||||
if (err) return done(err);
|
||||
if (dataSource.connector.replaceOrCreate) {
|
||||
triggered.should.eql([
|
||||
hookMonitor.names.should.eql([
|
||||
'access',
|
||||
'before save',
|
||||
'persist',
|
||||
|
@ -2137,7 +2137,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
// loopback-datasource-juggler/issues#836.
|
||||
// 2) It, also, gets triggered in "replaceAttributes()"
|
||||
// in this chain replaceORCreate()->replaceAttributes()
|
||||
triggered.should.eql([
|
||||
hookMonitor.names.should.eql([
|
||||
'access',
|
||||
'loaded',
|
||||
'before save',
|
||||
|
@ -2234,8 +2234,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
});
|
||||
|
||||
it('triggers hooks only once', function(done) {
|
||||
TestModel.observe('access', pushNameAndNext('access'));
|
||||
TestModel.observe('before save', pushNameAndNext('before save'));
|
||||
monitorHookExecution(['access', 'before save']);
|
||||
|
||||
TestModel.observe('access', function(ctx, next) {
|
||||
ctx.query = { where: { id: { neq: existingInstance.id }}};
|
||||
|
@ -2246,7 +2245,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
{ id: 'ignored', name: 'new name' },
|
||||
function(err, instance) {
|
||||
if (err) return done(err);
|
||||
observersCalled.should.eql(['access', 'before save']);
|
||||
hookMonitor.names.should.eql(['access', 'before save']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -2808,8 +2807,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
});
|
||||
|
||||
it('triggers hooks only once', function(done) {
|
||||
TestModel.observe('access', pushNameAndNext('access'));
|
||||
TestModel.observe('after delete', pushNameAndNext('after delete'));
|
||||
monitorHookExecution();
|
||||
TestModel.observe('access', function(ctx, next) {
|
||||
ctx.query = { where: { id: { neq: existingInstance.id }}};
|
||||
next();
|
||||
|
@ -2817,7 +2815,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
|
||||
existingInstance.delete(function(err) {
|
||||
if (err) return done(err);
|
||||
observersCalled.should.eql(['access', 'after delete']);
|
||||
hookMonitor.names.should.eql(['access', 'before delete', 'after delete']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -2979,13 +2977,6 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
|
||||
});
|
||||
|
||||
function pushNameAndNext(name) {
|
||||
return function(context, next) {
|
||||
observersCalled.push(name);
|
||||
next();
|
||||
};
|
||||
}
|
||||
|
||||
function nextWithError(err) {
|
||||
return function(context, next) {
|
||||
next(err);
|
||||
|
@ -3016,13 +3007,8 @@ module.exports = function(dataSource, should, connectorCapabilities) {
|
|||
TestModel.findOne({ where: { id: id }}, { notify: false }, cb);
|
||||
}
|
||||
|
||||
function monitorHookExecution() {
|
||||
triggered = [];
|
||||
TestModel._notify = TestModel.notifyObserversOf;
|
||||
TestModel.notifyObserversOf = function(operation, context, callback) {
|
||||
triggered.push(operation);
|
||||
this._notify.apply(this, arguments);
|
||||
};
|
||||
function monitorHookExecution(hookNames) {
|
||||
hookMonitor.install(TestModel, hookNames);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue