using Xunit; namespace Admin.NET.Plugin.AiDOP.Tests.DataPlatform; public class MdpSourceIdentityBackfillContractTests { [Fact] public void StartupPath_DefersHistoricalBackfillUntilApplicationStarted() { var aligner = ReadPluginSource("DataPlatform/Schema/MdpSchemaAligner.cs"); var worker = ReadPluginSource("DataPlatform/Schema/MdpSourceIdentityBackfillWorker.cs"); var startup = ReadPluginSource("Startup.cs"); var ensureStart = aligner.IndexOf("public static async Task EnsureSourceIdentityAsync", StringComparison.Ordinal); var backfillDeclaration = aligner.IndexOf("public static async Task BackfillProvenSourceAsync", StringComparison.Ordinal); Assert.True(ensureStart >= 0 && backfillDeclaration > ensureStart); Assert.DoesNotContain( "BackfillProvenSourceAsync(", aligner[ensureStart..backfillDeclaration], StringComparison.Ordinal); Assert.Contains("ApplicationStarted.Register", worker, StringComparison.Ordinal); Assert.Contains("await started.Task.WaitAsync", worker, StringComparison.Ordinal); Assert.Contains("BackfillProvenSourceAsync", worker, StringComparison.Ordinal); Assert.Contains("AddHostedService", startup); } [Fact] public void Backfill_BuildsCandidatesPerTableAndFailsClosedOnConflicts() { var aligner = ReadPluginSource("DataPlatform/Schema/MdpSchemaAligner.cs"); Assert.Contains("CREATE TEMPORARY TABLE tmp_mdp_proven_source", aligner, StringComparison.Ordinal); Assert.Contains("foreach (var table in stgNames)", aligner, StringComparison.Ordinal); Assert.Contains("ON DUPLICATE KEY UPDATE", aligner, StringComparison.Ordinal); Assert.Contains("g.tenant_id IS NOT NULL", aligner, StringComparison.Ordinal); Assert.Contains("x.conflicted=0", aligner, StringComparison.Ordinal); Assert.DoesNotContain("var union = string.Join(\" UNION ALL \"", aligner, StringComparison.Ordinal); } private static string ReadPluginSource(string relativePath) => File.ReadAllText(Path.Combine( RepoRoot(), "server", "Plugins", "Admin.NET.Plugin.AiDOP", relativePath.Replace('/', Path.DirectorySeparatorChar))); private static string RepoRoot() { var dir = new DirectoryInfo(AppContext.BaseDirectory); while (dir != null && !Directory.Exists(Path.Combine(dir.FullName, "server"))) dir = dir.Parent; return dir?.FullName ?? throw new DirectoryNotFoundException("Repository root not found."); } }