161 lines
5.1 KiB
C#
161 lines
5.1 KiB
C#
using ZB.MOM.WW.Secrets.Cli.Interactive;
|
|
using ZB.MOM.WW.Secrets.MasterKey;
|
|
|
|
namespace ZB.MOM.WW.Secrets.Tests.Cli.Interactive;
|
|
|
|
/// <summary>
|
|
/// Tests for <see cref="TargetConfigReader"/>: it must compose the target app's configuration
|
|
/// (base json + optional environment overlay + environment variables) exactly the way the app
|
|
/// would at startup, so fixes land in the store the app actually reads.
|
|
/// </summary>
|
|
public sealed class TargetConfigReaderTests : IDisposable
|
|
{
|
|
private readonly List<string> _tempDirs = [];
|
|
|
|
public void Dispose()
|
|
{
|
|
foreach (string dir in _tempDirs)
|
|
{
|
|
if (Directory.Exists(dir))
|
|
{
|
|
try { Directory.Delete(dir, recursive: true); } catch (IOException) { /* best-effort temp cleanup */ }
|
|
}
|
|
}
|
|
}
|
|
|
|
private string NewTempDir()
|
|
{
|
|
string dir = Path.Combine(Path.GetTempPath(), "zb-secrets-cfg-" + Guid.NewGuid().ToString("N"));
|
|
Directory.CreateDirectory(dir);
|
|
_tempDirs.Add(dir);
|
|
return dir;
|
|
}
|
|
|
|
[Fact]
|
|
public void Reads_secrets_section_and_binds_options()
|
|
{
|
|
string dir = NewTempDir();
|
|
string path = Path.Combine(dir, "appsettings.json");
|
|
File.WriteAllText(path, """
|
|
{
|
|
"Secrets": {
|
|
"SqlitePath": "custom.db",
|
|
"MasterKey": {
|
|
"Source": "Environment",
|
|
"EnvVarName": "MY_KEY"
|
|
}
|
|
}
|
|
}
|
|
""");
|
|
|
|
StoreTarget target = new TargetConfigReader().Read(path);
|
|
|
|
Assert.Equal(MasterKeySource.Environment, target.Secrets.MasterKey.Source);
|
|
Assert.Equal("MY_KEY", target.Secrets.MasterKey.EnvVarName);
|
|
Assert.Equal(Path.Combine(dir, "custom.db"), target.Secrets.SqlitePath);
|
|
}
|
|
|
|
[Fact]
|
|
public void Environment_overlay_wins_over_base()
|
|
{
|
|
string dir = NewTempDir();
|
|
File.WriteAllText(Path.Combine(dir, "appsettings.json"), """
|
|
{
|
|
"Secrets": { "SqlitePath": "base.db" }
|
|
}
|
|
""");
|
|
File.WriteAllText(Path.Combine(dir, "appsettings.Production.json"), """
|
|
{
|
|
"Secrets": { "SqlitePath": "prod.db" }
|
|
}
|
|
""");
|
|
|
|
StoreTarget target = new TargetConfigReader().Read(
|
|
Path.Combine(dir, "appsettings.json"), environment: "Production");
|
|
|
|
Assert.Equal(Path.Combine(dir, "prod.db"), target.Secrets.SqlitePath);
|
|
}
|
|
|
|
[Fact]
|
|
public void Binds_sqlserver_options_when_section_present()
|
|
{
|
|
string dir = NewTempDir();
|
|
File.WriteAllText(Path.Combine(dir, "appsettings.json"), """
|
|
{
|
|
"Secrets": {
|
|
"SqlitePath": "secrets.db",
|
|
"SqlServer": {
|
|
"ConnectionString": "Server=hub;Database=ZbSecrets;Trusted_Connection=True"
|
|
}
|
|
}
|
|
}
|
|
""");
|
|
|
|
StoreTarget withSql = new TargetConfigReader().Read(Path.Combine(dir, "appsettings.json"));
|
|
|
|
Assert.NotNull(withSql.SqlServer);
|
|
Assert.Equal(
|
|
"Server=hub;Database=ZbSecrets;Trusted_Connection=True",
|
|
withSql.SqlServer!.ConnectionString);
|
|
|
|
string dir2 = NewTempDir();
|
|
File.WriteAllText(Path.Combine(dir2, "appsettings.json"), """
|
|
{
|
|
"Secrets": { "SqlitePath": "secrets.db" }
|
|
}
|
|
""");
|
|
|
|
StoreTarget noSql = new TargetConfigReader().Read(Path.Combine(dir2, "appsettings.json"));
|
|
|
|
Assert.Null(noSql.SqlServer);
|
|
}
|
|
|
|
[Fact]
|
|
public void SqlitePath_is_resolved_relative_to_the_app_directory()
|
|
{
|
|
string dir = NewTempDir();
|
|
File.WriteAllText(Path.Combine(dir, "appsettings.json"), """
|
|
{
|
|
"Secrets": { "SqlitePath": "secrets.db" }
|
|
}
|
|
""");
|
|
|
|
StoreTarget target = new TargetConfigReader().Read(Path.Combine(dir, "appsettings.json"));
|
|
|
|
Assert.True(Path.IsPathRooted(target.Secrets.SqlitePath));
|
|
Assert.Equal(Path.Combine(dir, "secrets.db"), target.Secrets.SqlitePath);
|
|
}
|
|
|
|
[Fact]
|
|
public void Missing_file_throws_FileNotFoundException_with_path()
|
|
{
|
|
string dir = NewTempDir();
|
|
string path = Path.Combine(dir, "appsettings.json");
|
|
|
|
FileNotFoundException ex = Assert.Throws<FileNotFoundException>(
|
|
() => new TargetConfigReader().Read(path));
|
|
|
|
Assert.Contains(path, ex.Message);
|
|
}
|
|
|
|
[Fact]
|
|
public void Custom_section_path_is_honored()
|
|
{
|
|
string dir = NewTempDir();
|
|
File.WriteAllText(Path.Combine(dir, "appsettings.json"), """
|
|
{
|
|
"MySecrets": {
|
|
"SqlitePath": "elsewhere.db",
|
|
"MasterKey": { "EnvVarName": "OTHER_KEY" }
|
|
}
|
|
}
|
|
""");
|
|
|
|
StoreTarget target = new TargetConfigReader().Read(
|
|
Path.Combine(dir, "appsettings.json"), sectionPath: "MySecrets");
|
|
|
|
Assert.Equal("OTHER_KEY", target.Secrets.MasterKey.EnvVarName);
|
|
Assert.Equal(Path.Combine(dir, "elsewhere.db"), target.Secrets.SqlitePath);
|
|
}
|
|
}
|