using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace ScadaLink.SiteEventLogging.Tests; /// /// Regression tests for SiteEventLogging-007: the purge and query services must not /// downcast an injected to the concrete type. They now /// depend on the concrete directly, and DI must resolve /// the recorder, query service, and purge service to a single shared instance. /// public class ServiceWiringTests : IDisposable { private readonly string _dbPath; private ServiceProvider? _provider; public ServiceWiringTests() { _dbPath = Path.Combine(Path.GetTempPath(), $"test_wiring_{Guid.NewGuid()}.db"); } public void Dispose() { _provider?.Dispose(); if (File.Exists(_dbPath)) File.Delete(_dbPath); } [Fact] public void AddSiteEventLogging_ResolvesAllServices_SharingOneRecorderInstance() { var services = new ServiceCollection(); services.AddLogging(); services.Configure(o => o.DatabasePath = _dbPath); services.AddSiteEventLogging(); _provider = services.BuildServiceProvider(); var recorderViaInterface = _provider.GetRequiredService(); var recorderConcrete = _provider.GetRequiredService(); var queryService = _provider.GetRequiredService(); // The interface registration must forward to the concrete singleton — purge // and query depend on that same instance, so all three share one connection. Assert.Same(recorderConcrete, recorderViaInterface); Assert.NotNull(queryService); // The hosted purge service must also resolve without an InvalidCastException. var hosted = _provider.GetServices(); Assert.Contains(hosted, h => h is EventLogPurgeService); } [Fact] public void PurgeAndQueryServices_AcceptConcreteRecorder_WithoutDowncast() { // The services no longer take ISiteEventLogger and downcast it; they take the // concrete SiteEventLogger. Constructing them directly must compile and work. var options = Options.Create(new SiteEventLogOptions { DatabasePath = _dbPath }); using var loggerFactory = LoggerFactory.Create(_ => { }); using var recorder = new SiteEventLogger( options, loggerFactory.CreateLogger()); var purge = new EventLogPurgeService( recorder, options, loggerFactory.CreateLogger()); var query = new EventLogQueryService( recorder, options, loggerFactory.CreateLogger()); Assert.NotNull(purge); Assert.NotNull(query); } }