Adds ability to update a subscription (#2935)

* Adds ability to update a subscription

* Adds unsubscribe to the RequestSchema, makes sure to not fire unsubscribe to the client when updating

* Fix failing tests

* More extensive tests

* fix annotation
This commit is contained in:
Florent Vilmart
2016-10-31 08:12:11 -04:00
committed by GitHub
parent 94178df4d2
commit 48865c765f
3 changed files with 82 additions and 2 deletions

View File

@@ -335,6 +335,35 @@ describe('ParseLiveQueryServer', function() {
expect(JSON.stringify(args[1])).toBe(unsubscribeRequest); 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() { it('can set unknown command message handler for a parseWebSocket', function() {
var parseLiveQueryServer = new ParseLiveQueryServer(10, 10, {}); var parseLiveQueryServer = new ParseLiveQueryServer(10, 10, {});
// Make mock parseWebsocket // Make mock parseWebsocket

View File

@@ -257,6 +257,9 @@ class ParseLiveQueryServer {
case 'subscribe': case 'subscribe':
this._handleSubscribe(parseWebsocket, request); this._handleSubscribe(parseWebsocket, request);
break; break;
case 'update':
this._handleUpdateSubscription(parseWebsocket, request);
break;
case 'unsubscribe': case 'unsubscribe':
this._handleUnsubscribe(parseWebsocket, request); this._handleUnsubscribe(parseWebsocket, request);
break; break;
@@ -471,7 +474,12 @@ class ParseLiveQueryServer {
logger.verbose('Current client number: %d', this.clients.size); 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 we can not find this client, return error to client
if (!parseWebsocket.hasOwnProperty('clientId')) { if (!parseWebsocket.hasOwnProperty('clientId')) {
Client.pushError(parseWebsocket, 2, 'Can not find this client, make sure you connect to server before unsubscribing'); Client.pushError(parseWebsocket, 2, 'Can not find this client, make sure you connect to server before unsubscribing');
@@ -510,6 +518,10 @@ class ParseLiveQueryServer {
if (classSubscriptions.size === 0) { if (classSubscriptions.size === 0) {
this.subscriptions.delete(className); this.subscriptions.delete(className);
} }
if (!notifyClient) {
return;
}
client.pushUnsubscribe(request.requestId); client.pushUnsubscribe(request.requestId);

View File

@@ -4,7 +4,7 @@ let general = {
'properties': { 'properties': {
'op': { 'op': {
'type': 'string', 'type': 'string',
'enum': ['connect', 'subscribe', 'unsubscribe'] 'enum': ['connect', 'subscribe', 'unsubscribe', 'update']
}, },
}, },
}; };
@@ -78,6 +78,44 @@ let subscribe = {
'additionalProperties': false '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 = { let unsubscribe = {
'title': 'Unsubscribe operation schema', 'title': 'Unsubscribe operation schema',
'type': 'object', 'type': 'object',
@@ -95,6 +133,7 @@ let RequestSchema = {
'general': general, 'general': general,
'connect': connect, 'connect': connect,
'subscribe': subscribe, 'subscribe': subscribe,
'update': update,
'unsubscribe': unsubscribe 'unsubscribe': unsubscribe
} }