test_author_asset_pool.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. """优质老年作者入池:纯50+占比>30% 且 TGI>120 才收;填 elderly_ratio/tgi;非抖音/不达标不收。"""
  2. from content_agent.business_modules.result_source_lookup import _build_author_assets
  3. def _item(author_id, content_id, platform="douyin"):
  4. return {
  5. "platform": platform,
  6. "platform_author_id": author_id,
  7. "platform_content_id": content_id,
  8. "content_discovery_id": f"cd_{content_id}",
  9. "author_display_name": f"作者{author_id}",
  10. "tags": ["历史"],
  11. }
  12. def _decision(content_id, fifty_status=None, band_percent=None, band_tgi=None):
  13. scorecard = {"total_score": 73, "query_relevance_score": 90, "platform_performance_score": 70}
  14. if fifty_status is not None:
  15. scorecard["fifty_plus_status"] = fifty_status
  16. if fifty_status == "ok":
  17. scorecard["fifty_plus_components"] = {"band": "50+", "band_percent": band_percent, "band_tgi": band_tgi}
  18. return {
  19. "decision_id": f"dec_{content_id}",
  20. "decision_target_id": content_id,
  21. "decision_action": "ADD_TO_CONTENT_POOL",
  22. "scorecard": scorecard,
  23. }
  24. def _run(items, decisions):
  25. decision_by_target_id = {d["decision_target_id"]: d for d in decisions}
  26. paths = {it["platform_content_id"]: [] for it in items}
  27. return _build_author_assets("run", "policy_run", items, decision_by_target_id, paths)
  28. def test_eligible_author_pooled_with_elderly_fields():
  29. items = [_item("A", "c_a")]
  30. decisions = [_decision("c_a", "ok", band_percent=36.86, band_tgi=155.72)]
  31. _summaries, asset_rows, role_rows = _run(items, decisions)
  32. assert len(asset_rows) == 1
  33. row = asset_rows[0]
  34. assert row["platform_author_id"] == "A"
  35. assert row["elderly_ratio"] == 36.86
  36. assert row["elderly_tgi"] == 155.72
  37. assert row["eligible_as_source"] == 1
  38. assert "high_50plus_profile" in _summaries[0]["roles"]
  39. assert any(r["role"] == "high_50plus_profile" for r in role_rows)
  40. def test_ratio_below_30_rejected():
  41. items = [_item("B", "c_b")]
  42. decisions = [_decision("c_b", "ok", band_percent=22.21, band_tgi=140)] # 占比<30
  43. _s, asset_rows, _r = _run(items, decisions)
  44. assert asset_rows == []
  45. def test_tgi_below_120_rejected():
  46. items = [_item("C", "c_c")]
  47. decisions = [_decision("c_c", "ok", band_percent=40, band_tgi=100)] # TGI<120
  48. _s, asset_rows, _r = _run(items, decisions)
  49. assert asset_rows == []
  50. def test_non_douyin_no_portrait_rejected():
  51. items = [_item("D", "c_d", platform="kuaishou")]
  52. decisions = [_decision("c_d", fifty_status=None)] # 无 fifty_plus → 不收
  53. _s, asset_rows, _r = _run(items, decisions)
  54. assert asset_rows == []
  55. def test_boundary_exactly_30_and_120_excluded():
  56. # 严格大于:占比=30、TGI=120 都不算达标。
  57. items = [_item("E", "c_e")]
  58. decisions = [_decision("c_e", "ok", band_percent=30, band_tgi=120)]
  59. _s, asset_rows, _r = _run(items, decisions)
  60. assert asset_rows == []