feat: consume transactional email notifications
Add contract validation, SMTP delivery results, terminal failure context, neutral development seeding, and local Docker setup. Ref: IT-1033
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
namespace HrynCo.NotificationService.Services.Tests;
|
||||
|
||||
using HrynCo.NotificationService.DAL.Abstract.Providers;
|
||||
using HrynCo.NotificationService.DAL.Abstract.Repositories;
|
||||
using HrynCo.NotificationService.DAL.Abstract.Templates;
|
||||
using HrynCo.NotificationService.Migrator;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using NSubstitute;
|
||||
|
||||
public sealed class DevelopmentDataSeederTests
|
||||
{
|
||||
private readonly IEmailChannelRepository _channels = Substitute.For<IEmailChannelRepository>();
|
||||
private readonly IEmailTemplateRepository _templates = Substitute.For<IEmailTemplateRepository>();
|
||||
|
||||
[Fact]
|
||||
public async Task SeedAsync_WhenConfigurationIsMissing_CreatesMailpitChannelAndTestTemplate()
|
||||
{
|
||||
_channels.GetByServiceAsync("TestService", Arg.Any<CancellationToken>())
|
||||
.Returns(Array.Empty<EmailChannel>());
|
||||
_templates.GetAsync("TestService", "TestEmail", "en", Arg.Any<CancellationToken>())
|
||||
.Returns((EmailTemplate?)null);
|
||||
|
||||
DevelopmentDataSeeder seeder = CreateSeeder();
|
||||
|
||||
await seeder.SeedAsync("TestService", CancellationToken.None);
|
||||
|
||||
await _channels.Received(1).AddAsync(
|
||||
Arg.Is<EmailChannel>(channel => IsMailpitChannel(channel)),
|
||||
Arg.Any<CancellationToken>());
|
||||
await _templates.Received(1).AddAsync(
|
||||
Arg.Is<EmailTemplate>(template =>
|
||||
template.ServiceName == "TestService" &&
|
||||
template.Key == "TestEmail" &&
|
||||
template.Variables.Any(variable => variable.Name == "Message" && variable.Required)),
|
||||
Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SeedAsync_WhenConfigurationExists_DoesNotDuplicateOrOverwriteIt()
|
||||
{
|
||||
_channels.GetByServiceAsync("TestService", Arg.Any<CancellationToken>())
|
||||
.Returns([new EmailChannel
|
||||
{
|
||||
ServiceName = "TestService",
|
||||
EmailChannelType = EmailChannelType.Smtp,
|
||||
Settings = new SmtpChannelSettings()
|
||||
}]);
|
||||
_templates.GetAsync("TestService", "TestEmail", "en", Arg.Any<CancellationToken>())
|
||||
.Returns(new EmailTemplate
|
||||
{
|
||||
ServiceName = "TestService",
|
||||
Key = "TestEmail",
|
||||
LanguageCode = "en",
|
||||
Subject = "Existing",
|
||||
HtmlBody = "Existing",
|
||||
TextBody = "Existing"
|
||||
});
|
||||
|
||||
DevelopmentDataSeeder seeder = CreateSeeder();
|
||||
|
||||
await seeder.SeedAsync("TestService", CancellationToken.None);
|
||||
|
||||
await _channels.DidNotReceive().AddAsync(Arg.Any<EmailChannel>(), Arg.Any<CancellationToken>());
|
||||
await _templates.DidNotReceive().AddAsync(Arg.Any<EmailTemplate>(), Arg.Any<CancellationToken>());
|
||||
await _channels.DidNotReceive().UpdateAsync(Arg.Any<EmailChannel>(), Arg.Any<CancellationToken>());
|
||||
await _templates.DidNotReceive().UpdateAsync(Arg.Any<EmailTemplate>(), Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
private DevelopmentDataSeeder CreateSeeder() => new(
|
||||
_channels,
|
||||
_templates,
|
||||
NullLogger<DevelopmentDataSeeder>.Instance);
|
||||
|
||||
private static bool IsMailpitChannel(EmailChannel channel)
|
||||
{
|
||||
return channel.ServiceName == "TestService" &&
|
||||
channel.IsActive &&
|
||||
channel.Settings is SmtpChannelSettings smtp &&
|
||||
smtp.Host == "mailpit" &&
|
||||
smtp.Port == 1025 &&
|
||||
!smtp.UseSsl;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user