From fe382bdd6965f841d92fe1e96b34dbde1b97bc0c Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Fri, 14 Aug 2026 20:42:25 +0800 Subject: [PATCH] fix(test): update mediakit cover tests for unified cover pipeline --- tests/unit/test_mediakit_cover.py | 120 +++++------------------------- 1 file changed, 17 insertions(+), 103 deletions(-) diff --git a/tests/unit/test_mediakit_cover.py b/tests/unit/test_mediakit_cover.py index 4b063e4f4..7c87bffbc 100755 --- a/tests/unit/test_mediakit_cover.py +++ b/tests/unit/test_mediakit_cover.py @@ -141,93 +141,13 @@ class TestMediaKitClient: class TestAICoverService: - """AI 封面服务测试(已迁移到 FFmpeg 本地抽帧)。""" - - @patch("packages.shared.ai_service.http_requests.head") - @patch("packages.shared.ai_service._extract_frames_with_ffmpeg") - def test_call_ai_cover_with_ffmpeg_success(self, mock_ffmpeg, mock_head): - """FFmpeg 本地抽帧成功.""" - import tempfile - - mock_head.return_value.status_code = 200 - - tmp = tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) - tmp.write(b"\xff\xd8" + b"\x00" * 50) - tmp.close() - - mock_ffmpeg.return_value = [{"local_path": tmp.name, "frame_time": 3.5}] - - with patch("packages.shared.storage.get_shared_storage_service") as mock_storage_fn: - mock_storage = Mock() - mock_storage.upload_file = Mock() - mock_storage.get_url.return_value = "https://example.com/frame.jpg" - mock_storage_fn.return_value = mock_storage - - from packages.shared.ai_service import _call_ai_cover_service - - result = _call_ai_cover_service( - plan_id="plan-123", - asset_ids=["asset-1"], - cover_type="ai_frame", - primary_video_url="https://example.com/video.mp4", - ) - - assert result["type"] == "ai_frame" - assert result["image_url"] == "https://example.com/frame.jpg" - assert result["frame_time"] == 3.5 - assert result["confidence"] == 0.85 - - Path(tmp.name).unlink(missing_ok=True) - - @patch("packages.shared.ai_service.http_requests.head") - def test_call_ai_cover_video_url_unreachable(self, mock_head): - """视频 URL 不可访问时抛出 RuntimeError.""" - mock_head.return_value.status_code = 404 + """AI 封面服务测试(统一封面管道后)。""" + def test_call_ai_cover_ai_frame_raises(self): + """ai_frame type raises RuntimeError in unified pipeline.""" from packages.shared.ai_service import _call_ai_cover_service - with pytest.raises(RuntimeError, match="预览视频URL不可访问"): - _call_ai_cover_service( - plan_id="plan-123", - asset_ids=["asset-1"], - cover_type="ai_frame", - primary_video_url="https://example.com/nonexistent.mp4", - ) - - @patch("packages.shared.ai_service.http_requests.head") - @patch("packages.shared.ai_service._extract_frames_with_ffmpeg") - def test_call_ai_cover_url_double_slash_normalized(self, mock_ffmpeg, mock_head): - """URL 路径中的双斜杠应被规范化.""" - dirty_url = "https://oss.example.com/generated/projects//tasks/abc123/rendered.mp4" - clean_url = "https://oss.example.com/generated/projects/tasks/abc123/rendered.mp4" - - mock_head.return_value.status_code = 200 - mock_ffmpeg.return_value = [] - - from packages.shared.ai_service import _call_ai_cover_service - - with pytest.raises(RuntimeError): - _call_ai_cover_service( - plan_id="plan-1", - asset_ids=["a1"], - cover_type="ai_frame", - primary_video_url=dirty_url, - ) - - # HEAD 请求使用规范化后的 URL - mock_head.assert_called_once() - assert mock_head.call_args[0][0] == clean_url - - @patch("packages.shared.ai_service.http_requests.head") - @patch("packages.shared.ai_service._extract_frames_with_ffmpeg") - def test_call_ai_cover_ffmpeg_failure_raises(self, mock_ffmpeg, mock_head): - """FFmpeg 抽帧失败时抛出 RuntimeError.""" - mock_head.return_value.status_code = 200 - mock_ffmpeg.side_effect = Exception("ffmpeg error") - - from packages.shared.ai_service import _call_ai_cover_service - - with pytest.raises(RuntimeError, match="无法从视频抽帧"): + with pytest.raises(RuntimeError, match="封面数据不可用"): _call_ai_cover_service( plan_id="plan-123", asset_ids=["asset-1"], @@ -235,11 +155,22 @@ class TestAICoverService: primary_video_url="https://example.com/video.mp4", ) + def test_call_ai_cover_ai_regenerate_raises(self): + """ai_regenerate type raises RuntimeError in unified pipeline.""" + from packages.shared.ai_service import _call_ai_cover_service + + with pytest.raises(RuntimeError, match="封面数据不可用"): + _call_ai_cover_service( + plan_id="plan-123", + asset_ids=["asset-1"], + cover_type="ai_regenerate", + ) + def test_call_ai_cover_without_video_url_raises(self): - """没有视频 URL 时抛出 RuntimeError.""" + """ai_frame without video URL still raises RuntimeError.""" from packages.shared.ai_service import _call_ai_cover_service - with pytest.raises(RuntimeError, match="无法从视频抽帧"): + with pytest.raises(RuntimeError, match="封面数据不可用"): _call_ai_cover_service( plan_id="plan-123", asset_ids=["asset-1"], @@ -276,23 +207,6 @@ class TestAICoverService: assert result["type"] == "manual" assert result["frame_time"] == 5.0 - @patch("packages.shared.ai_service.http_requests.head") - @patch("packages.shared.ai_service._extract_frames_with_ffmpeg") - def test_call_ai_cover_empty_frames_raises(self, mock_ffmpeg, mock_head): - """FFmpeg 返回空帧列表时抛出 RuntimeError.""" - mock_head.return_value.status_code = 200 - mock_ffmpeg.return_value = [] - - from packages.shared.ai_service import _call_ai_cover_service - - with pytest.raises(RuntimeError, match="无法从视频抽帧"): - _call_ai_cover_service( - plan_id="plan-123", - asset_ids=["asset-1"], - cover_type="ai_frame", - primary_video_url="https://example.com/video.mp4", - ) - class TestGenerateCover: """run_generate_cover 测试."""