using System.Text.RegularExpressions; using Shouldly; using Xunit; namespace ZB.MOM.WW.OtOpcUa.Host.Tests.Configuration; /// /// Pins the one AddZbSecrets call that no executable test can reach: the pre-host /// ${secret:} expander in Program.cs (top-level statements). That call composes the /// secrets subsystem in a throwaway ServiceCollection with no IHostEnvironment, so /// it MUST pass the content root explicitly (the Secrets 0.6.1 four-argument overload) — dropped /// back to the three-argument form, the under-content-root store rule silently vanishes at /// exactly the moment the migrator creates the store file, and a rejected path gains an empty /// database before the real host aborts (the 0.6.0 defect; the runtime half of this pin is /// SecretsStorePathValidationTests.Without_the_explicit_content_root_the_prehost_hole_reopens /// in Host.IntegrationTests). /// public sealed class SecretsPreHostContentRootSourceTests { [Fact] public void The_prehost_expander_passes_the_content_root_explicitly() { var source = ReadProgramSource(); // The throwaway container's AddZbSecrets call, allowing for formatting drift but requiring // the third argument to be the builder's content root. Regex.IsMatch( source, @"new\s+ServiceCollection\(\)\s*\.\s*AddZbSecrets\(\s*builder\.Configuration\s*,\s*""Secrets""\s*,\s*builder\.Environment\.ContentRootPath\s*\)", RegexOptions.Singleline) .ShouldBeTrue( "Program.cs's pre-host secrets expander must call the four-argument AddZbSecrets " + "overload with builder.Environment.ContentRootPath — the throwaway container has no " + "IHostEnvironment, and without the explicit root the under-content-root store rule " + "is skipped while the migrator creates the store file"); } private static string ReadProgramSource() { var dir = new DirectoryInfo(AppContext.BaseDirectory); while (dir is not null && !File.Exists(Path.Combine(dir.FullName, "ZB.MOM.WW.OtOpcUa.slnx"))) dir = dir.Parent!; dir.ShouldNotBeNull(); return File.ReadAllText(Path.Combine( dir.FullName, "src", "Server", "ZB.MOM.WW.OtOpcUa.Host", "Program.cs")); } }