|
|
@@ -5,58 +5,64 @@ from content_agent.business_modules.content_discovery.platform_observable_perfor
|
|
|
)
|
|
|
|
|
|
|
|
|
-def test_douyin_play_count_is_natural_missing_and_score_is_bounded():
|
|
|
+# M11:平台表现改"量级分 + 收缩后比例分"(配置驱动 observable_performance)。
|
|
|
+# 三平台按真实字段可得性走不同 component:抖音互动间比例 / 快手 per 播放真互动率 / 视频号仅点赞量级。
|
|
|
+
|
|
|
+
|
|
|
+def test_douyin_v2_volume_plus_inter_metric_ratios():
|
|
|
result = performance_score(
|
|
|
- {
|
|
|
- "digg_count": 100000,
|
|
|
- "comment_count": 1000,
|
|
|
- "share_count": 500,
|
|
|
- "collect_count": 1000,
|
|
|
- },
|
|
|
+ {"digg_count": 100000, "comment_count": 1000, "share_count": 500, "collect_count": 1000},
|
|
|
"douyin",
|
|
|
)
|
|
|
-
|
|
|
assert 0 <= result["platform_performance_score"] <= 100
|
|
|
- assert {row["field"] for row in result["platform_performance_components"]} == {
|
|
|
- "statistics.digg_count",
|
|
|
- "statistics.comment_count",
|
|
|
- "statistics.share_count",
|
|
|
- "statistics.collect_count",
|
|
|
- }
|
|
|
- assert result["missing_observable_fields"] == [
|
|
|
- {
|
|
|
- "field": "statistics.play_count",
|
|
|
- "missing_type": "natural_platform_missing",
|
|
|
- "platform": "douyin",
|
|
|
- "evidence": "跨平台字段映射.json",
|
|
|
- }
|
|
|
+ assert [row["field"] for row in result["platform_performance_components"]] == [
|
|
|
+ "total_interaction",
|
|
|
+ "share_ratio",
|
|
|
+ "collect_ratio",
|
|
|
+ "comment_ratio",
|
|
|
]
|
|
|
+ assert result["platform_performance_components"][0]["type"] == "absolute"
|
|
|
+ assert result["platform_performance_components"][1]["type"] == "ratio"
|
|
|
+ # play_count 抖音天然缺失仍如实上报
|
|
|
+ assert {
|
|
|
+ "field": "statistics.play_count",
|
|
|
+ "missing_type": "natural_platform_missing",
|
|
|
+ "platform": "douyin",
|
|
|
+ "evidence": "跨平台字段映射.json",
|
|
|
+ } in result["missing_observable_fields"]
|
|
|
assert "platform_heat" not in result
|
|
|
|
|
|
|
|
|
-def test_kuaishou_all_five_fields_supported():
|
|
|
+def test_kuaishou_v2_per_view_rates_no_share():
|
|
|
result = performance_score(
|
|
|
- {
|
|
|
- "play_count": 10000,
|
|
|
- "digg_count": 2000,
|
|
|
- "comment_count": 200,
|
|
|
- "share_count": 100,
|
|
|
- "collect_count": 100,
|
|
|
- },
|
|
|
+ {"play_count": 10000, "digg_count": 2000, "comment_count": 200, "share_count": 100, "collect_count": 100},
|
|
|
"kuaishou",
|
|
|
)
|
|
|
-
|
|
|
- assert len(result["platform_performance_components"]) == 5
|
|
|
- assert result["missing_observable_fields"] == []
|
|
|
+ # 快手:播放量级 + 三个 per 播放真互动率;无转发项(share 恒 0)
|
|
|
+ assert [row["field"] for row in result["platform_performance_components"]] == [
|
|
|
+ "play_count",
|
|
|
+ "like_rate",
|
|
|
+ "collect_rate",
|
|
|
+ "comment_rate",
|
|
|
+ ]
|
|
|
assert result["platform_performance_score"] is not None
|
|
|
+ assert result["missing_observable_fields"] == [] # play 在 → 比例分母不缺
|
|
|
|
|
|
|
|
|
-def test_shipinhao_only_digg_supported_and_other_fields_natural_missing():
|
|
|
- result = performance_score({"digg_count": 500}, "shipinhao")
|
|
|
-
|
|
|
- assert [row["field"] for row in result["platform_performance_components"]] == [
|
|
|
- "statistics.digg_count"
|
|
|
+def test_kuaishou_missing_play_count_marks_ratio_denominator_missing():
|
|
|
+ # 快手缺 play_count → per 播放比例分母为 0 → 记 runtime_missing、只剩播放量级一项
|
|
|
+ result = performance_score({"digg_count": 2000, "comment_count": 200, "collect_count": 100}, "kuaishou")
|
|
|
+ runtime_missing = [
|
|
|
+ row for row in result["missing_observable_fields"] if row.get("missing_type") == "runtime_missing"
|
|
|
]
|
|
|
+ assert {row["field"] for row in runtime_missing} == {"like_rate", "collect_rate", "comment_rate"}
|
|
|
+ assert [row["field"] for row in result["platform_performance_components"]] == ["play_count"]
|
|
|
+
|
|
|
+
|
|
|
+def test_shipinhao_only_digg_volume():
|
|
|
+ result = performance_score({"digg_count": 500}, "shipinhao")
|
|
|
+ assert [row["field"] for row in result["platform_performance_components"]] == ["digg_count"]
|
|
|
+ assert result["platform_performance_components"][0]["type"] == "absolute"
|
|
|
assert {row["field"] for row in result["missing_observable_fields"]} == {
|
|
|
"statistics.comment_count",
|
|
|
"statistics.share_count",
|
|
|
@@ -65,15 +71,13 @@ def test_shipinhao_only_digg_supported_and_other_fields_natural_missing():
|
|
|
}
|
|
|
|
|
|
|
|
|
-def test_supported_field_absent_is_runtime_missing():
|
|
|
- result = performance_score({"digg_count": 10}, "douyin")
|
|
|
-
|
|
|
- runtime_missing = [
|
|
|
- row for row in result["missing_observable_fields"]
|
|
|
- if row.get("missing_type") == "runtime_missing"
|
|
|
- ]
|
|
|
- assert {row["field"] for row in runtime_missing} == {
|
|
|
- "statistics.comment_count",
|
|
|
- "statistics.share_count",
|
|
|
- "statistics.collect_count",
|
|
|
- }
|
|
|
+def test_ratio_shrinkage_pulls_low_sample_toward_prior():
|
|
|
+ # 抖音转发率:小样本(3 赞 1 转=33%)被收缩拉回正常,不给虚高分;大样本真高比例保留。
|
|
|
+ low = performance_score({"digg_count": 3, "share_count": 1, "comment_count": 0, "collect_count": 0}, "douyin")
|
|
|
+ high = performance_score({"digg_count": 100000, "share_count": 35000, "comment_count": 5000, "collect_count": 50000}, "douyin")
|
|
|
+ low_share = next(c for c in low["platform_performance_components"] if c["field"] == "share_ratio")
|
|
|
+ high_share = next(c for c in high["platform_performance_components"] if c["field"] == "share_ratio")
|
|
|
+ assert low_share["raw_ratio"] > 0.3 # 原始 33%
|
|
|
+ assert low_share["shrunk_ratio"] < 0.15 # 收缩后被拉回(prior 0.12 附近)
|
|
|
+ assert low_share["normalized_score"] < 60
|
|
|
+ assert high_share["normalized_score"] == 100 # 真·高转发占满
|