Fix push notifications for account runtimes

This commit is contained in:
jjbrunton committed 2026-08-11 22:36:21 +01:00
1 parent a71ad56f3c
commit c028637556
5 files changed
+178 -1

No files matched your search

@@ -0,0 +1,87 @@
import { describe, expect, it, vi } from 'vitest';
import {
wireAccountChatEvents,
type AccountRuntimeEventReporter,
} from '../src/services/account-runtime-event-wiring.js';
import type {
MediaReceivedListener,
NewReplyListener,
SyncProgressListener,
} from '../src/services/chat/index.js';
function harness() {
let progressListener: SyncProgressListener | null = null;
let replyListener: NewReplyListener | null = null;
let mediaListener: MediaReceivedListener | null = null;
const chatService = {
setProgressListener: vi.fn((listener: SyncProgressListener | null) => { progressListener = listener; }),
setNewReplyListener: vi.fn((listener: NewReplyListener | null) => { replyListener = listener; }),
setMediaReceivedListener: vi.fn((listener: MediaReceivedListener | null) => { mediaListener = listener; }),
};
const events = {
conversation: vi.fn(),
reply: vi.fn(),
mediaReceived: vi.fn(),
sync: vi.fn(),
} satisfies AccountRuntimeEventReporter;
wireAccountChatEvents(chatService, events, '@t2_account:reddit.com');
return {
events,
progress: (value: Parameters<SyncProgressListener>[0], completion?: Parameters<SyncProgressListener>[1]) => {
if (!progressListener) throw new Error('Progress listener was not installed');
progressListener(value, completion);
},
reply: (value: Parameters<NewReplyListener>[0]) => {
if (!replyListener) throw new Error('Reply listener was not installed');
replyListener(value);
},
media: (value: Parameters<MediaReceivedListener>[0]) => {
if (!mediaListener) throw new Error('Media listener was not installed');
mediaListener(value);
},
};
}
describe('wireAccountChatEvents', () => {
it('publishes replies and media received by an account-owned chat service', () => {
const fixture = harness();
fixture.reply({
conversationId: '!room:reddit.com', replyId: 'event-1', username: 'alice', replySnippet: 'hello',
});
fixture.media({ conversationId: '!room:reddit.com', username: 'alice', count: 2 });
expect(fixture.events.conversation).toHaveBeenCalledWith({
id: '!room:reddit.com', state: 'replied', unread: 1,
});
expect(fixture.events.reply).toHaveBeenCalledWith({
conversationId: '!room:reddit.com', id: 'event-1', username: 'alice', body: 'hello',
});
expect(fixture.events.mediaReceived).toHaveBeenCalledWith({
conversationId: '!room:reddit.com', username: 'alice', count: 2,
});
});
it('publishes account-scoped sync progress and failures', () => {
const fixture = harness();
const progress = {
kind: 'delta', phase: 'starting', current: 0, total: 4, startedAt: 123,
} as const;
fixture.progress(progress);
fixture.progress({ ...progress, phase: 'listing-rooms', current: 2, label: 'Loading rooms' });
fixture.progress(null, { status: 'failed', error: 'Matrix unavailable' });
expect(fixture.events.sync).toHaveBeenNthCalledWith(1, {
phase: 'started', id: 'chat-@t2_account:reddit.com-123', kind: 'delta',
});
expect(fixture.events.sync).toHaveBeenNthCalledWith(2, {
phase: 'progress', id: 'chat-@t2_account:reddit.com-123', kind: 'delta',
current: 2, total: 4, label: 'Loading rooms',
});
expect(fixture.events.sync).toHaveBeenNthCalledWith(3, {
phase: 'failed', id: 'chat-@t2_account:reddit.com-123', kind: 'delta', error: 'Matrix unavailable',
});
});
});