cursor-init/src/modules/dict/dict.test.md
expressgy 5580941ffb feat(dict): 新增字典项排序接口
- 实现了 PUT /api/dict/sort 接口,用于批量排序和移动字典项。
- 添加了 SortDictSchema 用于请求验证。
- 添加了 SortDictResponsesSchema 用于 API 文档。
- 使用原生 SQL 和 CASE 语句实现了 sortDict 服务层方法,进行高效的批量更新,解决了之前遇到的 ORM 类型问题。
- 在字典模块的控制器中添加了新路由。
- 在 dict.test.md 中为排序接口添加了全面的测试用例。
2025-07-07 21:56:18 +08:00

8.5 KiB
Raw Blame History

字典模块测试用例文档

1. 创建字典项接口 (POST /api/dict)

场景1: 成功创建顶级字典项

  • 名称: 成功创建一个顶级的、无父级的字典项
  • 前置条件: 数据库中不存在 code 为 test_root 的字典项
  • 请求方法: POST
  • 请求路径: /api/dict
  • 请求体:
    {
        "code": "test_root",
        "name": "测试顶级字典",
        "description": "这是一个用于测试的顶级字典项",
        "status": "active"
    }
    
  • 预期响应 (200 OK):
    • 响应体包含创建成功的字典项信息,pid 为 '0'level 为 1。
    • 数据库中存在该条记录。

场景2: 成功创建子级字典项

  • 名称: 成功创建一个子级的字典项
  • 前置条件:
    1. 数据库中存在一个 code 为 test_root 的字典项,其 id 为 100
    2. 数据库中不存在 code 为 test_child 的字典项。
  • 请求方法: POST
  • 请求路径: /api/dict
  • 请求体:
    {
        "code": "test_child",
        "name": "测试子级字典",
        "pid": "100",
        "description": "这是一个用于测试的子级字典项",
        "status": "active"
    }
    
  • 预期响应 (200 OK):
    • 响应体包含创建成功的字典项信息,pid 为 '100'level 为父级 level + 1。
    • 数据库中存在该条记录。

场景3: 失败 - code冲突

  • 名称: 因 code 重复导致创建失败
  • 前置条件: 数据库中已存在 code 为 test_root 的字典项。
  • 请求方法: POST
  • 请求路径: /api/dict
  • 请求体:
    {
        "code": "test_root",
        "name": "重复Code测试"
    }
    
  • 预期响应 (409 Conflict):
    • 响应体包含错误信息,提示 "字典代码已存在"。

场景4: 失败 - 父级不存在

  • 名称: 因父级 ID 不存在导致创建失败
  • 前置条件: -
  • 请求方法: POST
  • 请求路径: /api/dict
  • 请求体:
    {
        "code": "test_no_parent",
        "name": "无效父级测试",
        "pid": "99999"
    }
    
  • 预期响应 (404 Not Found):
    • 响应体包含错误信息,提示 "父级字典不存在"。

2. 获取字典项内容接口 (GET /api/dict/:id)

场景1: 成功获取存在的字典项

  • 名称: 根据存在的 ID 成功获取字典项
  • 前置条件: 数据库中存在一个 id 为 100 的字典项。
  • 请求方法: GET
  • 请求路径: /api/dict/100
  • 预期响应 (200 OK):
    • 响应体包含 id 为 100 的字典项的完整信息。

场景2: 失败 - 字典项不存在

  • 名称: 因 ID 不存在导致获取失败
  • 前置条件: 数据库中不存在 id 为 99999 的字典项。
  • 请求方法: GET
  • 请求路径: /api/dict/99999
  • 预期响应 (404 Not Found):
    • 响应体包含错误信息,提示 "字典项不存在"。

场景3: 失败 - ID格式错误

  • 名称: 因 ID 格式无效(非数字)导致获取失败
  • 前置条件: -
  • 请求方法: GET
  • 请求路径: /api/dict/abc
  • 预期响应 (400 Bad Request / 422 Unprocessable Entity):
    • 响应体包含参数验证错误信息。

3. 获取完整字典树接口 (GET /api/dict/tree)

场景1: 成功获取所有字典

  • 名称: 成功获取完整的字典树结构
  • 前置条件: 数据库中存在多个字典项,可以构成树形结构。
  • 请求方法: GET
  • 请求路径: /api/dict/tree
  • 预期响应 (200 OK):
    • 响应体 data 是一个数组,每个元素是一个顶层字典节点。
    • 每个节点包含 children 数组,递归地包含其子节点。
    • 节点按 sortOrder 排序。

场景2: 根据状态过滤 (active)

  • 名称: 获取所有状态为 'active' 的字典树
  • 前置条件: 数据库中同时存在 'active' 和 'inactive' 状态的字典项。
  • 请求方法: GET
  • 请求路径: /api/dict/tree?status=active
  • 预期响应 (200 OK):
    • 响应的树结构中只包含 status 为 'active' 的节点。

