Files
hrynco-notification-service/HrynCo.NotificationService.Services.Tests/Push/PushDeliveryTests.cs
T
agrynco aba4173827 feat(templates): add localized push templates and actions
Share template keys across email and push with independent editors and revisions. Render localized actions and preserve version-one delivery.

Ref: IT-1627
2026-10-31 09:38:05 +02:00

61 lines
3.0 KiB
C#

namespace HrynCo.NotificationService.Services.Tests.Push;
using FirebaseAdmin.Messaging;
using HrynCo.NotificationService.Contracts.Messages;
using HrynCo.NotificationService.DAL.Abstract.Push;
using HrynCo.NotificationService.Worker.Services.Push;
using Hrynco.RabbitMq;
using NSubstitute;
public sealed class PushDeliveryTests
{
[Theory]
[InlineData(MessagingErrorCode.Unregistered, true)]
[InlineData(MessagingErrorCode.SenderIdMismatch, false)]
[InlineData(MessagingErrorCode.InvalidArgument, false)]
public void OnlyUnregisteredInvalidatesTheInstallation(MessagingErrorCode code, bool invalid)
{
var result = FirebasePushClient.Classify(code);
Assert.Equal(invalid, result.InvalidRegistration);
Assert.NotNull(result.Error);
}
[Theory]
[InlineData(MessagingErrorCode.Internal)]
[InlineData(MessagingErrorCode.Unavailable)]
[InlineData(MessagingErrorCode.QuotaExceeded)]
public void TransientFailuresPreserveRetryAfter(MessagingErrorCode code)
{
var exception = Assert.Throws<PushRetryException>(() => FirebasePushClient.Classify(code, TimeSpan.FromMinutes(3)));
Assert.Equal(TimeSpan.FromMinutes(3), exception.RetryAfter);
Assert.True(PushDeliveryService.RetryDelay(0, exception.RetryAfter) >= TimeSpan.FromMinutes(3));
Assert.True(PushDeliveryService.RetryDelay(1, TimeSpan.Zero) >= TimeSpan.FromMinutes(2));
}
[Fact]
public async Task ExhaustedReplyRetriesReplaySavedSuccessWithoutSendingAgain()
{
var repository = Substitute.For<IPushDeliveryRepository>();
var sender = Substitute.For<IPushSender>();
var publisher = Substitute.For<IRabbitMqPublisher>();
repository.DeliverOnceAsync(Arg.Any<Guid>(), Arg.Any<string>(),
Arg.Any<Func<CancellationToken, Task<PushDeliveryOutcome>>>(), Arg.Any<CancellationToken>())
.Returns(new PushDeliveryOutcome(null));
var service = new PushDeliveryService(repository, sender, publisher);
var id = Guid.NewGuid();
var message = new SendPushMessage
{
CorrelationContext = new CorrelationContext { CorrelationId = id.ToString(), ReplyTo = "results" },
Data = new SendPushMessageData
{
RegistrationId = Guid.NewGuid(), BindingId = Guid.NewGuid(), UserId = Guid.NewGuid(),
ExpiresAt = DateTimeOffset.UtcNow.AddMinutes(10), ServiceName = "Invemory", Version = 2, TemplateKey = "Test", LanguageCode = "en", TemplateData = new PushTemplateData { Bindings = new Dictionary<string, string>(), Actions = new Dictionary<string, PushActionMetadata>() }, TokenHash = new string('a', 64)
}
};
await service.CompleteFailureAsync(id, message, default);
await publisher.Received(1).PublishAsync("results",
Arg.Is<NotificationResultMessage>(x => x.Data.IsSuccess && x.Data.PushBindingId == message.Data.BindingId), default);
await sender.DidNotReceive().SendAsync(Arg.Any<Guid>(), Arg.Any<SendPushMessageData>(), Arg.Any<CancellationToken>());
}
}