---
name: 文件预览语法高亮验收用例
description: 详细的测试场景，包括正向路径、错误路径、边界条件和安全测试
type: acceptance-cases
---

# 验收测试用例：文件预览语法高亮

## 命名约定
- **AC-P**: 正向路径 (Positive Path)
- **AC-E**: 错误路径 (Error Path)
- **AC-B**: 边界条件 (Boundary)
- **AC-S**: 安全测试 (Security)

---

## 正向路径测试

### AC-P-001: Python 文件语法高亮
- **前置条件**：用户已登录，技能包含 Python 文件（< 500KB）
- **步骤**：
  1. 打开技能详情页
  2. 点击文件树中的 `main.py` 文件
  3. 等待文件预览弹窗加载
- **预期结果**：
  - 显示语法高亮的 Python 代码
  - 关键字（`def`, `class`, `import`）显示为特定颜色
  - 字符串显示为特定颜色
  - 注释显示为特定颜色
  - 样式与 Markdown 代码块一致
- **相关约束**：BR-001, BR-007

### AC-P-002: Shell 脚本语法高亮
- **前置条件**：用户已登录，技能包含 Shell 脚本（< 500KB）
- **步骤**：
  1. 打开审核详情页
  2. 点击文件树中的 `install.sh` 文件
  3. 等待文件预览弹窗加载
- **预期结果**：
  - 显示语法高亮的 Shell 代码
  - 命令（`echo`, `cd`, `mkdir`）显示为特定颜色
  - 变量（`$VAR`）显示为特定颜色
  - 注释（`#`）显示为特定颜色
- **相关约束**：BR-001, BR-007

### AC-P-003: JSON 配置文件语法高亮
- **前置条件**：用户已登录，技能包含 JSON 文件（< 500KB）
- **步骤**：
  1. 打开技能详情页
  2. 点击文件树中的 `config.json` 文件
  3. 等待文件预览弹窗加载
- **预期结果**：
  - 显示语法高亮的 JSON 代码
  - 键名显示为特定颜色
  - 字符串值显示为特定颜色
  - 数字值显示为特定颜色
  - 布尔值显示为特定颜色
- **相关约束**：BR-001, BR-007

### AC-P-004: YAML 配置文件语法高亮
- **前置条件**：用户已登录，技能包含 YAML 文件（< 500KB）
- **步骤**：
  1. 打开技能详情页
  2. 点击文件树中的 `skill.yaml` 文件
  3. 等待文件预览弹窗加载
- **预期结果**：
  - 显示语法高亮的 YAML 代码
  - 键名显示为特定颜色
  - 字符串值显示为特定颜色
  - 缩进结构清晰可见
- **相关约束**：BR-001, BR-007

### AC-P-005: 多种语言混合测试
- **前置条件**：用户已登录，技能包含多种语言文件
- **步骤**：
  1. 打开技能详情页
  2. 依次点击 `main.py`, `install.sh`, `config.json`, `README.md`
  3. 观察每个文件的渲染效果
- **预期结果**：
  - 每种文件类型都正确渲染
  - Python 显示语法高亮
  - Shell 显示语法高亮
  - JSON 显示语法高亮
  - Markdown 显示富文本渲染（已有功能）
- **相关约束**：BR-001, BR-007

### AC-P-006: 语言自动识别
- **前置条件**：用户已登录，技能包含代码文件
- **步骤**：
  1. 打开技能详情页
  2. 点击文件树中的 `script.py` 文件
  3. 观察语法高亮效果
- **预期结果**：
  - 根据文件扩展名 `.py` 自动识别为 Python
  - 应用 Python 语法高亮规则
  - 无需用户手动选择语言
- **相关约束**：BR-001

### AC-P-007: 主题自动切换（Light → Dark）
- **前置条件**：用户已登录，系统主题为 Light 模式
- **步骤**：
  1. 打开技能详情页，预览 Python 文件
  2. 切换系统主题到 Dark 模式
  3. 观察语法高亮颜色变化
- **预期结果**：
  - 语法高亮主题自动切换到 Dark 模式
  - 颜色对比度适合暗色背景
  - 无需刷新页面
- **相关约束**：BR-006

### AC-P-008: 主题自动切换（Dark → Light）
- **前置条件**：用户已登录，系统主题为 Dark 模式
- **步骤**：
  1. 打开技能详情页，预览 Python 文件
  2. 切换系统主题到 Light 模式
  3. 观察语法高亮颜色变化
