Skip to content

Commit 22516ac

Browse files
soimyclaude
andcommitted
docs(card): add image block test migration handoff document
Document the CardBlock[] format migration, test fixes for the 3 remaining failures, and the new media → image block behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 259c298 commit 22516ac

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# Handoff: Card v2 Image Block 测试迁移完成
2+
3+
## 状态
4+
5+
**测试进度**: 829/829 全部通过 ✅
6+
7+
**分支**: `card-template-v2`
8+
9+
**完成日期**: 2026-04-04
10+
11+
## 核心变更
12+
13+
card-draft-controller 从 markdown 字符串格式迁移到 JSON `CardBlock[]` 格式。
14+
15+
### 格式对比
16+
17+
**旧格式 (markdown)**
18+
```
19+
> 思考中...
20+
21+
> 工具调用结果...
22+
23+
最终答案文本
24+
```
25+
26+
**新格式 (JSON CardBlock[])**
27+
```json
28+
[
29+
{"type": 1, "markdown": "思考中..."},
30+
{"type": 2, "markdown": "工具调用结果..."},
31+
{"type": 0, "markdown": "最终答案文本"},
32+
{"type": 3, "mediaId": "xxx"}
33+
]
34+
```
35+
36+
### CardBlock 类型定义
37+
38+
```typescript
39+
type CardBlock =
40+
| { type: 0; markdown: string } // answer
41+
| { type: 1; markdown: string } // thinking
42+
| { type: 2; markdown: string } // tool
43+
| { type: 3; mediaId: string }; // image
44+
```
45+
46+
## 修复的 3 个测试失败
47+
48+
### 1. card-service.test.ts > createAICard returns card instance
49+
50+
**问题**: 测试期望 `cardParamMap` 不包含 `hasQuote`/`quoteContent`,但实际代码添加了这些字段。
51+
52+
**修复**: 更新测试断言以包含新字段:
53+
```typescript
54+
expect(body.cardData?.cardParamMap).toEqual({
55+
config: '{"autoLayout":true,"enableForward":true}',
56+
content: '',
57+
stop_action: 'true',
58+
hasQuote: 'false',
59+
quoteContent: '',
60+
});
61+
```
62+
63+
### 2. inbound-handler.test.ts > finalizes card with default content when no textual output is produced
64+
65+
**问题**: 测试期望 `"✅ Done"`,但得到 `"[]"` (空 JSON 数组)。
66+
67+
**根本原因**: `getRenderedContent()` 返回 JSON 字符串。当没有内容时,返回 `"[]"` 而不是空字符串。由于 `"[]"` 是 truthy,`||` fallback 不触发。
68+
69+
**修复**: 在 `card-draft-controller.ts``getRenderedContent` 中检查空数组:
70+
```typescript
71+
getRenderedContent: (options?) => {
72+
const blocks = renderTimelineAsBlocks(options);
73+
if (blocks.length === 0) {
74+
return "";
75+
}
76+
return JSON.stringify(blocks);
77+
},
78+
```
79+
80+
### 3. inbound-handler.test.ts > card mode + media
81+
82+
**问题**: 测试期望 `sendMessage` 被调用(旧行为),但新行为使用 `uploadMedia → appendImageBlock`
83+
84+
**根本原因**:
85+
1. `send-service` mock 缺少 `uploadMedia` 导出
86+
2. 测试期望基于旧的 markdown fallback 行为
87+
88+
**修复**:
89+
1. 添加 `uploadMediaMock` 到 shared mocks
90+
2. 更新 `send-service` mock 导出 `uploadMedia`
91+
3. 更新测试预期匹配新行为:
92+
```typescript
93+
// 旧: expect(sendMessageMock).toHaveBeenCalledWith(...)
94+
// 新:
95+
expect(shared.uploadMediaMock).toHaveBeenCalledWith(
96+
expect.objectContaining({ dmPolicy: "open", messageType: "card" }),
97+
"https://cdn.example.com/report.pdf",
98+
"image",
99+
undefined,
100+
);
101+
expect(shared.finishAICardMock).toHaveBeenCalledWith(
102+
card,
103+
JSON.stringify([
104+
{ type: 3, mediaId: "media_img_123" },
105+
{ type: 0, markdown: "final output" },
106+
]),
107+
undefined,
108+
{ quotedRef: {...} },
109+
);
110+
```
111+
112+
## 测试迁移辅助函数
113+
114+
`card-draft-controller.test.ts` 中添加:
115+
116+
```typescript
117+
function parseBlocks(content: string): CardBlock[] {
118+
try {
119+
return JSON.parse(content);
120+
} catch {
121+
return [];
122+
}
123+
}
124+
125+
function getBlockText(blocks: CardBlock[], index: number): string {
126+
const block = blocks[index];
127+
if (!block) return "";
128+
return "markdown" in block ? block.markdown : "";
129+
}
130+
```
131+
132+
## 关键文件变更
133+
134+
| 文件 | 变更类型 |
135+
|------|----------|
136+
| `src/card-draft-controller.ts` | `getRenderedContent` 返回 JSON,空数组返回 `""` |
137+
| `src/reply-strategy-card.ts` | mediaUrls → `uploadMedia``appendImageBlock` |
138+
| `tests/unit/card-service.test.ts` | 添加 `hasQuote`/`quoteContent` 断言 |
139+
| `tests/unit/inbound-handler.test.ts` | 添加 `uploadMediaMock`,更新 media 测试预期 |
140+
| `tests/unit/card-draft-controller.test.ts` | 添加 `parseBlocks`/`getBlockText` 辅助函数 |
141+
142+
## 下一步
143+
144+
- [ ] 真机验证 image block 渲染
145+
- [ ] 确认 mediaId 上传后图片正常显示
146+
- [ ] 合并到主分支

0 commit comments

Comments
 (0)