using System.Text; using Microsoft.EntityFrameworkCore; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.AdminUI.Deployments; using ZB.MOM.WW.OtOpcUa.Configuration.Entities; using ZB.MOM.WW.OtOpcUa.Configuration.Enums; namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests.Deployments; /// /// The SQL-Server-backed half of (lmxopcua#815). EF InMemory runs /// ScanAsync's deployment query as LINQ-to-Objects, so an untranslatable predicate passes there and throws on /// every real boot — exactly what the #815 live gate found (ArtifactBlob.Length > 0). Here it must translate. /// [Collection(nameof(AdminUiSqlServerCollection))] public sealed class CredentialReferencePreflightSqlServerTests(AdminUiSqlServerFixture sql) { [SqlServerFact] public async Task ScanAsync_translates_and_reads_the_latest_sealed_artifact() { // Far-future timestamps so this test's rows are the latest whatever else the shared database holds. var anchor = new DateTime(2999, 1, 1, 0, 0, 0, DateTimeKind.Utc); var sealedId = Guid.NewGuid(); var failedId = Guid.NewGuid(); const string artifact = """ {"DriverInstances":[{"DriverInstanceId":"ouc-sql","Name":"UpstreamSql","DriverType":"OpcUaClient", "DriverConfig":"{\"Password\":\"secret:plant/opcua-pw\"}"}]} """; await using (var db = await sql.Factory.CreateDbContextAsync(TestContext.Current.CancellationToken)) { db.Deployments.Add(new Deployment { DeploymentId = sealedId, RevisionHash = "preflight-sealed", CreatedBy = "t", Status = DeploymentStatus.Sealed, CreatedAtUtc = anchor, ArtifactBlob = Encoding.UTF8.GetBytes(artifact), }); db.Deployments.Add(new Deployment { DeploymentId = failedId, RevisionHash = "preflight-failed", CreatedBy = "t", Status = DeploymentStatus.PartiallyFailed, CreatedAtUtc = anchor.AddMinutes(1), ArtifactBlob = Encoding.UTF8.GetBytes("""{"DriverInstances":[]}"""), }); await db.SaveChangesAsync(TestContext.Current.CancellationToken); } try { var findings = await new CredentialReferencePreflight(sql.Factory).ScanAsync(TestContext.Current.CancellationToken); findings.ShouldContain(f => f.Source == CredentialFindingSource.Deployed && f.DriverName == "UpstreamSql"); } finally { await using var db = await sql.Factory.CreateDbContextAsync(CancellationToken.None); await db.Deployments.Where(d => d.DeploymentId == sealedId || d.DeploymentId == failedId).ExecuteDeleteAsync(CancellationToken.None); } } }