Skip to content

Commit

Permalink
Merge pull request #1092 from ParsePlatform/wangmengyan.add_livequery…
Browse files Browse the repository at this point in the history
…_support

Add LiveQuery to parse server
  • Loading branch information
gfosco committed Mar 18, 2016
2 parents cf36062 + 555e25b commit d5931f7
Show file tree
Hide file tree
Showing 33 changed files with 3,580 additions and 48 deletions.
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,24 @@
"deepcopy": "^0.6.1",
"express": "^4.13.4",
"gcloud": "^0.28.0",
"lru-cache": "^4.0.0",
"mailgun-js": "^0.7.7",
"mime": "^1.3.4",
"mongodb": "~2.1.0",
"multer": "^1.1.0",
"node-gcm": "^0.14.0",
"parse": "^1.7.0",
"redis": "^2.5.0-1",
"request": "^2.65.0",
"winston": "^2.1.1"
"tv4": "^1.2.7",
"winston": "^2.1.1",
"ws": "^1.0.1"
},
"devDependencies": {
"babel-cli": "^6.5.1",
"babel-core": "^6.5.1",
"babel-istanbul": "^0.6.0",
"babel-plugin-syntax-flow": "^6.5.0",
"babel-plugin-transform-flow-strip-types": "^6.5.0",
"babel-preset-es2015": "^6.5.0",
"babel-preset-stage-0": "^6.5.0",
Expand Down
290 changes: 290 additions & 0 deletions spec/Client.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,290 @@
var Client = require('../src/LiveQuery/Client').Client;
var ParseWebSocket = require('../src/LiveQuery/ParseWebSocketServer').ParseWebSocket;

describe('Client', function() {

it('can be initialized', function() {
var parseWebSocket = new ParseWebSocket({});
var client = new Client(1, parseWebSocket);

expect(client.id).toBe(1);
expect(client.parseWebSocket).toBe(parseWebSocket);
expect(client.subscriptionInfos.size).toBe(0);
});

it('can push response', function() {
var parseWebSocket = {
send: jasmine.createSpy('send')
};
Client.pushResponse(parseWebSocket, 'message');

expect(parseWebSocket.send).toHaveBeenCalledWith('message');
});

it('can push error', function() {
var parseWebSocket = {
send: jasmine.createSpy('send')
};
Client.pushError(parseWebSocket, 1, 'error', true);

var lastCall = parseWebSocket.send.calls.first();
var messageJSON = JSON.parse(lastCall.args[0]);
expect(messageJSON.op).toBe('error');
expect(messageJSON.error).toBe('error');
expect(messageJSON.code).toBe(1);
expect(messageJSON.reconnect).toBe(true);
});

it('can add subscription information', function() {
var subscription = {};
var fields = ['test'];
var subscriptionInfo = {
subscription: subscription,
fields: fields
}
var client = new Client(1, {});
client.addSubscriptionInfo(1, subscriptionInfo);

expect(client.subscriptionInfos.size).toBe(1);
expect(client.subscriptionInfos.get(1)).toBe(subscriptionInfo);
});

it('can get subscription information', function() {
var subscription = {};
var fields = ['test'];
var subscriptionInfo = {
subscription: subscription,
fields: fields
}
var client = new Client(1, {});
client.addSubscriptionInfo(1, subscriptionInfo);
var subscriptionInfoAgain = client.getSubscriptionInfo(1);

expect(subscriptionInfoAgain).toBe(subscriptionInfo);
});

it('can delete subscription information', function() {
var subscription = {};
var fields = ['test'];
var subscriptionInfo = {
subscription: subscription,
fields: fields
}
var client = new Client(1, {});
client.addSubscriptionInfo(1, subscriptionInfo);
client.deleteSubscriptionInfo(1);

expect(client.subscriptionInfos.size).toBe(0);
});


it('can generate ParseObject JSON with null selected field', function() {
var parseObjectJSON = {
key : 'value',
className: 'test',
objectId: 'test',
updatedAt: '2015-12-07T21:27:13.746Z',
createdAt: '2015-12-07T21:27:13.746Z',
ACL: 'test',
};
var client = new Client(1, {});

expect(client._toJSONWithFields(parseObjectJSON, null)).toBe(parseObjectJSON);
});

it('can generate ParseObject JSON with undefined selected field', function() {
var parseObjectJSON = {
key : 'value',
className: 'test',
objectId: 'test',
updatedAt: '2015-12-07T21:27:13.746Z',
createdAt: '2015-12-07T21:27:13.746Z',
ACL: 'test',
};
var client = new Client(1, {});

expect(client._toJSONWithFields(parseObjectJSON, undefined)).toBe(parseObjectJSON);
});

it('can generate ParseObject JSON with selected fields', function() {
var parseObjectJSON = {
key : 'value',
className: 'test',
objectId: 'test',
updatedAt: '2015-12-07T21:27:13.746Z',
createdAt: '2015-12-07T21:27:13.746Z',
ACL: 'test',
test: 'test'
};
var client = new Client(1, {});

expect(client._toJSONWithFields(parseObjectJSON, ['test'])).toEqual({
className: 'test',
objectId: 'test',
updatedAt: '2015-12-07T21:27:13.746Z',
createdAt: '2015-12-07T21:27:13.746Z',
ACL: 'test',
test: 'test'
});
});

it('can generate ParseObject JSON with nonexistent selected fields', function() {
var parseObjectJSON = {
key : 'value',
className: 'test',
objectId: 'test',
updatedAt: '2015-12-07T21:27:13.746Z',
createdAt: '2015-12-07T21:27:13.746Z',
ACL: 'test',
test: 'test'
};
var client = new Client(1, {});
var limitedParseObject = client._toJSONWithFields(parseObjectJSON, ['name']);

expect(limitedParseObject).toEqual({
className: 'test',
objectId: 'test',
updatedAt: '2015-12-07T21:27:13.746Z',
createdAt: '2015-12-07T21:27:13.746Z',
ACL: 'test',
});
expect('name' in limitedParseObject).toBe(false);
});

it('can push connect response', function() {
var parseWebSocket = {
send: jasmine.createSpy('send')
};
var client = new Client(1, parseWebSocket);
client.pushConnect();

var lastCall = parseWebSocket.send.calls.first();
var messageJSON = JSON.parse(lastCall.args[0]);
expect(messageJSON.op).toBe('connected');
expect(messageJSON.clientId).toBe(1);
});

it('can push subscribe response', function() {
var parseWebSocket = {
send: jasmine.createSpy('send')
};
var client = new Client(1, parseWebSocket);
client.pushSubscribe(2);

var lastCall = parseWebSocket.send.calls.first();
var messageJSON = JSON.parse(lastCall.args[0]);
expect(messageJSON.op).toBe('subscribed');
expect(messageJSON.clientId).toBe(1);
expect(messageJSON.requestId).toBe(2);
});

it('can push unsubscribe response', function() {
var parseWebSocket = {
send: jasmine.createSpy('send')
};
var client = new Client(1, parseWebSocket);
client.pushUnsubscribe(2);

var lastCall = parseWebSocket.send.calls.first();
var messageJSON = JSON.parse(lastCall.args[0]);
expect(messageJSON.op).toBe('unsubscribed');
expect(messageJSON.clientId).toBe(1);
expect(messageJSON.requestId).toBe(2);
});

it('can push create response', function() {
var parseObjectJSON = {
key : 'value',
className: 'test',
objectId: 'test',
updatedAt: '2015-12-07T21:27:13.746Z',
createdAt: '2015-12-07T21:27:13.746Z',
ACL: 'test',
test: 'test'
};
var parseWebSocket = {
send: jasmine.createSpy('send')
};
var client = new Client(1, parseWebSocket);
client.pushCreate(2, parseObjectJSON);

var lastCall = parseWebSocket.send.calls.first();
var messageJSON = JSON.parse(lastCall.args[0]);
expect(messageJSON.op).toBe('create');
expect(messageJSON.clientId).toBe(1);
expect(messageJSON.requestId).toBe(2);
expect(messageJSON.object).toEqual(parseObjectJSON);
});

it('can push enter response', function() {
var parseObjectJSON = {
key : 'value',
className: 'test',
objectId: 'test',
updatedAt: '2015-12-07T21:27:13.746Z',
createdAt: '2015-12-07T21:27:13.746Z',
ACL: 'test',
test: 'test'
};
var parseWebSocket = {
send: jasmine.createSpy('send')
};
var client = new Client(1, parseWebSocket);
client.pushEnter(2, parseObjectJSON);

var lastCall = parseWebSocket.send.calls.first();
var messageJSON = JSON.parse(lastCall.args[0]);
expect(messageJSON.op).toBe('enter');
expect(messageJSON.clientId).toBe(1);
expect(messageJSON.requestId).toBe(2);
expect(messageJSON.object).toEqual(parseObjectJSON);
});

it('can push update response', function() {
var parseObjectJSON = {
key : 'value',
className: 'test',
objectId: 'test',
updatedAt: '2015-12-07T21:27:13.746Z',
createdAt: '2015-12-07T21:27:13.746Z',
ACL: 'test',
test: 'test'
};
var parseWebSocket = {
send: jasmine.createSpy('send')
};
var client = new Client(1, parseWebSocket);
client.pushUpdate(2, parseObjectJSON);

var lastCall = parseWebSocket.send.calls.first();
var messageJSON = JSON.parse(lastCall.args[0]);
expect(messageJSON.op).toBe('update');
expect(messageJSON.clientId).toBe(1);
expect(messageJSON.requestId).toBe(2);
expect(messageJSON.object).toEqual(parseObjectJSON);
});

it('can push leave response', function() {
var parseObjectJSON = {
key : 'value',
className: 'test',
objectId: 'test',
updatedAt: '2015-12-07T21:27:13.746Z',
createdAt: '2015-12-07T21:27:13.746Z',
ACL: 'test',
test: 'test'
};
var parseWebSocket = {
send: jasmine.createSpy('send')
};
var client = new Client(1, parseWebSocket);
client.pushLeave(2, parseObjectJSON);

var lastCall = parseWebSocket.send.calls.first();
var messageJSON = JSON.parse(lastCall.args[0]);
expect(messageJSON.op).toBe('leave');
expect(messageJSON.clientId).toBe(1);
expect(messageJSON.requestId).toBe(2);
expect(messageJSON.object).toEqual(parseObjectJSON);
});
});
44 changes: 44 additions & 0 deletions spec/EventEmitterPubSub.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
var EventEmitterPubSub = require('../src/LiveQuery/EventEmitterPubSub').EventEmitterPubSub;

describe('EventEmitterPubSub', function() {

it('can publish and subscribe', function() {
var publisher = EventEmitterPubSub.createPublisher();
var subscriber = EventEmitterPubSub.createSubscriber();
subscriber.subscribe('testChannel');
// Register mock checked for subscriber
var isChecked = false;
subscriber.on('message', function(channel, message) {
isChecked = true;
expect(channel).toBe('testChannel');
expect(message).toBe('testMessage');
});

publisher.publish('testChannel', 'testMessage');
// Make sure the callback is checked
expect(isChecked).toBe(true);
});

it('can unsubscribe', function() {
var publisher = EventEmitterPubSub.createPublisher();
var subscriber = EventEmitterPubSub.createSubscriber();
subscriber.subscribe('testChannel');
subscriber.unsubscribe('testChannel');
// Register mock checked for subscriber
var isCalled = false;
subscriber.on('message', function(channel, message) {
isCalled = true;
});

publisher.publish('testChannel', 'testMessage');
// Make sure the callback is not called
expect(isCalled).toBe(false);
});

it('can unsubscribe not subscribing channel', function() {
var subscriber = EventEmitterPubSub.createSubscriber();

// Make sure subscriber does not throw exception
subscriber.unsubscribe('testChannel');
});
});
Loading

0 comments on commit d5931f7

Please sign in to comment.