test(wave100 🎯): 40 unit tests for 3 application layer modules (milestone) #964

Closed
xiaoxia wants to merge 7 commits from test/wave100-application-modules into develop
Owner

🎯 第100波里程碑

清理 3 个零测试的 application 层模块,新增 40 个单元测试。

覆盖模块

generated_videos.py (25 tests)

  • ListGeneratedVideosUseCase (4): 参数校验 + strip
  • ListGeneratedVideosPaginatedUseCase (7): 分页参数夹紧 + 全过滤条件
  • GetGeneratedVideoUseCase (2): 存在/不存在
  • ListGeneratedVideosByTaskUseCase (3): 参数校验
  • GetGeneratedVideoDownloadUrlUseCase (2)
  • UpdateVideoReviewStatusUseCase (7): 3种状态 + 校验 + 不存在返回None
  • GetVideosByIdsUseCase (2)

assets.py (6 tests)

  • CreateAssetCommand 数据类 + ListAssetsUseCase + CreateAssetUseCase

asset_libraries.py (5 tests)

  • CreateAssetLibraryCommand + ListAssetLibrariesUseCase + CreateAssetLibraryUseCase

测试策略

  • Mock repository,专注测参数校验 + 委托行为 + 边界值
  • 所有 ValueError 异常路径全覆盖

测试结果

本地 40 passed

## 🎯 第100波里程碑 清理 3 个零测试的 application 层模块,新增 40 个单元测试。 ## 覆盖模块 ### generated_videos.py (25 tests) - **ListGeneratedVideosUseCase** (4): 参数校验 + strip - **ListGeneratedVideosPaginatedUseCase** (7): 分页参数夹紧 + 全过滤条件 - **GetGeneratedVideoUseCase** (2): 存在/不存在 - **ListGeneratedVideosByTaskUseCase** (3): 参数校验 - **GetGeneratedVideoDownloadUrlUseCase** (2) - **UpdateVideoReviewStatusUseCase** (7): 3种状态 + 校验 + 不存在返回None - **GetVideosByIdsUseCase** (2) ### assets.py (6 tests) - CreateAssetCommand 数据类 + ListAssetsUseCase + CreateAssetUseCase ### asset_libraries.py (5 tests) - CreateAssetLibraryCommand + ListAssetLibrariesUseCase + CreateAssetLibraryUseCase ## 测试策略 - Mock repository,专注测参数校验 + 委托行为 + 边界值 - 所有 ValueError 异常路径全覆盖 ## 测试结果 本地 40 passed
xiaoxia added 7 commits 2026-07-26 20:13:07 +08:00
- Extract safe_parse_fps, is_valid_media, and constants from ingest.py
- New module: packages/domain/media_validation.py
- 70 new unit tests: safe_parse_fps(18) + constants(11) + is_valid_media(41)
- ingest.py: 424 -> 340 lines (-84, -20%)
- Backward compatible: private aliases preserved, original 25 tests pass
- Project: create validation + access control (is_owner/is_shared_with/can_access) = 13 tests
- AssetLibrary: create validation + kind variants = 6 tests
- AssetStatus: enum values + _missing_ backward compatibility (20+ aliases) = 26 tests
- Asset: create validation + file_type property + tag operations (add/remove/dedup) = 23 tests
- IngestJob: create validation + field stripping = 11 tests
- User: dataclass default values + admin + pro subscription = 3 tests
Total: 82 unit tests for entities.py 292 lines
- JobType enum: 3 tests
- JobStatus enum: 2 tests
- TERMINAL_STATUSES: 5 tests
- Job.create: 17 tests (validation + string enum + fields)
- is_terminal / is_retryable: 12 tests
- transition_to (state machine): 16 tests (all valid + invalid transitions)
- mark_running / mark_success / mark_failed / mark_cancelled: 8 tests
- update_progress: 9 tests
- prepare_retry: 4 tests
- to_dict serialization: 3 tests
Total: 76 unit tests for job.py (289 lines)
- QuotaDimension enum: 3 tests
- QuotaTier: 6 tests (get_limit / is_unlimited)
- QUOTA_TIERS: 4 tests (free/basic/premium + monotonic)
- QuotaWarningLevel: 1 test
- QuotaCheckResult.usage_percent: 6 tests
- QuotaRegistry: 9 tests (init / register / idempotent / tiers)
- QuotaChecker: 18 tests (check / multiple / warning levels / edge cases)
- get_warning_level + global singletons: 6 tests
Total: 53 unit tests for quota.py (270 lines)
- PresetBGM dataclass (frozen): 7 tests
- PRESET_BGM_LIBRARY integrity: 6 tests (unique IDs / valid styles / positive duration)
- BGM_STYLES: 2 tests
- get_preset_bgm: 4 tests
- list_preset_bgm_by_style: 6 tests (4 styles + empty + order)
- search_preset_bgm: 8 tests (name/desc/tag/case-insensitive/no match/empty/dup)
Total: 31 tests
Clean up zero-test small domain modules in one batch:
- EditingMode enum: 4 tests
- TemplateSegment dataclass: 2 tests
- ClipType + TransitionEffect enums: 3 tests
- TemplateClipConfig create + properties: 11 tests (validation + duration range + transition)
- EditTemplateVersion create: 6 tests
- VoiceLibraryItem: 2 tests
- TitleLibraryItem: 4 tests
- RecipeItem: 3 tests
Total: 35 tests across 8 modules
test(wave100): 40 unit tests for 3 application layer modules (milestone)
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 22s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 41s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m7s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m21s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 30s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 28s
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 2m12s
AI Code Review / AI Code Review (pull_request) Successful in 1m9s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m0s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m7s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 3m2s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m38s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Unit Tests (pull_request) Successful in 3m30s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m17s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Has been cancelled
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 14s
301d07e110
Milestone wave #100 — cleaning up zero-test application modules:
- generated_videos.py: 8 UseCases fully covered (25 tests)
  - ListGeneratedVideosUseCase: 4 tests
  - ListGeneratedVideosPaginatedUseCase: 7 tests (page clamp / page_size clamp / filters)
  - GetGeneratedVideoUseCase: 2 tests
  - ListGeneratedVideosByTaskUseCase: 3 tests
  - GetGeneratedVideoDownloadUrlUseCase: 2 tests
  - UpdateVideoReviewStatusUseCase: 7 tests (3 valid statuses + validation)
  - GetVideosByIdsUseCase: 2 tests
