test_postgres_repository_contract.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. from __future__ import annotations
  2. from uuid import uuid4
  3. from acquisition.repositories.postgres import PostgresAcquisitionRepository
  4. class RecordingPostgresRepo(PostgresAcquisitionRepository):
  5. def __init__(self):
  6. super().__init__(conn=None)
  7. self.one_calls = []
  8. self.all_calls = []
  9. self.one_results = []
  10. self.all_results = []
  11. def _one(self, sql, params):
  12. self.one_calls.append((sql, params))
  13. return self.one_results.pop(0)
  14. def _all(self, sql, params):
  15. self.all_calls.append((sql, params))
  16. return self.all_results.pop(0)
  17. def test_postgres_summary_uses_formal_run_job_item_tables():
  18. run_id = uuid4()
  19. batch_id = uuid4()
  20. query_id = uuid4()
  21. repo = RecordingPostgresRepo()
  22. repo.one_results.append(
  23. {
  24. "id": run_id,
  25. "run_key": "r1",
  26. "batch_id": batch_id,
  27. "status": "done",
  28. "query_count": 1,
  29. "job_count": 3,
  30. "candidate_count": 7,
  31. "creation_hit_count": 2,
  32. "started_at": None,
  33. "finished_at": None,
  34. }
  35. )
  36. repo.all_results.append(
  37. [
  38. {
  39. "query_id": query_id,
  40. "query_text": "脚本 开头",
  41. "job_count": 3,
  42. "candidate_count": 7,
  43. "creation_hit_count": 2,
  44. "platforms": {"xiaohongshu": {"status": "done"}},
  45. }
  46. ]
  47. )
  48. summary = repo.get_run_summary(run_id)
  49. first_sql, first_params = repo.one_calls[0]
  50. second_sql, second_params = repo.all_calls[0]
  51. assert "FROM acquisition_runs ar" in first_sql
  52. assert "LEFT JOIN acquisition_jobs aj" in first_sql
  53. assert "LEFT JOIN candidate_items ci" in first_sql
  54. assert "LEFT JOIN item_classifications ic" in first_sql
  55. assert first_params == (run_id,)
  56. assert "jsonb_object_agg" in second_sql
  57. assert "WHERE aj.run_id = %s" in second_sql
  58. assert second_params == (run_id,)
  59. assert summary["queries"][0]["query_id"] == query_id
  60. def test_postgres_repository_lists_only_creation_candidates_for_decode():
  61. run_id = uuid4()
  62. item_id = uuid4()
  63. repo = RecordingPostgresRepo()
  64. repo.all_results.append(
  65. [
  66. {
  67. "id": item_id,
  68. "platform": "xiaohongshu",
  69. "platform_item_id": "x1",
  70. "canonical_url": "https://xhs.test/1",
  71. "status": "candidate",
  72. }
  73. ]
  74. )
  75. items = repo.list_creation_candidate_items(run_id=run_id, limit=20)
  76. sql, params = repo.all_calls[0]
  77. assert "JOIN acquisition_jobs aj ON aj.id = ci.job_id" in sql
  78. assert "JOIN item_classifications ic ON ic.item_id = ci.id" in sql
  79. assert "ic.is_creation_knowledge IS TRUE" in sql
  80. assert "LIMIT %s" in sql
  81. assert params == (run_id, 20)
  82. assert items[0].id == item_id
  83. assert items[0].platform == "xiaohongshu"
  84. def test_postgres_query_detail_loads_media_and_classifications_only_when_items_exist():
  85. run_id = uuid4()
  86. query_id = uuid4()
  87. item_id = uuid4()
  88. repo = RecordingPostgresRepo()
  89. repo.one_results.append({"id": query_id, "query_text": "q", "status": "ready"})
  90. repo.all_results.extend(
  91. [
  92. [{"id": uuid4(), "run_id": run_id, "query_id": query_id, "platform": "weixin"}],
  93. [{"id": item_id, "platform": "weixin", "query_id": query_id, "status": "candidate"}],
  94. [{"id": uuid4(), "item_id": item_id, "media_type": "image", "status": "done"}],
  95. [{"id": uuid4(), "item_id": item_id, "status": "classified"}],
  96. ]
  97. )
  98. detail = repo.get_query_detail(run_id=run_id, query_id=query_id)
  99. assert len(repo.all_calls) == 4
  100. assert "SELECT * FROM media_assets" in repo.all_calls[2][0]
  101. assert "SELECT * FROM item_classifications" in repo.all_calls[3][0]
  102. assert detail["items"][0]["id"] == item_id
  103. assert detail["media_assets"][0]["item_id"] == item_id