Adding support for AfterFind (#2968)
This commit is contained in:
@@ -1306,4 +1306,134 @@ describe('beforeFind hooks', () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
describe('afterFind hooks', () => {
|
||||
it('should add afterFind trigger using get',(done) => {
|
||||
Parse.Cloud.afterFind('MyObject', (req, res) => {
|
||||
for(let i = 0 ; i < req.objects.length ; i++){
|
||||
req.objects[i].set("secretField","###");
|
||||
}
|
||||
res.success(req.objects);
|
||||
});
|
||||
let obj = new Parse.Object('MyObject');
|
||||
obj.set('secretField', 'SSID');
|
||||
obj.save().then(function() {
|
||||
let query = new Parse.Query('MyObject');
|
||||
query.get(obj.id).then(function(result) {
|
||||
expect(result.get('secretField')).toEqual('###');
|
||||
done();
|
||||
}, function(error) {
|
||||
fail(error);
|
||||
done();
|
||||
});
|
||||
}, function(error) {
|
||||
fail(error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should add afterFind trigger using find',(done) => {
|
||||
Parse.Cloud.afterFind('MyObject', (req, res) => {
|
||||
for(let i = 0 ; i < req.objects.length ; i++){
|
||||
req.objects[i].set("secretField","###");
|
||||
}
|
||||
res.success(req.objects);
|
||||
});
|
||||
let obj = new Parse.Object('MyObject');
|
||||
obj.set('secretField', 'SSID');
|
||||
obj.save().then(function() {
|
||||
let query = new Parse.Query('MyObject');
|
||||
query.equalTo('objectId',obj.id);
|
||||
query.find().then(function(results) {
|
||||
expect(results[0].get('secretField')).toEqual('###');
|
||||
done();
|
||||
}, function(error) {
|
||||
fail(error);
|
||||
done();
|
||||
});
|
||||
}, function(error) {
|
||||
fail(error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should filter out results',(done) => {
|
||||
Parse.Cloud.afterFind('MyObject', (req, res) => {
|
||||
let filteredResults = [];
|
||||
for(let i = 0 ; i < req.objects.length ; i++){
|
||||
if(req.objects[i].get("secretField")==="SSID1") {
|
||||
filteredResults.push(req.objects[i]);
|
||||
}
|
||||
}
|
||||
res.success(filteredResults);
|
||||
});
|
||||
let obj0 = new Parse.Object('MyObject');
|
||||
obj0.set('secretField', 'SSID1');
|
||||
let obj1 = new Parse.Object('MyObject');
|
||||
obj1.set('secretField', 'SSID2');
|
||||
Parse.Object.saveAll([obj0, obj1]).then(function() {
|
||||
let query = new Parse.Query('MyObject');
|
||||
query.find().then(function(results) {
|
||||
expect(results[0].get('secretField')).toEqual('SSID1');
|
||||
expect(results.length).toEqual(1);
|
||||
done();
|
||||
}, function(error) {
|
||||
fail(error);
|
||||
done();
|
||||
});
|
||||
}, function(error) {
|
||||
fail(error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle failures',(done) => {
|
||||
Parse.Cloud.afterFind('MyObject', (req, res) => {
|
||||
res.error(Parse.Error.SCRIPT_FAILED, "It should fail");
|
||||
});
|
||||
let obj = new Parse.Object('MyObject');
|
||||
obj.set('secretField', 'SSID');
|
||||
obj.save().then(function() {
|
||||
let query = new Parse.Query('MyObject');
|
||||
query.equalTo('objectId',obj.id);
|
||||
query.find().then(function(results) {
|
||||
fail("AfterFind should handle response failure correctly");
|
||||
done();
|
||||
}, function(error) {
|
||||
done();
|
||||
});
|
||||
}, function(error) {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should also work with promise',(done) => {
|
||||
Parse.Cloud.afterFind('MyObject', (req, res) => {
|
||||
let promise = new Parse.Promise();
|
||||
setTimeout(function(){
|
||||
for(let i = 0 ; i < req.objects.length ; i++){
|
||||
req.objects[i].set("secretField","###");
|
||||
}
|
||||
promise.resolve(req.objects);
|
||||
}, 1000);
|
||||
return promise;
|
||||
});
|
||||
let obj = new Parse.Object('MyObject');
|
||||
obj.set('secretField', 'SSID');
|
||||
obj.save().then(function() {
|
||||
let query = new Parse.Query('MyObject');
|
||||
query.equalTo('objectId',obj.id);
|
||||
query.find().then(function(results) {
|
||||
expect(results[0].get('secretField')).toEqual('###');
|
||||
done();
|
||||
}, function(error) {
|
||||
fail(error);
|
||||
});
|
||||
}, function(error) {
|
||||
fail(error);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
var SchemaController = require('./Controllers/SchemaController');
|
||||
var Parse = require('parse/node').Parse;
|
||||
const triggers = require('./triggers');
|
||||
|
||||
import { default as FilesController } from './Controllers/FilesController';
|
||||
|
||||
@@ -122,6 +123,8 @@ RestQuery.prototype.execute = function(executeOptions) {
|
||||
return this.runCount();
|
||||
}).then(() => {
|
||||
return this.handleInclude();
|
||||
}).then(() => {
|
||||
return this.runAfterFindTrigger();
|
||||
}).then(() => {
|
||||
return this.response;
|
||||
});
|
||||
@@ -468,6 +471,22 @@ RestQuery.prototype.handleInclude = function() {
|
||||
return pathResponse;
|
||||
};
|
||||
|
||||
//Returns a promise of a processed set of results
|
||||
RestQuery.prototype.runAfterFindTrigger = function() {
|
||||
if (!this.response) {
|
||||
return;
|
||||
}
|
||||
// Avoid doing any setup for triggers if there is no 'afterFind' trigger for this class.
|
||||
const hasAfterFindHook = triggers.triggerExists(this.className, triggers.Types.afterFind, this.config.applicationId);
|
||||
if (!hasAfterFindHook) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
// Run afterFind trigger and set the new results
|
||||
return triggers.maybeRunAfterFindTrigger(triggers.Types.afterFind, this.auth, this.className,this.response.results, this.config).then((results) => {
|
||||
this.response.results = results;
|
||||
});
|
||||
};
|
||||
|
||||
// Adds included values to the response.
|
||||
// Path is a list of field names.
|
||||
// Returns a promise for an augmented response.
|
||||
|
||||
@@ -50,6 +50,11 @@ ParseCloud.beforeFind = function(parseClass, handler) {
|
||||
triggers.addTrigger(triggers.Types.beforeFind, className, handler, Parse.applicationId);
|
||||
};
|
||||
|
||||
ParseCloud.afterFind = function(parseClass, handler) {
|
||||
const className = getClassName(parseClass);
|
||||
triggers.addTrigger(triggers.Types.afterFind, className, handler, Parse.applicationId);
|
||||
};
|
||||
|
||||
ParseCloud._removeAllHooks = () => {
|
||||
triggers._unregisterAll();
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ export const Types = {
|
||||
afterSave: 'afterSave',
|
||||
beforeDelete: 'beforeDelete',
|
||||
afterDelete: 'afterDelete',
|
||||
beforeFind: 'beforeFind'
|
||||
beforeFind: 'beforeFind',
|
||||
afterFind: 'afterFind'
|
||||
};
|
||||
|
||||
const baseStore = function() {
|
||||
@@ -185,6 +186,15 @@ export function getRequestQueryObject(triggerType, auth, query, config) {
|
||||
export function getResponseObject(request, resolve, reject) {
|
||||
return {
|
||||
success: function(response) {
|
||||
if (request.triggerName === Types.afterFind) {
|
||||
if(!response){
|
||||
response = request.objects;
|
||||
}
|
||||
response = response.map(object => {
|
||||
return object.toJSON();
|
||||
});
|
||||
return resolve(response);
|
||||
}
|
||||
// Use the JSON response
|
||||
if (response && !request.object.equals(response)
|
||||
&& request.triggerName === Types.beforeSave) {
|
||||
@@ -240,6 +250,42 @@ function logTriggerErrorBeforeHook(triggerType, className, input, auth, error) {
|
||||
});
|
||||
}
|
||||
|
||||
export function maybeRunAfterFindTrigger(triggerType, auth, className, objects, config) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const trigger = getTrigger(className, triggerType, config.applicationId);
|
||||
if (!trigger) {
|
||||
return resolve();
|
||||
}
|
||||
const request = getRequestObject(triggerType, auth, null, null, config);
|
||||
const response = getResponseObject(request,
|
||||
object => {
|
||||
resolve(object);
|
||||
},
|
||||
error => {
|
||||
reject(error);
|
||||
});
|
||||
logTriggerSuccessBeforeHook(triggerType, className, 'AfterFind', JSON.stringify(objects), auth);
|
||||
request.objects = objects.map(object => {
|
||||
//setting the class name to transform into parse object
|
||||
object.className=className;
|
||||
return Parse.Object.fromJSON(object);
|
||||
});
|
||||
const triggerPromise = trigger(request, response);
|
||||
if (triggerPromise && typeof triggerPromise.then === "function") {
|
||||
return triggerPromise.then(promiseResults => {
|
||||
if(promiseResults) {
|
||||
resolve(promiseResults);
|
||||
}else{
|
||||
return reject(new Parse.Error(Parse.Error.SCRIPT_FAILED, "AfterFind expect results to be returned in the promise"));
|
||||
}
|
||||
});
|
||||
}
|
||||
}).then((results) => {
|
||||
logTriggerAfterHook(triggerType, className, JSON.stringify(results), auth);
|
||||
return results;
|
||||
});
|
||||
}
|
||||
|
||||
export function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, config, auth) {
|
||||
let trigger = getTrigger(className, triggerType, config.applicationId);
|
||||
if (!trigger) {
|
||||
|
||||
Reference in New Issue
Block a user