test: 补充表单上传端点单元测试 #123

Merged
xiaoxia merged 2 commits from test/unit-tests-core-modules into develop 2026-06-30 15:35:46 +08:00
Owner

变更内容

新增测试文件

  • tests/unit/test_form_upload_routes.py - 表单上传端点单元测试(10个测试用例)

修复

  • apps/api/app/api/routes/upload.py - 修复表单参数处理,从 Annotated[Model, Form()] 改为独立 Form() 参数,确保 FastAPI 正确解析 multipart/form-data

测试覆盖场景

  1. 视频文件上传成功
  2. 图片文件上传成功
  3. 验证调用 find_by_project 而非 list_by_project
  4. 缺少文件字段返回 422
  5. 缺少 project_id 返回 422
  6. 缺少 library_id 返回 422
  7. project_id 为空字符串返回 422(min_length=1)
  8. 项目不存在返回 404
  9. 素材库不属于该项目返回 404
  10. OSS 未配置返回 503

测试结果

10 passed in 0.83s

所有测试通过,与现有 test_upload_routes.pytest_chunked_upload_routes.py 测试风格保持一致。

🤖 Generated with Claude Code

## 变更内容 ### 新增测试文件 - **tests/unit/test_form_upload_routes.py** - 表单上传端点单元测试(10个测试用例) ### 修复 - **apps/api/app/api/routes/upload.py** - 修复表单参数处理,从 `Annotated[Model, Form()]` 改为独立 `Form()` 参数,确保 FastAPI 正确解析 multipart/form-data ### 测试覆盖场景 1. ✅ 视频文件上传成功 2. ✅ 图片文件上传成功 3. ✅ 验证调用 `find_by_project` 而非 `list_by_project` 4. ✅ 缺少文件字段返回 422 5. ✅ 缺少 project_id 返回 422 6. ✅ 缺少 library_id 返回 422 7. ✅ project_id 为空字符串返回 422(min_length=1) 8. ✅ 项目不存在返回 404 9. ✅ 素材库不属于该项目返回 404 10. ✅ OSS 未配置返回 503 ### 测试结果 ``` 10 passed in 0.83s ``` 所有测试通过,与现有 `test_upload_routes.py` 和 `test_chunked_upload_routes.py` 测试风格保持一致。 🤖 Generated with [Claude Code](https://claude.com/claude-code)
xiaoxia added 1 commit 2026-06-30 13:13:17 +08:00
test: 补充表单上传端点单元测试
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Has been cancelled
CI/CD Pipeline / Frontend Lint (pull_request) Has been cancelled
16b18dc2fd
- 新增 tests/unit/test_form_upload_routes.py,覆盖10个测试场景
- 修复 upload.py 表单参数处理:从 Annotated[Model, Form()] 改为独立 Form() 参数
- 测试覆盖:正常上传成功、缺少文件字段、缺少必填参数、项目/素材库不存在、OSS未配置
- 所有测试通过,与现有 upload/chunked_upload 测试风格保持一致

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
xiaoxia added 1 commit 2026-06-30 15:28:20 +08:00
test: 扩展表单上传测试到24个用例
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Has been cancelled
CI/CD Pipeline / Frontend Lint (pull_request) Has been cancelled
b1f27b0ef6
根据灵应的规格补充测试覆盖:
- 正常路径(5): 视频/音频/图片上传成功、创建导入任务、响应包含URL
- 文件名校验(5): 路径遍历防护、反斜杠处理、空文件名、特殊字符、无扩展名
- 异常路径(8): 不支持文件类型、项目/素材库不存在、存储服务错误、缺少参数
- 多格式支持(3): 多种视频(4种)/音频(5种)/图片(6种)格式
- MIME验证(3): 有效类型、空类型(400)、不支持类型(415)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Author
Owner

🔍 代码审查 — PR #123

结论: 审查通过,可以合并。


变更分析

1. upload.py 路由签名重构(+2/-3)

form_data: Annotated[UploadAssetRequest, Form()] 改为独立的 project_id / library_id Form 字段。

合理改动。FastAPI 对 Pydantic Form 模型的支持有限,拆分为独立字段更可靠,且 min_length=1 直接在框架层阻止空字符串。

⚠️ 注意:这是破坏性变更,前端如有调用此端点需确认已适配新参数格式(直接发 project_idlibrary_id 表单字段,而非嵌套 JSON)。

2. test_form_upload_routes.py(+650 行,24 用例)

