test(unit): P3-1 第五波 新增3个领域模块单元测试(54个用例) #683

Merged
auto-approve-bot merged 1 commits from test/p3-1-wave5-domain-tests into develop 2026-07-21 19:47:24 +08:00
3 changed files with 446 additions and 0 deletions
+166
View File
@@ -0,0 +1,166 @@
"""
PresetVoice 预置音色领域模型单元测试
"""
import pytest
from domain.preset_voices import (
PRESET_VOICES,
PresetVoice,
get_preset_voice_by_id,
get_preset_voices,
is_preset_voice,
)
class TestPresetVoice:
"""PresetVoice 数据类测试"""
def test_create_required_fields(self):
v = PresetVoice(
voice_id="test_v1",
name="测试音色",
description="测试描述",
gender="female",
)
assert v.voice_id == "test_v1"
assert v.name == "测试音色"
assert v.description == "测试描述"
assert v.gender == "female"
def test_default_language(self):
v = PresetVoice(voice_id="v1", name="n", description="d", gender="female")
assert v.language == "zh-CN"
def test_default_preview_url(self):
v = PresetVoice(voice_id="v1", name="n", description="d", gender="female")
assert v.preview_url == ""
def test_default_tags_none(self):
v = PresetVoice(voice_id="v1", name="n", description="d", gender="female")
assert v.tags is None
def test_custom_tags(self):
v = PresetVoice(
voice_id="v1",
name="n",
description="d",
gender="female",
tags=["温柔", "女声"],
)
assert v.tags == ["温柔", "女声"]
def test_is_frozen(self):
v = PresetVoice(voice_id="v1", name="n", description="d", gender="female")
with pytest.raises(AttributeError):
v.name = "改了"
class TestPresetVoiceToDict:
"""to_dict 序列化测试"""
def test_to_dict_basic(self):
v = PresetVoice(
voice_id="longxiaochun_v3",
name="龙小淳",
description="温柔女声",
gender="female",
language="zh-CN",
preview_url="https://example.com/audio.mp3",
tags=["温柔", "女声"],
)
d = v.to_dict()
assert d["voice_id"] == "longxiaochun_v3"
assert d["name"] == "龙小淳"
assert d["description"] == "温柔女声"
assert d["gender"] == "female"
assert d["language"] == "zh-CN"
assert d["preview_url"] == "https://example.com/audio.mp3"
assert d["tags"] == ["温柔", "女声"]
def test_to_dict_tags_none_becomes_empty_list(self):
v = PresetVoice(voice_id="v1", name="n", description="d", gender="female")
d = v.to_dict()
assert d["tags"] == []
class TestPresetVoiceList:
"""预置音色列表测试"""
def test_list_not_empty(self):
voices = get_preset_voices()
assert len(voices) > 0
def test_all_are_preset_voice_instances(self):
for v in PRESET_VOICES:
assert isinstance(v, PresetVoice)
def test_voice_ids_unique(self):
ids = [v.voice_id for v in PRESET_VOICES]
assert len(ids) == len(set(ids))
def test_all_have_required_fields(self):
for v in PRESET_VOICES:
assert v.voice_id
assert v.name
assert v.description
assert v.gender in ("male", "female")
assert v.language
def test_total_count(self):
assert len(PRESET_VOICES) == 8
class TestGetPresetVoiceById:
"""按 ID 查询预置音色测试"""
def test_existing_voice(self):
v = get_preset_voice_by_id("longxiaochun_v3")
assert v is not None
assert v.name == "龙小淳"
assert v.gender == "female"
def test_nonexistent_voice(self):
v = get_preset_voice_by_id("nonexistent_voice")
assert v is None
def test_empty_string(self):
v = get_preset_voice_by_id("")
assert v is None
class TestIsPresetVoice:
"""判断是否预置音色测试"""
def test_existing_is_preset(self):
assert is_preset_voice("longxiaochen_v3") is True
def test_nonexistent_not_preset(self):
assert is_preset_voice("custom_voice_123") is False
def test_empty_not_preset(self):
assert is_preset_voice("") is False
class TestPresetVoiceSamples:
"""预置音色样本验证"""
@pytest.mark.parametrize(
"voice_id,expected_name,gender",
[
("longxiaochun_v3", "龙小淳", "female"),
("longxiaoxia_v3", "龙小夏", "female"),
("longxiaochen_v3", "龙小晨", "male"),
("longyue_v3", "龙悦", "female"),
("longshu_v3", "龙书", "male"),
("longjing_v3", "龙静", "female"),
("longbo_v3", "龙博", "male"),
("longtian_v3", "龙甜", "female"),
],
)
def test_all_preset_voices_sample(self, voice_id, expected_name, gender):
v = get_preset_voice_by_id(voice_id)
assert v is not None
assert v.name == expected_name
assert v.gender == gender
assert v.language == "zh-CN"
assert len(v.tags or []) >= 2
+153
View File
@@ -0,0 +1,153 @@
"""
Template 模板领域模型单元测试
"""
from domain.template import Template, TemplateCategory, TemplateSegment
class TestTemplateSegment:
"""TemplateSegment 测试"""
def test_create_segment(self):
seg = TemplateSegment(
id="seg-1",
template_id="tpl-1",
segment_order=1,
duration_min=3.0,
duration_max=5.0,
)
assert seg.id == "seg-1"
assert seg.template_id == "tpl-1"
assert seg.segment_order == 1
assert seg.duration_min == 3.0
assert seg.duration_max == 5.0
assert seg.material_type is None
def test_segment_with_material_type(self):
seg = TemplateSegment(
id="seg-1",
template_id="tpl-1",
segment_order=0,
duration_min=2.0,
duration_max=4.0,
material_type="人物",
)
assert seg.material_type == "人物"
def test_segment_has_timestamps(self):
seg = TemplateSegment(
id="seg-1",
template_id="tpl-1",
segment_order=1,
duration_min=1.0,
duration_max=2.0,
)
assert seg.created_at is not None
assert seg.updated_at is not None
class TestTemplate:
"""Template 测试"""
def test_create_template_minimal(self):
t = Template(
id="tpl-1",
user_id="user-1",
name="测试模板",
mode="one_take",
)
assert t.id == "tpl-1"
assert t.user_id == "user-1"
assert t.name == "测试模板"
assert t.mode == "one_take"
def test_default_values(self):
t = Template(id="tpl-1", user_id="u1", name="n", mode="one_take")
assert t.category == ""
assert t.tags == []
assert t.title_config == {}
assert t.subtitle_config == {}
assert t.bgm_config == {}
assert t.estimated_duration == 0.0
assert t.segments == []
assert t.is_active is True
def test_with_segments(self):
segs = [
TemplateSegment(id="s1", template_id="t1", segment_order=0, duration_min=2, duration_max=4),
TemplateSegment(id="s2", template_id="t1", segment_order=1, duration_min=3, duration_max=5),
]
t = Template(
id="tpl-1",
user_id="u1",
name="n",
mode="voice_over",
segments=segs,
)
assert len(t.segments) == 2
assert t.segments[0].segment_order == 0
assert t.segments[1].segment_order == 1
def test_all_modes(self):
for mode in ["pip", "voice_pip", "one_take", "voice_over"]:
t = Template(id="t1", user_id="u1", name="n", mode=mode)
assert t.mode == mode
def test_with_configs(self):
t = Template(
id="t1",
user_id="u1",
name="n",
mode="one_take",
title_config={"font_size": 24, "color": "#ffffff"},
subtitle_config={"style": "bottom"},
bgm_config={"volume": 0.5},
)
assert t.title_config["font_size"] == 24
assert t.subtitle_config["style"] == "bottom"
assert t.bgm_config["volume"] == 0.5
def test_estimated_duration(self):
t = Template(
id="t1",
user_id="u1",
name="n",
mode="one_take",
estimated_duration=30.5,
)
assert t.estimated_duration == 30.5
def test_is_active_false(self):
t = Template(id="t1", user_id="u1", name="n", mode="one_take", is_active=False)
assert t.is_active is False
def test_has_timestamps(self):
t = Template(id="t1", user_id="u1", name="n", mode="one_take")
assert t.created_at is not None
assert t.updated_at is not None
def test_tags_list(self):
t = Template(
id="t1",
user_id="u1",
name="n",
mode="one_take",
tags=["风景", "vlog"],
)
assert "风景" in t.tags
assert "vlog" in t.tags
assert len(t.tags) == 2
class TestTemplateCategory:
"""TemplateCategory 测试"""
def test_create_category(self):
cat = TemplateCategory(id="cat-1", user_id="u1", name="风景")
assert cat.id == "cat-1"
assert cat.user_id == "u1"
assert cat.name == "风景"
def test_category_has_timestamp(self):
cat = TemplateCategory(id="cat-1", user_id="u1", name="风景")
assert cat.created_at is not None
+127
View File
@@ -0,0 +1,127 @@
"""
EditTemplateVersion 模板版本领域模型单元测试
"""
import pytest
from domain.template_version import EditTemplateVersion
class TestEditTemplateVersionCreate:
"""创建模板版本测试"""
def test_create_required_fields(self):
v = EditTemplateVersion.create(template_id="tpl-1", version=1)
assert v.id is not None
assert len(v.id) == 32
assert v.template_id == "tpl-1"
assert v.version == 1
def test_default_values(self):
v = EditTemplateVersion.create(template_id="tpl-1", version=1)
assert v.name == ""
assert v.editing_mode == "one_take"
assert v.config == {}
assert v.clip_configs == []
assert v.change_note == ""
assert v.published_by == ""
def test_with_name_and_mode(self):
v = EditTemplateVersion.create(
template_id="tpl-1",
version=2,
name="风景Vlog模板",
editing_mode="voice_over",
)
assert v.name == "风景Vlog模板"
assert v.editing_mode == "voice_over"
def test_with_config(self):
config = {
"title": {"font_size": 24},
"subtitle": {"style": "bottom"},
"bgm": {"volume": 0.5},
}
v = EditTemplateVersion.create(
template_id="tpl-1",
version=1,
config=config,
)
assert v.config == config
assert v.config["title"]["font_size"] == 24
def test_with_clip_configs(self):
clips = [
{"clip_id": 1, "duration": 3.0, "transition": "fade"},
{"clip_id": 2, "duration": 5.0, "transition": "slide"},
]
v = EditTemplateVersion.create(
template_id="tpl-1",
version=1,
clip_configs=clips,
)
assert len(v.clip_configs) == 2
assert v.clip_configs[0]["clip_id"] == 1
def test_config_none_defaults_to_empty_dict(self):
v = EditTemplateVersion.create(template_id="tpl-1", version=1, config=None)
assert v.config == {}
def test_clip_configs_none_defaults_to_empty_list(self):
v = EditTemplateVersion.create(template_id="tpl-1", version=1, clip_configs=None)
assert v.clip_configs == []
def test_with_change_note(self):
v = EditTemplateVersion.create(
template_id="tpl-1",
version=3,
change_note="优化转场效果,新增滤镜",
)
assert v.change_note == "优化转场效果,新增滤镜"
def test_with_published_by(self):
v = EditTemplateVersion.create(
template_id="tpl-1",
version=1,
published_by="user-123",
)
assert v.published_by == "user-123"
def test_full_version(self):
config = {"bgm": {"volume": 0.3}}
clips = [{"clip_id": 1, "duration": 2.5}]
v = EditTemplateVersion.create(
template_id="tpl-abc",
version=5,
name="正式版v5",
editing_mode="one_take",
config=config,
clip_configs=clips,
change_note="第五次发布",
published_by="admin",
)
assert v.template_id == "tpl-abc"
assert v.version == 5
assert v.name == "正式版v5"
assert v.editing_mode == "one_take"
assert v.config == config
assert v.clip_configs == clips
assert v.change_note == "第五次发布"
assert v.published_by == "admin"
def test_version_number(self):
for ver in [1, 2, 5, 10, 99]:
v = EditTemplateVersion.create(template_id="t1", version=ver)
assert v.version == ver
def test_has_created_at(self):
v = EditTemplateVersion.create(template_id="t1", version=1)
assert v.created_at is not None
class TestEditTemplateVersionSlots:
"""slots 模式属性测试"""
def test_cannot_add_new_attribute(self):
v = EditTemplateVersion.create(template_id="t1", version=1)
with pytest.raises(AttributeError):
v.nonexistent_field = "value" # type: ignore[attr-defined]