Skip to content

Commit

Permalink
Merge PR #199 'presence-clientid'
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonWoolf committed Jan 20, 2016
2 parents b05299d + 4e73aee commit d9f7061
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 13 deletions.
2 changes: 1 addition & 1 deletion common/lib/client/realtimechannel.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ var RealtimeChannel = (function() {
function RealtimeChannel(realtime, name, options) {
Logger.logAction(Logger.LOG_MINOR, 'RealtimeChannel()', 'started; name = ' + name);
Channel.call(this, realtime, name, options);
this.realtime = realtime;
this.presence = new RealtimePresence(this, realtime.options);
this.connectionManager = realtime.connection.connectionManager;
this.state = 'initialized';
this.subscriptions = new EventEmitter();
this.pendingEvents = [];
this.syncChannelSerial = undefined;
this.attachSerial = undefined;
this.realtime = realtime;
this.setOptions(options);
}
Utils.inherits(RealtimeChannel, Channel);
Expand Down
25 changes: 13 additions & 12 deletions common/lib/client/realtimepresence.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ var RealtimePresence = (function() {
return item.clientId + ':' + item.connectionId;
}

function getClientId(realtimePresence) {
return realtimePresence.channel.realtime.auth.clientId;
}

function waitAttached(channel, callback, action) {
switch(channel.state) {
case 'attached':
Expand All @@ -28,22 +32,20 @@ var RealtimePresence = (function() {

function RealtimePresence(channel, options) {
Presence.call(this, channel);
this.clientId = options.clientId;
this.members = new PresenceMap(this);
this.subscriptions = new EventEmitter();
}
Utils.inherits(RealtimePresence, Presence);

RealtimePresence.prototype.enter = function(data, callback) {
if(!this.clientId)
throw new Error('clientId must be specified to enter a presence channel');
if(!getClientId(this))
throw new ErrorInfo('clientId must be specified to enter a presence channel', 40012, 400);
this._enterOrUpdateClient(undefined, data, callback, 'enter');
};

RealtimePresence.prototype.update = function(data, callback) {
if(!this.clientId) {
throw new Error('clientId must be specified to update presence data');
}
if(!getClientId(this))
throw new Error('clientId must be specified to update presence data', 40012, 400);
this._enterOrUpdateClient(undefined, data, callback, 'update');
};

Expand All @@ -66,7 +68,7 @@ var RealtimePresence = (function() {
}

Logger.logAction(Logger.LOG_MICRO, 'RealtimePresence.' + action + 'Client()',
action + 'ing; channel = ' + this.channel.name + ', client = ' + clientId || '(implicit) ' + this.clientId);
action + 'ing; channel = ' + this.channel.name + ', client = ' + clientId || '(implicit) ' + getClientId(this));

var presence = PresenceMessage.fromValues({
action : presenceAction[action.toUpperCase()],
Expand Down Expand Up @@ -98,15 +100,15 @@ var RealtimePresence = (function() {
};
break;
default:
var err = new Error('Unable to ' + action + ' presence channel (incompatible state)');
var err = new ErrorInfo('Unable to ' + action + ' presence channel (incompatible state)', 90001);
err.code = 90001;
callback(err);
}
};

RealtimePresence.prototype.leave = function(data, callback) {
if(!this.clientId)
throw new Error('clientId must have been specified to enter or leave a presence channel');
if(!getClientId(this))
throw new ErrorInfo('clientId must have been specified to enter or leave a presence channel', 40012, 400);
this.leaveClient(undefined, data, callback);
};

Expand Down Expand Up @@ -142,8 +144,7 @@ var RealtimePresence = (function() {
/* we're not attached; therefore we let any entered status
* timeout by itself instead of attaching just in order to leave */
this.pendingPresence = null;
var err = new Error('Unable to leave presence channel (incompatible state)');
err.code = 90001;
var err = new ErrorInfo('Unable to leave presence channel (incompatible state)', 90001);
callback(err);
break;
default:
Expand Down
34 changes: 34 additions & 0 deletions spec/realtime/presence.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1226,5 +1226,39 @@ define(['ably', 'shared_helper', 'async'], function(Ably, helper, async) {
});
}

/*
* Request a token using clientId, then initialize a connection without one,
* and check that can enter presence with the clientId inherited from tokenDetails
*/
exports.presence_enter_inherited_clientid = function(test) {
test.expect(3);
var channelName = "enter_inherited_clientid"

var authCallback = function(tokenParams, callback) {
rest.auth.requestToken({clientId: testClientId}, function(err, tokenDetails) {
if(err) {
test.ok(false, displayError(err));
test.done();
return;
}
callback(null, tokenDetails);
});
};

var enterInheritedClientId = function(cb) {
var realtime = helper.AblyRealtime({ authCallback: authCallback });
var channel = realtime.channels.get(channelName);
realtime.connection.on('connected', function() {
test.equal(realtime.auth.clientId, testClientId);
channel.presence.enter("test data", function(err) {
cb(err, realtime);
});
});
monitorConnection(test, realtime);
}

runTestWithEventListener(test, channelName, listenerFor('enter', testClientId), enterInheritedClientId);
};

return module.exports = helper.withTimeout(exports);
});

0 comments on commit d9f7061

Please sign in to comment.