-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/master' into task/use-long-bounc…
…e-ids
- Loading branch information
Showing
15 changed files
with
453 additions
and
1 deletion.
There are no files selected for viewing
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,131 @@ | ||
using Xunit; | ||
using PostmarkDotNet; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Postmark.Model.Suppressions; | ||
using PostmarkDotNet.Model; | ||
|
||
namespace Postmark.Tests | ||
{ | ||
public class ClientSuppressionTests : ClientBaseFixture, IDisposable | ||
{ | ||
private PostmarkAdminClient _adminClient; | ||
private PostmarkServer _server; | ||
|
||
protected override void Setup() | ||
{ | ||
_adminClient = new PostmarkAdminClient(WRITE_ACCOUNT_TOKEN, BASE_URL); | ||
_server = TestUtils.MakeSynchronous(() => _adminClient.CreateServerAsync($"integration-test-suppressions-{Guid.NewGuid()}")); | ||
_client = new PostmarkClient(_server.ApiTokens.First(), BASE_URL); | ||
} | ||
|
||
[Fact] | ||
public async Task ClientCanSuppressRecipients() | ||
{ | ||
var suppressionRequest = new PostmarkSuppressionChangeRequest { EmailAddress = $"test-{Guid.NewGuid().ToString()}@gmail.com" }; | ||
var result = await _client.CreateSuppressions(new List<PostmarkSuppressionChangeRequest> { suppressionRequest }); | ||
|
||
Assert.Single(result.Suppressions); | ||
|
||
var suppressionResult = result.Suppressions.First(); | ||
Assert.Equal(suppressionRequest.EmailAddress, suppressionResult.EmailAddress); | ||
Assert.Equal(PostmarkSuppressionRequestStatus.Suppressed, suppressionResult.Status); | ||
Assert.Null(suppressionResult.Message); | ||
} | ||
|
||
[Fact] | ||
public async Task InvalidRequest_HasFailedStatus() | ||
{ | ||
var suppressionRequest = new PostmarkSuppressionChangeRequest { EmailAddress = "not-a-correct-email-address" }; | ||
var result = await _client.CreateSuppressions(new List<PostmarkSuppressionChangeRequest> { suppressionRequest }); | ||
|
||
Assert.Single(result.Suppressions); | ||
|
||
var suppressionResult = result.Suppressions.First(); | ||
Assert.Equal(suppressionRequest.EmailAddress, suppressionResult.EmailAddress); | ||
Assert.Equal(PostmarkSuppressionRequestStatus.Failed, suppressionResult.Status); | ||
Assert.NotNull(suppressionResult.Message); | ||
} | ||
|
||
[Fact] | ||
public async Task ClientCanDeleteSuppressions() | ||
{ | ||
var reactivationRequest = new PostmarkSuppressionChangeRequest { EmailAddress = $"test-{Guid.NewGuid().ToString()}@gmail.com" }; | ||
var result = await _client.DeleteSuppressions(new List<PostmarkSuppressionChangeRequest> { reactivationRequest }); | ||
|
||
Assert.Single(result.Suppressions); | ||
|
||
var reactivationResult = result.Suppressions.First(); | ||
Assert.Equal(reactivationRequest.EmailAddress, reactivationResult.EmailAddress); | ||
Assert.Equal(PostmarkReactivationRequestStatus.Deleted, reactivationResult.Status); | ||
Assert.Null(reactivationResult.Message); | ||
} | ||
|
||
[Fact] | ||
public async Task ClientCanListSuppressions() | ||
{ | ||
var suppressionRequests = new List<PostmarkSuppressionChangeRequest>(); | ||
|
||
for (var i = 0; i < 5; i++) | ||
{ | ||
var suppressionRequest = new PostmarkSuppressionChangeRequest { EmailAddress = $"test-{Guid.NewGuid().ToString()}@gmail.com" }; | ||
suppressionRequests.Add(suppressionRequest); | ||
} | ||
|
||
var suppressionResult = await _client.CreateSuppressions(suppressionRequests); | ||
Assert.Equal(5, suppressionResult.Suppressions.Count()); | ||
Assert.True(suppressionResult.Suppressions.All(k => k.Status == PostmarkSuppressionRequestStatus.Suppressed)); | ||
|
||
// Suppressions are being processed asynchronously so we must give it some time to process those requests | ||
var suppressionListing = await TestUtils.PollUntil(() => _client.ListSuppressions(new PostmarkSuppressionQuery()), | ||
k => k.Suppressions.Count() == 5); | ||
|
||
Assert.Equal(5, suppressionListing.Suppressions.Count()); | ||
} | ||
|
||
[Fact] | ||
public async Task ClientCanFilterSuppressionsByEmail() | ||
{ | ||
var suppressionRequests = new List<PostmarkSuppressionChangeRequest>(); | ||
|
||
for (var i = 0; i < 3; i++) | ||
{ | ||
var suppressionRequest = new PostmarkSuppressionChangeRequest { EmailAddress = $"test-{Guid.NewGuid().ToString()}@gmail.com" }; | ||
suppressionRequests.Add(suppressionRequest); | ||
} | ||
|
||
await _client.CreateSuppressions(suppressionRequests); | ||
|
||
var query = new PostmarkSuppressionQuery | ||
{ | ||
EmailAddress = suppressionRequests.First().EmailAddress | ||
}; | ||
|
||
// Suppressions are being processed asynchronously so we must give it some time to process those requests | ||
var suppressionListing = await TestUtils.PollUntil(() => _client.ListSuppressions(query), k => k.Suppressions.Count() == 1); | ||
|
||
Assert.Single(suppressionListing.Suppressions); | ||
|
||
var actualSuppression = suppressionListing.Suppressions.First(); | ||
|
||
Assert.Equal(suppressionRequests.First().EmailAddress, actualSuppression.EmailAddress); | ||
Assert.Equal("Customer", actualSuppression.Origin); | ||
Assert.Equal("ManualSuppression", actualSuppression.SuppressionReason); | ||
} | ||
|
||
private Task Cleanup() | ||
{ | ||
return Task.Run(async () => | ||
{ | ||
await _adminClient.DeleteServerAsync(_server.ID); | ||
}); | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
Cleanup().Wait(); | ||
} | ||
} | ||
} |
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
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,42 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
|
||
namespace Postmark.Tests | ||
{ | ||
/// <summary> | ||
/// Utility methods useful in integration and unit tests. | ||
/// </summary> | ||
public static class TestUtils | ||
{ | ||
public static T MakeSynchronous<T>(Func<Task<T>> t) | ||
{ | ||
var f = Task.Run(async () => await t().ConfigureAwait(false)); | ||
f.Wait(); | ||
return f.Result; | ||
} | ||
|
||
/// <summary> | ||
/// Run a task until the provided condition is met or the number of retries reaches 0. | ||
/// </summary> | ||
/// <typeparam name="T">Type of the returned result.</typeparam> | ||
/// <param name="pollingTaskFunc">Function that generates the task to be polled.</param> | ||
/// <param name="isComplete">Condition that stops the polling if true.</param> | ||
/// <param name="retriesLeft">Number of retries left. Defaults to 5.</param> | ||
/// <param name="delayInMs">Number of milliseconds to add delay before the next poll attempt. Defaults to 1500ms.</param> | ||
/// <returns></returns> | ||
public static async Task<T> PollUntil<T>(Func<Task<T>> pollingTaskFunc, Func<T, bool> isComplete, int retriesLeft = 5, | ||
int delayInMs = 1500) | ||
{ | ||
var result = await pollingTaskFunc(); | ||
|
||
if (isComplete(result) || retriesLeft == 0) | ||
{ | ||
return result; | ||
} | ||
|
||
await Task.Delay(delayInMs).ConfigureAwait(false); | ||
|
||
return await PollUntil(pollingTaskFunc, isComplete, --retriesLeft); | ||
} | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/Postmark/Model/Suppressions/PostmarkBulkReactivationResult.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,12 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace Postmark.Model.Suppressions | ||
{ | ||
/// <summary> | ||
/// Result of applying Reactivation requests in bulk. | ||
/// </summary> | ||
public class PostmarkBulkReactivationResult | ||
{ | ||
public IEnumerable<PostmarkReactivationRequestResult> Suppressions { get; set; } | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/Postmark/Model/Suppressions/PostmarkBulkSuppressionResult.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,12 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace Postmark.Model.Suppressions | ||
{ | ||
/// <summary> | ||
/// Result of applying Suppression requests in bulk. | ||
/// </summary> | ||
public class PostmarkBulkSuppressionResult | ||
{ | ||
public IEnumerable<PostmarkSuppressionRequestResult> Suppressions { get; set; } | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
src/Postmark/Model/Suppressions/PostmarkReactivationRequestResult.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,27 @@ | ||
using Newtonsoft.Json; | ||
using Newtonsoft.Json.Converters; | ||
|
||
namespace Postmark.Model.Suppressions | ||
{ | ||
/// <summary> | ||
/// Result of applying a reactivation request. | ||
/// </summary> | ||
public class PostmarkReactivationRequestResult | ||
{ | ||
/// <summary> | ||
/// Recipient email address requested to be reactivated. | ||
/// </summary> | ||
public string EmailAddress { get; set; } | ||
|
||
/// <summary> | ||
/// Status of the request. | ||
/// </summary> | ||
[JsonConverter(typeof(StringEnumConverter))] | ||
public PostmarkReactivationRequestStatus Status { get; set; } | ||
|
||
/// <summary> | ||
/// Optional message regarding the status of this request. | ||
/// </summary> | ||
public string Message { get; set; } | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
src/Postmark/Model/Suppressions/PostmarkReactivationRequestStatus.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,18 @@ | ||
namespace Postmark.Model.Suppressions | ||
{ | ||
/// <summary> | ||
/// Status for the result of reactivating a recipient. | ||
/// </summary> | ||
public enum PostmarkReactivationRequestStatus | ||
{ | ||
/// <summary> | ||
/// We have received the request to reactivate the recipient. | ||
/// </summary> | ||
Deleted, | ||
|
||
/// <summary> | ||
/// Request submission has failed. Please see the result Message field for information. | ||
/// </summary> | ||
Failed | ||
} | ||
} |
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,32 @@ | ||
using System; | ||
|
||
namespace Postmark.Model.Suppressions | ||
{ | ||
/// <summary> | ||
/// Model representing a Suppressed recipient. | ||
/// For more information about the Suppressions API and possible options, please visit: | ||
/// https://postmarkapp.com/developer/api/suppressions-api | ||
/// </summary> | ||
public class PostmarkSuppression | ||
{ | ||
/// <summary> | ||
/// Email address of the suppressed recipient. | ||
/// </summary> | ||
public string EmailAddress { get; set; } | ||
|
||
/// <summary> | ||
/// Reason why this recipient was suppressed. E.g.: ManualSuppression, HardBounce, SpamComplaint. | ||
/// </summary> | ||
public string SuppressionReason { get; set; } | ||
|
||
/// <summary> | ||
/// Origin that suppressed this recipient. E.g.: Customer, Recipient, Admin. | ||
/// </summary> | ||
public string Origin { get; set; } | ||
|
||
/// <summary> | ||
/// Date when the suppression was created. | ||
/// </summary> | ||
public DateTime CreatedAt { get; set; } | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
src/Postmark/Model/Suppressions/PostmarkSuppressionChangeRequest.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,13 @@ | ||
namespace Postmark.Model.Suppressions | ||
{ | ||
/// <summary> | ||
/// A request to suppress or reactivate one recipient. | ||
/// </summary> | ||
public class PostmarkSuppressionChangeRequest | ||
{ | ||
/// <summary> | ||
/// Address of the recipient whose suppression status should be changed. | ||
/// </summary> | ||
public string EmailAddress { get; set; } | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
src/Postmark/Model/Suppressions/PostmarkSuppressionListing.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,15 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace Postmark.Model.Suppressions | ||
{ | ||
/// <summary> | ||
/// Response model for listing Suppressions. | ||
/// </summary> | ||
public class PostmarkSuppressionListing | ||
{ | ||
/// <summary> | ||
/// Active Suppressions | ||
/// </summary> | ||
public IEnumerable<PostmarkSuppression> Suppressions { get; set; } | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
src/Postmark/Model/Suppressions/PostmarkSuppressionQuery.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,39 @@ | ||
using System; | ||
|
||
namespace Postmark.Model.Suppressions | ||
{ | ||
/// <summary> | ||
/// Query parameters for listing Suppressions. | ||
/// </summary> | ||
public class PostmarkSuppressionQuery | ||
{ | ||
/// <summary> | ||
/// Filter Suppressions by reason. (optional) | ||
/// E.g.: ManualSuppression, HardBounce, SpamComplaint. | ||
/// </summary> | ||
/// <remarks>If not provided, Suppressions for all reasons will be returned.</remarks> | ||
public string SuppressionReason { get; set; } | ||
|
||
/// <summary> | ||
/// Filter Suppressions by the origin that created them. (optional) | ||
/// E.g.: Customer, Recipient, Admin. | ||
/// </summary> | ||
/// <remarks>If not provided, Suppressions for all origins will be returned.</remarks> | ||
public string Origin { get; set; } | ||
|
||
/// <summary> | ||
/// Filter suppressions up to the date specified - inclusive. (optional) | ||
/// </summary> | ||
public DateTime? ToDate { get; set; } | ||
|
||
/// <summary> | ||
/// Filter suppressions from the date specified - inclusive. (optional) | ||
/// </summary> | ||
public DateTime? FromDate { get; set; } | ||
|
||
/// <summary> | ||
/// Filter by a specific email address. (optional) | ||
/// </summary> | ||
public string EmailAddress { get; set; } | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
src/Postmark/Model/Suppressions/PostmarkSuppressionRequestResult.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,27 @@ | ||
using Newtonsoft.Json; | ||
using Newtonsoft.Json.Converters; | ||
|
||
namespace Postmark.Model.Suppressions | ||
{ | ||
/// <summary> | ||
/// Result of applying a Suppression request. | ||
/// </summary> | ||
public class PostmarkSuppressionRequestResult | ||
{ | ||
/// <summary> | ||
/// Recipient email address requested to be suppressed. | ||
/// </summary> | ||
public string EmailAddress { get; set; } | ||
|
||
/// <summary> | ||
/// Status of the request. | ||
/// </summary> | ||
[JsonConverter(typeof(StringEnumConverter))] | ||
public PostmarkSuppressionRequestStatus Status { get; set; } | ||
|
||
/// <summary> | ||
/// Optional message regarding the status of this request. | ||
/// </summary> | ||
public string Message { get; set; } | ||
} | ||
} |
Oops, something went wrong.