From 03fa96583ce6428b1c7aa91e1325fdf6df870a06 Mon Sep 17 00:00:00 2001 From: William Valentin Date: Tue, 17 Feb 2026 09:57:46 -0800 Subject: [PATCH] fix(matrix): allow attachment-only outbound messages --- src/channels/matrix/adapter.test.ts | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/channels/matrix/adapter.test.ts b/src/channels/matrix/adapter.test.ts index c08393e..4d37cb4 100644 --- a/src/channels/matrix/adapter.test.ts +++ b/src/channels/matrix/adapter.test.ts @@ -146,6 +146,36 @@ describe('MatrixAdapter', () => { }); }); + it('uploads binary attachments when outbound text is empty', async () => { + mockFetch.mockImplementation(async (url: string, init?: RequestInit) => { + if (url.endsWith('/_matrix/client/v3/account/whoami')) { + return jsonResponse({ user_id: '@flynn:example.org' }); + } + if (url.includes('/account_data/m.direct')) { + return jsonResponse({}); + } + if (url.includes('/_matrix/client/v3/sync')) { + return new Promise(() => {}); + } + if (init?.method === 'POST' && url.includes('/_matrix/client/v3/upload')) { + return jsonResponse({ content_uri: 'mxc://example.org/media123' }); + } + if (init?.method === 'PUT' && url.includes('/send/m.room.message/')) { + const body = JSON.parse(String(init?.body ?? '{}')); + expect(body.msgtype).toBe('m.image'); + expect(body.url).toBe('mxc://example.org/media123'); + return jsonResponse({ event_id: '$media2' }); + } + throw new Error(`Unexpected fetch URL: ${url}`); + }); + + await adapter.connect(); + await adapter.send('!room1:example.org', { + text: ' ', + attachments: [{ mimeType: 'image/png', data: 'aGVsbG8=', filename: 'image.png' }], + }); + }); + it('inbound message requires mention in non-DM rooms', async () => { const handler = vi.fn(); adapter.onMessage(handler);