Merge pull request #1149 from strongloop/near_loaded_oh

Add support for `loaded` operation hook for DAO.find() when near is used
This commit is contained in:
Amirali Jafarian 2016-10-28 15:01:21 -04:00 committed by GitHub
commit 839bb9a81e
2 changed files with 90 additions and 9 deletions

View File

@ -1821,7 +1821,7 @@ DataAccessObject.find = function find(query, options, cb) {
} }
function queryGeo(query) { function queryGeo(query) {
function geoCallback(err, data) { function geoCallbackWithoutNotify(err, data) {
var memory = new Memory(); var memory = new Memory();
var modelName = self.modelName; var modelName = self.modelName;
@ -1847,6 +1847,29 @@ DataAccessObject.find = function find(query, options, cb) {
} }
} }
function geoCallbackWithNotify(err, data) {
if (err) return cb(err);
async.map(data, function(item, next) {
var context = {
Model: self,
data: item,
isNewInstance: false,
hookState: hookState,
options: options,
};
self.notifyObserversOf('loaded', context, function(err) {
if (err) return next(err);
next(null, context.data);
});
}, function(err, results) {
if (err) return cb(err);
geoCallbackWithoutNotify(null, results);
});
}
var geoCallback = options.notify === false ? geoCallbackWithoutNotify : geoCallbackWithNotify;
if (connector.all.length === 4) { if (connector.all.length === 4) {
connector.all(self.modelName, {}, options, geoCallback); connector.all(self.modelName, {}, options, geoCallback);
} else { } else {

View File

@ -6,10 +6,12 @@
'use strict'; 'use strict';
var ValidationError = require('../').ValidationError; var ValidationError = require('../').ValidationError;
var async = require('async');
var contextTestHelpers = require('./helpers/context-test-helpers'); var contextTestHelpers = require('./helpers/context-test-helpers');
var ContextRecorder = contextTestHelpers.ContextRecorder; var ContextRecorder = contextTestHelpers.ContextRecorder;
var deepCloneToObject = contextTestHelpers.deepCloneToObject; var deepCloneToObject = contextTestHelpers.deepCloneToObject;
var aCtxForModel = contextTestHelpers.aCtxForModel; var aCtxForModel = contextTestHelpers.aCtxForModel;
var GeoPoint = require('../lib/geo.js').GeoPoint;
var uid = require('./helpers/uid-generator'); var uid = require('./helpers/uid-generator');
var getLastGeneratedUid = uid.last; var getLastGeneratedUid = uid.last;
@ -24,7 +26,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
} }
describe('Persistence hooks', function() { describe('Persistence hooks', function() {
var ctxRecorder, hookMonitor, expectedError; var ctxRecorder, hookMonitor, expectedError;
var TestModel, existingInstance; var TestModel, existingInstance, GeoModel;
var migrated = false; var migrated = false;
var undefinedValue = undefined; var undefinedValue = undefined;
@ -41,12 +43,25 @@ module.exports = function(dataSource, should, connectorCapabilities) {
extra: {type: String, required: false}, extra: {type: String, required: false},
}); });
GeoModel = dataSource.createModel('GeoModel', {
id: {type: String, id: true},
name: {type: String, required: false},
location: {type: GeoPoint, required: false},
});
uid.reset(); uid.reset();
if (migrated) { if (migrated) {
TestModel.deleteAll(done); async.series([
function(cb) {
TestModel.deleteAll(cb);
},
function(cb) {
GeoModel.deleteAll(cb);
},
], done);
} else { } else {
dataSource.automigrate(TestModel.modelName, function(err) { dataSource.automigrate([TestModel.modelName, 'GeoModel'], function(err) {
migrated = true; migrated = true;
done(err); done(err);
}); });
@ -64,7 +79,12 @@ module.exports = function(dataSource, should, connectorCapabilities) {
TestModel.create({name: 'second'}, function(err) { TestModel.create({name: 'second'}, function(err) {
if (err) return done(err); if (err) return done(err);
done(); var location1 = new GeoPoint({lat: 10.2, lng: 6.7});
GeoModel.create([
{name: 'Rome', location: location1},
], function(err) {
done(err);
});
}); });
}); });
}); });
@ -100,13 +120,51 @@ module.exports = function(dataSource, should, connectorCapabilities) {
}); });
it('triggers correct hooks when near filter is used', function(done) { it('triggers correct hooks when near filter is used', function(done) {
monitorHookExecution(); var hookMonitorGeoModel;
hookMonitorGeoModel = new HookMonitor({includeModelName: false});
function monitorHookExecutionGeoModel(hookNames) {
hookMonitorGeoModel.install(GeoModel, hookNames);
}
monitorHookExecutionGeoModel();
var query = { var query = {
where: {location: {near: '10,20', maxDistance: '10', unit: 'meters'}}, where: {location: {near: '10,5'}},
}; };
TestModel.find(query, function(err, list) { GeoModel.find(query, function(err, list) {
if (err) return done(err); if (err) return done(err);
hookMonitor.names.should.eql(['access']); hookMonitorGeoModel.names.should.eql(['access', 'loaded']);
done();
});
});
it('applies updates from `loaded` hook when near filter is used', function(done) {
GeoModel.observe('loaded', function(ctx, next) {
ctx.data.name = 'Berlin';
next();
});
var query = {
where: {location: {near: '10,5'}},
};
GeoModel.find(query, function(err, list) {
if (err) return done(err);
list.map(get('name')).should.eql(['Berlin']);
done();
});
});
it('applies updates from `loaded` hook when near filter is not used', function(done) {
TestModel.observe('loaded', function(ctx, next) {
ctx.data.name = 'Paris';
next();
});
TestModel.find(function(err, list) {
if (err) return done(err);
list.map(get('name')).should.eql(['Paris', 'Paris']);
done(); done();
}); });
}); });