- **预期结果**：
  - 语法高亮主题自动切换到 Light 模式
  - 颜色对比度适合亮色背景
  - 无需刷新页面
- **相关约束**：BR-006

### AC-P-009: 复制代码功能
- **前置条件**：用户已登录，正在预览 Python 文件
- **步骤**：
  1. 打开文件预览弹窗
  2. 点击"复制"按钮
  3. 粘贴到文本编辑器
- **预期结果**：
  - 复制完整文件内容到剪贴板
  - 复制的是纯文本（无 HTML 标签）
  - 显示"已复制到剪贴板"提示
  - 复制按钮显示动画效果（旋转 → ✅）
- **相关约束**：BR-008

### AC-P-010: 下载代码功能
- **前置条件**：用户已登录，正在预览 Python 文件
- **步骤**：
  1. 打开文件预览弹窗
  2. 点击"下载"按钮
- **预期结果**：
  - 下载文件到本地
  - 文件名为原文件名（如 `main.py`）
  - 文件内容完整
- **相关约束**：BR-008

---

## 错误路径测试

### AC-E-001: 无法识别的语言（自定义扩展名）
- **前置条件**：用户已登录，技能包含自定义扩展名文件（如 `.custom`）
- **步骤**：
  1. 打开技能详情页
  2. 点击文件树中的 `script.custom` 文件
  3. 等待文件预览弹窗加载
- **预期结果**：
  - 显示纯文本（无语法高亮）
  - 不显示错误提示
  - 复制和下载功能正常
- **相关约束**：BR-003

### AC-E-002: 语法高亮渲染失败
- **前置条件**：模拟 highlight.js 渲染异常
- **步骤**：
  1. 打开技能详情页
  2. 点击文件树中的 Python 文件
  3. 触发渲染异常（通过测试 mock）
- **预期结果**：
  - 降级到纯文本显示
  - 显示友好的错误提示："语法高亮加载失败，已切换到纯文本模式"
  - 复制和下载功能正常
  - 记录错误日志到控制台
- **相关约束**：BR-004

### AC-E-003: 内存不足导致渲染失败
- **前置条件**：模拟浏览器内存不足
- **步骤**：
  1. 打开技能详情页
  2. 点击文件树中的大文件（接近 500KB）
  3. 触发内存不足异常（通过测试 mock）
- **预期结果**：
  - 降级到纯文本显示
  - 显示提示："文件较大，已切换到纯文本模式以节省内存"
  - 复制和下载功能正常
- **相关约束**：BR-005

### AC-E-004: 网络请求失败
- **前置条件**：模拟网络请求失败
- **步骤**：
  1. 打开技能详情页
  2. 点击文件树中的 Python 文件
  3. 触发网络请求失败（通过测试 mock）
- **预期结果**：
  - 显示错误提示："文件加载失败，请重试"
  - 提供"重试"按钮
  - 不显示文件内容
- **相关约束**：无（现有错误处理）

### AC-E-005: 文件内容为空
- **前置条件**：用户已登录，技能包含空文件
- **步骤**：
  1. 打开技能详情页
  2. 点击文件树中的空文件（0 字节）
  3. 等待文件预览弹窗加载
- **预期结果**：
  - 显示空白内容区域
  - 不显示错误提示
  - 复制按钮禁用或显示"文件为空"
- **相关约束**：无

---

## 边界条件测试

### AC-B-001: 文件大小刚好 500KB
- **前置条件**：用户已登录，技能包含 500KB 的 Python 文件
- **步骤**：
  1. 打开技能详情页
  2. 点击文件树中的 500KB Python 文件
  3. 等待文件预览弹窗加载
- **预期结果**：
  - 显示语法高亮（500KB 是阈值，包含在内）
  - 渲染时间 < 500ms
  - 无性能问题
- **相关约束**：BR-001

### AC-B-002: 文件大小 501KB（超过语法高亮阈值）
- **前置条件**：用户已登录，技能包含 501KB 的 Python 文件
- **步骤**：
  1. 打开技能详情页
  2. 点击文件树中的 501KB Python 文件
  3. 等待文件预览弹窗加载
- **预期结果**：
  - 显示纯文本（无语法高亮）
  - 显示提示："文件较大（501KB），已切换到纯文本模式"
  - 复制和下载功能正常
- **相关约束**：BR-001

