diff --git a/tests/unit/test_viral_video_wiring.py b/tests/unit/test_viral_video_wiring.py index fe5ada00e..cbb0b4e16 100644 --- a/tests/unit/test_viral_video_wiring.py +++ b/tests/unit/test_viral_video_wiring.py @@ -97,21 +97,28 @@ def invalidate_loader_cache(): class TestImageAnalysisWiring: - def test_uses_loader_template_and_xml_parse(self, job): + def test_v2_batch_analysis_returns_products(self, job): + """V2 路径:_step_image_analysis 批量调用 analyze_images_v2,返回 products。""" from apps.worker.worker_app.tasks import viral_video as vv - with patch("packages.shared.ai_service.call_vision", return_value=IMAGE_XML) as mock_v: - result = vv._analyze_single_image(0, "https://img/1.jpg", "vlm-lite", 15) + fake_product = { + "name": "lipstick", + "brand": "品牌X", + "category": "唇部彩妆", + "key_features": ["显白", "持久"], + "text_on_package": ["品牌X", "211"], + "_source": "v2_fast_json", + } + with patch("worker_app.tasks.vision.analyze_images_v2", return_value=[fake_product]) as mock_aiv2: + result = vv._step_image_analysis(job) - mock_v.assert_called_once() - # 验证调用时传入了 system_prompt(说明走了 loader 渲染的模板) - call_kwargs = mock_v.call_args.kwargs - assert "system_prompt" in call_kwargs and call_kwargs["system_prompt"] - # 结果包含从 XML 解析出的产品信息 - assert result["name"] == "lipstick" - assert result["brand"] == "品牌X" - assert "显白" in result["key_features"] - assert result["text_on_package"] == ["品牌X", "211"] + mock_aiv2.assert_called_once() + products = result["products"] + assert len(products) == 1 + assert products[0]["name"] == "lipstick" + assert products[0]["brand"] == "品牌X" + assert "显白" in products[0]["key_features"] + assert products[0]["text_on_package"] == ["品牌X", "211"] # ── 2) 意图解析走模板 ─────────────────────────────────────────────── @@ -252,18 +259,22 @@ class TestEndToEndLoaderUsed: called_types.append(prompt_type) return real_get(prompt_type, **kwargs) + # V2 图片分析不再走 prompt_loader(固定 lite JSON prompt),用 mock 产品代替 + img_res = { + "name": "lipstick", + "brand": "品牌X", + "key_features": ["显白", "持久"], + "text_on_package": ["品牌X"], + } with ( patch.object(pl, "get_template", side_effect=spy_get), - patch("packages.shared.ai_service.call_vision", return_value=IMAGE_XML), patch("packages.shared.ai_service.call_llm", return_value=INTENT_XML), ): - # 1) image - img_res = vv._analyze_single_image(0, "https://img/1.jpg", "vlm", 15) - # 2) intent + # intent intent_res = vv._step_intent_parsing(job, {"products": [img_res]}) - # 前两步分别调用了 image_analysis 和 intent_parsing - assert "image_analysis" in called_types + # V2 图片分析走固定 prompt(不经 loader);intent 仍走 loader + assert "image_analysis" not in called_types assert "intent_parsing" in called_types # script 和 review 单独验证(需要不同的 LLM 返回)