From 678b8ca6b82a9ea657de52875f18f2b4227c3721 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Tue, 25 Oct 2016 13:04:50 -0400 Subject: [PATCH 1/5] Adds ability to update a subscription --- spec/ParseLiveQueryServer.spec.js | 26 ++++++++++++++++++++++++++ src/LiveQuery/ParseLiveQueryServer.js | 8 ++++++++ 2 files changed, 34 insertions(+) diff --git a/spec/ParseLiveQueryServer.spec.js b/spec/ParseLiveQueryServer.spec.js index 562570b606..3f3a3bb1b7 100644 --- a/spec/ParseLiveQueryServer.spec.js +++ b/spec/ParseLiveQueryServer.spec.js @@ -335,6 +335,32 @@ 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(); + 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..fb24929237 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,6 +476,11 @@ class ParseLiveQueryServer { logger.verbose('Current client number: %d', this.clients.size); } + _handleUpdateSubscription(parseWebsocket: any, request: any): any { + this._handleUnsubscribe(parseWebsocket, request); + this._handleSubscribe(parseWebsocket, request); + } + _handleUnsubscribe(parseWebsocket: any, request: any): any { // If we can not find this client, return error to client if (!parseWebsocket.hasOwnProperty('clientId')) { From 4dd499b7d19a704c2e323f4f6f389b33506d3066 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Tue, 25 Oct 2016 20:36:54 -0400 Subject: [PATCH 2/5] Adds unsubscribe to the RequestSchema, makes sure to not fire unsubscribe to the client when updating --- src/LiveQuery/ParseLiveQueryServer.js | 14 +++++---- src/LiveQuery/RequestSchema.js | 41 ++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/LiveQuery/ParseLiveQueryServer.js b/src/LiveQuery/ParseLiveQueryServer.js index fb24929237..17e96b6605 100644 --- a/src/LiveQuery/ParseLiveQueryServer.js +++ b/src/LiveQuery/ParseLiveQueryServer.js @@ -477,11 +477,18 @@ class ParseLiveQueryServer { } _handleUpdateSubscription(parseWebsocket: any, request: any): any { - this._handleUnsubscribe(parseWebsocket, request); + this._removeClientSubscription(parseWebsocket, request); this._handleSubscribe(parseWebsocket, request); } _handleUnsubscribe(parseWebsocket: any, request: any): any { + let client = this._removeClientSubscription(parseWebsocket, request); + client.pushUnsubscribe(request.requestId); + + logger.verbose('Delete client: %d | subscription: %d', parseWebsocket.clientId, request.requestId); + } + + _removeClientSubscription(parseWebsocket: any, request: any): 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'); @@ -520,10 +527,7 @@ class ParseLiveQueryServer { if (classSubscriptions.size === 0) { this.subscriptions.delete(className); } - - client.pushUnsubscribe(request.requestId); - - logger.verbose('Delete client: %d | subscription: %d', parseWebsocket.clientId, request.requestId); + return client; } } 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 } From a7afe0f95bbdc9dd9ad7de3aa69a0556699c739e Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Tue, 25 Oct 2016 20:52:40 -0400 Subject: [PATCH 3/5] Fix failing tests --- src/LiveQuery/ParseLiveQueryServer.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/LiveQuery/ParseLiveQueryServer.js b/src/LiveQuery/ParseLiveQueryServer.js index 17e96b6605..4261942962 100644 --- a/src/LiveQuery/ParseLiveQueryServer.js +++ b/src/LiveQuery/ParseLiveQueryServer.js @@ -477,18 +477,11 @@ class ParseLiveQueryServer { } _handleUpdateSubscription(parseWebsocket: any, request: any): any { - this._removeClientSubscription(parseWebsocket, request); + this._handleUnsubscribe(parseWebsocket, request, false); this._handleSubscribe(parseWebsocket, request); } - _handleUnsubscribe(parseWebsocket: any, request: any): any { - let client = this._removeClientSubscription(parseWebsocket, request); - client.pushUnsubscribe(request.requestId); - - logger.verbose('Delete client: %d | subscription: %d', parseWebsocket.clientId, request.requestId); - } - - _removeClientSubscription(parseWebsocket: any, request: any): any { + _handleUnsubscribe(parseWebsocket: any, request: any, notifyClient = true: bool): 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'); @@ -527,7 +520,14 @@ class ParseLiveQueryServer { if (classSubscriptions.size === 0) { this.subscriptions.delete(className); } - return client; + + if (!notifyClient) { + return; + } + + client.pushUnsubscribe(request.requestId); + + logger.verbose('Delete client: %d | subscription: %d', parseWebsocket.clientId, request.requestId); } } From a53dfa46c5900f59c718d730bd5ef50867c77f3a Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Tue, 25 Oct 2016 20:55:46 -0400 Subject: [PATCH 4/5] More extensive tests --- spec/ParseLiveQueryServer.spec.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/ParseLiveQueryServer.spec.js b/spec/ParseLiveQueryServer.spec.js index 3f3a3bb1b7..cfd89426c2 100644 --- a/spec/ParseLiveQueryServer.spec.js +++ b/spec/ParseLiveQueryServer.spec.js @@ -358,6 +358,9 @@ describe('ParseLiveQueryServer', function() { 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(); }); From 18d85f88d657d215c4e7f391b0f8fbd7bb708e7f Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Tue, 25 Oct 2016 21:13:45 -0400 Subject: [PATCH 5/5] fix annotation --- src/LiveQuery/ParseLiveQueryServer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LiveQuery/ParseLiveQueryServer.js b/src/LiveQuery/ParseLiveQueryServer.js index 4261942962..70f859a9ae 100644 --- a/src/LiveQuery/ParseLiveQueryServer.js +++ b/src/LiveQuery/ParseLiveQueryServer.js @@ -481,7 +481,7 @@ class ParseLiveQueryServer { this._handleSubscribe(parseWebsocket, request); } - _handleUnsubscribe(parseWebsocket: any, request: any, notifyClient = true: bool): any { + _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');