From c370f9b853430451baff930fda49e89f6d9787ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Fri, 4 Sep 2026 11:52:12 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E8=81=8A=E5=A4=A9=20Markdown?= =?UTF-8?q?=20=E6=B8=B2=E6=9F=93=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 覆盖 GFM、代码块和表格展示 覆盖用户纯文本与流式中间态 覆盖 HTML、链接和图片安全边界 --- .../tests/ChatMarkdownMessage.test.tsx | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 apps/ai-game-creator-shell/tests/ChatMarkdownMessage.test.tsx diff --git a/apps/ai-game-creator-shell/tests/ChatMarkdownMessage.test.tsx b/apps/ai-game-creator-shell/tests/ChatMarkdownMessage.test.tsx new file mode 100644 index 000000000..b679cd6d5 --- /dev/null +++ b/apps/ai-game-creator-shell/tests/ChatMarkdownMessage.test.tsx @@ -0,0 +1,77 @@ +// @vitest-environment jsdom + +import { render } from '@testing-library/react'; +import { describe, expect, it } from 'vitest'; + +import { ChatMarkdownMessage } from '../src/components/ChatMarkdownMessage'; + +describe('ChatMarkdownMessage', () => { + it('渲染 assistant 的 GFM 内容与代码块', () => { + const { container } = render( + , + ); + + expect(container.querySelector('h2')?.textContent).toBe('标题'); + expect(container.querySelectorAll('li')).toHaveLength(2); + expect(container.querySelector('pre code')?.textContent).toContain( + 'const answer = 42;', + ); + }); + + it('保留流式 assistant 文本并标记 streaming 状态', () => { + const { container } = render( + , + ); + + expect(container.querySelector('[data-streaming="true"]')).toBeTruthy(); + expect(container.textContent).toContain('正在生成'); + expect(container.textContent).toContain('结果'); + }); + + it('用户消息保持纯文本,不解析 Markdown', () => { + const { container } = render( + , + ); + + expect(container.querySelector('strong')).toBeNull(); + expect(container.querySelector('code')).toBeNull(); + expect(container.textContent).toContain('**不要解析**'); + expect(container.textContent).toContain('`/read game`'); + }); + + it('不输出原始 HTML、可点击链接或图片节点', () => { + const { container } = render( + alert(1)\n\n[外链](https://example.com) ![示意图](x.png)' + } + />, + ); + + expect(container.querySelector('script')).toBeNull(); + expect(container.querySelector('a')).toBeNull(); + expect(container.querySelector('img')).toBeNull(); + expect(container.textContent).toContain('外链'); + expect(container.textContent).toContain('图片:示意图'); + }); + + it('支持表格并允许窄视口横向滚动', () => { + const { container } = render( + , + ); + + expect(container.querySelectorAll('table th')).toHaveLength(2); + expect(container.querySelector('div.overflow-x-auto')).toBeTruthy(); + }); +});