AidopMenuLinkSyncContractTests.cs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. using Xunit;
  2. namespace Admin.NET.Plugin.AiDOP.Tests.Infrastructure;
  3. public class AidopMenuLinkSyncContractTests
  4. {
  5. [Fact]
  6. public void StartupSync_MaintainsTenantMenus_ButNeverReconcilesRoleMenus()
  7. {
  8. var source = File.ReadAllText(FindSourceFile());
  9. var ensureLinked = ExtractMethod(source, "public static void EnsureLinked(IServiceProvider services)");
  10. Assert.Contains("SysTenantMenu", ensureLinked);
  11. Assert.DoesNotContain("SysRoleMenu", ensureLinked);
  12. }
  13. private static string ExtractMethod(string source, string signature)
  14. {
  15. var signatureIndex = source.IndexOf(signature, StringComparison.Ordinal);
  16. Assert.True(signatureIndex >= 0, $"Method not found: {signature}");
  17. var bodyStart = source.IndexOf('{', signatureIndex);
  18. Assert.True(bodyStart >= 0, $"Method body not found: {signature}");
  19. var depth = 0;
  20. for (var i = bodyStart; i < source.Length; i++)
  21. {
  22. if (source[i] == '{') depth++;
  23. if (source[i] != '}') continue;
  24. depth--;
  25. if (depth == 0) return source[signatureIndex..(i + 1)];
  26. }
  27. throw new InvalidOperationException($"Method body is incomplete: {signature}");
  28. }
  29. private static string FindSourceFile()
  30. {
  31. var directory = new DirectoryInfo(AppContext.BaseDirectory);
  32. while (directory != null)
  33. {
  34. var candidate = Path.Combine(
  35. directory.FullName,
  36. "server",
  37. "Plugins",
  38. "Admin.NET.Plugin.AiDOP",
  39. "Infrastructure",
  40. "AidopMenuLinkSync.cs");
  41. if (File.Exists(candidate)) return candidate;
  42. directory = directory.Parent;
  43. }
  44. throw new FileNotFoundException("AidopMenuLinkSync.cs not found from test output path.");
  45. }
  46. }