using Microsoft.Extensions.Configuration; using Serilog.Events; namespace ScadaLink.Host.Tests; /// /// Host-011: ScadaLink:Logging:MinimumLevel must actually drive the Serilog /// minimum level. Previously the value was bound into /// but never read, so editing it had no effect. /// public class LoggerConfigurationTests { private static IConfiguration BuildConfig(string? minimumLevel) { var values = new Dictionary(); if (minimumLevel != null) values["ScadaLink:Logging:MinimumLevel"] = minimumLevel; return new ConfigurationBuilder().AddInMemoryCollection(values).Build(); } [Fact] public void MinimumLevel_Warning_SuppressesInformationLogs() { var sink = new InMemorySink(); var logger = LoggerConfigurationFactory .Build(BuildConfig("Warning"), "Central", "central", "node1") .WriteTo.Sink(sink) .CreateLogger(); logger.Information("info message"); logger.Warning("warning message"); Assert.Single(sink.LogEvents); Assert.Equal(LogEventLevel.Warning, sink.LogEvents[0].Level); } [Fact] public void MinimumLevel_Debug_AllowsDebugLogs() { var sink = new InMemorySink(); var logger = LoggerConfigurationFactory .Build(BuildConfig("Debug"), "Site", "site-a", "node1") .WriteTo.Sink(sink) .CreateLogger(); logger.Debug("debug message"); Assert.Single(sink.LogEvents); Assert.Equal(LogEventLevel.Debug, sink.LogEvents[0].Level); } [Fact] public void MinimumLevel_Absent_DefaultsToInformation() { var sink = new InMemorySink(); var logger = LoggerConfigurationFactory .Build(BuildConfig(null), "Central", "central", "node1") .WriteTo.Sink(sink) .CreateLogger(); logger.Debug("debug message"); logger.Information("info message"); Assert.Single(sink.LogEvents); Assert.Equal(LogEventLevel.Information, sink.LogEvents[0].Level); } /// /// Host-022: an unrecognised ScadaLink:Logging:MinimumLevel (e.g. a typo /// like "Informaiton") must NOT abort startup but MUST emit a one-shot warning /// naming the offending value and the fallback so the silent coercion is /// visible. Null/blank is treated as "unset" and silently defaults. /// [Fact] public void ParseLevel_UnrecognisedValue_FallsBackAndWarns() { var writer = new StringWriter(); var result = LoggerConfigurationFactory.ParseLevel("Informaiton", writer); Assert.Equal(LogEventLevel.Information, result); var warning = writer.ToString(); Assert.Contains("warning", warning, StringComparison.OrdinalIgnoreCase); Assert.Contains("Informaiton", warning); Assert.Contains("Information", warning); } [Fact] public void ParseLevel_NullOrBlank_FallsBackSilently() { var writer = new StringWriter(); var nullResult = LoggerConfigurationFactory.ParseLevel(null, writer); var blankResult = LoggerConfigurationFactory.ParseLevel(" ", writer); Assert.Equal(LogEventLevel.Information, nullResult); Assert.Equal(LogEventLevel.Information, blankResult); Assert.Empty(writer.ToString()); } [Fact] public void ParseLevel_RecognisedValue_NoWarning() { var writer = new StringWriter(); var result = LoggerConfigurationFactory.ParseLevel("Warning", writer); Assert.Equal(LogEventLevel.Warning, result); Assert.Empty(writer.ToString()); } }