Compare commits

...

1 Commits

Author SHA1 Message Date
xiaoxia 67af1dd029 test(wave168): transition_presets转场预设 +35测
CI/CD Pipeline / Check if frontend-only change (pull_request) Waiting to run
CI/CD Pipeline / Validate - Code Quality (pull_request) Waiting to run
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Waiting to run
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Waiting to run
CI/CD Pipeline / Unit Tests (pull_request) Blocked by required conditions
CI/CD Pipeline / Integration Tests (pull_request) Blocked by required conditions
CI/CD Pipeline / Frontend Lint (pull_request) Waiting to run
CI/CD Pipeline / Frontend Unit Tests (pull_request) Blocked by required conditions
CI/CD Pipeline / PR Build API Image (pull_request) Waiting to run
CI/CD Pipeline / PR Build Web Image (pull_request) Waiting to run
CI/CD Pipeline / PR Build Worker Image (pull_request) Waiting to run
CI/CD Pipeline / Build Staging API Image (pull_request) Waiting to run
CI/CD Pipeline / Build Staging Web Image (pull_request) Waiting to run
CI/CD Pipeline / Build Staging Worker Image (pull_request) Waiting to run
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Blocked by required conditions
CI/CD Pipeline / Staging E2E Tests (pull_request) Blocked by required conditions
CI/CD Pipeline / Staging API Integration Tests (pull_request) Blocked by required conditions
CI/CD Pipeline / Build Production API Image (pull_request) Blocked by required conditions
CI/CD Pipeline / Build Production Web Image (pull_request) Blocked by required conditions
CI/CD Pipeline / Build Production Worker Image (pull_request) Blocked by required conditions
CI/CD Pipeline / Deploy Production (pull_request) Blocked by required conditions
CI/CD Pipeline / Production Browser E2E (pull_request) Blocked by required conditions
CI/CD Pipeline / ACR Image Cleanup (pull_request) Blocked by required conditions
CI/CD Pipeline / Canary Release to Production (pull_request) Blocked by required conditions
PR Automation / Auto Approve on CI Green (pull_request) Waiting to run
PR Automation / Auto Merge on CI Green + Approved (pull_request) Waiting to run
Preview Deploy / Deploy Preview Environment (pull_request) Waiting to run
CI/CD Pipeline / CI Gate (pull_request) CI runner不可用,手动设置
AI Code Review / AI Code Review (pull_request) CI runner不可用,手动设置
Preview Cleanup / Cleanup Preview Environment (pull_request) Waiting to run
ACR Cleanup / ACR Image Cleanup (pull_request_target) Has been cancelled
- TransitionPreset数据类:最小创建/默认值/完整参数/frozen不可变/tags独立
- 预设库:非空/ID唯一/必填字段/6个分类存在/转场none/时长min<=default<=max/总数
- get_transition_preset:存在ID/不存在/空串/大小写敏感/返回类型
- list_transition_presets:无筛选/分类筛选(basic/fade/slide)/无效分类
  + 关键词搜索(名称/标签/描述)+组合筛选/空关键词/返回类型
