from __future__ import annotations import acquisition.classification.coarse as coarse import acquisition.classify as legacy_classify from core.config import PgConfig, Settings from core.text_limits import CLASSIFY_BODY_MAX_CHARS def _settings() -> Settings: return Settings( pg=PgConfig(host="h", port=5432, user="u", password="p", database="d"), aiddit_crawler_base_url="http://crawler.test", crawler_timeout=30, openrouter_timeout_seconds=90, openrouter_model="m", openrouter_base_url="http://openrouter.test", openrouter_api_key="k", llm_model="m", max_cards=12, frames_dir="f", douyin_ratio="540p", data_dir="data", ) def test_formal_classify_imgtext_passes_http_image_urls(monkeypatch): captured = {} def fake_judge(messages, settings, timeout): captured["messages"] = messages return 1, "ok", "先定受众", "" monkeypatch.setattr(coarse, "_judge", fake_judge) result = coarse.classify_imgtext( { "platform": "xiaohongshu", "title": "脚本创作", "body_text": "讲怎么设计开头", "images": ["https://cdn.test/a.jpg"], }, _settings(), ) assert result[0] == 1 user_content = captured["messages"][1]["content"] assert {"type": "image_url", "image_url": {"url": "https://cdn.test/a.jpg"}} in user_content def test_formal_classify_imgtext_uses_wide_body_limit(monkeypatch): captured = {} def fake_judge(messages, settings, timeout): captured["messages"] = messages return 1, "ok", "长正文方法", "" monkeypatch.setattr(coarse, "_judge", fake_judge) long_body = "甲" * (CLASSIFY_BODY_MAX_CHARS + 7) coarse.classify_imgtext( { "platform": "xiaohongshu", "title": "长文", "body_text": long_body, "images": [], }, _settings(), ) user_text = captured["messages"][1]["content"][0]["text"] assert user_text.count("甲") == CLASSIFY_BODY_MAX_CHARS def test_legacy_classify_imgtext_also_passes_http_image_urls(monkeypatch): captured = {} def fake_judge(messages, settings, timeout): captured["messages"] = messages return 1, "ok", "先定受众", "" monkeypatch.setattr(legacy_classify, "_judge", fake_judge) result = legacy_classify.classify_imgtext( { "platform": "weixin", "title": "公众号选题", "body_text": "讲怎么做标题", "images": ["https://cdn.test/w.jpg"], }, _settings(), ) assert result[0] == 1 user_content = captured["messages"][1]["content"] assert {"type": "image_url", "image_url": {"url": "https://cdn.test/w.jpg"}} in user_content def test_legacy_classify_video_includes_title_and_body_text(monkeypatch): captured = {} def fake_judge(messages, settings, timeout): captured["messages"] = messages return 1, "ok", "视频方法", "" monkeypatch.setattr(legacy_classify, "_judge", fake_judge) legacy_classify.classify_video( { "platform": "douyin", "title": "视频标题", "body_text": "视频文案", "video": "https://cdn.test/video.mp4", }, _settings(), ) user_text = captured["messages"][1]["content"][0]["text"] assert "平台:douyin" in user_text assert "标题:视频标题" in user_text assert "正文/文案:视频文案" in user_text def test_coarse_classify_item_maps_judge_result(monkeypatch): monkeypatch.setattr( coarse, "classify_imgtext", lambda payload, settings: (0, "不是创作知识", "", ""), ) result = coarse.coarse_classify_item( platform="weixin", title="普通知识", body_text="只是作品介绍", image_urls=["https://cdn.test/a.jpg"], settings=_settings(), ) assert result.is_creation_knowledge is False assert result.label == "not_creation" assert result.status == "classified" def test_coarse_classify_item_routes_douyin_image_post_to_imgtext(monkeypatch): called = {} def fake_imgtext(payload, settings): called["imgtext"] = payload return 1, "是创作知识", "图片方法", "" def fake_video(payload, settings): called["video"] = payload return 1, "不应调用", "", "" monkeypatch.setattr(coarse, "classify_imgtext", fake_imgtext) monkeypatch.setattr(coarse, "classify_video", fake_video) result = coarse.coarse_classify_item( platform="douyin", content_mode="image_post", title="图片帖", body_text="图片正文", image_urls=["https://cdn.test/dy.jpg"], settings=_settings(), ) assert result.is_creation_knowledge is True assert "imgtext" in called assert "video" not in called def test_coarse_classify_item_skips_unsupported_and_missing_video(): unsupported = coarse.coarse_classify_item( platform="douyin", content_mode="unsupported", settings=_settings(), ) missing_video = coarse.coarse_classify_item( platform="douyin", content_mode="video_post", settings=_settings(), ) assert unsupported.status == "skipped" assert unsupported.label == "unsupported_content_mode" assert missing_video.status == "skipped" assert missing_video.label == "video_missing"