shoc-backend/Api.SeaHavenIndustries.Tests/PasswordResetEmailSenderTracingTests.cs

56 lines
2.4 KiB
C#
Raw Normal View History

using Api.SeaHavenIndustries.HostedServices;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using Sentry;
using SeaHaven.Services.Interfaces;
using Xunit;
namespace Api.SeaHavenIndustries.Tests;
public class PasswordResetEmailSenderTracingTests
{
[Theory]
[InlineData(true)]
[InlineData(false)]
public async Task Each_send_finishes_its_transaction_as_ok_only_when_the_provider_accepts_it(bool accepted)
{
var transaction = new Mock<ITransactionTracer>();
var hub = new Mock<IHub>();
hub.Setup(h => h.PushScope()).Returns(Mock.Of<IDisposable>());
hub.Setup(h => h.StartTransaction(It.IsAny<ITransactionContext>(), It.IsAny<IReadOnlyDictionary<string, object?>>()))
.Returns(transaction.Object);
var sender = new Mock<IEmailSender>();
sender.Setup(s => s.SendEmailAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())).ReturnsAsync(accepted);
var services = new ServiceCollection().AddSingleton(sender.Object).BuildServiceProvider();
var channel = new PasswordResetEmailChannel(NullLogger<PasswordResetEmailChannel>.Instance);
var worker = new PasswordResetEmailSenderHostedService(
channel,
services.GetRequiredService<IServiceScopeFactory>(),
NullLogger<PasswordResetEmailSenderHostedService>.Instance,
hub.Object);
await worker.StartAsync(CancellationToken.None);
Assert.True(channel.TryEnqueue("user@example.com", "subject", "Your code is 123456"));
var deadline = DateTime.UtcNow.AddSeconds(10);
while (channel.Pending > 0 && DateTime.UtcNow < deadline)
await Task.Delay(10);
await worker.StopAsync(CancellationToken.None);
Assert.Equal(0, channel.Pending);
if (accepted)
{
transaction.Verify(t => t.Finish(SpanStatus.Ok), Times.Once);
transaction.Verify(t => t.Finish(It.IsAny<Exception>(), It.IsAny<SpanStatus>()), Times.Never);
}
else
{
transaction.Verify(t => t.Finish(SpanStatus.Ok), Times.Never);
transaction.Verify(t => t.Finish(
It.Is<Exception>(ex => !ex.Message.Contains("user@example.com") && !ex.Message.Contains("123456")),
SpanStatus.InternalError), Times.Once);
}
}
}