1631786ce2
Add push contracts, provider delivery and channel diagnostics. Link email channels to services and document migration and validation. Ref: IT-1074
128 lines
4.8 KiB
C#
128 lines
4.8 KiB
C#
namespace HrynCo.NotificationService.Services.Tests.EmailProcessing;
|
|
|
|
using HrynCo.NotificationService.Contracts.Messages;
|
|
using HrynCo.NotificationService.DAL.Abstract.Providers;
|
|
using HrynCo.NotificationService.DAL.Abstract.Repositories;
|
|
using HrynCo.NotificationService.DAL.Abstract.Templates;
|
|
using HrynCo.NotificationService.Worker.Services.EmailProcessing;
|
|
using Hrynco.RabbitMq;
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
|
using NSubstitute;
|
|
|
|
public sealed class SendEmailServiceTests
|
|
{
|
|
[Fact]
|
|
public async Task ProcessAsync_ValidItemTrackerMessage_SendsOnceAndUpdatesUsage()
|
|
{
|
|
Guid channelId = Guid.NewGuid();
|
|
var settings = new SmtpChannelSettings
|
|
{
|
|
Host = "smtp.example.invalid",
|
|
Port = 587,
|
|
Username = "smtp-user",
|
|
Password = "not-a-real-secret",
|
|
UseSsl = true,
|
|
FromEmail = "notifications@example.com",
|
|
FromName = "Invemory"
|
|
};
|
|
var channel = new EmailChannel
|
|
{
|
|
Id = channelId,
|
|
ServiceId = Guid.NewGuid(),
|
|
Priority = 1,
|
|
EmailChannelType = EmailChannelType.Smtp,
|
|
Settings = settings,
|
|
IsActive = true
|
|
};
|
|
var template = new EmailTemplate
|
|
{
|
|
ServiceName = "Invemory-Prod",
|
|
Key = "EmailVerification",
|
|
LanguageCode = "uk",
|
|
Subject = "Verify {{AppName}}",
|
|
HtmlBody = "<p>{{AppName}}</p>",
|
|
TextBody = "{{AppName}}",
|
|
Variables = [new EmailTemplateVariable { Name = "AppName", Required = true }]
|
|
};
|
|
|
|
IEmailChannelRepository channels = Substitute.For<IEmailChannelRepository>();
|
|
channels.GetByServiceAsync(channel.ServiceId, Arg.Any<CancellationToken>())
|
|
.Returns([channel]);
|
|
var services = Substitute.For<INotificationServiceRepository>();
|
|
services.GetByNameAsync("Invemory-Prod", Arg.Any<CancellationToken>())
|
|
.Returns(new NotificationServiceInfo { Id = channel.ServiceId, Name = "Invemory-Prod" });
|
|
IEmailChannelUsageRepository usage = Substitute.For<IEmailChannelUsageRepository>();
|
|
IEmailTemplateService templates = Substitute.For<IEmailTemplateService>();
|
|
templates.GetAsync("Invemory-Prod", "EmailVerification", "uk", Arg.Any<CancellationToken>())
|
|
.Returns(template);
|
|
var renderer = new EmailTemplateRenderingService();
|
|
var smtp = new RecordingSmtpEmailSender();
|
|
INotificationResultPublisher resultPublisher = Substitute.For<INotificationResultPublisher>();
|
|
var service = new SendEmailService(
|
|
channels,
|
|
services,
|
|
usage,
|
|
templates,
|
|
renderer,
|
|
smtp,
|
|
resultPublisher,
|
|
NullLogger<SendEmailService>.Instance);
|
|
var message = new SendEmailMessage
|
|
{
|
|
CorrelationContext = new CorrelationContext
|
|
{
|
|
CorrelationId = Guid.NewGuid().ToString("D")
|
|
},
|
|
Data = new SendEmailMessageData
|
|
{
|
|
ServiceName = "Invemory-Prod",
|
|
TemplateKey = "EmailVerification",
|
|
RecipientEmail = "owner@example.com",
|
|
RecipientName = "Owner",
|
|
LanguageCode = "uk",
|
|
Variables = new Dictionary<string, string> { ["AppName"] = "Invemory" }
|
|
}
|
|
};
|
|
|
|
await service.ProcessAsync(message, CancellationToken.None);
|
|
|
|
Assert.Equal(1, smtp.SendCount);
|
|
Assert.Same(settings, smtp.Settings);
|
|
Assert.Equal("Verify Invemory", smtp.Email?.Subject);
|
|
Assert.Equal("owner@example.com", smtp.RecipientEmail);
|
|
Assert.Equal("Owner", smtp.RecipientName);
|
|
await usage.Received(1).IncrementUsageAsync(
|
|
channelId,
|
|
Arg.Any<DateOnly>(),
|
|
CancellationToken.None);
|
|
await resultPublisher.Received(1).PublishAsync(
|
|
message,
|
|
null,
|
|
CancellationToken.None);
|
|
}
|
|
|
|
private sealed class RecordingSmtpEmailSender : ISmtpEmailSender
|
|
{
|
|
public int SendCount { get; private set; }
|
|
public SmtpChannelSettings? Settings { get; private set; }
|
|
public RenderedEmail? Email { get; private set; }
|
|
public string? RecipientEmail { get; private set; }
|
|
public string? RecipientName { get; private set; }
|
|
|
|
public Task SendAsync(
|
|
SmtpChannelSettings settings,
|
|
RenderedEmail email,
|
|
string recipientEmail,
|
|
string recipientName,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
SendCount++;
|
|
Settings = settings;
|
|
Email = email;
|
|
RecipientEmail = recipientEmail;
|
|
RecipientName = recipientName;
|
|
return Task.CompletedTask;
|
|
}
|
|
}
|
|
}
|