test_gate1_terminal_element.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. """M9E:Gate 1 需求级终端元素准入(非抖音 only,只读 PG 判叶子,PG client 用 fake)。"""
  2. from content_agent.run_service import RunService
  3. from content_agent.schemas import RunStartRequest
  4. class FakePatternPg:
  5. def __init__(self, has_terminal: bool) -> None:
  6. self.has_terminal = has_terminal
  7. self.calls: list[tuple] = []
  8. def has_terminal_element(self, execution_id, category_ids):
  9. self.calls.append((execution_id, list(category_ids)))
  10. return self.has_terminal
  11. def _source(category_ids):
  12. return {
  13. "ext_data": {
  14. "evidence_pack": {
  15. "pattern_execution_id": 581,
  16. "itemset_items": [{"category_id": cid} for cid in category_ids],
  17. }
  18. }
  19. }
  20. def _svc(has_terminal):
  21. return RunService(pattern_pg=FakePatternPg(has_terminal))
  22. def _req(platform, mode="real"):
  23. return RunStartRequest(platform=platform, platform_mode=mode)
  24. def test_gate1_blocks_non_douyin_without_terminal_element():
  25. svc = _svc(has_terminal=False)
  26. assert svc._gate1_block_reason(_req("kuaishou"), _source([1, 2])) == "gate1_no_terminal_element"
  27. def test_gate1_allows_non_douyin_with_terminal_element():
  28. svc = _svc(has_terminal=True)
  29. assert svc._gate1_block_reason(_req("shipinhao"), _source([1, 2])) is None
  30. def test_gate1_skips_douyin():
  31. pg = FakePatternPg(has_terminal=False)
  32. svc = RunService(pattern_pg=pg)
  33. assert svc._gate1_block_reason(_req("douyin"), _source([1, 2])) is None
  34. assert pg.calls == [] # 抖音不查 PG
  35. def test_gate1_skips_mock_mode():
  36. pg = FakePatternPg(has_terminal=False)
  37. svc = RunService(pattern_pg=pg)
  38. assert svc._gate1_block_reason(_req("kuaishou", mode="mock"), _source([1, 2])) is None
  39. assert pg.calls == []
  40. def test_gate1_skips_when_no_category_ids():
  41. pg = FakePatternPg(has_terminal=False)
  42. svc = RunService(pattern_pg=pg)
  43. assert svc._gate1_block_reason(_req("kuaishou"), _source([])) is None
  44. assert pg.calls == []
  45. def test_gate1_blocked_state_shape(tmp_path):
  46. svc = RunService(runtime_root=tmp_path / "runtime", pattern_pg=FakePatternPg(False))
  47. initial = {"run_id": "v1_run_t", "policy_run_id": "policy_run_t", "platform": "kuaishou"}
  48. blocked = svc._gate1_blocked_state(initial, "gate1_no_terminal_element")
  49. assert blocked["status"] == "blocked"
  50. assert blocked["current_step"] == "blocked_gate1"
  51. assert blocked["error_code"] == "gate1_no_terminal_element"