test_enterprise_identity_navigation_contract.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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. start_token = "\n" + " " * indent + "{\n"
  7. name_token = " " * (indent + 2) + f"name: '{name}'"
  8. assert name_token in source, f"route {name!r} marker not found"
  9. name_at = source.index(name_token)
  10. start = source.rfind(start_token, 0, name_at)
  11. if start >= 0:
  12. start += 1
  13. elif source.startswith(start_token[1:]):
  14. start = 0
  15. terminators = [
  16. "\n" + " " * indent + "},",
  17. "\n" + " " * indent + "}",
  18. ]
  19. ends = [(source.find(token, name_at), token) for token in terminators]
  20. valid_ends = [(end, token) for end, token in ends if end >= 0]
  21. assert start >= 0 and valid_ends, f"route {name!r} block boundaries not found"
  22. end, end_token = min(valid_ends)
  23. return source[start : end + len(end_token)]
  24. def _assert_exact_line(block: str, *, indent: int, field: str, value: str) -> None:
  25. expected = " " * indent + f"{field}: {value}"
  26. assert re.search(rf"(?m)^{re.escape(expected)},?$", block), f"missing exact line: {expected}"
  27. def _meta_block(route: str, *, indent: int) -> str:
  28. start_token = "\n" + " " * indent + "meta: {\n"
  29. end_token = "\n" + " " * indent + "},"
  30. start = route.find(start_token)
  31. end = route.find(end_token, start)
  32. assert start >= 0 and end >= 0, "route meta block boundaries not found"
  33. return route[start + 1 : end + len(end_token)]
  34. def test_enterprise_identity_is_owned_only_by_system_management():
  35. routes = ROUTES.read_text(encoding="utf-8")
  36. data_research = _route_block(routes, indent=4, name="data-governance")
  37. system = _route_block(routes, indent=4, name="systemManage")
  38. assert "systemEnterpriseIdentity" not in data_research
  39. assert "path: '/systemManage/enterprise-identity'" not in data_research
  40. assert "component: 'systemManage/enterpriseIdentity'" not in data_research
  41. assert routes.count("name: 'systemEnterpriseIdentity'") == 1
  42. assert routes.count("path: '/systemManage/enterprise-identity'") == 1
  43. assert routes.count("component: 'systemManage/enterpriseIdentity'") == 1
  44. identity = _route_block(system, indent=8, name="systemEnterpriseIdentity")
  45. for field, value in [
  46. ("hidden", "0"),
  47. ("type", "1"),
  48. ("title", "'企业身份与 SSO'"),
  49. ("path", "'/systemManage/enterprise-identity'"),
  50. ("children", "[]"),
  51. ("label", "'企业身份与 SSO'"),
  52. ("sort", "2"),
  53. ("component", "'systemManage/enterpriseIdentity'"),
  54. ("name", "'systemEnterpriseIdentity'"),
  55. ("alwaysShow", "0"),
  56. ]:
  57. _assert_exact_line(identity, indent=10, field=field, value=value)
  58. meta = _meta_block(identity, indent=10)
  59. for field, value in [
  60. ("title", "'企业身份与 SSO'"),
  61. ("icon", "'mdi-account-key-outline'"),
  62. ("permissions", "['identity:manage']"),
  63. ]:
  64. _assert_exact_line(meta, indent=12, field=field, value=value)
  65. def test_system_management_navigation_order_is_stable():
  66. routes = ROUTES.read_text(encoding="utf-8")
  67. system = _route_block(routes, indent=4, name="systemManage")
  68. names = [
  69. "systemUserManage",
  70. "systemEnterpriseIdentity",
  71. "systemResponsibilityManage",
  72. "systemGovernanceAudit",
  73. "systemAgentGovernance",
  74. ]
  75. for name in names:
  76. assert routes.count(f"name: '{name}'") == 1
  77. positions = []
  78. for name in names:
  79. marker = f"name: '{name}'"
  80. assert marker in system, f"System Management is missing route {name!r}"
  81. positions.append(system.index(marker))
  82. assert positions == sorted(positions)
  83. for expected, name in enumerate(names, start=1):
  84. block = _route_block(system, indent=8, name=name)
  85. assert re.search(rf"(?m)^\s+sort: {expected},?$", block)