test_api.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. from __future__ import annotations
  2. def _evidence():
  3. from app.core.knowledge.retrieval.contracts import KnowledgeEvidence
  4. return KnowledgeEvidence(
  5. chunk_id="chunk-1",
  6. content="客户同步用途",
  7. score=0.9,
  8. retriever="lexical+vector",
  9. object_uid="object-1",
  10. object_type="DataFlow",
  11. object_version=2,
  12. business_domain_uid="domain-a",
  13. point_keys=("DataFlow/object-1/purpose",),
  14. point_revisions=(3,),
  15. generation=1,
  16. source_updated_at="2026-07-23T00:00:00+00:00",
  17. )
  18. def test_viewer_can_post_search_and_receives_stable_canonical_contract(monkeypatch):
  19. from app import create_app
  20. from app.core.knowledge.access import KnowledgeAccessContext
  21. from app.core.knowledge.retrieval.contracts import SearchResult
  22. class Pipeline:
  23. def search(self, *_args, **_kwargs):
  24. return SearchResult((_evidence(),), "semantic")
  25. monkeypatch.setattr(
  26. "app.core.system.permissions.authenticate_request",
  27. lambda: {"id": "user-1", "roles": ["viewer"]},
  28. )
  29. monkeypatch.setattr(
  30. "app.api.knowledge_base.routes.build_access_context",
  31. lambda *_args, **_kwargs: KnowledgeAccessContext(
  32. subject_id="user-1",
  33. roles=frozenset({"viewer"}),
  34. permissions=frozenset({"governance:read"}),
  35. business_domain_uids=frozenset({"domain-a"}),
  36. correlation_id="correlation-1",
  37. ),
  38. )
  39. app = create_app()
  40. app.extensions["knowledge_retrieval_pipeline"] = Pipeline()
  41. response = app.test_client().post(
  42. "/api/knowledge/search", json={"query": "用途", "mode": "semantic"}
  43. )
  44. assert response.status_code == 200
  45. payload = response.get_json()["data"]
  46. assert payload["evidence"][0]["object_uid"] == "object-1"
  47. assert payload["evidence"][0]["point_revisions"] == [3]
  48. assert payload["evidence"][0]["index_generation"] == 1
  49. def test_search_rejects_client_domain_filter_shape_before_retrieval(monkeypatch):
  50. from app import create_app
  51. monkeypatch.setattr(
  52. "app.core.system.permissions.authenticate_request",
  53. lambda: {"id": "user-1", "roles": ["viewer"]},
  54. )
  55. app = create_app()
  56. response = app.test_client().post(
  57. "/api/knowledge/search",
  58. json={"query": "用途", "business_domain_uids": "domain-a"},
  59. )
  60. assert response.status_code == 400
  61. def test_search_rejects_non_numeric_limit(monkeypatch):
  62. from app import create_app
  63. monkeypatch.setattr(
  64. "app.core.system.permissions.authenticate_request",
  65. lambda: {"id": "user-1", "roles": ["viewer"]},
  66. )
  67. app = create_app()
  68. response = app.test_client().post(
  69. "/api/knowledge/search",
  70. json={"query": "用途", "limit": "many"},
  71. )
  72. assert response.status_code == 400
  73. assert response.get_json()["message"] == "limit 必须为整数"