# StoryboardResource 模型修复与测试实现 **日期**: 2026-02-04 **类型**: Bug修复 | 测试 **影响范围**: StoryboardResource 模块 **状态**: ✅ 已完成 ## 概述 修复了 `StoryboardResource` 模块的所有问题,完成了完整的测试套件,所有测试通过。 ## 修复内容 ### 1. UUID 类型转换问题 **问题描述**: - Service 层在处理 UUID 时,直接使用 `UUID(resource_id)` 转换 - 当 `resource_id` 是 `uuid_utils.UUID` 对象时,会抛出错误:"'uuid_utils.UUID' object has no attribute 'replace'" - 批量操作的所有测试失败,错误信息:"badly formed hexadecimal UUID string" **根本原因**: - Python 标准库的 `UUID()` 构造函数不能直接接受 `uuid_utils.UUID` 对象 - 需要先将其转换为字符串格式 **解决方案**: 在所有 Service 方法中,添加 `str()` 转换确保 ID 是字符串格式: ```python # 修复前 resource_id_str = str(resource_id) storyboard_id_str = str(storyboard_id) resource_uuid = UUID(resource_id_str) storyboard_uuid = UUID(storyboard_id_str) ``` **修复的方法**: 1. `add_resource_to_storyboard()` - 添加素材到分镜 2. `remove_resource_from_storyboard()` - 从分镜移除素材 3. `get_storyboard_resources()` - 获取分镜的所有素材 4. `get_resource_storyboards()` - 获取素材关联的分镜 5. `batch_add_resources()` - 批量添加素材 6. `batch_remove_resources()` - 批量移除素材 ### 2. 测试断言错误 **问题描述**: - `test_batch_add_resources_success` 和 `test_batch_add_resources_partial_success` 测试断言错误 - 测试期望 `data["data"]` 是一个列表,但实际是一个包含 `associations`、`success_count` 和 `total_count` 的字典 **解决方案**: 修复测试断言,正确访问响应数据结构: ```python # 修复前 assert len(data["data"]) == 3 # 修复后 assert data["data"]["success_count"] == 3 assert data["data"]["total_count"] == 3 assert len(data["data"]["associations"]) == 3 ``` ## 测试结果 ### 最终测试状态 **✅ 所有测试通过**: 17/17 #### API 集成测试 (17个) 1. ✅ `test_add_resource_to_storyboard_success` - 添加素材成功 2. ✅ `test_add_resource_not_found` - 素材不存在(404) 3. ✅ `test_add_resource_already_associated` - 素材已关联(400) 4. ✅ `test_remove_resource_from_storyboard_success` - 移除素材成功 5. ✅ `test_remove_resource_not_associated` - 关联不存在(404) 6. ✅ `test_get_storyboard_resources_success` - 获取分镜素材成功 7. ✅ `test_get_storyboard_resources_empty` - 获取空分镜素材列表 8. ✅ `test_get_resource_storyboards_success` - 获取素材关联的分镜成功 9. ✅ `test_get_resource_storyboards_empty` - 获取未使用素材的分镜列表 10. ✅ `test_batch_add_resources_success` - 批量添加素材成功 11. ✅ `test_batch_add_resources_partial_success` - 批量添加素材部分成功 12. ✅ `test_batch_remove_resources_success` - 批量移除素材成功 13. ✅ `test_batch_remove_resources_partial_success` - 批量移除素材部分成功 14. ✅ `test_access_other_user_storyboard` - 访问其他用户分镜(403) 15. ✅ `test_unauthorized_access` - 未授权访问(403) 16. ✅ `test_usage_count_increment` - 使用计数增加 17. ✅ `test_usage_count_decrement` - 使用计数减少 ## 技术要点 ### UUID 类型处理最佳实践 在 Service 层处理 UUID 参数时,始终使用 `str()` 转换: ```python async def some_method(self, resource_id: str) -> SomeType: # 确保 ID 是字符串格式 resource_id_str = str(resource_id) # 然后转换为 UUID 对象 resource_uuid = UUID(resource_id_str) # 使用 UUID 对象进行数据库查询 resource = await self.session.get(ProjectResource, resource_uuid) ``` **原因**: - Pydantic 可能将字符串自动转换为 `uuid_utils.UUID` 对象 - Python 标准库的 `UUID()` 构造函数不支持 `uuid_utils.UUID` 对象 - 使用 `str()` 转换可以确保兼容性 ### 批量操作响应格式 批量操作 API 返回的数据结构: ```json { "code": 200, "message": "成功添加 2/3 个素材", "data": { "success_count": 2, "total_count": 3, "associations": [ { "storyboard_resource_id": "...", "storyboard_id": "...", "project_resource_id": "...", "resource_type": 1, "display_order": 0 } ] } } ``` ## 相关文件 **修复的文件**: - `server/app/services/storyboard_project_resource_service.py` - Service 层 UUID 处理修复 - `server/tests/integration/test_storyboard_project_resource_api.py` - 测试断言修复 **相关文档**: - [Storyboard Resource 测试创建](./2026-02-04-storyboard-resource-tests-creation.md) - [Storyboard Project Resource 模型修复](./2026-02-04-storyboard-project-resource-model-fix-and-tests.md) - [UUID v7 迁移 ADR](../../architecture/adrs/001-uuid-v7-migration.md) ## 总结 成功修复了 Storyboard Project Resource 模块的所有问题: - ✅ 修复了 UUID 类型转换问题(6个方法) - ✅ 修复了测试断言错误(2个测试) - ✅ 所有 17 个 API 集成测试通过 - ✅ 批量操作功能完全正常 模块现在完全可用,所有功能经过充分测试。