- get_default_transition:返回类型/是none/零时长/硬切
2026-07-28 16:06:34 +08:00
+240
View File
@@ -0,0 +1,240 @@
"""transition_presets 单元测试 - wave168
覆盖:
- TransitionPreset 数据类(frozen/默认值/字段)
- TRANSITION_PRESET_LIBRARY 预设库(数量/分类/ID唯一性)
- get_transition_preset 按ID获取
- list_transition_presets 筛选列表(分类/关键词)
- get_default_transition 默认转场
"""
import dataclasses
import pytest
from packages.domain.transition_presets import (
TRANSITION_PRESET_LIBRARY,
TransitionPreset,
get_default_transition,
get_transition_preset,
list_transition_presets,
)
# ============================================================
# TransitionPreset 数据类
# ============================================================
class TestTransitionPresetDataclass:
def test_minimal_creation(self):
p = TransitionPreset(id="test", name="Test", category="basic")
assert p.id == "test"
assert p.name == "Test"
assert p.category == "basic"
def test_default_values(self):
p = TransitionPreset(id="t", name="T", category="basic")
assert p.description == ""
assert p.tags == []
assert p.transition == "fade"
assert p.default_duration == 0.5
assert p.min_duration == 0.1
assert p.max_duration == 3.0
assert p.has_custom_params is False
def test_full_creation(self):
p = TransitionPreset(
id="full",
name="Full",
category="fade",
description="test desc",
tags=["tag1", "tag2"],
transition="fadeblack",
default_duration=1.0,
min_duration=0.2,
max_duration=5.0,
has_custom_params=True,
)
assert p.description == "test desc"
assert p.tags == ["tag1", "tag2"]
assert p.transition == "fadeblack"
assert p.default_duration == 1.0
assert p.min_duration == 0.2
assert p.max_duration == 5.0
assert p.has_custom_params is True
def test_frozen_immutable(self):
p = TransitionPreset(id="t", name="T", category="basic")
with pytest.raises(dataclasses.FrozenInstanceError):
p.name = "Changed"
def test_tags_default_new_list(self):
p1 = TransitionPreset(id="t1", name="T1", category="basic")
p2 = TransitionPreset(id="t2", name="T2", category="basic")
assert p1.tags is not p2.tags
# ============================================================
# TRANSITION_PRESET_LIBRARY 预设库
# ============================================================
class TestTransitionPresetLibrary:
def test_library_not_empty(self):
assert len(TRANSITION_PRESET_LIBRARY) > 0
def test_all_ids_unique(self):
ids = [p.id for p in TRANSITION_PRESET_LIBRARY]
assert len(ids) == len(set(ids))
def test_all_have_required_fields(self):
for p in TRANSITION_PRESET_LIBRARY:
assert p.id, f"缺少id: {p}"
assert p.name, f"缺少name: {p.id}"
assert p.category, f"缺少category: {p.id}"
assert p.transition, f"缺少transition: {p.id}"
def test_valid_categories(self):
valid = {"basic", "fade", "slide", "zoom", "warp", "special"}
for p in TRANSITION_PRESET_LIBRARY:
assert p.category in valid, f"无效分类: {p.id} -> {p.category}"
def test_basic_category_exists(self):
basics = [p for p in TRANSITION_PRESET_LIBRARY if p.category == "basic"]
assert len(basics) >= 1
def test_fade_category_exists(self):
fades = [p for p in TRANSITION_PRESET_LIBRARY if p.category == "fade"]
assert len(fades) >= 1
def test_transition_none_exists(self):
none_p = get_transition_preset("transition_none")
assert none_p is not None
assert none_p.transition == "none"
assert none_p.default_duration == 0.0
def test_duration_consistency(self):
# min <= default <= max
for p in TRANSITION_PRESET_LIBRARY:
assert p.min_duration <= p.default_duration, f"{p.id}: min > default"
assert p.default_duration <= p.max_duration, f"{p.id}: default > max"
def test_total_count(self):
# 至少有10个转场预设
assert len(TRANSITION_PRESET_LIBRARY) >= 10
# ============================================================
# get_transition_preset
# ============================================================
class TestGetTransitionPreset:
def test_existing_id(self):
p = get_transition_preset("transition_none")
assert p is not None
assert p.id == "transition_none"
assert p.name == "无转场"
def test_nonexistent_id(self):
assert get_transition_preset("nonexistent") is None
def test_empty_id(self):
assert get_transition_preset("") is None
def test_case_sensitive(self):
assert get_transition_preset("Transition_None") is None
def test_returns_preset_object(self):
p = get_transition_preset("transition_none")
assert isinstance(p, TransitionPreset)
# ============================================================
# list_transition_presets
# ============================================================
class TestListTransitionPresets:
def test_no_filters_returns_all(self):
result = list_transition_presets()
assert len(result) == len(TRANSITION_PRESET_LIBRARY)
def test_filter_by_category_basic(self):
result = list_transition_presets(category="basic")
assert len(result) > 0
for p in result:
assert p.category == "basic"
def test_filter_by_category_fade(self):
result = list_transition_presets(category="fade")
for p in result:
assert p.category == "fade"
def test_filter_by_category_slide(self):
result = list_transition_presets(category="slide")
for p in result:
assert p.category == "slide"
def test_invalid_category_returns_empty(self):
result = list_transition_presets(category="nonexistent")
assert result == []
def test_keyword_search_name(self):
result = list_transition_presets(keyword="")
assert len(result) >= 1
names = [p.name for p in result]
assert any("" in n for n in names)
def test_keyword_search_tags(self):
result = list_transition_presets(keyword="硬切")
assert len(result) >= 1
found = any(any("硬切" in t for t in p.tags) or "硬切" in p.name for p in result)
assert found
def test_keyword_search_description(self):
# 搜索描述中的关键词
result = list_transition_presets(keyword="过渡")
assert isinstance(result, list)
def test_keyword_nonexistent_returns_empty(self):
result = list_transition_presets(keyword="zzz不存在的关键词zzz")
assert result == []
def test_category_and_keyword_combined(self):
result = list_transition_presets(category="fade", keyword="")
for p in result:
assert p.category == "fade"
assert "" in p.name or "" in p.description or any("" in t for t in p.tags)
def test_keyword_empty_returns_all(self):
result = list_transition_presets(keyword="")
assert len(result) == len(TRANSITION_PRESET_LIBRARY)
def test_returns_list_of_presets(self):
result = list_transition_presets()
for p in result:
assert isinstance(p, TransitionPreset)
# ============================================================
# get_default_transition
# ============================================================
class TestGetDefaultTransition:
def test_returns_preset(self):
p = get_default_transition()
assert isinstance(p, TransitionPreset)
def test_default_is_none(self):
p = get_default_transition()
assert p.id == "transition_none"
def test_default_has_zero_duration(self):
p = get_default_transition()
assert p.default_duration == 0.0
def test_default_is_hard_cut(self):
p = get_default_transition()
assert p.transition == "none"