test_enterprise_connector_metadata_navigation_contract.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import re
  2. from pathlib import Path
  3. ROOT = Path(__file__).resolve().parents[1]
  4. ROUTES = ROOT / "frontend/src/router/routes.js"
  5. def _route_block(source: str, *, indent: int, name: str) -> str:
  6. """Return one route object, scoped to its direct indentation level."""
  7. start_token = "\n" + " " * indent + "{\n"
  8. name_token = " " * (indent + 2) + f"name: '{name}'"
  9. assert source.count(name_token) == 1, f"route {name!r} must be unique"
  10. name_at = source.index(name_token)
  11. start = source.rfind(start_token, 0, name_at)
  12. if start >= 0:
  13. start += 1
  14. elif source.startswith(start_token[1:]):
  15. start = 0
  16. terminators = [
  17. "\n" + " " * indent + "},",
  18. "\n" + " " * indent + "}",
  19. ]
  20. ends = [(source.find(token, name_at), token) for token in terminators]
  21. valid_ends = [(end, token) for end, token in ends if end >= 0]
  22. assert start >= 0 and valid_ends, f"route {name!r} block boundaries not found"
  23. end, end_token = min(valid_ends)
  24. return source[start : end + len(end_token)]
  25. def _assert_exact_line(block: str, *, indent: int, field: str, value: str) -> None:
  26. expected = " " * indent + f"{field}: {value}"
  27. assert re.search(rf"(?m)^{re.escape(expected)},?$", block), f"missing exact line: {expected}"
  28. def _assert_inline_meta_permission(route: str, *, indent: int, permission: str) -> None:
  29. marker = " " * indent + "meta: { permissions: ["
  30. match = re.search(rf"(?m)^{re.escape(marker)}([^\]]*)\]", route)
  31. assert match, "route meta permissions array not found"
  32. assert match.group(1).strip() == f"'{permission}'", (
  33. f"permissions must be exactly ['{permission}']"
  34. )
  35. def _direct_child_names(parent_route: str, *, child_indent: int) -> list[str]:
  36. return re.findall(
  37. rf"(?m)^{re.escape(' ' * (child_indent + 2))}name: '([^']+)'",
  38. parent_route,
  39. )
  40. def test_enterprise_connectors_are_owned_only_by_data_factory():
  41. routes = ROUTES.read_text(encoding="utf-8")
  42. data_research = _route_block(routes, indent=4, name="data-governance")
  43. data_factory = _route_block(routes, indent=4, name="dataFactory")
  44. assert routes.count("name: 'enterpriseConnectors'") == 1
  45. assert "enterpriseConnectors" not in data_research
  46. assert "path: '/data-governance/development/enterprise-connectors'" not in data_research
  47. assert "component: 'dataGovernance/development/enterpriseConnectors'" not in data_research
  48. connector = _route_block(data_factory, indent=8, name="enterpriseConnectors")
  49. for field, value in [
  50. ("icon", "'mdi-connection'"),
  51. ("title", "'企业连接器'"),
  52. ("path", "'/data-governance/development/enterprise-connectors'"),
  53. ("children", "[]"),
  54. ("label", "'企业连接器'"),
  55. ("sort", "4"),
  56. ("component", "'dataGovernance/development/enterpriseConnectors'"),
  57. ("name", "'enterpriseConnectors'"),
  58. ]:
  59. _assert_exact_line(connector, indent=10, field=field, value=value)
  60. _assert_inline_meta_permission(connector, indent=10, permission="connectors:read")
  61. def test_data_factory_connector_and_orchestration_navigation_order_is_stable():
  62. routes = ROUTES.read_text(encoding="utf-8")
  63. data_factory = _route_block(routes, indent=4, name="dataFactory")
  64. names = [
  65. "enterpriseConnectors",
  66. "productionLineDeployment",
  67. "productionLine",
  68. "workflowIndex",
  69. "dataObservability",
  70. "connectionPoolIndex",
  71. ]
  72. child_blocks = [_route_block(data_factory, indent=8, name=name) for name in names]
  73. child_names = _direct_child_names(data_factory, child_indent=8)
  74. connector_index = child_names.index("enterpriseConnectors")
  75. deployment_index = child_names.index("productionLineDeployment")
  76. assert deployment_index == connector_index + 1
  77. assert child_names[connector_index : child_names.index("connectionPoolIndex") + 1] == names
  78. assert [re.search(r"(?m)^\s+name: '([^']+)'", block).group(1) for block in child_blocks] == names