feat(gateway): add sender presence tracking
This commit is contained in:
@@ -132,6 +132,71 @@ describe('ChannelRegistry', () => {
|
||||
expect(adapter.sendFn).toHaveBeenCalledWith('user-42', { text: 'pong' });
|
||||
});
|
||||
|
||||
it('tracks presence from inbound messages', async () => {
|
||||
const adapter = createMockAdapter('test-channel');
|
||||
registry.register(adapter);
|
||||
registry.setMessageHandler(async () => {});
|
||||
|
||||
adapter.triggerMessage(makeMessage('test-channel'));
|
||||
|
||||
await vi.waitFor(() => {
|
||||
expect(registry.getPresence()).toHaveLength(1);
|
||||
});
|
||||
|
||||
const [presence] = registry.getPresence();
|
||||
expect(presence.channel).toBe('test-channel');
|
||||
expect(presence.senderId).toBe('user-42');
|
||||
expect(presence.messageCount).toBe(1);
|
||||
expect(presence.status).toBe('online');
|
||||
});
|
||||
|
||||
it('marks presence offline after inactivity window', async () => {
|
||||
vi.useFakeTimers();
|
||||
try {
|
||||
registry = new ChannelRegistry({ offlineAfterMs: 1000 });
|
||||
const adapter = createMockAdapter('test-channel');
|
||||
registry.register(adapter);
|
||||
registry.setMessageHandler(async () => {});
|
||||
|
||||
adapter.triggerMessage(makeMessage('test-channel'));
|
||||
await vi.runAllTimersAsync();
|
||||
|
||||
vi.advanceTimersByTime(1500);
|
||||
const [presence] = registry.getPresence();
|
||||
expect(presence.status).toBe('offline');
|
||||
} finally {
|
||||
vi.useRealTimers();
|
||||
}
|
||||
});
|
||||
|
||||
it('filters presence by channel and status', async () => {
|
||||
vi.useFakeTimers();
|
||||
try {
|
||||
registry = new ChannelRegistry({ offlineAfterMs: 1000 });
|
||||
const a1 = createMockAdapter('telegram');
|
||||
const a2 = createMockAdapter('discord');
|
||||
registry.register(a1);
|
||||
registry.register(a2);
|
||||
registry.setMessageHandler(async () => {});
|
||||
|
||||
a1.triggerMessage(makeMessage('telegram'));
|
||||
a2.triggerMessage({ ...makeMessage('discord'), senderId: 'user-99' });
|
||||
await vi.runAllTimersAsync();
|
||||
vi.advanceTimersByTime(1500);
|
||||
a2.triggerMessage({ ...makeMessage('discord'), senderId: 'user-99' });
|
||||
|
||||
const telegramOnly = registry.getPresence({ channel: 'telegram' });
|
||||
expect(telegramOnly).toHaveLength(1);
|
||||
expect(telegramOnly[0].channel).toBe('telegram');
|
||||
|
||||
const onlineOnly = registry.getPresence({ status: 'online' });
|
||||
expect(onlineOnly).toHaveLength(1);
|
||||
expect(onlineOnly[0].channel).toBe('discord');
|
||||
} finally {
|
||||
vi.useRealTimers();
|
||||
}
|
||||
});
|
||||
|
||||
it('routes reply using metadata.replyPeerId when provided', async () => {
|
||||
const adapter = createMockAdapter('test-channel');
|
||||
registry.register(adapter);
|
||||
|
||||
Reference in New Issue
Block a user