"""generated_video 单测. domain 层生成视频实体纯逻辑模块,0 外部依赖。 覆盖:create工厂/校验、默认值、数据完整性。 """ from __future__ import annotations from packages.domain.generated_video import GeneratedVideo class TestGeneratedVideoCreate: """GeneratedVideo.create 工厂测试.""" def test_create_required_fields(self): """最简创建(仅必填字段).""" v = GeneratedVideo.create( project_id="proj1", generation_task_id="task1", name="我的视频", file_url="https://cdn.example.com/v.mp4", ) assert v.project_id == "proj1" assert v.generation_task_id == "task1" assert v.name == "我的视频" assert v.file_url == "https://cdn.example.com/v.mp4" assert isinstance(v.id, str) assert len(v.id) > 0 def test_create_defaults(self): """默认值正确.""" v = GeneratedVideo.create( project_id="p1", generation_task_id="t1", name="v", file_url="http://x/v.mp4", ) assert v.file_size == 0 assert v.duration == 0.0 assert v.width == 0 assert v.height == 0 assert v.fps == 0.0 assert v.thumbnail_url is None assert v.status == "completed" assert v.review_status == "pending_review" assert v.generation_params == {} assert v.video_fingerprint is None assert v.is_duplicate is False assert v.duplicate_of is None def test_create_with_all_fields(self): """带全部字段创建.""" v = GeneratedVideo.create( project_id="proj1", generation_task_id="task1", name=" 测试视频 ", file_url=" https://cdn.example.com/v.mp4 ", file_size=1024000, duration=120.5, width=1920, height=1080, fps=30.0, thumbnail_url="https://cdn.example.com/thumb.jpg", generation_params={"template": "tpl1", "bgm": "bgm1"}, ) assert v.name == "测试视频" # strip assert v.file_url == "https://cdn.example.com/v.mp4" # strip assert v.file_size == 1024000 assert v.duration == 120.5 assert v.width == 1920 assert v.height == 1080 assert v.fps == 30.0 assert v.thumbnail_url == "https://cdn.example.com/thumb.jpg" assert v.generation_params == {"template": "tpl1", "bgm": "bgm1"} def test_create_strips_fields(self): """字符串字段会 strip.""" v = GeneratedVideo.create( project_id=" p1 ", generation_task_id=" t1 ", name=" v ", file_url=" http://x/v ", ) assert v.project_id == "p1" assert v.generation_task_id == "t1" assert v.name == "v" assert v.file_url == "http://x/v" def test_create_empty_project_id(self): """空 project_id 无效.""" try: GeneratedVideo.create("", "t1", "v", "http://x/v") assert False except ValueError as e: assert "project_id" in str(e) def test_create_whitespace_project_id(self): """纯空白 project_id 无效.""" try: GeneratedVideo.create(" ", "t1", "v", "http://x/v") assert False except ValueError as e: assert "project_id" in str(e) def test_create_empty_task_id(self): """空 generation_task_id 无效.""" try: GeneratedVideo.create("p1", "", "v", "http://x/v") assert False except ValueError as e: assert "generation_task_id" in str(e) def test_create_empty_name(self): """空 name 无效.""" try: GeneratedVideo.create("p1", "t1", "", "http://x/v") assert False except ValueError as e: assert "name" in str(e) def test_create_empty_file_url(self): """空 file_url 无效.""" try: GeneratedVideo.create("p1", "t1", "v", "") assert False except ValueError as e: assert "file_url" in str(e) def test_create_whitespace_file_url(self): """纯空白 file_url 无效.""" try: GeneratedVideo.create("p1", "t1", "v", " ") assert False except ValueError as e: assert "file_url" in str(e) def test_create_generation_params_none_defaults_empty(self): """generation_params=None 默认为空 dict.""" v = GeneratedVideo.create("p1", "t1", "v", "http://x/v", generation_params=None) assert v.generation_params == {} def test_create_unique_id(self): """不同视频 id 不同.""" v1 = GeneratedVideo.create("p", "t", "v", "http://x/v") v2 = GeneratedVideo.create("p", "t", "v", "http://x/v") assert v1.id != v2.id def test_create_has_timestamps(self): """有生成和创建时间.""" v = GeneratedVideo.create("p", "t", "v", "http://x/v") assert v.generated_at is not None assert v.created_at is not None def test_zero_dimensions_valid(self): """宽高为 0 合法(未指定分辨率).""" v = GeneratedVideo.create("p", "t", "v", "http://x/v", width=0, height=0) assert v.width == 0 assert v.height == 0 def test_zero_fps_valid(self): """fps 为 0 合法.""" v = GeneratedVideo.create("p", "t", "v", "http://x/v", fps=0.0) assert v.fps == 0.0 def test_generation_params_independent(self): """不同实例的 generation_params 独立.""" v1 = GeneratedVideo.create("p", "t", "v", "http://x/v") v2 = GeneratedVideo.create("p", "t", "v", "http://x/v") v1.generation_params["key"] = "value" assert "key" not in v2.generation_params