Files
xiaoxia-saas/tests/unit/test_classification_domain.py
T
xiaoxia 07f6705534
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / Build Production API Image (push) Has been skipped
CI/CD Pipeline / Build Production Web Image (push) Has been skipped
CI/CD Pipeline / Build Production Worker Image (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 / Build Staging Web Image (push) Successful in 36s
CI/CD Pipeline / Frontend Lint (push) Successful in 1m36s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 1m47s
CI/CD Pipeline / Build Staging API Image (push) Successful in 2m15s
CI/CD Pipeline / Validate Code Quality And Tests (push) Successful in 2m23s
CI/CD Pipeline / Unit Tests (push) Successful in 2m23s
CI/CD Pipeline / Integration Tests (push) Successful in 1m3s
CI/CD Pipeline / Build Staging Worker Image (push) Has been cancelled
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (push) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (push) Has been cancelled
CI/CD Pipeline / ACR Image Cleanup (push) Has been cancelled
test(unit): P3-1 第四波 新增3个领域模块单元测试(65个用例) (#682)
Co-authored-by: CI Bot <dev@xiaoxiajianji.com>
Co-committed-by: CI Bot <dev@xiaoxiajianji.com>
2026-07-21 19:38:28 +08:00

140 lines
5.0 KiB
Python
Executable File

"""classification 模块单元测试."""
import pytest
from domain.classification import (
AssetClassification,
AssetLibraryKind,
ClassificationJob,
ClassificationJobStatus,
IngestJobStatus,
)
class TestAssetLibraryKind:
"""AssetLibraryKind 枚举测试."""
def test_values(self):
assert AssetLibraryKind.VIDEO == "video"
assert AssetLibraryKind.VOICE == "voice"
class TestIngestJobStatus:
"""IngestJobStatus 枚举测试."""
def test_values(self):
assert IngestJobStatus.PENDING == "pending"
assert IngestJobStatus.PROCESSING == "processing"
assert IngestJobStatus.COMPLETED == "completed"
assert IngestJobStatus.FAILED == "failed"
class TestClassificationJobStatus:
"""ClassificationJobStatus 枚举测试."""
def test_values(self):
assert ClassificationJobStatus.PENDING == "pending"
assert ClassificationJobStatus.PROCESSING == "processing"
assert ClassificationJobStatus.COMPLETED == "completed"
assert ClassificationJobStatus.FAILED == "failed"
class TestAssetClassification:
"""AssetClassification 枚举测试."""
def test_values(self):
assert AssetClassification.SCENIC == "scenic"
assert AssetClassification.PRODUCT == "product"
assert AssetClassification.PERSON == "person"
assert AssetClassification.ANIMAL == "animal"
assert AssetClassification.FOOD == "food"
assert AssetClassification.TECH == "tech"
assert AssetClassification.SPORT == "sport"
assert AssetClassification.MUSIC == "music"
assert AssetClassification.OTHER == "other"
class TestClassificationJobCreate:
"""ClassificationJob.create 工厂方法测试."""
def test_create_with_valid_params(self):
job = ClassificationJob.create(project_id="proj_001", asset_id="asset_001")
assert job.id
assert len(job.id) == 32
assert job.project_id == "proj_001"
assert job.asset_id == "asset_001"
assert job.status == ClassificationJobStatus.PENDING
assert job.classification == ""
assert job.confidence == 0.0
assert job.error_message == ""
assert job.created_at is not None
assert job.updated_at is not None
def test_create_strips_strings(self):
job = ClassificationJob.create(
project_id=" proj_002 ",
asset_id=" asset_002 ",
)
assert job.project_id == "proj_002"
assert job.asset_id == "asset_002"
def test_create_empty_project_id_raises(self):
with pytest.raises(ValueError, match="project_id"):
ClassificationJob.create(project_id="", asset_id="a")
def test_create_whitespace_project_id_raises(self):
with pytest.raises(ValueError, match="project_id"):
ClassificationJob.create(project_id=" ", asset_id="a")
def test_create_empty_asset_id_raises(self):
with pytest.raises(ValueError, match="asset_id"):
ClassificationJob.create(project_id="p", asset_id="")
def test_create_whitespace_asset_id_raises(self):
with pytest.raises(ValueError, match="asset_id"):
ClassificationJob.create(project_id="p", asset_id=" ")
def test_create_ids_are_unique(self):
j1 = ClassificationJob.create(project_id="p", asset_id="a")
j2 = ClassificationJob.create(project_id="p", asset_id="b")
assert j1.id != j2.id
def test_create_timestamps_are_utc(self):
job = ClassificationJob.create(project_id="p", asset_id="a")
assert job.created_at.tzinfo is not None
assert job.updated_at.tzinfo is not None
class TestClassificationJobState:
"""ClassificationJob 状态操作测试"""
def test_set_processing(self):
job = ClassificationJob.create(project_id="proj-1", asset_id="asset-1")
job.status = ClassificationJobStatus.PROCESSING
assert job.status == ClassificationJobStatus.PROCESSING
def test_set_completed_with_result(self):
job = ClassificationJob.create(project_id="proj-1", asset_id="asset-1")
job.status = ClassificationJobStatus.COMPLETED
job.classification = AssetClassification.SCENIC
job.confidence = 0.95
assert job.status == ClassificationJobStatus.COMPLETED
assert job.classification == "scenic"
assert job.confidence == pytest.approx(0.95)
def test_set_failed_with_error(self):
job = ClassificationJob.create(project_id="proj-1", asset_id="asset-1")
job.status = ClassificationJobStatus.FAILED
job.error_message = "model timeout"
assert job.status == ClassificationJobStatus.FAILED
assert job.error_message == "model timeout"
def test_confidence_range_zero(self):
job = ClassificationJob.create(project_id="proj-1", asset_id="asset-1")
job.confidence = 0.0
assert job.confidence == 0.0
def test_confidence_range_one(self):
job = ClassificationJob.create(project_id="proj-1", asset_id="asset-1")
job.confidence = 1.0
assert job.confidence == 1.0