Skip to content

Commit

Permalink
PresenceMap: only emit a leave if a member was present
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonWoolf committed Nov 13, 2024
1 parent e94ddbd commit c28f836
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .mocharc.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const config = {
// if you've defined specs in your config. therefore we work around it by only adding specs to the
// config if none are passed as arguments
if (!process.argv.slice(2).some(isTestFile)) {
config.spec = ['test/realtime/*.test.js', 'test/rest/*.test.js'];
config.spec = ['test/realtime/*.test.js', 'test/rest/*.test.js', 'test/unit/*.test.js'];
}

function isTestFile(arg) {
Expand Down
2 changes: 1 addition & 1 deletion src/common/lib/client/presencemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export class PresenceMap extends EventEmitter {
delete map[key];
}

return true;
return !!existingItem;
}

startSync() {
Expand Down
48 changes: 48 additions & 0 deletions test/unit/presencemap.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use strict';

define(['chai', 'ably'], function (chai, Ably) {
const { assert } = chai;
const PresenceMap = Ably.Realtime._PresenceMap;

describe('PresenceMap', () => {
let presenceMap;

// Helper function to create a presence message
const createPresenceMessage = (clientId, connectionId, action, timestamp) => ({
clientId,
connectionId,
timestamp,
action,
});

beforeEach(() => {
// Initialize with a simple memberKey function that uses clientId as the key
presenceMap = new PresenceMap(
null,
(item) => item.clientId + ':' + item.connectionId,
(i, j) => i.timestamp > j.timestamp,
);
});

describe('remove()', () => {
it('should return false when no matching member present', () => {
const incoming = createPresenceMessage('client1', 'conn1', 'leave', 100);
assert.isFalse(presenceMap.remove(incoming));
});

it('should return true when removing an (older) matching member', () => {
const original = createPresenceMessage('client1', 'conn1', 'present', 100);
presenceMap.put(original);
const incoming = createPresenceMessage('client1', 'conn1', 'leave', 150);
assert.isTrue(presenceMap.remove(incoming));
});

it('should return false when trying to remove a newer matching member', () => {
const original = createPresenceMessage('client1', 'conn1', 'present', 100);
presenceMap.put(original);
const incoming = createPresenceMessage('client1', 'conn1', 'leave', 50);
assert.isFalse(presenceMap.remove(incoming));
});
});
});
});

0 comments on commit c28f836

Please sign in to comment.