- assets.py: 6 tests (CreateAssetCommand + ListAssets + CreateAsset)
- asset_libraries.py: 5 tests (Command + List + Create)
Total: 40 tests across 3 modules
xiaoxia force-pushed test/wave100-application-modules from 9b248f711f to 301d07e110 2026-07-26 20:13:07 +08:00 Compare
Collaborator

代码审查结果 - PR #964

⚠️ 问题(2个需要修改)

  1. packages/domain/media_validation.py 第80-88行safe_parse_fps 函数缺少对 TypeError 的捕获。

    • 问题描述:当传入的 fps_strNone 时,执行 "/" in fps_strfloat(fps_str) 会抛出 TypeError,导致程序崩溃。当前仅捕获了 ValueErrorZeroDivisionError
    • 修改建议:在 except 块中增加 TypeError,或者在函数入口处增加对 fps_str 的非空校验。
  2. packages/domain/media_validation.py 第98-114行is_valid_media 函数中数值转换存在 TypeError 风险。

    • 问题描述:代码使用 int(metadata.get("size_bytes", 0)) 等方式获取数值。如果 metadata 字典中对应的 key 存在但值为 None(例如 {"width": None}),int(None) 会抛出 TypeError,导致校验失败。
    • 修改建议:使用 int(metadata.get("width") or 0) 或者在转换时增加 try-except TypeError 保护,确保即使 ffprobe 返回了 None 值也能正常处理。

💡 建议(1个可选)

  1. packages/domain/media_validation.py 第98行:建议对 media_type 进行大小写标准化处理。
    • 具体内容:虽然目前调用方可能传入小写,但作为 Domain 层的工具函数,建议在函数开头执行 media_type = media_type.lower(),以提高鲁棒性,避免因大小写不一致导致校验逻辑被跳过(直接返回 False)。

格式检查通过 | 逻辑审查需修改 | 性能无明显问题


🤖 由 AI 代码审查机器人自动生成 | 2026-07-26 12:29:10 | 模型:

## 代码审查结果 - PR #964 ### ⚠️ 问题(2个需要修改) 1. **packages/domain/media_validation.py 第80-88行**:`safe_parse_fps` 函数缺少对 `TypeError` 的捕获。 - 问题描述:当传入的 `fps_str` 为 `None` 时,执行 `"/" in fps_str` 或 `float(fps_str)` 会抛出 `TypeError`,导致程序崩溃。当前仅捕获了 `ValueError` 和 `ZeroDivisionError`。 - 修改建议:在 `except` 块中增加 `TypeError`,或者在函数入口处增加对 `fps_str` 的非空校验。 2. **packages/domain/media_validation.py 第98-114行**:`is_valid_media` 函数中数值转换存在 `TypeError` 风险。 - 问题描述:代码使用 `int(metadata.get("size_bytes", 0))` 等方式获取数值。如果 `metadata` 字典中对应的 key 存在但值为 `None`(例如 `{"width": None}`),`int(None)` 会抛出 `TypeError`,导致校验失败。 - 修改建议:使用 `int(metadata.get("width") or 0)` 或者在转换时增加 `try-except TypeError` 保护,确保即使 `ffprobe` 返回了 None 值也能正常处理。 ### 💡 建议(1个可选) 1. **packages/domain/media_validation.py 第98行**:建议对 `media_type` 进行大小写标准化处理。 - 具体内容:虽然目前调用方可能传入小写,但作为 Domain 层的工具函数,建议在函数开头执行 `media_type = media_type.lower()`,以提高鲁棒性,避免因大小写不一致导致校验逻辑被跳过(直接返回 False)。 --- ✅ 格式检查通过 | ❌ 逻辑审查需修改 | ✅ 性能无明显问题 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-07-26 12:29:10 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->

🚀 预览环境已部署

项目 详情
PR号 #964
预览链接 https://pr-964.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #964 | | 预览链接 | [https://pr-964.preview.xiaoxiajianji.com](https://pr-964.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
xiaoxia closed this pull request 2026-07-27 15:27:33 +08:00

🗑️ 预览环境已清理

PR #964 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #964 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Some checks are pending
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 22s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 41s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m7s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m21s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 30s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 28s
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 2m12s
AI Code Review / AI Code Review (pull_request) Successful in 1m9s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m0s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m7s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 3m2s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m38s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Unit Tests (pull_request) Successful in 3m30s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m17s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Has been cancelled
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 14s

Pull request closed

Sign in to join this conversation.