Files
DigitalData.MessagingService/tests/DigitalData.MessagingService.Tests/Integration/EmailSenderTests.cs
TekH efdd5805d3 test(client): await async EmailSender.Send in integration tests
Record.Exception does not observe faults from an async method. Convert the affected tests to async Task and use Record.ExceptionAsync so publish failures are actually asserted.
2026-11-02 10:11:31 +01:00

110 lines
3.8 KiB
C#

using DigitalData.MessagingService.Application.Common.Dto;
using DigitalData.MessagingService.Client;
using DigitalData.MessagingService.Domain.Entities;
namespace DigitalData.MessagingService.Tests.Integration;
/// <summary>
/// xUnit collection that serializes all <see cref="EmailSenderTests"/> so they share
/// the same process-wide static state of <see cref="EmailSender.LazyProvider"/>.
/// </summary>
[CollectionDefinition(Name)]
public sealed class EmailSenderCollection : ICollectionFixture<EmailSenderFixture>
{
public const string Name = "EmailSender";
}
/// <summary>
/// Fixture that connects <see cref="EmailSender"/> once before all tests in the collection run.
/// </summary>
public sealed class EmailSenderFixture
{
public EmailSenderFixture()
{
// EmailSender is a static class with a Lazy<IServiceProvider>.
// ConnectRabbitMq can only be called successfully once per process.
if (!EmailSender.IsConnected)
{
EmailSender.ConnectRabbitMq(cfg =>
{
cfg.HostName = RabbitMqTestConfig.HostName;
cfg.Port = RabbitMqTestConfig.Port;
cfg.UserName = RabbitMqTestConfig.UserName;
cfg.Password = RabbitMqTestConfig.Password;
cfg.VirtualHost = RabbitMqTestConfig.VirtualHost;
cfg.QueueName = RabbitMqTestConfig.QueueName;
cfg.ExchangeName = RabbitMqTestConfig.ExchangeName;
cfg.RoutingKey = RabbitMqTestConfig.RoutingKey;
cfg.DlqQueueName = RabbitMqTestConfig.DlqQueueName;
cfg.DlqExchangeName = RabbitMqTestConfig.DlqExchangeName;
cfg.DlqRoutingKey = RabbitMqTestConfig.DlqRoutingKey;
});
}
}
}
/// <summary>
/// Integration tests for the <see cref="EmailSender"/> static client.
/// All tests run inside <see cref="EmailSenderCollection"/> to share the single
/// static connection established by <see cref="EmailSenderFixture"/>.
/// </summary>
[Collection(EmailSenderCollection.Name)]
public sealed class EmailSenderTests
{
[Fact]
public void IsConnected_AfterConnectRabbitMq_ReturnsTrue()
{
Assert.True(EmailSender.IsConnected);
}
[Fact]
public void ConnectRabbitMq_WhenAlreadyConnected_WithThrowException_ThrowsInvalidOperationException()
{
Assert.Throws<InvalidOperationException>(() =>
EmailSender.ConnectRabbitMq(cfg => { }, OnReconnect.ThrowException));
}
[Fact]
public void ConnectRabbitMq_WhenAlreadyConnected_WithIgnore_DoesNotThrow()
{
var exception = Record.Exception(() =>
EmailSender.ConnectRabbitMq(cfg => { }, OnReconnect.Ignore));
Assert.Null(exception);
}
[Fact]
public async Task Send_WithValidEmail_DoesNotThrow()
{
var email = new EmailContext
{
Sender = new EmailAccount { Username = "test@example.com", Password = "password", SmtpServer = "smtp.example.com" },
Recipients = ["hakanttek@gmail.com"],
Subject = "EmailSender.Send Integration Test",
Body = "<p>Sent via EmailSender static client.</p>",
IsHtml = true,
};
var exception = await Record.ExceptionAsync(() => EmailSender.Send(email));
Assert.Null(exception);
}
[Fact]
public async Task Send_WithPlainTextBody_DoesNotThrow()
{
var email = new EmailContext
{
Sender = new EmailAccount { Username = "test@example.com", Password = "password", SmtpServer = "smtp.example.com" },
Recipients = ["hakanttek@gmail.com"],
Subject = "Plain Text Test",
Body = "This is a plain text email.",
IsHtml = false
};
var exception = await Record.ExceptionAsync(() => EmailSender.Send(email));
Assert.Null(exception);
}
}