- 新增 BUG_TRACKER.md 记录已修复和开放的bug - 新增 TEST_EXECUTION_2026-04-30.md 自动化测试执行报告 - 新增 TEST_PROGRESS.md 测试进度跟踪文档 - 修复 Android SDK connectedCheck 内存不足问题 - 修复 Android sample-app CAMERA 权限 lint 失败 - 修复 Android UpdateSDK longVersionCode minSdk lint 失败 - 修复 RN Chat Demo Jest 无法解析本地 SDK 源码包 - 修复 Python Server SDK 回调消息解析与顶层导出错误 - 修复 Vue3 SDK package exports 条件顺序警告 - 修复 im-service 群消息不进入会话聚合列表问题 - 修复 im-service 对外时间字段单位不一致问题 - 修复 RN SDK 历史消息 upsert 丢失回推状态问题 - 修复 Android 黑名单操作静默失败问题 - 修复 AppSecret 调用无鉴权安全问题 - 修复 IM Token 无过期信息问题 - 修复 RN SDK 草稿同步服务端数据污染问题 - 修复 Vue3 SDK 撤回编辑后依赖 WS 刷新延迟问题 - 修复 im-service 消息摘要不支持媒体类型问题
8.0 KiB
XuqmGroup Vue3 SDK 测试报告
生成时间: 2026-04-30
测试环境: Node.js v22.22.2, macOS
服务端: 192.168.113.37 (本地 IntelliJ 启动)
参考文档:/Users/xuqinmin/Projects/XuqmGroup/ANDROID_SDK_DEBUG.md
一、测试概览
| 类别 | 数量 | 通过 | 失败 |
|---|---|---|---|
| 单元测试 | 39 | 39 | 0 |
| 集成测试 (E2E) | 36 | 36 | 0 |
| 总计 | 75 | 75 | 0 |
二、发现的 Bug 及修复
🔴 Bug 1: ImClient 未实现 STOMP 协议
现象: WebSocket 连接成功,但发送消息后服务端不处理,history 中无记录,无实时推送。
根因: Vue3 SDK 的 ImClient.ts 发送的是自定义 JSON 格式:
{"destination": "/app/chat.send", "payload": {...}}
而服务端 Spring STOMP 期望标准 STOMP 协议帧:
SEND\ndestination:/app/chat.send\ncontent-type:application/json\n\n{body}\x00
修复: 重写 ImClient.ts,完整实现 STOMP 协议:
- CONNECT / CONNECTED 握手
- SEND 帧发送消息
- SUBSCRIBE 自动订阅
/user/queue/messages - MESSAGE / ERROR 帧解析
- DISCONNECT 优雅关闭
状态: ✅ 已修复并验证
🔴 Bug 2: CONNECT 帧缺少 Authorization Header
现象: STOMP 连接后发送消息,服务端 principal 为 null,消息被静默丢弃。
根因: 服务端 WebSocketConfig.java 从 STOMP CONNECT 帧的 Authorization header 提取 token:
String token = accessor.getFirstNativeHeader("Authorization");
而 Vue3 SDK 的 connect() 未在 CONNECT 帧中携带 Authorization: Bearer <token> header。
Android SDK 对比: Android SDK 的 sendConnectFrame 明确包含了:
"Authorization" to "Bearer $token"
修复: ImClient.ts 的 connect() 方法在构建 CONNECT 帧时添加:
const token = getToken()
if (token) headers['Authorization'] = `Bearer ${token}`
状态: ✅ 已修复并验证
🔴 Bug 3: connect() 中 token 未捕获,存在竞态条件
现象: 多客户端场景下,clientA 发送消息时使用错误的 token,导致认证失败。
根因: connect() 在 onopen 回调中调用 getToken() 获取当前 token。如果全局 token 在 clientA 连接建立前被其他客户端覆盖,clientA 会使用错误的 token 发送 CONNECT 帧。
修复: 在 connect() 方法入口处立即捕获 token 和 URL,后续 onopen 回调使用捕获值:
connect(): void {
const token = getToken() // 立即捕获
const url = `${config.wsUrl || DEFAULT_IM_WS_URL}?token=${token ?? ''}`
// ... onopen 中使用捕获的 token
}
状态: ✅ 已修复并验证
🟡 Bug 4: SDKConfig 不支持自定义 baseUrl / wsUrl
现象: SDK 只能连接 https://dev.xuqinmin.com,无法切换到本地测试环境 192.168.113.37。
根因: init() 硬编码使用 DEFAULT_API_BASE_URL 和 DEFAULT_IM_WS_URL,未从 SDKConfig 读取自定义 URL。
修复:
SDKConfig类型添加baseUrl?: string和wsUrl?: stringinit()使用config.baseUrl || DEFAULT_API_BASE_URLImClient.connect()使用config.wsUrl || DEFAULT_IM_WS_URL
状态: ✅ 已修复并验证
🟡 Bug 5: 缺少 sendMessage / createGroup API 封装
现象: SDK 没有暴露 sendMessage 和 createGroup 函数,用户需直接调用 http.post。
根因: api.ts 中缺少这两个常用 API 的封装。
修复: 在 src/im/api.ts 中添加:
export function sendMessage(params: {...}): Promise<ImMessage>
export function createGroup(params: {...}): Promise<ImGroup>
并在 src/index.ts 中导出。
状态: ✅ 已修复并验证
三、测试详情
3.1 单元测试
| 模块 | 测试数 | 说明 |
|---|---|---|
| core/sdk | 7 | init, getConfig, setToken, getToken, setUserId, getUserId |
| core/http | 8 | configureHttp, buildUrl, GET/POST/PUT/DELETE, query 参数处理, Date 序列化, 错误处理 |
| im/ImClient | 15 | STOMP 连接/发送/接收/撤回/重连/断开, 事件监听/取消, messageId 生成 |
| im/useIm | 9 | Composable 状态管理, 消息增删改, 会话排序, 已读标记, 连接/断开 |
3.2 集成测试 (E2E)
| 模块 | 测试项 | 结果 |
|---|---|---|
| Authentication | user_a / user_b 登录获取 token | ✅ |
| SDK Initialization | 自定义 baseUrl/wsUrl | ✅ |
| User Profile API | getProfile / updateProfile | ✅ |
| Conversations API | listConversations / markRead | ✅ |
| Message History API | fetchHistory / searchMessages | ✅ |
| Friends API | listFriends / listFriendRequests / searchUsers | ✅ |
| Groups API | listGroups / searchGroups / getGroupInfo | ✅ |
| WebSocket Connection | 双端 STOMP 连接 | ✅ |
| WebSocket Message Flow | send → history 确认 → sender echo → receiver push | ✅ |
| Read Receipt | markRead HTTP + WS READ 状态推送 | ✅ |
| Message Revoke | revoke WS + receiver revoke 事件 | ✅ |
| Conversation Management | pin / mute / draft / delete | ✅ |
| Group Operations | createGroup / fetchGroupHistory | ✅ |
| Message Edit | editMessage | ✅ |
四、Demo 应用
已创建独立 Vue3 Demo 应用:/Users/xuqinmin/Projects/XuqmGroup/XuqmGroup-Vue3SDK-Demo/
功能特性
- 快捷登录(user_a / user_b / user_ascii)
- WebSocket 实时连接状态显示
- 会话列表(含未读角标)
- 好友列表 / 群组列表
- 实时聊天(发送/接收/撤回)
- API 测试控制台(一键测试所有 API)
- 操作日志面板
启动方式
cd /Users/xuqinmin/Projects/XuqmGroup/XuqmGroup-Vue3SDK-Demo
npx vite
# 访问 http://localhost:5173
五、代码变更清单
| 文件 | 变更类型 | 说明 |
|---|---|---|
src/types/index.ts |
修改 | SDKConfig 添加 baseUrl / wsUrl |
src/core/sdk.ts |
修改 | init() 支持自定义 baseUrl |
src/im/ImClient.ts |
重写 | 完整 STOMP 协议实现 |
src/im/api.ts |
修改 | 添加 sendMessage / createGroup |
src/index.ts |
修改 | 导出新增 API |
package.json |
修改 | 添加 test / test:watch / test:coverage 脚本 |
vitest.config.ts |
新增 | Vitest 测试配置 |
__tests__/unit/core/sdk.test.ts |
新增 | SDK 单元测试 |
__tests__/unit/core/http.test.ts |
新增 | HTTP 客户端单元测试 |
__tests__/unit/im/ImClient.test.ts |
新增 | ImClient 单元测试 |
__tests__/unit/im/useIm.test.ts |
新增 | useIm Composable 单元测试 |
__tests__/integration/e2e.node.mjs |
新增 | Node.js 端到端集成测试 |
XuqmGroup-Vue3SDK-Demo/ |
新增 | Vue3 Demo 应用 |
六、服务端观察(非 SDK Bug)
在测试过程中,对服务端 im-service 的 WebSocketConfig.java 进行了代码审查:
String token = accessor.getFirstNativeHeader("Authorization");
if (token != null && token.startsWith("Bearer ")) {
token = token.substring(7);
if (jwtUtil.isValid(token)) {
String userId = jwtUtil.getSubject(token);
...
accessor.setUser(auth);
}
}
观察: 服务端仅从 STOMP header 读取 Authorization,不支持 URL query param ?token=xxx。这是合理的设计(STOMP 规范推荐),但需在 SDK 文档中明确说明:WebSocket 认证必须通过 CONNECT 帧的 Authorization header 传递。
七、下一步建议
- 发布新版 SDK: 当前修复包含重大协议变更(自定义 JSON → STOMP),建议发布新版本。
- 更新官方文档: 在 README 中补充
baseUrl/wsUrl配置说明。 - Tenant Platform 集成: 已在 tenant-platform 目录结构中找到 IM 管理页面,建议将 Vue3 SDK 集成到
tenant-platform中作为管理员 IM 测试工具。 - CI/CD 集成: 将
npm run test和node __tests__/integration/e2e.node.mjs纳入 Jenkins 流水线。
测试结论: Vue3 SDK 经过全面测试和修复,HTTP API 和 WebSocket 实时消息流均工作正常,所有 75 项测试通过。