### AC-B-003: 文件大小刚好 1MB
- **前置条件**：用户已登录，技能包含 1MB 的 Python 文件
- **步骤**：
  1. 打开技能详情页
  2. 点击文件树中的 1MB Python 文件
  3. 等待文件预览弹窗加载
- **预期结果**：
  - 显示纯文本（无语法高亮）
  - 显示提示："文件较大（1MB），已切换到纯文本模式"
  - 复制和下载功能正常
- **相关约束**：BR-001, BR-002

### AC-B-004: 文件大小 1.1MB（超过预览上限）
- **前置条件**：用户已登录，技能包含 1.1MB 的 Python 文件
- **步骤**：
  1. 打开技能详情页
  2. 点击文件树中的 1.1MB Python 文件
  3. 观察文件预览弹窗
- **预期结果**：
  - 不显示文件内容
  - 仅显示下载按钮
  - 显示提示："文件过大（1.1MB），请下载后查看"
- **相关约束**：BR-002

### AC-B-005: 文件名包含特殊字符
- **前置条件**：用户已登录，技能包含特殊字符文件名（如 `my-script (1).py`）
- **步骤**：
  1. 打开技能详情页
  2. 点击文件树中的特殊字符文件
  3. 等待文件预览弹窗加载
- **预期结果**：
  - 正常显示语法高亮
  - 文件名正确显示（包含特殊字符）
  - 下载时文件名保持原样
- **相关约束**：无

### AC-B-006: 文件内容包含 Unicode 字符
- **前置条件**：用户已登录，技能包含 Unicode 字符的 Python 文件（如中文注释）
- **步骤**：
  1. 打开技能详情页
  2. 点击文件树中的 Python 文件
  3. 等待文件预览弹窗加载
- **预期结果**：
  - 正常显示语法高亮
  - Unicode 字符（中文注释）正确显示
  - 复制时保留 Unicode 字符
- **相关约束**：无

### AC-B-007: 极长的单行代码（> 1000 字符）
- **前置条件**：用户已登录，技能包含极长单行代码的文件
- **步骤**：
  1. 打开技能详情页
  2. 点击文件树中的文件
  3. 观察渲染效果
- **预期结果**：
  - 正常显示语法高亮
  - 水平滚动条出现
  - 不影响页面布局
- **相关约束**：无

---

## 安全测试

### AC-S-001: XSS 防护（恶意 HTML 标签）
- **前置条件**：用户已登录，技能包含包含 HTML 标签的代码文件
- **步骤**：
  1. 上传包含 `<script>alert('XSS')</script>` 的 Python 文件
  2. 打开技能详情页
  3. 点击文件树中的该文件
  4. 观察是否执行脚本
- **预期结果**：
  - HTML 标签被转义显示为纯文本
  - 不执行任何脚本
  - 语法高亮正常工作
- **相关约束**：安全约束

### AC-S-002: XSS 防护（恶意事件处理器）
- **前置条件**：用户已登录，技能包含包含事件处理器的代码文件
- **步骤**：
  1. 上传包含 `<img src=x onerror=alert('XSS')>` 的文件
  2. 打开技能详情页
  3. 点击文件树中的该文件
  4. 观察是否执行脚本
- **预期结果**：
  - 事件处理器被转义显示为纯文本
  - 不执行任何脚本
  - 不加载任何外部资源
- **相关约束**：安全约束

### AC-S-003: 路径遍历防护
- **前置条件**：用户已登录
- **步骤**：
  1. 尝试访问 `/api/v1/reviews/1/file?path=../../../etc/passwd`
  2. 观察响应
- **预期结果**：
  - 返回 400 Bad Request
  - 不返回任何文件内容
  - 记录安全日志
- **相关约束**：安全约束（现有防护）

---

## 覆盖率矩阵

| 类型 | 数量 | 覆盖的约束 |
|------|------|-----------|
| 正向路径 (AC-P) | 10 | BR-001, BR-006, BR-007, BR-008 |
| 错误路径 (AC-E) | 5 | BR-003, BR-004, BR-005 |
| 边界条件 (AC-B) | 7 | BR-001, BR-002 |
| 安全测试 (AC-S) | 3 | 安全约束 |
| **总计** | **25** | **所有约束** |

---

## 变更日志
| 日期 | 章节 | 变更 | 原因 | 触发者 |
|------|------|------|------|--------|
| 2026-03-22 | 初始版本 | 创建验收用例文档 | 需求澄清完成 | requirements-clarity |
