Files
xiaoxia-saas/tests/unit/test_duplication_use_cases.py
T
灵应 e25fd86171
Deploy / Staging E2E Tests (push) Has been skipped
Deploy / Build Production Runtime Images (push) Has been skipped
Deploy / Deploy Production (push) Has been skipped
Deploy / Production Browser E2E (push) Has been skipped
Deploy / Deploy Staging (push) Failing after 137h58m6s
CI/CD Pipeline / Frontend Lint (push) Failing after 137h58m12s
CI/CD Pipeline / Validate Code Quality And Tests (push) Failing after 137h58m12s
style: 后端代码isort import排序
2026-07-03 18:56:16 +08:00

233 lines
7.3 KiB
Python

"""查重应用层用例单元测试。
覆盖:
- UploadForDuplicationUseCase — 创建查重记录
- ListDuplicationRecordsUseCase — 列表查询(含分页)
- GetDuplicationDetailUseCase — 详情查询
- DeleteDuplicationRecordUseCase — 删除记录
- RetryDuplicationUseCase — 重试查重(含状态校验)
"""
from __future__ import annotations
from unittest.mock import MagicMock
import pytest
from packages.application.duplication import (
DeleteDuplicationRecordUseCase,
GetDuplicationDetailUseCase,
ListDuplicationRecordsUseCase,
RetryDuplicationUseCase,
UploadForDuplicationCommand,
UploadForDuplicationUseCase,
)
from packages.domain.duplication import DuplicateSegment, DuplicationRecord
def _make_record(status="pending", **kwargs):
"""创建测试用 DuplicationRecord。"""
record = DuplicationRecord.create(
user_id=kwargs.get("user_id", "user-1"),
filename=kwargs.get("filename", "test.mp4"),
file_size=kwargs.get("file_size", 1024),
storage_key=kwargs.get("storage_key", "oss/key"),
duration_seconds=kwargs.get("duration", 30.0),
)
if status != "pending":
record.mark_processing()
if status == "completed":
record.mark_completed(duplicate_rate=15.0, duplicate_count=1, segments=[])
elif status == "failed":
record.mark_failed("处理失败")
return record
class TestUploadForDuplicationUseCase:
"""上传查重用例测试。"""
def test_execute_creates_and_persists_record(self):
mock_repo = MagicMock()
mock_repo.create.side_effect = lambda r: r
use_case = UploadForDuplicationUseCase(mock_repo)
command = UploadForDuplicationCommand(
user_id="user-1",
filename="video.mp4",
file_size=2048,
storage_key="oss/video.mp4",
duration_seconds=60.0,
)
result = use_case.execute(command)
assert result.user_id == "user-1"
assert result.filename == "video.mp4"
assert result.file_size == 2048
assert result.status == "pending"
mock_repo.create.assert_called_once()
def test_execute_with_default_duration(self):
mock_repo = MagicMock()
mock_repo.create.side_effect = lambda r: r
use_case = UploadForDuplicationUseCase(mock_repo)
command = UploadForDuplicationCommand(
user_id="user-1",
filename="video.mp4",
file_size=1024,
storage_key="oss/key",
)
result = use_case.execute(command)
assert result.duration_seconds == 0.0
def test_execute_invalid_user_id_raises(self):
mock_repo = MagicMock()
use_case = UploadForDuplicationUseCase(mock_repo)
command = UploadForDuplicationCommand(
user_id="",
filename="video.mp4",
file_size=1024,
storage_key="oss/key",
)
with pytest.raises(ValueError, match="user_id"):
use_case.execute(command)
mock_repo.create.assert_not_called()
class TestListDuplicationRecordsUseCase:
"""列表查询用例测试。"""
def test_execute_returns_records(self):
records = [_make_record(), _make_record(filename="b.mp4")]
mock_repo = MagicMock()
mock_repo.list_by_user.return_value = records
use_case = ListDuplicationRecordsUseCase(mock_repo)
result = use_case.execute("user-1")
assert len(result) == 2
mock_repo.list_by_user.assert_called_once_with("user-1", offset=0, limit=50)
def test_execute_with_pagination(self):
mock_repo = MagicMock()
mock_repo.list_by_user.return_value = []
use_case = ListDuplicationRecordsUseCase(mock_repo)
use_case.execute("user-1", offset=10, limit=20)
mock_repo.list_by_user.assert_called_once_with("user-1", offset=10, limit=20)
def test_execute_empty_user_id_raises(self):
mock_repo = MagicMock()
use_case = ListDuplicationRecordsUseCase(mock_repo)
with pytest.raises(ValueError):
use_case.execute("")
mock_repo.list_by_user.assert_not_called()
def test_execute_whitespace_user_id_raises(self):
mock_repo = MagicMock()
use_case = ListDuplicationRecordsUseCase(mock_repo)
with pytest.raises(ValueError):
use_case.execute(" ")
def test_execute_strips_user_id(self):
mock_repo = MagicMock()
mock_repo.list_by_user.return_value = []
use_case = ListDuplicationRecordsUseCase(mock_repo)
use_case.execute(" user-1 ")
mock_repo.list_by_user.assert_called_once_with("user-1", offset=0, limit=50)
class TestGetDuplicationDetailUseCase:
"""详情查询用例测试。"""
def test_execute_returns_record(self):
record = _make_record()
mock_repo = MagicMock()
mock_repo.get.return_value = record
use_case = GetDuplicationDetailUseCase(mock_repo)
result = use_case.execute(record.id)
assert result is record
mock_repo.get.assert_called_once_with(record.id)
def test_execute_returns_none_for_missing(self):
mock_repo = MagicMock()
mock_repo.get.return_value = None
use_case = GetDuplicationDetailUseCase(mock_repo)
result = use_case.execute("nonexistent")
assert result is None
class TestDeleteDuplicationRecordUseCase:
"""删除用例测试。"""
def test_execute_deletes_record(self):
mock_repo = MagicMock()
mock_repo.delete.return_value = True
use_case = DeleteDuplicationRecordUseCase(mock_repo)
result = use_case.execute("record-1")
assert result is True
mock_repo.delete.assert_called_once_with("record-1")
def test_execute_returns_false_for_missing(self):
mock_repo = MagicMock()
mock_repo.delete.return_value = False
use_case = DeleteDuplicationRecordUseCase(mock_repo)
result = use_case.execute("nonexistent")
assert result is False
class TestRetryDuplicationUseCase:
"""重试用例测试。"""
def test_execute_resets_failed_record(self):
record = _make_record(status="failed")
mock_repo = MagicMock()
mock_repo.get.return_value = record
mock_repo.update.side_effect = lambda r: r
use_case = RetryDuplicationUseCase(mock_repo)
result = use_case.execute(record.id)
assert result is not None
assert result.status == "pending"
assert result.error_message == ""
assert result.duplicate_rate is None
assert result.duplicate_count == 0
assert result.segments == []
mock_repo.update.assert_called_once()
def test_execute_returns_none_for_missing(self):
mock_repo = MagicMock()
mock_repo.get.return_value = None
use_case = RetryDuplicationUseCase(mock_repo)
result = use_case.execute("nonexistent")
assert result is None
mock_repo.update.assert_not_called()
def test_execute_calls_repo_get_and_update(self):
record = _make_record(status="failed")
mock_repo = MagicMock()
mock_repo.get.return_value = record
mock_repo.update.side_effect = lambda r: r
use_case = RetryDuplicationUseCase(mock_repo)
use_case.execute(record.id)
mock_repo.get.assert_called_once_with(record.id)
mock_repo.update.assert_called_once()