Skip to content

Commit

Permalink
Fix RealtimePresence#leave handling of PresenceMessage argument
Browse files Browse the repository at this point in the history
RealtimePresence’s `enter*`, `update*` and `leave*` methods all
advertise themselves as accepting a PresenceMessage instance instead of
just a data object. This is the only way that ably-js supports passing
message extras to these methods.

However, `leave` does not handle a PresenceMessage argument properly; it
ends up nesting the PresenceMessage’s top-level fields inside the
payload’s `data` property.

To fix this, we change the argument handling to match that used by
`enter`.

Resolves #1465.
  • Loading branch information
lawrence-forooghian committed Oct 20, 2023
1 parent 83b4516 commit dfe425c
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 24 deletions.
6 changes: 2 additions & 4 deletions src/common/lib/client/realtimepresence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,8 @@ class RealtimePresence extends Presence {
'RealtimePresence.leaveClient()',
'leaving; channel = ' + this.channel.name + ', client = ' + clientId
);
const presence = PresenceMessage.fromValues({
action: 'leave',
data: data,
});
const presence = PresenceMessage.fromData(data);
presence.action = 'leave';
if (clientId) {
presence.clientId = clientId;
}
Expand Down
71 changes: 51 additions & 20 deletions test/realtime/presence.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -373,38 +373,69 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, helper, async

/*
* Attach to channel, enter presence channel with extras and check received
* PresenceMessage has extras.
* PresenceMessage has extras. Then do the same for leaving presence.
*/
it('presenceMessageExtras', function (done) {
var clientRealtime = helper.AblyRealtime({ clientId: testClientId, tokenDetails: authToken });
var channelName = 'presenceMessageExtras';
var channelName = 'presenceEnterWithExtras';
var clientChannel = clientRealtime.channels.get(channelName);
var presence = clientChannel.presence;
presence.subscribe(
function (presenceMessage) {
try {
expect(presenceMessage.extras).to.deep.equal(
{ headers: { key: 'value' } },
'extras should have headers "key=value"'

async.series(
[
function (cb) {
clientChannel.attach(cb);
},
// Test entering with extras
function (cb) {
presence.subscribe('enter', function (presenceMessage) {
try {
expect(presenceMessage.extras).to.deep.equal(
{ headers: { key: 'value' } },
'extras should have headers "key=value"'
);
} catch (err) {
cb(err);
return;
}
cb();
});
presence.enter(
PresenceMessage.fromValues({
extras: { headers: { key: 'value' } },
})
);
} catch (err) {
closeAndFinish(done, clientRealtime, err);
return;
}
closeAndFinish(done, clientRealtime);
},
function onPresenceSubscribe(err) {
},
// Test leaving with extras
function (cb) {
presence.subscribe('leave', function (presenceMessage) {
try {
expect(presenceMessage.extras).to.deep.equal(
{ headers: { otherKey: 'otherValue' } },
'extras should have headers "otherKey=otherValue"'
);
} catch (err) {
cb(err);
return;
}
cb();
});
presence.leave(
PresenceMessage.fromValues({
extras: { headers: { otherKey: 'otherValue' } },
})
);
},
],
function (err) {
if (err) {
closeAndFinish(done, clientRealtime, err);
return;
}
clientChannel.presence.enter(
PresenceMessage.fromValues({
extras: { headers: { key: 'value' } },
})
);
closeAndFinish(done, clientRealtime);
}
);

monitorConnection(done, clientRealtime);
});

Expand Down

0 comments on commit dfe425c

Please sign in to comment.