测试类 用例数 评价
TestFormUploadSuccess 5 覆盖视频/音频/图片上传、任务创建、响应结构
TestFormUploadFilenameValidation 5 路径遍历防护、反斜杠处理、特殊字符、空文件名
TestFormUploadMissingFile 1 缺文件字段返回 422
TestFormUploadMissingParameters 3 缺 project_id / library_id / 空字符串
TestFormUploadProjectNotFound 2 项目不存在、素材库不匹配
TestFormUploadOSSNotConfigured 1 OSS 未配置返回 503
TestFormUploadStorageErrors 1 存储服务通用错误返回 500
TestFormUploadMultipleFormats 3 视频4种/音频5种/图片6种格式遍历
TestFormUploadMIMEValidation 3 有效MIME/空MIME(400)/不支持MIME(415)

代码质量评价

  • Stub 设计优秀StubAssetLibraryRepository.list_by_project() 故意抛 AssertionError,与 PR #122 保持一致,防止回归
  • Mock 使用正确dependency_overrides 标准 FastAPI 测试模式
  • 断言有效:不仅检查状态码,还验证 storage_keyingest_job_idurl 等响应字段
  • 安全测试到位:路径遍历防护(../../../etc/passwd)测试是亮点
  • 无硬编码凭证:环境变量使用测试值

P2 建议(不阻塞合并)

  1. 前端适配确认:upload.py 签名从 Pydantic Form 改为独立字段,需确认前端 AssetLibrary.tsxuploadAsset 函数已适配
  2. 建议补充一个端到端集成测试,验证真实 multipart 上传流程

审查结论: 通过,24 个测试全部有意义,代码质量与 PR #122 保持一致。建议合并。

## 🔍 代码审查 — PR #123 **结论:✅ 审查通过,可以合并。** --- ### 变更分析 **1. `upload.py` 路由签名重构(+2/-3)** 将 `form_data: Annotated[UploadAssetRequest, Form()]` 改为独立的 `project_id` / `library_id` Form 字段。 ✅ 合理改动。FastAPI 对 Pydantic Form 模型的支持有限,拆分为独立字段更可靠,且 `min_length=1` 直接在框架层阻止空字符串。 ⚠️ **注意**:这是破坏性变更,前端如有调用此端点需确认已适配新参数格式(直接发 `project_id` 和 `library_id` 表单字段,而非嵌套 JSON)。 **2. `test_form_upload_routes.py`(+650 行,24 用例)** | 测试类 | 用例数 | 评价 | |--------|--------|------| | TestFormUploadSuccess | 5 | ✅ 覆盖视频/音频/图片上传、任务创建、响应结构 | | TestFormUploadFilenameValidation | 5 | ✅ 路径遍历防护、反斜杠处理、特殊字符、空文件名 | | TestFormUploadMissingFile | 1 | ✅ 缺文件字段返回 422 | | TestFormUploadMissingParameters | 3 | ✅ 缺 project_id / library_id / 空字符串 | | TestFormUploadProjectNotFound | 2 | ✅ 项目不存在、素材库不匹配 | | TestFormUploadOSSNotConfigured | 1 | ✅ OSS 未配置返回 503 | | TestFormUploadStorageErrors | 1 | ✅ 存储服务通用错误返回 500 | | TestFormUploadMultipleFormats | 3 | ✅ 视频4种/音频5种/图片6种格式遍历 | | TestFormUploadMIMEValidation | 3 | ✅ 有效MIME/空MIME(400)/不支持MIME(415) | ### 代码质量评价 - **Stub 设计优秀**:`StubAssetLibraryRepository.list_by_project()` 故意抛 `AssertionError`,与 PR #122 保持一致,防止回归 - **Mock 使用正确**:`dependency_overrides` 标准 FastAPI 测试模式 - **断言有效**:不仅检查状态码,还验证 `storage_key`、`ingest_job_id`、`url` 等响应字段 - **安全测试到位**:路径遍历防护(`../../../etc/passwd`)测试是亮点 - **无硬编码凭证**:环境变量使用测试值 ### P2 建议(不阻塞合并) 1. 前端适配确认:`upload.py` 签名从 Pydantic Form 改为独立字段,需确认前端 `AssetLibrary.tsx` 的 `uploadAsset` 函数已适配 2. 建议补充一个端到端集成测试,验证真实 multipart 上传流程 --- **审查结论:✅ 通过,24 个测试全部有意义,代码质量与 PR #122 保持一致。建议合并。**
xiaoxia merged commit e4f8b8d492 into develop 2026-06-30 15:35:46 +08:00
Sign in to join this conversation.