matrix-media.spec.ts 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import { MEDIA_MSGTYPES, isMediaMsgType, isMxcUrl, parseNativeMedia } from './matrix-media';
  2. /**
  3. * Matrix 原生附件解析。
  4. *
  5. * 实测问题:容器用 `m.file` + `mxc://` 交付成果,
  6. * App 只认 `m.text`,导致**交付物完全看不到**。
  7. */
  8. describe('matrix-media', () => {
  9. describe('isMediaMsgType', () => {
  10. it('识别四种原生附件类型', () => {
  11. for (const t of MEDIA_MSGTYPES) {
  12. expect(isMediaMsgType(t)).withContext(t).toBeTrue();
  13. }
  14. });
  15. it('普通文本不算附件', () => {
  16. expect(isMediaMsgType('m.text')).toBeFalse();
  17. expect(isMediaMsgType(undefined)).toBeFalse();
  18. });
  19. });
  20. describe('parseNativeMedia', () => {
  21. it('🔴 m.file + mxc URL → 正确解析(实测的真实数据)', () => {
  22. const r = parseNativeMedia({
  23. msgtype: 'm.file',
  24. body: 'index.html',
  25. url: 'mxc://fmode.cn/aKiI3e8vxB5iNX7rrWyB6h2kB6snadai',
  26. info: { mimetype: 'text/html', size: 9760 },
  27. });
  28. expect(r).not.toBeNull();
  29. expect(r!.name).toBe('index.html');
  30. expect(r!.mxcUrl).toBe('mxc://fmode.cn/aKiI3e8vxB5iNX7rrWyB6h2kB6snadai');
  31. expect(r!.mimeType).toBe('text/html');
  32. expect(r!.size).toBe(9760);
  33. });
  34. it('m.image 带宽高', () => {
  35. const r = parseNativeMedia({
  36. msgtype: 'm.image',
  37. body: 'preview-mobile.png',
  38. url: 'mxc://fmode.cn/8u62SDHz',
  39. info: { mimetype: 'image/png', w: 390, h: 844 },
  40. });
  41. expect(r!.width).toBe(390);
  42. expect(r!.height).toBe(844);
  43. });
  44. it('m.text 不是附件 → null', () => {
  45. expect(parseNativeMedia({ msgtype: 'm.text', body: 'hello' })).toBeNull();
  46. });
  47. it('没有 url → null(不产生坏数据)', () => {
  48. expect(parseNativeMedia({ msgtype: 'm.file', body: 'x' })).toBeNull();
  49. });
  50. it('info 缺失 → 用默认 mime,不崩', () => {
  51. const r = parseNativeMedia({ msgtype: 'm.file', body: 'a.bin', url: 'mxc://x/y' });
  52. expect(r!.mimeType).toBe('application/octet-stream');
  53. expect(r!.size).toBeUndefined();
  54. });
  55. it('body 缺失 → 用默认名,不产生空名字', () => {
  56. const r = parseNativeMedia({ msgtype: 'm.file', url: 'mxc://x/y' });
  57. expect(r!.name).toBe('file');
  58. });
  59. });
  60. describe('isMxcUrl', () => {
  61. it('🔴 mxc:// 是内部协议,不是公网地址', () => {
  62. expect(isMxcUrl('mxc://fmode.cn/abc')).toBeTrue();
  63. });
  64. it('http(s) 不是', () => {
  65. expect(isMxcUrl('https://s3.fmode.cn/a')).toBeFalse();
  66. });
  67. it('空值不崩', () => {
  68. expect(isMxcUrl('')).toBeFalse();
  69. });
  70. });
  71. });