using System.Text.RegularExpressions; using Admin.NET.Plugin.AiDOP.DataPlatform.Schema; using Xunit; namespace Admin.NET.Plugin.AiDOP.Tests.DataPlatform; public class MdpSchemaDefinitionTests { private static readonly Regex NeutralCreate = new( @"CREATE\s+TABLE\s+IF\s+NOT\s+EXISTS\s+`?(mdp_std_|mdp_stg_|dwd_)", RegexOptions.IgnoreCase | RegexOptions.Compiled); private static string PluginRoot() { var dir = new DirectoryInfo(AppContext.BaseDirectory); while (dir != null) { var candidate = Path.Combine(dir.FullName, "Plugins", "Admin.NET.Plugin.AiDOP"); if (Directory.Exists(candidate)) return candidate; // tests may run from server/Plugins/Admin.NET.Plugin.AiDOP.Tests/bin/... candidate = Path.Combine(dir.FullName, "Admin.NET.Plugin.AiDOP"); if (Directory.Exists(candidate) && File.Exists(Path.Combine(candidate, "Admin.NET.Plugin.AiDOP.csproj"))) return candidate; dir = dir.Parent; } throw new DirectoryNotFoundException("找不到 Admin.NET.Plugin.AiDOP 插件目录"); } [Fact] public void MdpSyncSources_MustNotEmbedNeutralCreates() { var root = PluginRoot(); var offenders = new List(); foreach (var file in Directory.EnumerateFiles(root, "*MdpSync*.cs", SearchOption.AllDirectories)) { var text = File.ReadAllText(file); if (!NeutralCreate.IsMatch(text)) continue; offenders.Add(Path.GetRelativePath(root, file)); } Assert.True( offenders.Count == 0, "中立层 CREATE 不得留在 *MdpSync* 服务内,应使用 MdpSchemaDefinition.Ddl:\n" + string.Join("\n", offenders)); } [Fact] public void Definition_ContainsRequiredTablesFromMovedCreates() { Assert.Contains("mdp_std_work_order_schedule", MdpSchemaDefinition.TableNames, StringComparer.OrdinalIgnoreCase); Assert.Contains("mdp_std_s6_report", MdpSchemaDefinition.TableNames, StringComparer.OrdinalIgnoreCase); // mdp_std_inv_trans 的 CREATE 原本不在本次搬迁的 *MdpSync* 文件中,故不登记、不断言。 var wo = MdpSchemaDefinition.Ddl("mdp_std_work_order_schedule"); Assert.Contains("approved_flag", wo, StringComparison.OrdinalIgnoreCase); Assert.Contains("void_flag", wo, StringComparison.OrdinalIgnoreCase); var report = MdpSchemaDefinition.Ddl("mdp_std_s6_report"); Assert.Contains("start_work_date", report, StringComparison.OrdinalIgnoreCase); Assert.Contains("task_no", report, StringComparison.OrdinalIgnoreCase); Assert.Contains("domain", report, StringComparison.OrdinalIgnoreCase); } [Fact] public void Ddl_UnknownTable_Throws() { Assert.Throws(() => MdpSchemaDefinition.Ddl("mdp_std_not_registered_xyz")); } }