Files
xiaoxia-saas/tests/unit/test_asset_batch_delete.py
T
灵应 f8bc252ded
CI/CD Pipeline / Build Production Runtime Images (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Staging E2E Tests (push) Failing after 49h30m34s
CI/CD Pipeline / Deploy Staging (push) Failing after 49h34m18s
CI/CD Pipeline / Frontend Lint (push) Failing after 49h36m48s
CI/CD Pipeline / Validate Code Quality And Tests (push) Failing after 49h36m54s
feat(assets): 批量删除接口 + 分页性能优化
- 新增 POST /assets/batch-delete 批量删除素材接口
  - 仓储层: abstract/SQLAlchemy/InMemory 均实现 batch_delete()
  - API层: 逐项校验项目权限后批量删除
  - Schema: BatchDeleteRequest/BatchDeleteResponse
- GET /assets 分页优化: 无 keyword/gender/style 过滤时走 DB 级 skip/limit
- 素材上传 duration 字段已全链路支持(domain/schema/ORM/repository)
- 新增 4 个批量删除单元测试,全量 1030 测试通过

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 11:06:24 +08:00

78 lines
2.5 KiB
Python

"""批量删除素材 + 分页优化 单元测试。"""
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "apps" / "api"))
from packages.adapters.in_memory.asset_repository import InMemoryAssetRepository
from packages.domain import Asset, AssetStatus
class TestBatchDelete:
"""batch_delete 仓储方法测试。"""
def _make_repo_with_assets(self):
repo = InMemoryAssetRepository()
for i in range(5):
asset = Asset.create(
project_id="proj-1",
library_id="lib-1",
name=f"voice_{i}.mp3",
storage_key=f"uploads/voice_{i}.mp3",
mime_type="audio/mpeg",
status=AssetStatus.READY,
)
repo.create(asset)
return repo
def test_batch_delete_removes_multiple(self):
repo = InMemoryAssetRepository()
assets = []
for i in range(5):
asset = Asset.create(
project_id="proj-1",
library_id="lib-1",
name=f"voice_{i}.mp3",
storage_key=f"uploads/voice_{i}.mp3",
mime_type="audio/mpeg",
)
repo.create(asset)
assets.append(asset)
ids_to_delete = [assets[0].id, assets[2].id, assets[4].id]
deleted_count = repo.batch_delete(ids_to_delete)
assert deleted_count == 3
# 验证确实被删了
assert repo.get(assets[0].id) is None
assert repo.get(assets[2].id) is None
assert repo.get(assets[4].id) is None
# 验证其他还在
assert repo.get(assets[1].id) is not None
assert repo.get(assets[3].id) is not None
def test_batch_delete_empty_list(self):
repo = self._make_repo_with_assets()
assert repo.batch_delete([]) == 0
def test_batch_delete_nonexistent_ids(self):
repo = self._make_repo_with_assets()
deleted = repo.batch_delete(["nonexistent-1", "nonexistent-2"])
assert deleted == 0
def test_batch_delete_mixed_existing_and_nonexistent(self):
repo = InMemoryAssetRepository()
asset = Asset.create(
project_id="proj-1",
library_id="lib-1",
name="voice.mp3",
storage_key="uploads/voice.mp3",
mime_type="audio/mpeg",
)
repo.create(asset)
deleted = repo.batch_delete([asset.id, "nonexistent"])
assert deleted == 1
assert repo.get(asset.id) is None