146 lines
8.5 KiB
Markdown
146 lines
8.5 KiB
Markdown
# TH Hotel SuperAgent MCP 联调测试用例
|
||
|
||
## 1. 文档信息
|
||
|
||
| 项目 | 内容 |
|
||
| --- | --- |
|
||
| 文档版本 | 0.1 |
|
||
| 日期 | 2026-07-09 |
|
||
| 状态 | 草案 |
|
||
| 适用范围 | SuperAgent HTTP MCP endpoint 联调和回归测试 |
|
||
|
||
## 2. 测试前置条件
|
||
|
||
测试前应确认:
|
||
|
||
- 后端 `server/` 已部署并暴露 `/mcp`。
|
||
- SuperAgent 已拿到 MCP 层访问凭证。
|
||
- 后端已配置 `MCP_ENABLED=true` 和 `MCP_AUTH_TOKEN`。
|
||
- 后端 `server/` dev/test 环境可访问。
|
||
- 测试数据不包含真实客户隐私、生产 Token、附件 URL 或支付信息。
|
||
|
||
## 3. 工具发现测试
|
||
|
||
| 用例 ID | 场景 | 期望结果 |
|
||
| --- | --- | --- |
|
||
| MCP-T00-001 | SuperAgent 连接 `/mcp` 并获取工具列表 | 能看到 5 个 TH Hotel tools |
|
||
| MCP-T00-002 | 未携带 MCP auth token | 返回 MCP 鉴权失败 |
|
||
| MCP-T00-003 | 使用错误 MCP auth token | 返回 MCP 鉴权失败,不调用后端 |
|
||
| MCP-T00-004 | 请求体不是合法 JSON | 返回 JSON-RPC parse error |
|
||
|
||
## 4. th_hotel_query_case_context
|
||
|
||
| 用例 ID | 场景 | 输入要点 | 期望结果 |
|
||
| --- | --- | --- | --- |
|
||
| MCP-T01-001 | 按 group code 查询 | `group_code`,`hotel_id` 可选 | 返回成功 envelope |
|
||
| MCP-T01-002 | 按 confirmation 查询 | `confirmation_number`,`hotel_id` 可选 | 返回成功 envelope |
|
||
| MCP-T01-003 | 缺少查询 key | 不传 `group_code` 和 `confirmation_number` | 返回 `QUERY_KEY_REQUIRED` |
|
||
| MCP-T01-004 | 缺省 hotel id | 不传 `hotel_id`,传 `group_code` | 后端按系统唯一 ACTIVE 酒店查询并返回成功 envelope |
|
||
| MCP-T01-005 | hotel id 不一致 | 传非系统酒店 `hotel_id` | 返回 `HOTEL_ACCESS_DENIED` 或 `HOTEL_ID_MISMATCH` |
|
||
|
||
## 5. th_hotel_query_object_detail
|
||
|
||
| 用例 ID | 场景 | 输入要点 | 期望结果 |
|
||
| --- | --- | --- | --- |
|
||
| MCP-T02-001 | 查询存在的订单对象 | `object_id=ORDER:{order_id}` | 返回对象详情 |
|
||
| MCP-T02-002 | 查询不存在对象 | 不存在的 `object_id` | 返回 `OBJECT_NOT_FOUND` |
|
||
| MCP-T02-003 | 缺少 object id | 只传 `hotel_id` | 返回请求参数错误 |
|
||
|
||
## 6. th_hotel_list_message_conversation_tasks
|
||
|
||
| 用例 ID | 场景 | 输入要点 | 期望结果 |
|
||
| --- | --- | --- | --- |
|
||
| MCP-T03-001 | 按外部会话 ID 查询任务 | `external_conversation_id` | 返回任务列表 |
|
||
| MCP-T03-002 | 按外部 source message id 锚点查询 | `source_message_id` | 返回该邮件所属会话任务 |
|
||
| MCP-T03-003 | 同 conversation id 不同 provider 隔离 | `source_provider=AGENTBUS` | 不返回其他 provider 的任务 |
|
||
| MCP-T03-004 | 会话不存在 | 不存在的 `external_conversation_id` | 返回 `MESSAGE_CONVERSATION_NOT_FOUND` |
|
||
| MCP-T03-005 | 缺少查询 key | 不传 `external_conversation_id` 和 `source_message_id` | 返回 `MESSAGE_CONVERSATION_QUERY_KEY_REQUIRED` |
|
||
|
||
排序验证:
|
||
|
||
- 任务先按邮件接收时间正序。
|
||
- 同一封邮件下按任务创建时间正序。
|
||
- 时间相同时按任务 ID 正序。
|
||
|
||
## 7. th_hotel_list_message_conversation_messages
|
||
|
||
| 用例 ID | 场景 | 输入要点 | 期望结果 |
|
||
| --- | --- | --- | --- |
|
||
| MCP-T04-001 | 按 source message id 查询邮件链正文 | `source_message_id` | 返回受控正文 |
|
||
| MCP-T04-002 | 按 external conversation id 查询邮件链正文 | `external_conversation_id` | 按接收时间正序返回正文 |
|
||
| MCP-T04-003 | 正文含图片和附件 URL | 测试 HTML 含 `src/href` | 响应不包含附件 URL 和图片 URL |
|
||
| MCP-T04-004 | 正文含原始 HTML | 后端有原文 HTML | 响应只包含 `html_body_sanitized` |
|
||
| MCP-T04-005 | 读取正文审计 | 调用正文工具 | 后端写入原文访问审计 |
|
||
|
||
禁止项验证:
|
||
|
||
- 响应不得包含 `attachments`。
|
||
- 响应不得包含 `inline_images`。
|
||
- 响应不得包含 `external_url`。
|
||
- 响应不得包含附件 URL。
|
||
- 响应不得包含原始未清洗 HTML。
|
||
|
||
## 8. th_hotel_submit_task_results
|
||
|
||
| 用例 ID | 场景 | 输入要点 | 期望结果 |
|
||
| --- | --- | --- | --- |
|
||
| MCP-T05-001 | V4 普通业务包 | `route_code=null + source_message + order_contexts[] + message_events[]` | 返回 `accepted_count`;只创建 V4 order task / cards,不创建旧 `workflow_reservation_task` |
|
||
| MCP-T05-001A | V4 普通业务包缺省 conversation_id | `source_message` 不传 `conversation_id` | 返回 `accepted_count`;仍只创建 V4 order task / cards |
|
||
| MCP-T05-002 | V4 type-known manual review | V4 `message_events[].manual_review=true`,业务字段可由 V4 入站识别 | 创建 V4 `REVIEW_REQUIRED` 卡,后续通过 V4 复核接口解阻 |
|
||
| MCP-T05-003 | V4 S10 来源通知 | `route_code=S10`,`order_contexts=[]`,`message_events=[]` | 创建 V4 source notification,不创建订单和旧任务 |
|
||
| MCP-T05-004 | V4 S99 来源通知 | `route_code=S99`,`order_contexts=[]`,`message_events=[]` | 创建 V4 source notification,不创建订单和旧任务 |
|
||
| MCP-T05-005 | source message 不存在 | V4 `source_message.source_message_id` 无法匹配 Inbox | 返回 `SOURCE_MESSAGE_NOT_FOUND` |
|
||
| MCP-T05-006 | 缺省 hotel id | 不传 `hotel_id`,source message 属于系统酒店 | 后端按系统唯一 ACTIVE 酒店写入成功 |
|
||
| MCP-T05-007 | source message 入库渠道为 OUTLOOK | 不传 `source_channel`,只传 V4 `source_message.source_message_id` | 后端按真实 Inbox 渠道写入成功 |
|
||
| MCP-T05-008 | source message 多渠道重复 | 同一酒店存在相同外部 `source_message_id` 的多条 Inbox | 返回 `SOURCE_MESSAGE_AMBIGUOUS` |
|
||
| MCP-T05-009 | V4 根结构缺字段 | 缺少 `order_contexts` 或 `message_events` | 返回 `MCP_SUBMIT_V4_REQUIRED`,不调用业务写入 Service |
|
||
| MCP-T05-010 | V4 source_message 字段错误 | 使用旧 `from/received_at/source_channel` 或缺少 `sender/body_content_type` | 返回 `MCP_SUBMIT_PAYLOAD_INVALID`,不调用业务写入 Service |
|
||
| MCP-T05-011 | V4 附件字段错误 | 附件缺少 `id/name/content_type/url` 或 `size` 不是数字 | 返回 `MCP_SUBMIT_PAYLOAD_INVALID`,不调用业务写入 Service |
|
||
| MCP-T05-012 | V4 event 业务契约错误 | event_type unsupported 或 Payment `attachment_ids[]` 不匹配同包附件 | 由业务入站层保存 `adapter_contract_error`,不创建用户可处理卡 |
|
||
| MCP-T05-013 | 旧 V3 业务根 | 含 `case_candidates` / `unhandled_current_intents` | 返回 `MCP_SUBMIT_V4_REQUIRED`,不调用业务写入 Service |
|
||
| MCP-T05-014 | 旧 V3 S10/S99 | 含 `handler_type` / `result_type=source_message_review_notification` | 返回 `MCP_SUBMIT_V4_REQUIRED`,不调用业务写入 Service |
|
||
| MCP-T05-015 | 旧 V2 task results | 顶层 `source_message_id + ai_task_results[]` | 返回 `MCP_SUBMIT_V4_REQUIRED`,不调用业务写入 Service |
|
||
|
||
写入验证:
|
||
|
||
- V4 `message_events[]` 顺序不能被 MCP endpoint 改变;业务层按数组顺序派生 event index。
|
||
- MCP endpoint 不能在日志输出完整 `extracted_fields` 中的敏感内容。
|
||
- 失败响应应保留后端错误码和 message。
|
||
- MCP adapter 校验失败时不进入业务写入 Service,且不自动重试。
|
||
- V4-only 模式下 `mapping_diagnostics_json` 为空对象;旧 V3 事件 ID 映射已经废弃。
|
||
|
||
## 9. MCP 鉴权和开关测试
|
||
|
||
| 用例 ID | 场景 | 期望结果 |
|
||
| --- | --- |
|
||
| MCP-AUTH-001 | `MCP_ENABLED=false` | `/mcp` 不暴露或不可调用 |
|
||
| MCP-AUTH-002 | 未携带 Bearer token | 返回 `MCP_AUTH_INVALID` |
|
||
| MCP-AUTH-003 | Bearer token 错误 | 返回 `MCP_AUTH_INVALID` |
|
||
| MCP-AUTH-004 | `MCP_ENABLE_SUBMIT_TASK_RESULTS=false` | 写入 tool 返回 `MCP_TOOL_DISABLED` |
|
||
| MCP-AUTH-005 | 请求体超过 `MCP_MAX_BODY_BYTES`,默认 10MB | 返回 `MCP_REQUEST_BODY_TOO_LARGE` |
|
||
|
||
## 10. 协议和内部异常测试
|
||
|
||
| 用例 ID | 场景 | 期望结果 |
|
||
| --- | --- |
|
||
| MCP-PROTO-001 | 调用不存在的 MCP method | 返回 `MCP_METHOD_NOT_FOUND` |
|
||
| MCP-PROTO-002 | 调用不存在的 tool | 返回 `MCP_TOOL_NOT_FOUND` |
|
||
| MCP-PROTO-003 | tool arguments 不合法 | 返回 `MCP_TOOL_ARGUMENTS_INVALID` |
|
||
| MCP-PROTO-004 | 发送 `notifications/initialized` | 返回 202 空响应体 |
|
||
|
||
## 11. 回归测试清单
|
||
|
||
每次 MCP endpoint 或 REST 契约变更后,至少回归:
|
||
|
||
- 5 个工具均能被发现。
|
||
- 5 个工具正常成功调用。
|
||
- 查询接口错误 envelope 不丢失。
|
||
- 任务结果写入成功和幂等重放正常。
|
||
- V4 submit payload adapter 的根结构、source_message、attachments 校验正常。
|
||
- 旧 V2/V3 submit payload 统一返回 `MCP_SUBMIT_V4_REQUIRED`,不会进入业务写入 Service。
|
||
- V4 S10/S99 来源通知可通过 MCP 写入工具。
|
||
- provider/channel 隔离正常。
|
||
- 受控正文不返回附件 URL。
|
||
- MCP auth 失败不进入业务 Service。
|
||
- REST HMAC 接口仍保持原有测试覆盖。
|