场景3: 根据系统字典过滤 (true)

  • 名称: 获取所有系统字典的字典树
  • 前置条件: 数据库中同时存在系统字典 (is_system=true) 和非系统字典 (is_system=false)。
  • 请求方法: GET
  • 请求路径: /api/dict/tree?is_system=true
  • 预期响应 (200 OK):
    • 响应的树结构中只包含 is_systemtrue 的节点。

场景4: 组合过滤

  • 名称: 获取所有状态为 'active' 且非系统字典的字典树
  • 前置条件: 数据库中存在满足各种组合条件的字典项。
  • 请求方法: GET
  • 请求路径: /api/dict/tree?status=active&is_system=false
  • 预期响应 (200 OK):
    • 响应的树结构中只包含 status 为 'active' 且 is_systemfalse 的节点。

场景5: 数据库为空

  • 名称: 在没有字典数据的情况下获取字典树
  • 前置条件: 数据库 sys_dict 表为空。
  • 请求方法: GET
  • 请求路径: /api/dict/tree
  • 预期响应 (200 OK):
    • 响应体 data 是一个空数组 []

4. 获取指定字典树接口 (GET /api/dict/tree/:code)

场景1: 成功获取存在的字典树

  • 名称: 根据存在的 code 成功获取指定的字典子树
  • 前置条件: 数据库中存在一个 code 为 user_gender 的字典项,且它有若干子项。
  • 请求方法: GET
  • 请求路径: /api/dict/tree/user_gender
  • 预期响应 (200 OK):
    • 响应体 data 是一个数组,仅包含一个根节点(即 user_gender 字典项)。
    • 该根节点包含其所有的子孙节点,形成一棵完整的子树。

场景2: 失败 - code 不存在

  • 名称: 因 code 不存在导致获取失败
  • 前置条件: 数据库中不存在 code 为 non_existent_code 的字典项。
  • 请求方法: GET
  • 请求路径: /api/dict/tree/non_existent_code
  • 预期响应 (404 Not Found):
    • 响应体包含错误信息,提示 "字典代码不存在"。

场景3: 带查询参数过滤

  • 名称: 获取指定字典树并根据状态过滤
  • 前置条件: user_gender 字典树中,部分子项的状态为 inactive
  • 请求方法: GET
  • 请求路径: /api/dict/tree/user_gender?status=active
  • 预期响应 (200 OK):
    • 返回的 user_gender 子树中,只包含状态为 active 的节点。

5. 更新字典项内容接口 (PUT /api/dict/:id)

场景1: 成功更新部分字段

  • 名称: 成功更新一个字典项的名称和描述
  • 前置条件: 数据库中存在一个 id 为 101 的字典项。
  • 请求方法: PUT
  • 请求路径: /api/dict/101
  • 请求体:
    {
        "name": "更新后的字典名称",
        "description": "这是更新后的描述信息。"
    }
    
  • 预期响应 (200 OK):
    • 响应体包含更新后的完整字典项信息。
    • 数据库中对应记录的 namedescription 字段已更新。

场景2: 失败 - ID 不存在

  • 名称: 因 ID 不存在导致更新失败
  • 前置条件: 数据库中不存在 id 为 99999 的字典项。
  • 请求方法: PUT
  • 请求路径: /api/dict/99999
  • 请求体:
    {
        "name": "任意名称"
    }
    
  • 预期响应 (404 Not Found):
    • 响应体包含错误信息,提示 "字典项不存在"。

场景3: 失败 - code 冲突

  • 名称: 更新时提供的 code 与其他字典项冲突
  • 前置条件:
    1. 数据库中存在 id 为 101 的字典项 (code: dict_a)。
    2. 数据库中存在另一个 id 为 102 的字典项 (code: dict_b)。
  • 请求方法: PUT
  • 请求路径: /api/dict/101
  • 请求体:
    {
        "code": "dict_b"
    }
    
  • 预期响应 (409 Conflict):
    • 响应体包含错误信息,提示 "字典代码已存在"。

场景4: 失败 - name 同级冲突

  • 名称: 更新时提供的 name 与同级其他字典项冲突
  • 前置条件:
    1. 数据库中存在一个父id为 100 的字典项 (id: 101, name: name_a)。
    2. 数据库中存在另一个父id也为 100 的字典项 (id: 102, name: name_b)。
  • 请求方法: PUT
  • 请求路径: /api/dict/101
  • 请求体:
    {
        "name": "name_b"
    }
    
  • 预期响应 (409 Conflict):
    • 响应体包含错误信息,提示 "同级下字典名称已存在"。