Files
xiaoxia-saas/tests/unit/test_asset_libraries_use_case.py
T
CI Bot 008404f0af
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 37s
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 / PR Build Web Image (pull_request) Successful in 53s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m2s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m14s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m14s
Preview Deploy / Deploy Preview Environment (pull_request) Failing after 34s
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 / Validate - Code Quality (pull_request) Successful in 3m16s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 2m36s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 4m2s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m36s
AI Code Review / AI Code Review (pull_request) Successful in 4m26s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m33s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 11m8s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 52m0s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 18s
test: P3-1 第32波单元测试
- bgm_utils: 12个测试(BGM合并逻辑/优先级/兼容层)
- domain/exceptions: 18个测试(NotFound/Validation/QuotaExceeded/继承关系)
- asset_libraries use case: 10个测试(列表/创建/命令对象)

合计+40
2026-07-24 09:32:05 +08:00

158 lines
4.8 KiB
Python
Executable File

"""素材库 UseCase 单元测试."""
from __future__ import annotations
from unittest.mock import MagicMock
import pytest
from packages.application.asset_libraries import (
CreateAssetLibraryCommand,
CreateAssetLibraryUseCase,
ListAssetLibrariesUseCase,
)
from packages.domain import AssetLibrary, AssetLibraryKind
@pytest.fixture
def mock_repo():
repo = MagicMock()
return repo
@pytest.fixture
def sample_library():
lib = AssetLibrary.create(
project_id="proj_456",
name="测试视频库",
kind=AssetLibraryKind.VIDEO,
)
lib.id = "lib_123"
return lib
class TestListAssetLibrariesUseCase:
"""ListAssetLibrariesUseCase 测试"""
def test_list_returns_repo_results(self, mock_repo, sample_library):
"""正常返回 repository 的查询结果"""
mock_repo.find_by_project.return_value = [sample_library]
use_case = ListAssetLibrariesUseCase(mock_repo)
result = use_case.execute("proj_456")
assert len(result) == 1
assert result[0].id == "lib_123"
mock_repo.find_by_project.assert_called_once_with("proj_456")
def test_empty_project_raises_value_error(self, mock_repo):
"""空 project_id 抛出 ValueError"""
use_case = ListAssetLibrariesUseCase(mock_repo)
with pytest.raises(ValueError, match="project_id 不能为空"):
use_case.execute("")
mock_repo.find_by_project.assert_not_called()
def test_whitespace_project_raises_value_error(self, mock_repo):
"""纯空格 project_id 也抛出 ValueError"""
use_case = ListAssetLibrariesUseCase(mock_repo)
with pytest.raises(ValueError, match="project_id 不能为空"):
use_case.execute(" ")
mock_repo.find_by_project.assert_not_called()
def test_project_id_stripped_before_query(self, mock_repo, sample_library):
"""project_id 会被 strip 后再查询"""
mock_repo.find_by_project.return_value = [sample_library]
use_case = ListAssetLibrariesUseCase(mock_repo)
use_case.execute(" proj_456 ")
mock_repo.find_by_project.assert_called_once_with("proj_456")
def test_empty_list(self, mock_repo):
"""项目没有素材库时返回空列表"""
mock_repo.find_by_project.return_value = []
use_case = ListAssetLibrariesUseCase(mock_repo)
result = use_case.execute("proj_456")
assert result == []
class TestCreateAssetLibraryUseCase:
"""CreateAssetLibraryUseCase 测试"""
def test_create_success(self, mock_repo, sample_library):
"""创建成功返回 AssetLibrary"""
mock_repo.create.return_value = sample_library
use_case = CreateAssetLibraryUseCase(mock_repo)
command = CreateAssetLibraryCommand(
project_id="proj_456",
name="新素材库",
kind=AssetLibraryKind.IMAGE,
)
result = use_case.execute(command)
assert result.id == "lib_123"
mock_repo.create.assert_called_once()
# 验证传入 repository 的是一个 AssetLibrary 对象
created = mock_repo.create.call_args[0][0]
assert isinstance(created, AssetLibrary)
assert created.project_id == "proj_456"
assert created.name == "新素材库"
assert created.kind == AssetLibraryKind.IMAGE
def test_create_with_video_kind(self, mock_repo):
"""创建视频类型素材库"""
mock_repo.create.side_effect = lambda x: x
use_case = CreateAssetLibraryUseCase(mock_repo)
command = CreateAssetLibraryCommand(
project_id="proj_1",
name="视频库",
kind=AssetLibraryKind.VIDEO,
)
result = use_case.execute(command)
assert result.kind == AssetLibraryKind.VIDEO
assert result.name == "视频库"
def test_create_with_voice_kind(self, mock_repo):
"""创建音色类型素材库"""
mock_repo.create.side_effect = lambda x: x
use_case = CreateAssetLibraryUseCase(mock_repo)
command = CreateAssetLibraryCommand(
project_id="proj_1",
name="音色库",
kind=AssetLibraryKind.VOICE,
)
result = use_case.execute(command)
assert result.kind == AssetLibraryKind.VOICE
class TestCreateAssetLibraryCommand:
"""CreateAssetLibraryCommand 数据类测试"""
def test_command_fields(self):
"""命令对象字段正确"""
cmd = CreateAssetLibraryCommand(
project_id="proj_1",
name="test",
kind=AssetLibraryKind.VIDEO,
)
assert cmd.project_id == "proj_1"
assert cmd.name == "test"
assert cmd.kind == AssetLibraryKind.VIDEO
def test_command_is_dataclass(self):
"""命令是 dataclass"""
from dataclasses import is_dataclass
assert is_dataclass(CreateAssetLibraryCommand)