2972f19954
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / PR Build API Image (push) Has been skipped
CI/CD Pipeline / PR Build Web Image (push) Has been skipped
CI/CD Pipeline / PR Build Worker Image (push) Has been skipped
CI/CD Pipeline / Frontend Lint (push) Successful in 58s
CI/CD Pipeline / Validate - Type Check (mypy) (push) Successful in 1m38s
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 / Validate - Migration (alembic) (push) Successful in 1m46s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 1m42s
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 1m18s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 3m23s
CI/CD Pipeline / Validate - Code Quality (push) Successful in 5m27s
CI/CD Pipeline / Unit Tests (push) Failing after 5m54s
CI/CD Pipeline / Integration Tests (push) Successful in 2m26s
CI/CD Pipeline / Build Staging API Image (push) Successful in 11m39s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 1m14s
CI/CD Pipeline / ACR Image Cleanup (push) Failing after 14s
CI/CD Pipeline / Staging E2E Tests (push) Failing after 2m3s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 4m14s
CI/CD Pipeline / Canary Release to Production (push) Has been skipped
210 lines
7.6 KiB
Python
Executable File
210 lines
7.6 KiB
Python
Executable File
from dataclasses import FrozenInstanceError
|
|
|
|
"""transition_presets 领域层单元测试 - 转场预设库"""
|
|
|
|
import pytest
|
|
|
|
from packages.domain.transition_presets import (
|
|
TRANSITION_PRESET_LIBRARY,
|
|
TransitionPreset,
|
|
get_default_transition,
|
|
get_transition_preset,
|
|
list_transition_presets,
|
|
)
|
|
|
|
|
|
class TestTransitionPreset:
|
|
"""TransitionPreset 数据类测试"""
|
|
|
|
def test_create_minimal(self):
|
|
preset = TransitionPreset(id="test", name="测试", category="basic", transition="fade")
|
|
assert preset.id == "test"
|
|
assert preset.name == "测试"
|
|
assert preset.category == "basic"
|
|
assert preset.transition == "fade"
|
|
assert preset.description == ""
|
|
assert preset.tags == []
|
|
assert preset.default_duration == 0.5
|
|
assert preset.min_duration == 0.1
|
|
assert preset.max_duration == 3.0
|
|
assert preset.has_custom_params is False
|
|
|
|
def test_create_with_all_params(self):
|
|
preset = TransitionPreset(
|
|
id="custom",
|
|
name="自定义转场",
|
|
category="special",
|
|
description="炫酷特效",
|
|
tags=["炫酷", "特效"],
|
|
transition="custom",
|
|
default_duration=1.0,
|
|
min_duration=0.5,
|
|
max_duration=5.0,
|
|
has_custom_params=True,
|
|
)
|
|
assert preset.description == "炫酷特效"
|
|
assert preset.tags == ["炫酷", "特效"]
|
|
assert preset.default_duration == 1.0
|
|
assert preset.min_duration == 0.5
|
|
assert preset.max_duration == 5.0
|
|
assert preset.has_custom_params is True
|
|
|
|
def test_frozen_immutable(self):
|
|
"""frozen dataclass 不可修改"""
|
|
preset = TransitionPreset(id="test", name="测试", category="basic")
|
|
with pytest.raises(FrozenInstanceError):
|
|
preset.name = "改名"
|
|
|
|
def test_tags_default_empty_list(self):
|
|
preset = TransitionPreset(id="t1", name="t1", category="basic")
|
|
preset2 = TransitionPreset(id="t2", name="t2", category="basic")
|
|
assert preset.tags == []
|
|
assert preset.tags is not preset2.tags
|
|
|
|
def test_default_transition_is_fade(self):
|
|
preset = TransitionPreset(id="test", name="测试", category="basic")
|
|
assert preset.transition == "fade"
|
|
|
|
|
|
class TestTransitionPresetLibrary:
|
|
"""TRANSITION_PRESET_LIBRARY 预设库测试"""
|
|
|
|
def test_library_not_empty(self):
|
|
assert len(TRANSITION_PRESET_LIBRARY) > 0
|
|
|
|
def test_all_presets_have_unique_ids(self):
|
|
"""所有预设 ID 唯一"""
|
|
ids = [p.id for p in TRANSITION_PRESET_LIBRARY]
|
|
assert len(ids) == len(set(ids))
|
|
|
|
def test_all_presets_have_required_fields(self):
|
|
"""所有预设都有必填字段"""
|
|
for preset in TRANSITION_PRESET_LIBRARY:
|
|
assert preset.id, "missing id"
|
|
assert preset.name, f"{preset.id} missing name"
|
|
assert preset.category, f"{preset.id} missing category"
|
|
assert preset.transition, f"{preset.id} missing transition"
|
|
|
|
def test_transition_none_exists(self):
|
|
"""无转场预设存在"""
|
|
none_preset = next((p for p in TRANSITION_PRESET_LIBRARY if p.id == "transition_none"), None)
|
|
assert none_preset is not None
|
|
assert none_preset.name == "无转场"
|
|
assert none_preset.transition == "none"
|
|
|
|
def test_transition_random_exists(self):
|
|
"""随机转场预设存在"""
|
|
random_preset = next((p for p in TRANSITION_PRESET_LIBRARY if p.id == "transition_random"), None)
|
|
assert random_preset is not None
|
|
assert random_preset.name == "随机"
|
|
|
|
def test_fade_category_exists(self):
|
|
"""淡入淡出分类有预设"""
|
|
fade_presets = [p for p in TRANSITION_PRESET_LIBRARY if p.category == "fade"]
|
|
assert len(fade_presets) >= 2
|
|
|
|
def test_duration_constraints_valid(self):
|
|
"""时长约束:min <= default <= max"""
|
|
for preset in TRANSITION_PRESET_LIBRARY:
|
|
assert preset.min_duration <= preset.default_duration, f"{preset.id}: min > default"
|
|
assert preset.default_duration <= preset.max_duration, f"{preset.id}: default > max"
|
|
assert preset.min_duration >= 0, f"{preset.id}: min < 0"
|
|
|
|
def test_known_categories_exist(self):
|
|
"""已知分类都有预设"""
|
|
categories = {p.category for p in TRANSITION_PRESET_LIBRARY}
|
|
assert "basic" in categories
|
|
assert "fade" in categories
|
|
|
|
|
|
class TestGetTransitionPreset:
|
|
"""get_transition_preset 函数测试"""
|
|
|
|
def test_get_existing_preset(self):
|
|
preset = get_transition_preset("transition_none")
|
|
assert preset is not None
|
|
assert preset.id == "transition_none"
|
|
|
|
def test_get_fade_preset(self):
|
|
preset = get_transition_preset("transition_fade")
|
|
assert preset is not None
|
|
assert preset.transition == "fade"
|
|
|
|
def test_get_nonexistent_preset(self):
|
|
assert get_transition_preset("nonexistent_transition") is None
|
|
|
|
def test_returns_transitionpreset_type(self):
|
|
preset = get_transition_preset("transition_fade")
|
|
assert isinstance(preset, TransitionPreset)
|
|
|
|
|
|
class TestListTransitionPresets:
|
|
"""list_transition_presets 函数测试"""
|
|
|
|
def test_list_all(self):
|
|
"""不带参数返回所有预设"""
|
|
all_presets = list_transition_presets()
|
|
assert len(all_presets) == len(TRANSITION_PRESET_LIBRARY)
|
|
|
|
def test_filter_by_category(self):
|
|
"""按分类筛选"""
|
|
fade_presets = list_transition_presets(category="fade")
|
|
assert len(fade_presets) > 0
|
|
assert all(p.category == "fade" for p in fade_presets)
|
|
|
|
def test_filter_by_basic_category(self):
|
|
basic_presets = list_transition_presets(category="basic")
|
|
assert len(basic_presets) >= 2
|
|
|
|
def test_filter_by_nonexistent_category(self):
|
|
result = list_transition_presets(category="nonexistent")
|
|
assert result == []
|
|
|
|
def test_search_by_name(self):
|
|
"""按名称搜索"""
|
|
result = list_transition_presets(keyword="淡入")
|
|
assert len(result) >= 1
|
|
assert any("淡入" in p.name for p in result)
|
|
|
|
def test_search_by_tag(self):
|
|
"""按标签搜索"""
|
|
tagged = [p for p in TRANSITION_PRESET_LIBRARY if p.tags]
|
|
if tagged:
|
|
tag = tagged[0].tags[0]
|
|
result = list_transition_presets(keyword=tag)
|
|
assert len(result) >= 1
|
|
|
|
def test_search_empty_returns_all(self):
|
|
result = list_transition_presets(keyword="")
|
|
assert len(result) == len(TRANSITION_PRESET_LIBRARY)
|
|
|
|
def test_combined_category_and_search(self):
|
|
result = list_transition_presets(category="fade", keyword="淡入")
|
|
assert all(p.category == "fade" for p in result)
|
|
|
|
def test_returns_list_of_transitionpreset(self):
|
|
result = list_transition_presets()
|
|
assert all(isinstance(p, TransitionPreset) for p in result)
|
|
|
|
|
|
class TestGetDefaultTransition:
|
|
"""get_default_transition 函数测试"""
|
|
|
|
def test_returns_preset(self):
|
|
preset = get_default_transition()
|
|
assert preset is not None
|
|
assert isinstance(preset, TransitionPreset)
|
|
|
|
def test_default_is_none(self):
|
|
"""默认转场是无转场(硬切)"""
|
|
preset = get_default_transition()
|
|
assert preset.id == "transition_none"
|
|
assert preset.transition == "none"
|
|
|
|
def test_default_has_zero_duration(self):
|
|
"""无转场默认时长为 0"""
|
|
preset = get_default_transition()
|
|
assert preset.default_duration == 0.0
|
|
assert preset.min_duration == 0.0
|
|
assert preset.max_duration == 0.0
|