From f34a5ab075cabdabdc4e4a24c5fc43dba5dd6bdb Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Tue, 28 Jul 2026 13:39:24 +0800 Subject: [PATCH] =?UTF-8?q?test(wave154):=20classification=E7=B4=A0?= =?UTF-8?q?=E6=9D=90=E5=88=86=E7=B1=BB=E5=8D=95=E6=B5=8B=20+34?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为 domain/classification.py 新增 34 个单测: - AssetLibraryKind 枚举:4个 - IngestJobStatus 枚举:5个 - ClassificationJobStatus 枚举:6个 - AssetClassification 枚举:10个 - ClassificationJob.create:9个 --- tests/unit/domain/test_classification.py | 181 +++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 tests/unit/domain/test_classification.py diff --git a/tests/unit/domain/test_classification.py b/tests/unit/domain/test_classification.py new file mode 100644 index 000000000..09077950a --- /dev/null +++ b/tests/unit/domain/test_classification.py @@ -0,0 +1,181 @@ +"""classification 单测. + +domain 层素材分类模块纯逻辑,0 外部依赖。 +覆盖:4个枚举 + ClassificationJob 工厂/校验。 +""" + +from __future__ import annotations + +from packages.domain.classification import ( + AssetClassification, + AssetLibraryKind, + ClassificationJob, + ClassificationJobStatus, + IngestJobStatus, +) + + +class TestAssetLibraryKind: + """AssetLibraryKind 枚举测试.""" + + def test_two_values(self): + """视频和配音两类.""" + assert len(AssetLibraryKind) == 2 + + def test_video(self): + assert AssetLibraryKind.VIDEO == "video" + + def test_voice(self): + assert AssetLibraryKind.VOICE == "voice" + + def test_str_compatible(self): + """StrEnum 字符串兼容.""" + assert AssetLibraryKind.VIDEO == "video" + + +class TestIngestJobStatus: + """IngestJobStatus 枚举测试.""" + + def test_four_statuses(self): + assert len(IngestJobStatus) == 4 + + def test_pending(self): + assert IngestJobStatus.PENDING == "pending" + + def test_processing(self): + assert IngestJobStatus.PROCESSING == "processing" + + def test_completed(self): + assert IngestJobStatus.COMPLETED == "completed" + + def test_failed(self): + assert IngestJobStatus.FAILED == "failed" + + +class TestClassificationJobStatus: + """ClassificationJobStatus 枚举测试.""" + + def test_four_statuses(self): + assert len(ClassificationJobStatus) == 4 + + def test_pending(self): + assert ClassificationJobStatus.PENDING == "pending" + + def test_processing(self): + assert ClassificationJobStatus.PROCESSING == "processing" + + def test_completed(self): + assert ClassificationJobStatus.COMPLETED == "completed" + + def test_failed(self): + assert ClassificationJobStatus.FAILED == "failed" + + def test_same_values_as_ingest(self): + """两种任务状态值相同.""" + assert set(ClassificationJobStatus) == set(IngestJobStatus) + + +class TestAssetClassification: + """AssetClassification 枚举测试.""" + + def test_nine_categories(self): + """9个分类.""" + assert len(AssetClassification) == 9 + + def test_scenic(self): + assert AssetClassification.SCENIC == "scenic" + + def test_product(self): + assert AssetClassification.PRODUCT == "product" + + def test_person(self): + assert AssetClassification.PERSON == "person" + + def test_animal(self): + assert AssetClassification.ANIMAL == "animal" + + def test_food(self): + assert AssetClassification.FOOD == "food" + + def test_tech(self): + assert AssetClassification.TECH == "tech" + + def test_sport(self): + assert AssetClassification.SPORT == "sport" + + def test_music(self): + assert AssetClassification.MUSIC == "music" + + def test_other(self): + assert AssetClassification.OTHER == "other" + + def test_all_values_unique(self): + """所有分类值唯一.""" + values = [c.value for c in AssetClassification] + assert len(values) == len(set(values)) + + +class TestClassificationJobCreate: + """ClassificationJob.create 测试.""" + + def test_create_valid(self): + """正常创建.""" + job = ClassificationJob.create(project_id="proj1", asset_id="asset1") + assert job.project_id == "proj1" + assert job.asset_id == "asset1" + assert job.status == ClassificationJobStatus.PENDING + assert job.classification == "" + assert job.confidence == 0.0 + assert job.error_message == "" + assert isinstance(job.id, str) + assert len(job.id) > 0 + + def test_create_strips(self): + """project_id 和 asset_id 会 strip.""" + job = ClassificationJob.create(project_id=" proj1 ", asset_id=" asset1 ") + assert job.project_id == "proj1" + assert job.asset_id == "asset1" + + def test_create_empty_project_id(self): + """空 project_id 无效.""" + try: + ClassificationJob.create(project_id="", asset_id="a1") + assert False + except ValueError as e: + assert "project_id" in str(e) + + def test_create_whitespace_project_id(self): + """纯空白 project_id 无效.""" + try: + ClassificationJob.create(project_id=" ", asset_id="a1") + assert False + except ValueError as e: + assert "project_id" in str(e) + + def test_create_empty_asset_id(self): + """空 asset_id 无效.""" + try: + ClassificationJob.create(project_id="p1", asset_id="") + assert False + except ValueError as e: + assert "asset_id" in str(e) + + def test_create_whitespace_asset_id(self): + """纯空白 asset_id 无效.""" + try: + ClassificationJob.create(project_id="p1", asset_id=" ") + assert False + except ValueError as e: + assert "asset_id" in str(e) + + def test_create_unique_id(self): + """不同 job id 不同.""" + j1 = ClassificationJob.create("p", "a") + j2 = ClassificationJob.create("p", "a") + assert j1.id != j2.id + + def test_create_has_timestamps(self): + """有创建和更新时间.""" + job = ClassificationJob.create("p", "a") + assert job.created_at is not None + assert job.updated_at is not None