using System.Text.Json; using MBN_STOCK_WEBVIEW.Infrastructure; using MMoneyCoderSharp.Data; namespace MBN_STOCK_WEBVIEW.Infrastructure.Tests; public sealed class DatabaseOptionsLoaderTests { [Fact] public void Load_MissingFile_ReturnsSafeUnconfiguredDefaults() { var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N"), "missing.json"); var loader = new DatabaseOptionsLoader(_ => null); var options = loader.Load(path); Assert.False(options.IsConfigured(DataSourceKind.Oracle)); Assert.False(options.IsConfigured(DataSourceKind.MariaDb)); Assert.Equal(1521, options.Oracle.Port); Assert.Equal(3306, options.MariaDb.Port); Assert.Null(options.Oracle.Password); Assert.Null(options.MariaDb.Password); } [Fact] public async Task LoadAsync_EnvironmentValuesOverrideJsonValues() { var directory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); Directory.CreateDirectory(directory); var path = Path.Combine(directory, "database.local.json"); try { var jsonOptions = new DatabaseOptions { Oracle = new OracleDatabaseOptions { Host = "json-oracle-host.invalid", Port = 1521, Sid = "JSONSID", UserName = "json-oracle-user", Password = "json-oracle-password" }, MariaDb = new MariaDbDatabaseOptions { Host = "json-maria-host.invalid", Port = 3306, Database = "json_database", UserName = "json-maria-user", Password = "json-maria-password", TlsMode = MariaDbTlsMode.Preferred }, Resilience = new DatabaseResilienceOptions { OperationTimeoutSeconds = 45, MaximumRetryCount = 2, InitialRetryDelayMilliseconds = 250 } }; await File.WriteAllTextAsync(path, JsonSerializer.Serialize(jsonOptions)); var environment = new Dictionary(StringComparer.Ordinal) { ["MBN_STOCK_ORACLE_HOST"] = "env-oracle-host.invalid", ["MBN_STOCK_ORACLE_PORT"] = "1522", ["MBN_STOCK_ORACLE_USERNAME"] = "env-oracle-user", ["MBN_STOCK_ORACLE_PASSWORD"] = "env-oracle-password", ["MBN_STOCK_MARIADB_HOST"] = "env-maria-host.invalid", ["MBN_STOCK_MARIADB_PORT"] = "3307", ["MBN_STOCK_MARIADB_DATABASE"] = "env_database", ["MBN_STOCK_MARIADB_USERNAME"] = "env-maria-user", ["MBN_STOCK_MARIADB_PASSWORD"] = "env-maria-password", ["MBN_STOCK_MARIADB_TLS_MODE"] = "Required", ["MBN_STOCK_DB_OPERATION_TIMEOUT_SECONDS"] = "12", ["MBN_STOCK_DB_MAX_RETRY_COUNT"] = "4", ["MBN_STOCK_DB_INITIAL_RETRY_DELAY_MS"] = "75" }; var loader = new DatabaseOptionsLoader( name => environment.TryGetValue(name, out var value) ? value : null); var options = await loader.LoadAsync(path); Assert.Equal("env-oracle-host.invalid", options.Oracle.Host); Assert.Equal(1522, options.Oracle.Port); Assert.Equal("JSONSID", options.Oracle.Sid); Assert.Equal("env-oracle-user", options.Oracle.UserName); Assert.Equal("env-oracle-password", options.Oracle.Password); Assert.Equal("env-maria-host.invalid", options.MariaDb.Host); Assert.Equal(3307, options.MariaDb.Port); Assert.Equal("env_database", options.MariaDb.Database); Assert.Equal("env-maria-user", options.MariaDb.UserName); Assert.Equal("env-maria-password", options.MariaDb.Password); Assert.Equal(MariaDbTlsMode.Required, options.MariaDb.TlsMode); Assert.Equal(12, options.Resilience.OperationTimeoutSeconds); Assert.Equal(4, options.Resilience.MaximumRetryCount); Assert.Equal(75, options.Resilience.InitialRetryDelayMilliseconds); } finally { Directory.Delete(directory, recursive: true); } } [Fact] public void ToString_DoesNotExposeHostUserOrPassword() { const string oracleHost = "oracle-host-sensitive-sentinel"; const string oracleUser = "oracle-user-sensitive-sentinel"; const string oraclePassword = "oracle-password-sensitive-sentinel"; const string mariaHost = "maria-host-sensitive-sentinel"; const string mariaUser = "maria-user-sensitive-sentinel"; const string mariaPassword = "maria-password-sensitive-sentinel"; var options = TestOptions.CreateConfigured(); options.Oracle.Host = oracleHost; options.Oracle.UserName = oracleUser; options.Oracle.Password = oraclePassword; options.MariaDb.Host = mariaHost; options.MariaDb.UserName = mariaUser; options.MariaDb.Password = mariaPassword; var representations = string.Join( Environment.NewLine, options.ToString(), options.Oracle.ToString(), options.MariaDb.ToString(), options.Resilience.ToString()); Assert.DoesNotContain(oracleHost, representations, StringComparison.Ordinal); Assert.DoesNotContain(oracleUser, representations, StringComparison.Ordinal); Assert.DoesNotContain(oraclePassword, representations, StringComparison.Ordinal); Assert.DoesNotContain(mariaHost, representations, StringComparison.Ordinal); Assert.DoesNotContain(mariaUser, representations, StringComparison.Ordinal); Assert.DoesNotContain(mariaPassword, representations, StringComparison.Ordinal); } }