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) '
+ }
+ />,
+ );
+
+ 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();
+ });
+});