XuqmGroup-Vue3SDK/VUE3_SDK_TEST_REPORT.md
XuqmGroup 49796f51ae docs(testing): 添加测试文档和修复多个平台SDK问题
- 新增 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 消息摘要不支持媒体类型问题
2026-04-30 16:54:10 +08:00

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.tsconnect() 方法在构建 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_URLDEFAULT_IM_WS_URL,未从 SDKConfig 读取自定义 URL。

修复:

  • SDKConfig 类型添加 baseUrl?: stringwsUrl?: string
  • init() 使用 config.baseUrl || DEFAULT_API_BASE_URL
  • ImClient.connect() 使用 config.wsUrl || DEFAULT_IM_WS_URL

状态: 已修复并验证


🟡 Bug 5: 缺少 sendMessage / createGroup API 封装

现象: SDK 没有暴露 sendMessagecreateGroup 函数,用户需直接调用 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-serviceWebSocketConfig.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 传递


七、下一步建议

  1. 发布新版 SDK: 当前修复包含重大协议变更(自定义 JSON → STOMP,建议发布新版本。
  2. 更新官方文档: 在 README 中补充 baseUrl / wsUrl 配置说明。
  3. Tenant Platform 集成: 已在 tenant-platform 目录结构中找到 IM 管理页面,建议将 Vue3 SDK 集成到 tenant-platform 中作为管理员 IM 测试工具。
  4. CI/CD 集成: 将 npm run testnode __tests__/integration/e2e.node.mjs 纳入 Jenkins 流水线。

测试结论: Vue3 SDK 经过全面测试和修复,HTTP API 和 WebSocket 实时消息流均工作正常,所有 75 项测试通过。