using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using NSubstitute;
using ScadaLink.Commons.Interfaces.Repositories;
using ScadaLink.Commons.Types.Enums;
using ScadaLink.NotificationOutbox.Delivery;
using ScadaLink.NotificationService;
namespace ScadaLink.NotificationOutbox.Tests;
///
/// Task 17: Tests for — the
/// DI registration extension for the Notification Outbox component. The extension binds
/// from the ScadaLink:NotificationOutbox
/// configuration section and registers the channel delivery adapter(s).
///
/// The Host wires both AddNotificationService and AddNotificationOutbox on the
/// central node; these tests do the same so the
/// adapter's SMTP dependencies (Func<ISmtpClientWrapper>, OAuth2TokenService,
/// NotificationOptions) are satisfied. — which the
/// takes directly and is registered scoped by the
/// Configuration Database component — is supplied here by a lightweight stub.
///
public class ServiceRegistrationTests
{
private static ServiceProvider BuildProvider()
{
var services = new ServiceCollection();
// Empty configuration: the options binding must still succeed and yield the
// documented NotificationOutboxOptions defaults.
var configuration = new ConfigurationBuilder().Build();
services.AddSingleton(configuration);
services.AddLogging();
// INotificationRepository is registered scoped by the Configuration Database
// component in production; a no-op stub stands in for it here.
services.AddScoped(_ => Substitute.For());
services.AddNotificationService();
services.AddNotificationOutbox();
return services.BuildServiceProvider();
}
[Fact]
public void AddNotificationOutbox_RegistersNotificationOutboxOptions_WithDefaults()
{
using var provider = BuildProvider();
var options = provider.GetRequiredService>().Value;
Assert.NotNull(options);
Assert.Equal(TimeSpan.FromSeconds(10), options.DispatchInterval);
Assert.Equal(100, options.DispatchBatchSize);
}
[Fact]
public void AddNotificationOutbox_OptionsSection_IsTheNotificationOutboxConfigPath()
{
Assert.Equal(
"ScadaLink:NotificationOutbox",
NotificationOutbox.ServiceCollectionExtensions.OptionsSection);
}
[Fact]
public void AddNotificationOutbox_BindsNotificationOutboxOptions_FromConfiguration()
{
var services = new ServiceCollection();
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary
{
["ScadaLink:NotificationOutbox:DispatchBatchSize"] = "250",
})
.Build();
services.AddSingleton(configuration);
services.AddLogging();
services.AddScoped(_ => Substitute.For());
services.AddNotificationService();
services.AddNotificationOutbox();
using var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService>().Value;
Assert.Equal(250, options.DispatchBatchSize);
}
[Fact]
public void AddNotificationOutbox_RegistersEmailDeliveryAdapter()
{
using var provider = BuildProvider();
using var scope = provider.CreateScope();
var adapter = scope.ServiceProvider.GetRequiredService();
Assert.NotNull(adapter);
Assert.Equal(NotificationType.Email, adapter.Type);
}
[Fact]
public void AddNotificationOutbox_RegistersEmailAdapter_AsINotificationDeliveryAdapter()
{
using var provider = BuildProvider();
using var scope = provider.CreateScope();
var adapters = scope.ServiceProvider.GetServices().ToList();
var email = Assert.Single(adapters);
Assert.IsType(email);
Assert.Equal(NotificationType.Email, email.Type);
}
}