test_product_governance_contract.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. from pathlib import Path
  2. from app.core.system.permissions import (
  3. DATA_PRODUCTS_MANAGE,
  4. DATA_PRODUCTS_OPERATE,
  5. DATA_PRODUCTS_READ,
  6. permission_for_request,
  7. permissions_for_roles,
  8. )
  9. ROOT = Path(__file__).resolve().parents[1]
  10. def test_product_governance_migration_is_additive_versioned_and_audited():
  11. migration = (
  12. ROOT / "migrations/versions/20260802_440_product_governance.py"
  13. ).read_text(encoding="utf-8")
  14. assert 'revision = "20260802_440"' in migration
  15. assert 'down_revision = "20260802_430"' in migration
  16. for table in (
  17. "governed_data_products",
  18. "data_product_governance_events",
  19. "data_product_applications",
  20. "data_product_application_events",
  21. "data_product_contracts",
  22. "data_product_contract_versions",
  23. "data_product_certificates",
  24. "data_product_feedback",
  25. ):
  26. assert f"CREATE TABLE public.{table}" in migration
  27. assert "REFERENCES public.data_products(id)" in migration
  28. assert "REFERENCES public.governance_tasks(uid)" in migration
  29. assert "raise RuntimeError" in migration
  30. assert "DROP TABLE" not in migration.upper()
  31. def test_product_governance_permissions_separate_read_operate_and_manage():
  32. assert DATA_PRODUCTS_READ in permissions_for_roles(["viewer"])
  33. assert DATA_PRODUCTS_OPERATE not in permissions_for_roles(["viewer"])
  34. assert DATA_PRODUCTS_OPERATE in permissions_for_roles(["editor"])
  35. assert DATA_PRODUCTS_MANAGE not in permissions_for_roles(["editor"])
  36. assert DATA_PRODUCTS_MANAGE in permissions_for_roles(["admin"])
  37. assert permission_for_request(
  38. "/api/dataservice/governance/products", "GET"
  39. ) == (DATA_PRODUCTS_READ,)
  40. assert permission_for_request(
  41. "/api/dataservice/governance/applications", "POST"
  42. ) == (DATA_PRODUCTS_OPERATE,)
  43. assert permission_for_request(
  44. "/api/dataservice/governance/feedback/x/transition", "POST"
  45. ) == (DATA_PRODUCTS_OPERATE,)
  46. assert permission_for_request(
  47. "/api/dataservice/governance/products/x/contracts", "POST"
  48. ) == (DATA_PRODUCTS_OPERATE,)
  49. def test_api_and_frontend_cover_the_complete_product_governance_surface():
  50. api = (
  51. ROOT / "app/api/data_service/product_governance_routes.py"
  52. ).read_text(encoding="utf-8")
  53. client = (ROOT / "frontend/src/api/productGovernance.js").read_text(
  54. encoding="utf-8"
  55. )
  56. view = (
  57. ROOT / "frontend/src/views/dataService/productGovernance/index.vue"
  58. ).read_text(encoding="utf-8")
  59. routes = (ROOT / "frontend/src/router/routes.js").read_text(encoding="utf-8")
  60. for path in (
  61. "/governance/products",
  62. "/governance/applications",
  63. "/contracts",
  64. "/compatibility",
  65. "/certificates",
  66. "/feedback",
  67. "/governance/dashboard",
  68. ):
  69. assert path in api
  70. for operation in (
  71. "registerGovernedProduct",
  72. "transitionGovernedProduct",
  73. "createProductApplication",
  74. "submitProductApplication",
  75. "reconcileProductApplication",
  76. "fulfillProductApplication",
  77. "createProductContract",
  78. "checkProductContractCompatibility",
  79. "reviseProductContract",
  80. "publishProductContract",
  81. "terminateProductContract",
  82. "issueProductCertificate",
  83. "createProductFeedback",
  84. "transitionProductFeedback",
  85. ):
  86. assert operation in client
  87. for capability in (
  88. "产品治理与运营",
  89. "通用申请",
  90. "数据合同",
  91. "产品合格证",
  92. "用户反馈",
  93. "不会自动下发数据权限",
  94. ):
  95. assert capability in view
  96. assert "/dataService/productGovernance" in routes
  97. assert "data-products:read" in routes
  98. def test_certificate_reads_canonical_evidence_and_never_grants_access():
  99. repository = (
  100. ROOT / "app/core/data_service/product_governance_repository.py"
  101. ).read_text(encoding="utf-8")
  102. service = (
  103. ROOT / "app/core/data_service/product_governance.py"
  104. ).read_text(encoding="utf-8")
  105. for evidence_table in (
  106. "quality_profile_runs",
  107. "quality_sla_events",
  108. "active_metadata_lineage",
  109. "data_rule_versions",
  110. "workflow_runs",
  111. ):
  112. assert evidence_table in repository
  113. assert "UnifiedWorkCenterService" in repository
  114. assert "approval_gateway.get_task" in service
  115. assert '"grants_data_access": False' in service