import { MEDIA_MSGTYPES, isMediaMsgType, isMxcUrl, parseNativeMedia } from './matrix-media'; /** * Matrix 原生附件解析。 * * 实测问题:容器用 `m.file` + `mxc://` 交付成果, * App 只认 `m.text`,导致**交付物完全看不到**。 */ describe('matrix-media', () => { describe('isMediaMsgType', () => { it('识别四种原生附件类型', () => { for (const t of MEDIA_MSGTYPES) { expect(isMediaMsgType(t)).withContext(t).toBeTrue(); } }); it('普通文本不算附件', () => { expect(isMediaMsgType('m.text')).toBeFalse(); expect(isMediaMsgType(undefined)).toBeFalse(); }); }); describe('parseNativeMedia', () => { it('🔴 m.file + mxc URL → 正确解析(实测的真实数据)', () => { const r = parseNativeMedia({ msgtype: 'm.file', body: 'index.html', url: 'mxc://fmode.cn/aKiI3e8vxB5iNX7rrWyB6h2kB6snadai', info: { mimetype: 'text/html', size: 9760 }, }); expect(r).not.toBeNull(); expect(r!.name).toBe('index.html'); expect(r!.mxcUrl).toBe('mxc://fmode.cn/aKiI3e8vxB5iNX7rrWyB6h2kB6snadai'); expect(r!.mimeType).toBe('text/html'); expect(r!.size).toBe(9760); }); it('m.image 带宽高', () => { const r = parseNativeMedia({ msgtype: 'm.image', body: 'preview-mobile.png', url: 'mxc://fmode.cn/8u62SDHz', info: { mimetype: 'image/png', w: 390, h: 844 }, }); expect(r!.width).toBe(390); expect(r!.height).toBe(844); }); it('m.text 不是附件 → null', () => { expect(parseNativeMedia({ msgtype: 'm.text', body: 'hello' })).toBeNull(); }); it('没有 url → null(不产生坏数据)', () => { expect(parseNativeMedia({ msgtype: 'm.file', body: 'x' })).toBeNull(); }); it('info 缺失 → 用默认 mime,不崩', () => { const r = parseNativeMedia({ msgtype: 'm.file', body: 'a.bin', url: 'mxc://x/y' }); expect(r!.mimeType).toBe('application/octet-stream'); expect(r!.size).toBeUndefined(); }); it('body 缺失 → 用默认名,不产生空名字', () => { const r = parseNativeMedia({ msgtype: 'm.file', url: 'mxc://x/y' }); expect(r!.name).toBe('file'); }); }); describe('isMxcUrl', () => { it('🔴 mxc:// 是内部协议,不是公网地址', () => { expect(isMxcUrl('mxc://fmode.cn/abc')).toBeTrue(); }); it('http(s) 不是', () => { expect(isMxcUrl('https://s3.fmode.cn/a')).toBeFalse(); }); it('空值不崩', () => { expect(isMxcUrl('')).toBeFalse(); }); }); });