"""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