-
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4c61d6d
commit 7661896
Showing
21 changed files
with
1,042 additions
and
12 deletions.
There are no files selected for viewing
225 changes: 225 additions & 0 deletions
225
src/AncillaryInfrastructure.IntegrationTests/MailgunApiSpec.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,225 @@ | ||
using System.Net; | ||
using AncillaryInfrastructure.IntegrationTests.Stubs; | ||
using ApiHost1; | ||
using Application.Persistence.Shared; | ||
using Application.Persistence.Shared.ReadModels; | ||
using Common.Extensions; | ||
using Domain.Common; | ||
using FluentAssertions; | ||
using Infrastructure.Shared.ApplicationServices.External; | ||
using Infrastructure.Web.Api.Common.Extensions; | ||
using Infrastructure.Web.Api.Operations.Shared._3rdParties.Mailgun; | ||
using Infrastructure.Web.Api.Operations.Shared.Ancillary; | ||
using IntegrationTesting.WebApi.Common; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Xunit; | ||
|
||
namespace AncillaryInfrastructure.IntegrationTests; | ||
|
||
[Trait("Category", "Integration.API")] | ||
[Collection("API")] | ||
public class MailgunApiSpec : WebApiSpec<Program> | ||
{ | ||
private readonly StubEmailDeliveryService _emailDeliveryService; | ||
|
||
public MailgunApiSpec(WebApiSetup<Program> setup) : base(setup, OverrideDependencies) | ||
{ | ||
EmptyAllRepositories(); | ||
_emailDeliveryService = setup.GetRequiredService<IEmailDeliveryService>().As<StubEmailDeliveryService>(); | ||
_emailDeliveryService.Reset(); | ||
} | ||
|
||
[Fact] | ||
public async Task WhenNotifyMailgunEventAndNotDeliveredEvent_ThenReturnsOk() | ||
{ | ||
var result = await Api.PostAsync(new MailgunNotifyWebhookEventRequest | ||
{ | ||
Signature = new MailgunSignature | ||
{ | ||
Timestamp = "1", | ||
Token = "atoken", | ||
Signature = "bf106940253fa7477ba4b55a027126b70037ce9b00e67aa3bf4f5bab2775d3e1" | ||
}, | ||
EventData = new MailgunEventData | ||
{ | ||
Event = "anunknownevent" | ||
} | ||
}); | ||
|
||
result.StatusCode.Should().Be(HttpStatusCode.OK); | ||
} | ||
|
||
[Fact] | ||
public async Task WhenNotifyMailgunEventAndDeliveredEvent_ThenReturnsOk() | ||
{ | ||
var receiptId = await DeliveryEmailAsync(); | ||
|
||
var deliveredAt = DateTime.UtcNow.ToUnixSeconds(); | ||
var result = await Api.PostAsync(new MailgunNotifyWebhookEventRequest | ||
{ | ||
Signature = new MailgunSignature | ||
{ | ||
Timestamp = "1", | ||
Token = "atoken", | ||
Signature = "bf106940253fa7477ba4b55a027126b70037ce9b00e67aa3bf4f5bab2775d3e1" | ||
}, | ||
EventData = new MailgunEventData | ||
{ | ||
Event = MailgunConstants.Events.Delivered, | ||
Timestamp = deliveredAt, | ||
Message = new MailgunMessage | ||
{ | ||
Headers = new MailgunMessageHeaders | ||
{ | ||
MessageId = receiptId | ||
} | ||
} | ||
} | ||
}); | ||
|
||
result.StatusCode.Should().Be(HttpStatusCode.OK); | ||
|
||
var login = await LoginUserAsync(LoginUser.Operator); | ||
var deliveries = await Api.GetAsync(new SearchEmailDeliveriesRequest(), | ||
req => req.SetJWTBearerToken(login.AccessToken)); | ||
|
||
deliveries.Content.Value.Emails![0].IsSent.Should().BeTrue(); | ||
deliveries.Content.Value.Emails![0].IsDelivered.Should().BeTrue(); | ||
deliveries.Content.Value.Emails![0].DeliveredAt.Should().Be(deliveredAt.FromUnixTimestamp()); | ||
deliveries.Content.Value.Emails![0].IsDeliveryFailed.Should().BeFalse(); | ||
deliveries.Content.Value.Emails![0].FailedDeliveryAt.Should().BeNull(); | ||
deliveries.Content.Value.Emails![0].FailedDeliveryReason.Should().BeNull(); | ||
} | ||
|
||
[Fact] | ||
public async Task WhenNotifyMailgunEventAndTemporaryFailedEvent_ThenReturnsOk() | ||
{ | ||
var receiptId = await DeliveryEmailAsync(); | ||
|
||
var failedAt = DateTime.UtcNow.ToUnixSeconds(); | ||
var result = await Api.PostAsync(new MailgunNotifyWebhookEventRequest | ||
{ | ||
Signature = new MailgunSignature | ||
{ | ||
Timestamp = "1", | ||
Token = "atoken", | ||
Signature = "bf106940253fa7477ba4b55a027126b70037ce9b00e67aa3bf4f5bab2775d3e1" | ||
}, | ||
EventData = new MailgunEventData | ||
{ | ||
Event = MailgunConstants.Events.Failed, | ||
Severity = MailgunConstants.Values.TemporarySeverity, | ||
DeliveryStatus = new MailgunDeliveryStatus | ||
{ | ||
Description = "areason" | ||
}, | ||
Timestamp = failedAt, | ||
Message = new MailgunMessage | ||
{ | ||
Headers = new MailgunMessageHeaders | ||
{ | ||
MessageId = receiptId | ||
} | ||
} | ||
} | ||
}); | ||
|
||
result.StatusCode.Should().Be(HttpStatusCode.OK); | ||
|
||
var login = await LoginUserAsync(LoginUser.Operator); | ||
var deliveries = await Api.GetAsync(new SearchEmailDeliveriesRequest(), | ||
req => req.SetJWTBearerToken(login.AccessToken)); | ||
|
||
deliveries.Content.Value.Emails![0].IsSent.Should().BeTrue(); | ||
deliveries.Content.Value.Emails![0].IsDelivered.Should().BeFalse(); | ||
deliveries.Content.Value.Emails![0].DeliveredAt.Should().BeNull(); | ||
deliveries.Content.Value.Emails![0].IsDeliveryFailed.Should().BeFalse(); | ||
deliveries.Content.Value.Emails![0].FailedDeliveryAt.Should().BeNull(); | ||
deliveries.Content.Value.Emails![0].FailedDeliveryReason.Should().BeNull(); | ||
} | ||
|
||
[Fact] | ||
public async Task WhenNotifyMailgunEventAndPermanentFailedEvent_ThenReturnsOk() | ||
{ | ||
var receiptId = await DeliveryEmailAsync(); | ||
|
||
var failedAt = DateTime.UtcNow.ToUnixSeconds(); | ||
var result = await Api.PostAsync(new MailgunNotifyWebhookEventRequest | ||
{ | ||
Signature = new MailgunSignature | ||
{ | ||
Timestamp = "1", | ||
Token = "atoken", | ||
Signature = "bf106940253fa7477ba4b55a027126b70037ce9b00e67aa3bf4f5bab2775d3e1" | ||
}, | ||
EventData = new MailgunEventData | ||
{ | ||
Event = MailgunConstants.Events.Failed, | ||
Severity = MailgunConstants.Values.PermanentSeverity, | ||
DeliveryStatus = new MailgunDeliveryStatus | ||
{ | ||
Description = "areason" | ||
}, | ||
Timestamp = failedAt, | ||
Message = new MailgunMessage | ||
{ | ||
Headers = new MailgunMessageHeaders | ||
{ | ||
MessageId = receiptId | ||
} | ||
} | ||
} | ||
}); | ||
|
||
result.StatusCode.Should().Be(HttpStatusCode.OK); | ||
|
||
var login = await LoginUserAsync(LoginUser.Operator); | ||
var deliveries = await Api.GetAsync(new SearchEmailDeliveriesRequest(), | ||
req => req.SetJWTBearerToken(login.AccessToken)); | ||
|
||
deliveries.Content.Value.Emails![0].IsSent.Should().BeTrue(); | ||
deliveries.Content.Value.Emails![0].IsDelivered.Should().BeFalse(); | ||
deliveries.Content.Value.Emails![0].DeliveredAt.Should().BeNull(); | ||
deliveries.Content.Value.Emails![0].IsDeliveryFailed.Should().BeTrue(); | ||
deliveries.Content.Value.Emails![0].FailedDeliveryAt.Should().Be(failedAt.FromUnixTimestamp()); | ||
deliveries.Content.Value.Emails![0].FailedDeliveryReason.Should().Be("areason"); | ||
} | ||
|
||
private async Task<string> DeliveryEmailAsync() | ||
{ | ||
_emailDeliveryService.SendingSucceeds = true; | ||
var request = new SendEmailRequest | ||
{ | ||
Message = new EmailMessage | ||
{ | ||
MessageId = CreateMessageId(), | ||
CallId = "acallid", | ||
CallerId = "acallerid", | ||
Html = new QueuedEmailHtmlMessage | ||
{ | ||
Subject = "asubject", | ||
HtmlBody = "anhtmlbody", | ||
ToEmailAddress = "[email protected]", | ||
ToDisplayName = "atodisplayname", | ||
FromEmailAddress = "[email protected]", | ||
FromDisplayName = "afromdisplayname" | ||
} | ||
}.ToJson()! | ||
}; | ||
var delivered = await Api.PostAsync(request, req => req.SetHMACAuth(request, "asecret")); | ||
delivered.Content.Value.IsSent.Should().BeTrue(); | ||
_emailDeliveryService.LastSubject.Should().Be("asubject"); | ||
|
||
return _emailDeliveryService.LastReceiptId; | ||
} | ||
|
||
private static void OverrideDependencies(IServiceCollection services) | ||
{ | ||
services.AddSingleton<IEmailDeliveryService, StubEmailDeliveryService>(); | ||
} | ||
|
||
private static string CreateMessageId() | ||
{ | ||
return new MessageQueueIdFactory().Create("email"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
151 changes: 151 additions & 0 deletions
151
src/AncillaryInfrastructure.UnitTests/Api/3rdParties/MailgunApiSpec.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
using AncillaryApplication; | ||
using AncillaryInfrastructure.Api._3rdParties; | ||
using Application.Interfaces; | ||
using Common; | ||
using Common.Configuration; | ||
using Common.Extensions; | ||
using FluentAssertions; | ||
using Infrastructure.Interfaces; | ||
using Infrastructure.Shared.ApplicationServices.External; | ||
using Infrastructure.Web.Api.Interfaces; | ||
using Infrastructure.Web.Api.Operations.Shared._3rdParties.Mailgun; | ||
using Moq; | ||
using UnitTesting.Common; | ||
using Xunit; | ||
|
||
namespace AncillaryInfrastructure.UnitTests.Api._3rdParties; | ||
|
||
[Trait("Category", "Unit")] | ||
public class MailgunApiSpec | ||
{ | ||
private readonly Mock<IAncillaryApplication> _ancillaryApplication; | ||
private readonly MailgunApi _api; | ||
private readonly MailgunSignature _signature; | ||
|
||
public MailgunApiSpec() | ||
{ | ||
var callerFactory = new Mock<ICallerContextFactory>(); | ||
callerFactory.Setup(cf => cf.Create()) | ||
.Returns(Mock.Of<ICallerContext>()); | ||
_ancillaryApplication = new Mock<IAncillaryApplication>(); | ||
var settings = new Mock<IConfigurationSettings>(); | ||
settings.Setup(s => s.Platform.GetString(MailgunConstants.WebhookSigningKeySettingName, It.IsAny<string>())) | ||
.Returns("asecret"); | ||
_signature = new MailgunSignature | ||
{ | ||
Timestamp = "1", | ||
Token = "atoken", | ||
Signature = "bf106940253fa7477ba4b55a027126b70037ce9b00e67aa3bf4f5bab2775d3e1" | ||
}; | ||
|
||
_api = new MailgunApi(callerFactory.Object, _ancillaryApplication.Object, settings.Object); | ||
} | ||
|
||
[Fact] | ||
public async Task WhenNotifyMailgunEventAndInvalidSignature_ThenReturnsError() | ||
{ | ||
var result = await _api.NotifyEmailDeliveryReceipt(new MailgunNotifyWebhookEventRequest | ||
{ | ||
Signature = new MailgunSignature() | ||
}, CancellationToken.None); | ||
|
||
result().Should().BeError(ErrorCode.NotAuthenticated); | ||
_ancillaryApplication.Verify(app => app.ConfirmEmailDeliveredAsync(It.IsAny<ICallerContext>(), | ||
It.IsAny<string>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()), Times.Never); | ||
} | ||
|
||
[Fact] | ||
public async Task WhenNotifyMailgunEventAndUnhandledEvent_ThenReturnsEmptyResponse() | ||
{ | ||
var result = await _api.NotifyEmailDeliveryReceipt(new MailgunNotifyWebhookEventRequest | ||
{ | ||
Signature = _signature, | ||
EventData = new MailgunEventData | ||
{ | ||
Event = "anunknownevent" | ||
} | ||
}, CancellationToken.None); | ||
|
||
result().Value.Should().BeOfType<EmptyResponse>(); | ||
_ancillaryApplication.Verify(app => app.ConfirmEmailDeliveredAsync(It.IsAny<ICallerContext>(), | ||
It.IsAny<string>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()), Times.Never); | ||
} | ||
|
||
[Fact] | ||
public async Task WhenNotifyMailgunEventAndWithNoReceiptId_ThenReturnsEmptyResponse() | ||
{ | ||
var result = await _api.NotifyEmailDeliveryReceipt(new MailgunNotifyWebhookEventRequest | ||
{ | ||
Signature = _signature, | ||
EventData = new MailgunEventData | ||
{ | ||
Event = MailgunConstants.Events.Delivered, | ||
Message = new MailgunMessage() | ||
} | ||
}, CancellationToken.None); | ||
|
||
result().Value.Should().BeOfType<EmptyResponse>(); | ||
_ancillaryApplication.Verify(app => app.ConfirmEmailDeliveredAsync(It.IsAny<ICallerContext>(), | ||
It.IsAny<string>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()), Times.Never); | ||
} | ||
|
||
[Fact] | ||
public async Task WhenNotifyMailgunEventAndWithDeliveredEvent_ThenReturnsEmptyResponse() | ||
{ | ||
_ancillaryApplication.Setup(app => app.ConfirmEmailDeliveredAsync(It.IsAny<ICallerContext>(), | ||
It.IsAny<string>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>())) | ||
.ReturnsAsync(Result.Ok); | ||
var deliveredAt = DateTime.UtcNow.ToNearestSecond().ToUnixSeconds(); | ||
var result = await _api.NotifyEmailDeliveryReceipt(new MailgunNotifyWebhookEventRequest | ||
{ | ||
Signature = _signature, | ||
EventData = new MailgunEventData | ||
{ | ||
Event = MailgunConstants.Events.Delivered, | ||
Message = new MailgunMessage | ||
{ | ||
Headers = new MailgunMessageHeaders | ||
{ | ||
MessageId = "areceiptid" | ||
} | ||
}, | ||
Timestamp = deliveredAt | ||
} | ||
}, CancellationToken.None); | ||
|
||
result().Value.Should().BeOfType<EmptyResponse>(); | ||
_ancillaryApplication.Verify(app => app.ConfirmEmailDeliveredAsync(It.IsAny<ICallerContext>(), | ||
"areceiptid", deliveredAt.FromUnixTimestamp(), It.IsAny<CancellationToken>())); | ||
} | ||
|
||
[Fact] | ||
public async Task WhenNotifyMailgunEventAndWithFailedEvent_ThenReturnsEmptyResponse() | ||
{ | ||
_ancillaryApplication.Setup(app => app.ConfirmEmailDeliveredAsync(It.IsAny<ICallerContext>(), | ||
It.IsAny<string>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>())) | ||
.ReturnsAsync(Result.Ok); | ||
var failedAt = DateTime.UtcNow.ToNearestSecond().ToUnixSeconds(); | ||
var result = await _api.NotifyEmailDeliveryReceipt(new MailgunNotifyWebhookEventRequest | ||
{ | ||
Signature = _signature, | ||
EventData = new MailgunEventData | ||
{ | ||
Event = MailgunConstants.Events.Failed, | ||
Message = new MailgunMessage | ||
{ | ||
Headers = new MailgunMessageHeaders | ||
{ | ||
MessageId = "areceiptid" | ||
} | ||
}, | ||
Timestamp = failedAt, | ||
Severity = MailgunConstants.Values.PermanentSeverity, | ||
Reason = "areason" | ||
} | ||
}, CancellationToken.None); | ||
|
||
result().Value.Should().BeOfType<EmptyResponse>(); | ||
_ancillaryApplication.Verify(app => app.ConfirmEmailDeliveryFailedAsync(It.IsAny<ICallerContext>(), | ||
"areceiptid", failedAt.FromUnixTimestamp(), "areason", It.IsAny<CancellationToken>())); | ||
} | ||
} |
Oops, something went wrong.