9554373f24
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 37s
CI/CD Pipeline / Build Staging API Image (push) Successful in 1m27s
CI/CD Pipeline / Frontend Lint (push) Successful in 1m31s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 1m54s
CI/CD Pipeline / Validate Code Quality And Tests (push) Successful in 2m32s
CI/CD Pipeline / Unit Tests (push) Successful in 2m37s
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
新增7个领域模块单元测试:classification、edit_plan_clip、filter_presets、generated_video、preset_bgm、template_clip_config、transition_presets,共231个用例
209 lines
8.2 KiB
Python
Executable File
209 lines
8.2 KiB
Python
Executable File
"""template_clip_config 领域模型单元测试."""
|
|
|
|
import pytest
|
|
from domain.template_clip_config import (
|
|
ClipType,
|
|
TemplateClipConfig,
|
|
TransitionEffect,
|
|
)
|
|
|
|
|
|
class TestClipType:
|
|
"""ClipType 枚举测试."""
|
|
|
|
def test_values(self):
|
|
assert ClipType.INTRO == "intro"
|
|
assert ClipType.MAIN == "main"
|
|
assert ClipType.TRANSITION == "transition"
|
|
assert ClipType.OUTRO == "outro"
|
|
assert ClipType.TITLE == "title"
|
|
assert ClipType.SUBTITLE == "subtitle"
|
|
|
|
|
|
class TestTransitionEffect:
|
|
"""TransitionEffect 枚举测试."""
|
|
|
|
def test_values(self):
|
|
assert TransitionEffect.CUT == "cut"
|
|
assert TransitionEffect.FADE == "fade"
|
|
assert TransitionEffect.SLIDE_LEFT == "slide_left"
|
|
assert TransitionEffect.SLIDE_RIGHT == "slide_right"
|
|
assert TransitionEffect.DISSOLVE == "dissolve"
|
|
assert TransitionEffect.WIPE == "wipe"
|
|
|
|
|
|
class TestTemplateClipConfigCreate:
|
|
"""TemplateClipConfig.create 工厂方法测试."""
|
|
|
|
def test_create_with_required_fields(self):
|
|
clip = TemplateClipConfig.create(template_id="tpl_001", clip_type=ClipType.MAIN, order=1)
|
|
assert clip.id
|
|
assert len(clip.id) == 32
|
|
assert clip.template_id == "tpl_001"
|
|
assert clip.clip_type == ClipType.MAIN
|
|
assert clip.order == 1
|
|
assert clip.min_duration == 0.0
|
|
assert clip.max_duration == 0.0
|
|
assert clip.text_template == ""
|
|
assert clip.material_requirements == {}
|
|
assert clip.transition_effect == TransitionEffect.CUT
|
|
assert clip.config == {}
|
|
|
|
def test_create_with_all_fields(self):
|
|
clip = TemplateClipConfig.create(
|
|
template_id="tpl_002",
|
|
clip_type=ClipType.INTRO,
|
|
order=2,
|
|
min_duration=3.0,
|
|
max_duration=10.0,
|
|
text_template="欢迎来到{channel}",
|
|
material_requirements={"type": "video", "min_count": 1},
|
|
transition_effect=TransitionEffect.FADE,
|
|
config={"key": "value"},
|
|
)
|
|
assert clip.clip_type == ClipType.INTRO
|
|
assert clip.min_duration == 3.0
|
|
assert clip.max_duration == 10.0
|
|
assert clip.text_template == "欢迎来到{channel}"
|
|
assert clip.material_requirements == {"type": "video", "min_count": 1}
|
|
assert clip.transition_effect == TransitionEffect.FADE
|
|
assert clip.config == {"key": "value"}
|
|
|
|
def test_create_with_string_clip_type(self):
|
|
clip = TemplateClipConfig.create(template_id="tpl_003", clip_type="title", order=1)
|
|
assert clip.clip_type == ClipType.TITLE
|
|
|
|
def test_create_with_string_transition_effect(self):
|
|
clip = TemplateClipConfig.create(
|
|
template_id="tpl_004",
|
|
clip_type=ClipType.MAIN,
|
|
order=1,
|
|
transition_effect="dissolve",
|
|
)
|
|
assert clip.transition_effect == TransitionEffect.DISSOLVE
|
|
|
|
def test_create_strips_strings(self):
|
|
clip = TemplateClipConfig.create(
|
|
template_id=" tpl_005 ",
|
|
clip_type=ClipType.MAIN,
|
|
order=1,
|
|
text_template=" 测试模板 ",
|
|
)
|
|
assert clip.template_id == "tpl_005"
|
|
assert clip.text_template == "测试模板"
|
|
|
|
def test_create_empty_template_id_raises(self):
|
|
with pytest.raises(ValueError, match="template_id"):
|
|
TemplateClipConfig.create(template_id="", clip_type=ClipType.MAIN, order=1)
|
|
|
|
def test_create_whitespace_template_id_raises(self):
|
|
with pytest.raises(ValueError, match="template_id"):
|
|
TemplateClipConfig.create(template_id=" ", clip_type=ClipType.MAIN, order=1)
|
|
|
|
def test_create_invalid_clip_type_raises(self):
|
|
with pytest.raises(ValueError):
|
|
TemplateClipConfig.create(template_id="tpl", clip_type="invalid_type", order=1)
|
|
|
|
def test_create_invalid_transition_effect_raises(self):
|
|
with pytest.raises(ValueError):
|
|
TemplateClipConfig.create(
|
|
template_id="tpl",
|
|
clip_type=ClipType.MAIN,
|
|
order=1,
|
|
transition_effect="invalid_effect",
|
|
)
|
|
|
|
def test_create_negative_min_duration_raises(self):
|
|
with pytest.raises(ValueError, match="min_duration"):
|
|
TemplateClipConfig.create(template_id="tpl", clip_type=ClipType.MAIN, order=1, min_duration=-1.0)
|
|
|
|
def test_create_negative_max_duration_raises(self):
|
|
with pytest.raises(ValueError, match="max_duration"):
|
|
TemplateClipConfig.create(template_id="tpl", clip_type=ClipType.MAIN, order=1, max_duration=-1.0)
|
|
|
|
def test_create_min_greater_than_max_raises(self):
|
|
with pytest.raises(ValueError, match="min_duration 不能大于 max_duration"):
|
|
TemplateClipConfig.create(
|
|
template_id="tpl",
|
|
clip_type=ClipType.MAIN,
|
|
order=1,
|
|
min_duration=10.0,
|
|
max_duration=5.0,
|
|
)
|
|
|
|
def test_create_min_equals_max_ok(self):
|
|
clip = TemplateClipConfig.create(
|
|
template_id="tpl",
|
|
clip_type=ClipType.MAIN,
|
|
order=1,
|
|
min_duration=5.0,
|
|
max_duration=5.0,
|
|
)
|
|
assert clip.min_duration == 5.0
|
|
assert clip.max_duration == 5.0
|
|
|
|
def test_create_zero_duration_range_ok(self):
|
|
clip = TemplateClipConfig.create(template_id="tpl", clip_type=ClipType.MAIN, order=1)
|
|
assert clip.min_duration == 0.0
|
|
assert clip.max_duration == 0.0
|
|
|
|
def test_create_none_material_requirements_defaults_to_empty_dict(self):
|
|
clip = TemplateClipConfig.create(
|
|
template_id="tpl", clip_type=ClipType.MAIN, order=1, material_requirements=None
|
|
)
|
|
assert clip.material_requirements == {}
|
|
|
|
def test_create_none_config_defaults_to_empty_dict(self):
|
|
clip = TemplateClipConfig.create(template_id="tpl", clip_type=ClipType.MAIN, order=1, config=None)
|
|
assert clip.config == {}
|
|
|
|
def test_create_ids_are_unique(self):
|
|
c1 = TemplateClipConfig.create(template_id="tpl", clip_type=ClipType.MAIN, order=1)
|
|
c2 = TemplateClipConfig.create(template_id="tpl", clip_type=ClipType.MAIN, order=2)
|
|
assert c1.id != c2.id
|
|
|
|
def test_create_timestamps_are_utc(self):
|
|
clip = TemplateClipConfig.create(template_id="tpl", clip_type=ClipType.MAIN, order=1)
|
|
assert clip.created_at.tzinfo is not None
|
|
assert clip.updated_at.tzinfo is not None
|
|
|
|
|
|
class TestTemplateClipConfigProperties:
|
|
"""属性方法测试."""
|
|
|
|
def test_has_duration_range_false_when_both_zero(self):
|
|
clip = TemplateClipConfig.create(template_id="tpl", clip_type=ClipType.MAIN, order=1)
|
|
assert clip.has_duration_range is False
|
|
|
|
def test_has_duration_range_true_when_min_set(self):
|
|
clip = TemplateClipConfig.create(template_id="tpl", clip_type=ClipType.MAIN, order=1, min_duration=2.0)
|
|
assert clip.has_duration_range is True
|
|
|
|
def test_has_duration_range_true_when_max_set(self):
|
|
clip = TemplateClipConfig.create(template_id="tpl", clip_type=ClipType.MAIN, order=1, max_duration=10.0)
|
|
assert clip.has_duration_range is True
|
|
|
|
def test_default_duration_both_zero(self):
|
|
clip = TemplateClipConfig.create(template_id="tpl", clip_type=ClipType.MAIN, order=1)
|
|
assert clip.default_duration == 0.0
|
|
|
|
def test_default_duration_only_min(self):
|
|
clip = TemplateClipConfig.create(template_id="tpl", clip_type=ClipType.MAIN, order=1, min_duration=5.0)
|
|
assert clip.default_duration == 5.0
|
|
|
|
def test_default_duration_only_max(self):
|
|
clip = TemplateClipConfig.create(template_id="tpl", clip_type=ClipType.MAIN, order=1, max_duration=10.0)
|
|
assert clip.default_duration == 10.0
|
|
|
|
def test_default_duration_both_set_is_midpoint(self):
|
|
clip = TemplateClipConfig.create(
|
|
template_id="tpl", clip_type=ClipType.MAIN, order=1, min_duration=5.0, max_duration=15.0
|
|
)
|
|
assert clip.default_duration == 10.0
|
|
|
|
def test_default_duration_min_equals_max(self):
|
|
clip = TemplateClipConfig.create(
|
|
template_id="tpl", clip_type=ClipType.MAIN, order=1, min_duration=5.0, max_duration=5.0
|
|
)
|
|
assert clip.default_duration == 5.0
|