| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- using System.Text.RegularExpressions;
- using Xunit;
- namespace Admin.NET.Plugin.AiDOP.Tests.DataPlatform;
- /// <summary>
- /// 指标计算与诊断依据不得再出现 T8 列名或中文业务类型字面量。
- /// T8 适配器文件不在扫描范围内。
- /// </summary>
- public class NeutralLayerTokenGuardTests
- {
- private static readonly string[] Files =
- [
- Path.Combine("Supply", "S3MdpSyncTransformService.cs"),
- Path.Combine("MaterialWarehouse", "S5MdpSyncTransformService.cs"),
- Path.Combine("Manufacturing", "S6MdpSyncTransformService.cs"),
- Path.Combine("FinishedWarehouse", "S7MdpSyncTransformService.cs"),
- Path.Combine("SmartOps", "SmartDiagnosisEvidenceRegistry.cs"),
- Path.Combine("SmartOps", "SmartOpsKpiAtomicBuildService.cs"),
- Path.Combine("SmartOps", "S9CompositeKpiWriter.cs")
- ];
- private static readonly string[] Tokens =
- [
- "mdp_std_t8_", "ztid", "lbs", "hzyn", "zfyn", "shyn", "shtime",
- "noid", "rwnoid", "lynoid", "gdyn", "gdtime", "jhdate", "slzx", "zzzt",
- "采购入库", "生产领料", "生产任务", "生产入库", "销售订单", "销售出库", "销售退货"
- ];
- [Fact]
- public void KpiReaders_DoNotContainT8Tokens()
- {
- var hits = new List<string>();
- foreach (var relative in Files)
- {
- var text = ReadPluginFile(relative);
- foreach (var token in Tokens)
- {
- var pattern = token.Any(c => c > 127)
- ? Regex.Escape(token)
- : $@"\b{Regex.Escape(token)}\b";
- if (Regex.IsMatch(text, pattern))
- hits.Add($"{relative}: {token}");
- }
- }
- Assert.Empty(hits);
- }
- [Fact]
- public void InventoryAndEmployeeKpiSql_FilterBySource()
- {
- var files = new[]
- {
- Path.Combine("Supply", "S3MdpSyncTransformService.cs"),
- Path.Combine("MaterialWarehouse", "S5MdpSyncTransformService.cs"),
- Path.Combine("Manufacturing", "S6MdpSyncTransformService.cs"),
- Path.Combine("FinishedWarehouse", "S7MdpSyncTransformService.cs")
- };
- var hits = new List<string>();
- foreach (var relative in files)
- {
- var text = ReadPluginFile(relative);
- foreach (Match match in Regex.Matches(text, @"from\s+mdp_std_(inv_trans|employee)\b", RegexOptions.IgnoreCase))
- {
- var window = text.Substring(match.Index, Math.Min(1200, text.Length - match.Index));
- if (!window.Contains("source_system", StringComparison.OrdinalIgnoreCase))
- hits.Add($"{relative}@{match.Index}");
- }
- }
- Assert.Empty(hits);
- }
- [Fact]
- public void S5S6S7MetricSql_DoesNotNameT8()
- {
- var files = new[]
- {
- Path.Combine("MaterialWarehouse", "S5MdpSyncTransformService.cs"),
- Path.Combine("Manufacturing", "S6MdpSyncTransformService.cs"),
- Path.Combine("FinishedWarehouse", "S7MdpSyncTransformService.cs"),
- Path.Combine("Supply", "S3MdpSyncTransformService.cs")
- };
- var hits = new List<string>();
- foreach (var relative in files)
- {
- var text = ReadPluginFile(relative);
- foreach (Match match in Regex.Matches(text, "@\"(?:[^\"]|\"\")*\"|\"\"\"[\\s\\S]*?\"\"\""))
- {
- if (match.Value.Contains("T8", StringComparison.Ordinal))
- hits.Add($"{relative}:{match.Index}");
- }
- }
- Assert.Empty(hits);
- }
- [Fact]
- public void RefreshService_DoesNotHardcodePbxfxp()
- {
- var text = ReadPluginFile(Path.Combine("DataPlatform", "AidopT8KpiManualRefreshService.cs"));
- Assert.DoesNotContain("pbxfxp", text, StringComparison.OrdinalIgnoreCase);
- }
- private static string ReadPluginFile(string relative)
- {
- var dir = new DirectoryInfo(AppContext.BaseDirectory);
- while (dir != null)
- {
- var candidate = Path.Combine(dir.FullName, "server", "Plugins", "Admin.NET.Plugin.AiDOP", relative);
- if (File.Exists(candidate)) return File.ReadAllText(candidate);
- dir = dir.Parent;
- }
- throw new FileNotFoundException(relative);
- }
- }
|