diff --git a/spec/ParseLiveQueryServer.spec.js b/spec/ParseLiveQueryServer.spec.js index 562570b606..cfd89426c2 100644 --- a/spec/ParseLiveQueryServer.spec.js +++ b/spec/ParseLiveQueryServer.spec.js @@ -335,6 +335,35 @@ describe('ParseLiveQueryServer', function() { expect(JSON.stringify(args[1])).toBe(unsubscribeRequest); }); + it('can set update command message handler for a parseWebSocket', function() { + var parseLiveQueryServer = new ParseLiveQueryServer(10, 10, {}); + // Register mock connect/subscribe/unsubscribe handler for the server + spyOn(parseLiveQueryServer, '_handleUpdateSubscription').and.callThrough(); + spyOn(parseLiveQueryServer, '_handleUnsubscribe').and.callThrough(); + spyOn(parseLiveQueryServer, '_handleSubscribe').and.callThrough(); + + // Make mock parseWebsocket + var EventEmitter = require('events'); + var parseWebSocket = new EventEmitter(); + + // Register message handlers for the parseWebSocket + parseLiveQueryServer._onConnect(parseWebSocket); + + // Check updateRequest request + var updateRequest = '{"op":"update"}'; + // Trigger message event + parseWebSocket.emit('message', updateRequest); + // Make sure _handleUnsubscribe is called + var args = parseLiveQueryServer._handleUpdateSubscription.calls.mostRecent().args; + expect(args[0]).toBe(parseWebSocket); + expect(JSON.stringify(args[1])).toBe(updateRequest); + expect(parseLiveQueryServer._handleUnsubscribe).toHaveBeenCalled(); + let unsubArgs = parseLiveQueryServer._handleUnsubscribe.calls.mostRecent().args; + expect(unsubArgs.length).toBe(3); + expect(unsubArgs[2]).toBe(false); + expect(parseLiveQueryServer._handleSubscribe).toHaveBeenCalled(); + }); + it('can set unknown command message handler for a parseWebSocket', function() { var parseLiveQueryServer = new ParseLiveQueryServer(10, 10, {}); // Make mock parseWebsocket diff --git a/src/LiveQuery/ParseLiveQueryServer.js b/src/LiveQuery/ParseLiveQueryServer.js index 68b1c22003..70f859a9ae 100644 --- a/src/LiveQuery/ParseLiveQueryServer.js +++ b/src/LiveQuery/ParseLiveQueryServer.js @@ -259,6 +259,9 @@ class ParseLiveQueryServer { case 'subscribe': this._handleSubscribe(parseWebsocket, request); break; + case 'update': + this._handleUpdateSubscription(parseWebsocket, request); + break; case 'unsubscribe': this._handleUnsubscribe(parseWebsocket, request); break; @@ -473,7 +476,12 @@ class ParseLiveQueryServer { logger.verbose('Current client number: %d', this.clients.size); } - _handleUnsubscribe(parseWebsocket: any, request: any): any { + _handleUpdateSubscription(parseWebsocket: any, request: any): any { + this._handleUnsubscribe(parseWebsocket, request, false); + this._handleSubscribe(parseWebsocket, request); + } + + _handleUnsubscribe(parseWebsocket: any, request: any, notifyClient: bool = true): any { // If we can not find this client, return error to client if (!parseWebsocket.hasOwnProperty('clientId')) { Client.pushError(parseWebsocket, 2, 'Can not find this client, make sure you connect to server before unsubscribing'); @@ -512,6 +520,10 @@ class ParseLiveQueryServer { if (classSubscriptions.size === 0) { this.subscriptions.delete(className); } + + if (!notifyClient) { + return; + } client.pushUnsubscribe(request.requestId); diff --git a/src/LiveQuery/RequestSchema.js b/src/LiveQuery/RequestSchema.js index 9811df5738..2932b95aa9 100644 --- a/src/LiveQuery/RequestSchema.js +++ b/src/LiveQuery/RequestSchema.js @@ -4,7 +4,7 @@ let general = { 'properties': { 'op': { 'type': 'string', - 'enum': ['connect', 'subscribe', 'unsubscribe'] + 'enum': ['connect', 'subscribe', 'unsubscribe', 'update'] }, }, }; @@ -78,6 +78,44 @@ let subscribe = { 'additionalProperties': false }; +let update = { + 'title': 'Update operation schema', + 'type': 'object', + 'properties': { + 'op': 'update', + 'requestId': { + 'type': 'number' + }, + 'query': { + 'title': 'Query field schema', + 'type': 'object', + 'properties': { + 'className': { + 'type': 'string' + }, + 'where': { + 'type': 'object' + }, + 'fields': { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "uniqueItems": true + } + }, + 'required': ['where', 'className'], + 'additionalProperties': false + }, + 'sessionToken': { + 'type': 'string' + } + }, + 'required': ['op', 'requestId', 'query'], + 'additionalProperties': false +}; + let unsubscribe = { 'title': 'Unsubscribe operation schema', 'type': 'object', @@ -95,6 +133,7 @@ let RequestSchema = { 'general': general, 'connect': connect, 'subscribe': subscribe, + 'update': update, 'unsubscribe': unsubscribe }