Skip to content

Commit 5d07966

Browse files
authored
Merge 1d1660a into 9b9c3a4
2 parents 9b9c3a4 + 1d1660a commit 5d07966

File tree

4 files changed

+101
-3
lines changed

4 files changed

+101
-3
lines changed

spec/ParseLiveQuery.spec.js

+39
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,45 @@ describe('ParseLiveQuery', function () {
800800
await object.save();
801801
});
802802

803+
it('can handle select beforeUnsubscribe trigger', async done => {
804+
await reconfigureServer({
805+
liveQuery: {
806+
classNames: ['TestObject'],
807+
},
808+
startLiveQueryServer: true,
809+
verbose: false,
810+
silent: true,
811+
});
812+
const user = new Parse.User();
813+
user.setUsername('username');
814+
user.setPassword('password');
815+
await user.signUp();
816+
817+
Parse.Cloud.beforeSubscribe(TestObject, req => {
818+
expect(req.requestId).toBe(1);
819+
expect(req.user).toBeDefined();
820+
});
821+
822+
Parse.Cloud.beforeUnsubscribe(TestObject, req => {
823+
expect(req.requestId).toBe(1);
824+
expect(req.user).toBeDefined();
825+
expect(req.user.get('username')).toBe('username');
826+
done();
827+
});
828+
829+
const object = new TestObject();
830+
await object.save();
831+
832+
const query = new Parse.Query(TestObject);
833+
query.equalTo('objectId', object.id);
834+
const subscription = await query.subscribe();
835+
836+
object.set({ foo: 'bar', yolo: 'abc' });
837+
await object.save();
838+
839+
await subscription.unsubscribe();
840+
});
841+
803842
it('LiveQuery with ACL', async () => {
804843
await reconfigureServer({
805844
liveQuery: {

src/LiveQuery/ParseLiveQueryServer.js

+25-3
Original file line numberDiff line numberDiff line change
@@ -968,7 +968,7 @@ class ParseLiveQueryServer {
968968
this._handleSubscribe(parseWebsocket, request);
969969
}
970970

971-
_handleUnsubscribe(parseWebsocket: any, request: any, notifyClient: boolean = true): any {
971+
async _handleUnsubscribe(parseWebsocket: any, request: any, notifyClient: boolean = true): any {
972972
// If we can not find this client, return error to client
973973
if (!Object.prototype.hasOwnProperty.call(parseWebsocket, 'clientId')) {
974974
Client.pushError(
@@ -1015,11 +1015,33 @@ class ParseLiveQueryServer {
10151015
return;
10161016
}
10171017

1018+
const subscription = subscriptionInfo.subscription;
1019+
const className = subscription.className;
1020+
const trigger = getTrigger(className, 'beforeUnsubscribe', Parse.applicationId);
1021+
if (trigger) {
1022+
const auth = await this.getAuthFromClient(client, request.requestId, request.sessionToken);
1023+
if (auth && auth.user) {
1024+
request.user = auth.user;
1025+
}
1026+
1027+
request.sessionToken = subscriptionInfo.sessionToken;
1028+
request.useMasterKey = client.hasMasterKey;
1029+
request.installationId = client.installationId;
1030+
1031+
try {
1032+
await runTrigger(trigger, `beforeUnsubscribe.${className}`, request, auth);
1033+
} catch (error) {
1034+
Client.pushError(parseWebsocket, error.code || Parse.Error.SCRIPT_FAILED, error.message || error, false);
1035+
logger.error(
1036+
`Failed running beforeUnsubscribe for session ${request.sessionToken} with:\n Error: ` +
1037+
JSON.stringify(error)
1038+
);
1039+
}
1040+
}
1041+
10181042
// Remove subscription from client
10191043
client.deleteSubscriptionInfo(requestId);
10201044
// Remove client from subscription
1021-
const subscription = subscriptionInfo.subscription;
1022-
const className = subscription.className;
10231045
subscription.deleteClientSubscription(parseWebsocket.clientId, requestId);
10241046
// If there is no client which is subscribing this subscription, remove it from subscriptions
10251047
const classSubscriptions = this.subscriptions.get(className);

src/cloud-code/Parse.Cloud.js

+36
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,42 @@ ParseCloud.onLiveQueryEvent = function (handler) {
729729
triggers.addLiveQueryEventHandler(handler, Parse.applicationId);
730730
};
731731

732+
/**
733+
* Registers a before live query subscription function.
734+
*
735+
* **Available in Cloud Code only.**
736+
*
737+
* If you want to use beforeUnsubscribe for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1.
738+
* ```
739+
* Parse.Cloud.beforeUnsubscribe('MyCustomClass', (request) => {
740+
* // code here
741+
* }, (request) => {
742+
* // validation code here
743+
* });
744+
*
745+
* Parse.Cloud.beforeUnsubscribe(Parse.User, (request) => {
746+
* // code here
747+
* }, { ...validationObject });
748+
*```
749+
*
750+
* @method beforeUnsubscribe
751+
* @name Parse.Cloud.beforeUnsubscribe
752+
* @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the before subscription function for. This can instead be a String that is the className of the subclass.
753+
* @param {Function} func The function to run before a subscription. This function can be async and should take one parameter, a {@link Parse.Cloud.TriggerRequest}.
754+
* @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}.
755+
*/
756+
ParseCloud.beforeUnsubscribe = function (parseClass, handler, validationHandler) {
757+
validateValidator(validationHandler);
758+
const className = triggers.getClassName(parseClass);
759+
triggers.addTrigger(
760+
triggers.Types.beforeUnsubscribe,
761+
className,
762+
handler,
763+
Parse.applicationId,
764+
validationHandler
765+
);
766+
};
767+
732768
/**
733769
* Registers an after live query server event function.
734770
*

src/triggers.js

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export const Types = {
1414
afterFind: 'afterFind',
1515
beforeConnect: 'beforeConnect',
1616
beforeSubscribe: 'beforeSubscribe',
17+
beforeUnsubscribe: 'beforeUnsubscribe',
1718
afterEvent: 'afterEvent',
1819
};
1920

0 commit comments

Comments
 (0)