From a15ceb3ec90667c48dc2d27fbf3a45f8a643d608 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Wed, 20 May 2026 11:14:03 -0400 Subject: [PATCH] feat(auditlog): scaffold ScadaLink.AuditLog project + tests project (#23) --- ScadaLink.slnx | 2 + .../Configuration/AuditLogOptions.cs | 10 ++++ .../ScadaLink.AuditLog.csproj | 28 +++++++++++ .../ServiceCollectionExtensions.cs | 36 +++++++++++++ .../AddAuditLogTests.cs | 50 +++++++++++++++++++ .../ScadaLink.AuditLog.Tests.csproj | 27 ++++++++++ 6 files changed, 153 insertions(+) create mode 100644 src/ScadaLink.AuditLog/Configuration/AuditLogOptions.cs create mode 100644 src/ScadaLink.AuditLog/ScadaLink.AuditLog.csproj create mode 100644 src/ScadaLink.AuditLog/ServiceCollectionExtensions.cs create mode 100644 tests/ScadaLink.AuditLog.Tests/AddAuditLogTests.cs create mode 100644 tests/ScadaLink.AuditLog.Tests/ScadaLink.AuditLog.Tests.csproj diff --git a/ScadaLink.slnx b/ScadaLink.slnx index 9b312e4..21b4f3a 100644 --- a/ScadaLink.slnx +++ b/ScadaLink.slnx @@ -1,5 +1,6 @@ + @@ -22,6 +23,7 @@ + diff --git a/src/ScadaLink.AuditLog/Configuration/AuditLogOptions.cs b/src/ScadaLink.AuditLog/Configuration/AuditLogOptions.cs new file mode 100644 index 0000000..757977c --- /dev/null +++ b/src/ScadaLink.AuditLog/Configuration/AuditLogOptions.cs @@ -0,0 +1,10 @@ +namespace ScadaLink.AuditLog.Configuration; + +/// +/// Configuration for Audit Log (#23). Bound from the "AuditLog" section of +/// appsettings.json. Bundle E (M1) ships the type so the DI scaffold can +/// register it; the full property set + validator are added by Task 9. +/// +public sealed class AuditLogOptions +{ +} diff --git a/src/ScadaLink.AuditLog/ScadaLink.AuditLog.csproj b/src/ScadaLink.AuditLog/ScadaLink.AuditLog.csproj new file mode 100644 index 0000000..4999344 --- /dev/null +++ b/src/ScadaLink.AuditLog/ScadaLink.AuditLog.csproj @@ -0,0 +1,28 @@ + + + + net10.0 + enable + enable + true + + + + + + + + + + + + + + + + + + + diff --git a/src/ScadaLink.AuditLog/ServiceCollectionExtensions.cs b/src/ScadaLink.AuditLog/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..7c93919 --- /dev/null +++ b/src/ScadaLink.AuditLog/ServiceCollectionExtensions.cs @@ -0,0 +1,36 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using ScadaLink.AuditLog.Configuration; + +namespace ScadaLink.AuditLog; + +/// +/// Composition root for the Audit Log (#23) component. M1 registers +/// ; later milestones extend this method to wire +/// up writers, telemetry actors, and the central ingest pipeline. Audit Log +/// (#23) sits alongside Notification Outbox (#21) and Site Call Audit (#22). +/// +public static class ServiceCollectionExtensions +{ + /// Configuration section bound to . + public const string ConfigSectionName = "AuditLog"; + + /// + /// Binds from the + /// section of . + /// M2+ will register writers, telemetry actors, and the central ingest + /// pipeline here. IAuditLogRepository is registered by + /// ScadaLink.ConfigurationDatabase.ServiceCollectionExtensions.AddConfigurationDatabase, + /// so the caller (the Host on the central node) must also call that. + /// + public static IServiceCollection AddAuditLog(this IServiceCollection services, IConfiguration config) + { + ArgumentNullException.ThrowIfNull(services); + ArgumentNullException.ThrowIfNull(config); + + services.AddOptions() + .Bind(config.GetSection(ConfigSectionName)); + + return services; + } +} diff --git a/tests/ScadaLink.AuditLog.Tests/AddAuditLogTests.cs b/tests/ScadaLink.AuditLog.Tests/AddAuditLogTests.cs new file mode 100644 index 0000000..a1057a1 --- /dev/null +++ b/tests/ScadaLink.AuditLog.Tests/AddAuditLogTests.cs @@ -0,0 +1,50 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using ScadaLink.AuditLog.Configuration; + +namespace ScadaLink.AuditLog.Tests; + +/// +/// Bundle E (M1) smoke tests for the Audit Log (#23) DI scaffold. Verifies +/// AddAuditLog registers against the +/// AuditLog configuration section. Bundle E ships only the scaffold; +/// the validator + full options surface land in Task 9. +/// +public class AddAuditLogTests +{ + [Fact] + public void AddAuditLog_RegistersAuditLogOptions() + { + var config = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary()) + .Build(); + + var services = new ServiceCollection(); + services.AddAuditLog(config); + var provider = services.BuildServiceProvider(); + + var opts = provider.GetService>(); + + Assert.NotNull(opts); + Assert.NotNull(opts!.Value); + } + + [Fact] + public void AddAuditLog_NullServices_Throws() + { + var config = new ConfigurationBuilder().Build(); + + Assert.Throws( + () => ServiceCollectionExtensions.AddAuditLog(null!, config)); + } + + [Fact] + public void AddAuditLog_NullConfig_Throws() + { + var services = new ServiceCollection(); + + Assert.Throws( + () => services.AddAuditLog(null!)); + } +} diff --git a/tests/ScadaLink.AuditLog.Tests/ScadaLink.AuditLog.Tests.csproj b/tests/ScadaLink.AuditLog.Tests/ScadaLink.AuditLog.Tests.csproj new file mode 100644 index 0000000..9a866be --- /dev/null +++ b/tests/ScadaLink.AuditLog.Tests/ScadaLink.AuditLog.Tests.csproj @@ -0,0 +1,27 @@ + + + + net10.0 + enable + enable + true + false + + + + + + + + + + + + + + + + + + +