docs(tests): fix CommentChecker findings across tests/ — 13,392 → 0 (repo-wide scan clean)
Comment/XML-doc changes only: - add summaries to ~10k test methods, fixtures, fakes and helpers (+ <param> on theories, <returns> on async Task methods, <inheritdoc/> on interface implementations the checker can resolve) - strip ~2.6k project-tracking references (WP*, P*-*, row-NN, Task N, #NN, Component-0NN) from comments, keeping the explanatory text; reword false positives in comments only - real docs on fakes implementing BCL/library interfaces (IDisposable, ILogger, IOptionsMonitor, IAsyncLifetime) - reword the last 5 src/ false positives (CWE-1236, failures-1, year-0001, M365) Only non-comment edits: four one-line nested classes split across lines so members can carry docs. Build 0 errors / 0 warnings.
This commit is contained in:
@@ -4,6 +4,7 @@ namespace ZB.MOM.WW.ScadaBridge.NotificationOutbox.Tests.Delivery;
|
||||
|
||||
public class DeliveryOutcomeTests
|
||||
{
|
||||
/// <summary>Verifies that a success outcome carries the resolved targets and no error.</summary>
|
||||
[Fact]
|
||||
public void Success_SetsResolvedTargets_AndNoError()
|
||||
{
|
||||
@@ -14,6 +15,7 @@ public class DeliveryOutcomeTests
|
||||
Assert.Null(outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a transient outcome carries an error and no resolved targets.</summary>
|
||||
[Fact]
|
||||
public void Transient_SetsError_AndNoResolvedTargets()
|
||||
{
|
||||
@@ -24,6 +26,7 @@ public class DeliveryOutcomeTests
|
||||
Assert.Null(outcome.ResolvedTargets);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a permanent outcome carries an error and no resolved targets.</summary>
|
||||
[Fact]
|
||||
public void Permanent_SetsError_AndNoResolvedTargets()
|
||||
{
|
||||
|
||||
+29
-1
@@ -11,7 +11,7 @@ using ZB.MOM.WW.ScadaBridge.NotificationService.Ews;
|
||||
namespace ZB.MOM.WW.ScadaBridge.NotificationOutbox.Tests.Delivery;
|
||||
|
||||
/// <summary>
|
||||
/// Task 5: Tests for the EWS transport branch of the Email outbox delivery adapter —
|
||||
/// Tests for the EWS transport branch of the Email outbox delivery adapter —
|
||||
/// the transport parse, the EWS config-shape validation (each failure permanent and
|
||||
/// short-circuiting before the sender is touched), the request the sender receives,
|
||||
/// the typed transient/permanent outcome mapping, and the proof that an unset or
|
||||
@@ -100,6 +100,8 @@ public class EmailNotificationDeliveryAdapterEwsTests
|
||||
Arg.Any<EwsSendRequest>(), Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
/// <summary>Verifies that delivery over the EWS transport goes through the EWS sender and returns success.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_EwsTransport_SendsThroughEwsSenderAndReturnsSuccess()
|
||||
{
|
||||
@@ -129,6 +131,8 @@ public class EmailNotificationDeliveryAdapterEwsTests
|
||||
Arg.Any<int>(), Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
/// <summary>Verifies that credentials are split on the first colon only so a password may contain colons.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_PasswordContainsColon_SplitsOnFirstColonOnly()
|
||||
{
|
||||
@@ -143,6 +147,8 @@ public class EmailNotificationDeliveryAdapterEwsTests
|
||||
Assert.Equal(DeliveryResult.Success, outcome.Result);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a transient EWS exception maps to a transient outcome.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_EwsTransientException_ReturnsTransient()
|
||||
{
|
||||
@@ -157,6 +163,8 @@ public class EmailNotificationDeliveryAdapterEwsTests
|
||||
Assert.Contains("server busy", outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a permanent EWS exception maps to a permanent outcome.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_EwsPermanentException_ReturnsPermanent()
|
||||
{
|
||||
@@ -171,6 +179,8 @@ public class EmailNotificationDeliveryAdapterEwsTests
|
||||
Assert.Contains("unauthorized", outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that an unclassified sender exception maps to a permanent outcome and redacts the credential.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_UnclassifiedSenderException_ReturnsPermanentAndRedactsCredential()
|
||||
{
|
||||
@@ -186,6 +196,8 @@ public class EmailNotificationDeliveryAdapterEwsTests
|
||||
Assert.DoesNotContain("super-secret-password", outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a cancelled token throws an operation-canceled exception.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_CancelledToken_ThrowsOperationCanceledException()
|
||||
{
|
||||
@@ -209,6 +221,8 @@ public class EmailNotificationDeliveryAdapterEwsTests
|
||||
() => adapter.DeliverAsync(MakeNotification(), cts.Token));
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a non-HTTPS endpoint returns a permanent failure without calling the sender.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_NonHttpsEndpoint_ReturnsPermanentWithoutCallingSender()
|
||||
{
|
||||
@@ -222,6 +236,8 @@ public class EmailNotificationDeliveryAdapterEwsTests
|
||||
await AssertSenderUntouched();
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a non-absolute endpoint returns a permanent failure without calling the sender.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_NonAbsoluteEndpoint_ReturnsPermanentWithoutCallingSender()
|
||||
{
|
||||
@@ -235,6 +251,8 @@ public class EmailNotificationDeliveryAdapterEwsTests
|
||||
await AssertSenderUntouched();
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a non-basic auth type returns a permanent failure without calling the sender.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_NonBasicAuthType_ReturnsPermanentWithoutCallingSender()
|
||||
{
|
||||
@@ -248,6 +266,9 @@ public class EmailNotificationDeliveryAdapterEwsTests
|
||||
await AssertSenderUntouched();
|
||||
}
|
||||
|
||||
/// <summary>Verifies that malformed credentials return a permanent failure without calling the sender.</summary>
|
||||
/// <param name="credentials">The malformed credentials string, or null.</param>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("")]
|
||||
@@ -267,6 +288,8 @@ public class EmailNotificationDeliveryAdapterEwsTests
|
||||
await AssertSenderUntouched();
|
||||
}
|
||||
|
||||
/// <summary>Verifies that an unknown transport returns a permanent failure without calling the sender.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_UnknownTransport_ReturnsPermanentWithoutCallingSender()
|
||||
{
|
||||
@@ -283,6 +306,8 @@ public class EmailNotificationDeliveryAdapterEwsTests
|
||||
Arg.Any<int>(), Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
/// <summary>Verifies that delivery with no EWS sender registered returns a permanent failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_NoEwsSenderRegistered_ReturnsPermanent()
|
||||
{
|
||||
@@ -296,6 +321,9 @@ public class EmailNotificationDeliveryAdapterEwsTests
|
||||
Assert.Contains("registered", outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that an SMTP or unset transport takes the SMTP path.</summary>
|
||||
/// <param name="transport">The configured transport, or null when unset.</param>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("Smtp")]
|
||||
|
||||
+26
-1
@@ -13,7 +13,7 @@ using ZB.MOM.WW.ScadaBridge.NotificationService;
|
||||
namespace ZB.MOM.WW.ScadaBridge.NotificationOutbox.Tests.Delivery;
|
||||
|
||||
/// <summary>
|
||||
/// Task 12: Tests for the Email outbox delivery adapter — list/recipient/SMTP-config
|
||||
/// Tests for the Email outbox delivery adapter — list/recipient/SMTP-config
|
||||
/// resolution, SMTP send, and the three-way (Success / Permanent / Transient) outcome
|
||||
/// classification.
|
||||
/// </summary>
|
||||
@@ -59,12 +59,15 @@ public class EmailNotificationDeliveryAdapterTests
|
||||
_repository.GetAllSmtpConfigurationsAsync().Returns(new List<SmtpConfiguration> { smtpConfig });
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the adapter reports the Email notification type.</summary>
|
||||
[Fact]
|
||||
public void Type_IsEmail()
|
||||
{
|
||||
Assert.Equal(NotificationType.Email, CreateAdapter().Type);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a successful delivery returns success with the resolved targets.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_HappyPath_ReturnsSuccessWithResolvedTargets()
|
||||
{
|
||||
@@ -80,6 +83,8 @@ public class EmailNotificationDeliveryAdapterTests
|
||||
Assert.Null(outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a missing notification list returns a permanent failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_ListNotFound_ReturnsPermanent()
|
||||
{
|
||||
@@ -93,6 +98,8 @@ public class EmailNotificationDeliveryAdapterTests
|
||||
Assert.Contains("not found", outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a list with no recipients returns a permanent failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_NoRecipients_ReturnsPermanent()
|
||||
{
|
||||
@@ -107,6 +114,8 @@ public class EmailNotificationDeliveryAdapterTests
|
||||
Assert.Contains("recipient", outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a missing SMTP configuration returns a permanent failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_NoSmtpConfig_ReturnsPermanent()
|
||||
{
|
||||
@@ -125,6 +134,8 @@ public class EmailNotificationDeliveryAdapterTests
|
||||
Assert.Contains("SMTP", outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a permanent SMTP exception returns a permanent failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_SmtpPermanentException_ReturnsPermanent()
|
||||
{
|
||||
@@ -141,6 +152,8 @@ public class EmailNotificationDeliveryAdapterTests
|
||||
Assert.Contains("mailbox unavailable", outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that an SMTP 5xx command exception returns a permanent failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_Smtp5xxCommandException_ReturnsPermanent()
|
||||
{
|
||||
@@ -157,6 +170,8 @@ public class EmailNotificationDeliveryAdapterTests
|
||||
Assert.Equal(DeliveryResult.PermanentFailure, outcome.Result);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a socket exception returns a transient failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_SocketException_ReturnsTransient()
|
||||
{
|
||||
@@ -173,6 +188,8 @@ public class EmailNotificationDeliveryAdapterTests
|
||||
Assert.NotNull(outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that an SMTP 4xx command exception returns a transient failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_Smtp4xxCommandException_ReturnsTransient()
|
||||
{
|
||||
@@ -189,6 +206,8 @@ public class EmailNotificationDeliveryAdapterTests
|
||||
Assert.Equal(DeliveryResult.TransientFailure, outcome.Result);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that an unclassified exception returns a permanent failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_UnclassifiedException_ReturnsPermanent()
|
||||
{
|
||||
@@ -205,6 +224,8 @@ public class EmailNotificationDeliveryAdapterTests
|
||||
Assert.NotNull(outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a malformed recipient address returns a permanent failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_MalformedRecipientAddress_ReturnsPermanent()
|
||||
{
|
||||
@@ -230,6 +251,8 @@ public class EmailNotificationDeliveryAdapterTests
|
||||
Assert.Contains(malformed, outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a cancelled token throws an <c>OperationCanceledException</c>.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_CancelledToken_ThrowsOperationCanceledException()
|
||||
{
|
||||
@@ -265,6 +288,8 @@ public class EmailNotificationDeliveryAdapterTests
|
||||
() => adapter.DeliverAsync(MakeNotification(), cts.Token));
|
||||
}
|
||||
|
||||
/// <summary>Verifies that when several SMTP configurations exist the one with the lowest id wins.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task MultipleSmtpConfigs_LowestIdWins()
|
||||
{
|
||||
|
||||
+52
@@ -32,7 +32,9 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
{
|
||||
private readonly Queue<Func<HttpRequestMessage, Task<HttpResponseMessage>>> _responders;
|
||||
|
||||
/// <summary>The HTTP requests received by the handler, in order.</summary>
|
||||
public List<HttpRequestMessage> Requests { get; } = new();
|
||||
/// <summary>The request bodies received by the handler, in order.</summary>
|
||||
public List<string> RequestBodies { get; } = new();
|
||||
|
||||
private ScriptedHttpMessageHandler(IEnumerable<Func<HttpRequestMessage, Task<HttpResponseMessage>>> responders)
|
||||
@@ -41,6 +43,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
}
|
||||
|
||||
/// <summary>One queued response per status code (one per recipient POST).</summary>
|
||||
/// <param name="statusCodes">The status codes to queue, one per expected request.</param>
|
||||
/// <returns>A handler that answers each request with the next queued status code.</returns>
|
||||
public static ScriptedHttpMessageHandler ForStatuses(params HttpStatusCode[] statusCodes) =>
|
||||
new(statusCodes.Select(code =>
|
||||
new Func<HttpRequestMessage, Task<HttpResponseMessage>>(
|
||||
@@ -50,9 +54,12 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
}))));
|
||||
|
||||
/// <summary>Custom per-request responders (e.g. to throw a transport exception).</summary>
|
||||
/// <param name="responders">The responders to queue, one per expected request.</param>
|
||||
/// <returns>A handler that answers each request with the next queued responder.</returns>
|
||||
public static ScriptedHttpMessageHandler ForResponders(
|
||||
params Func<HttpRequestMessage, Task<HttpResponseMessage>>[] responders) => new(responders);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async Task<HttpResponseMessage> SendAsync(
|
||||
HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
@@ -116,12 +123,15 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the adapter reports the SMS notification type.</summary>
|
||||
[Fact]
|
||||
public void Type_IsSms()
|
||||
{
|
||||
Assert.Equal(NotificationType.Sms, CreateAdapter(ScriptedHttpMessageHandler.ForStatuses()).Type);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that delivery to a single recipient with a 201 response succeeds and returns the resolved targets.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_SingleRecipient201_ReturnsSuccessWithResolvedTargets()
|
||||
{
|
||||
@@ -154,6 +164,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
_httpClientFactory.Received(1).CreateClient(SmsNotificationDeliveryAdapter.HttpClientName);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that delivery to several recipients that are all accepted succeeds.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_MultiRecipient201_AllAccepted_ReturnsSuccess()
|
||||
{
|
||||
@@ -169,6 +181,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.Equal(2, handler.Requests.Count);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that delivery uses the messaging service SID when no from number is configured.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_UsesMessagingServiceSid_WhenFromNumberAbsent()
|
||||
{
|
||||
@@ -191,6 +205,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.DoesNotContain("From=", body);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a 500 response is classified as a transient failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_500_ReturnsTransient()
|
||||
{
|
||||
@@ -204,6 +220,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.NotNull(outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a 429 response is classified as a transient failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_429_ReturnsTransient()
|
||||
{
|
||||
@@ -216,6 +234,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.Equal(DeliveryResult.TransientFailure, outcome.Result);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that an HTTP request exception is classified as a transient failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_HttpRequestException_ReturnsTransient()
|
||||
{
|
||||
@@ -229,6 +249,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.Equal(DeliveryResult.TransientFailure, outcome.Result);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a timeout is classified as a transient failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_Timeout_ReturnsTransient()
|
||||
{
|
||||
@@ -244,6 +266,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.Equal(DeliveryResult.TransientFailure, outcome.Result);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a 400 response is classified as a permanent failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_400_ReturnsPermanent()
|
||||
{
|
||||
@@ -257,6 +281,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.NotNull(outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a 401 response is classified as a permanent failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_401_ReturnsPermanent()
|
||||
{
|
||||
@@ -269,6 +295,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.Equal(DeliveryResult.PermanentFailure, outcome.Result);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a mix of accepted and permanently bad recipients succeeds and notes the bad number.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_MixAcceptedAndPermanentBad_ReturnsSuccessWithBadNumberNoted()
|
||||
{
|
||||
@@ -285,6 +313,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.Contains("+1BADNUMBER", outcome.ResolvedTargets);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a mix of accepted and transiently failed recipients is classified as transient.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_MixAcceptedAndTransient_ReturnsTransient()
|
||||
{
|
||||
@@ -299,6 +329,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.Equal(DeliveryResult.TransientFailure, outcome.Result);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a transient failure mid-list short-circuits so the remaining recipients are not attempted.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task MidListTransient_ShortCircuits_RemainingRecipientsNotAttempted()
|
||||
{
|
||||
@@ -317,6 +349,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.Single(handler.Requests);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a missing notification list is classified as a permanent failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_ListNotFound_ReturnsPermanent()
|
||||
{
|
||||
@@ -331,6 +365,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.Contains("not found", outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a list with no phone recipients is classified as a permanent failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_NoPhoneRecipients_ReturnsPermanent()
|
||||
{
|
||||
@@ -350,6 +386,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.Contains("no SMS recipients", outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a missing SMS configuration is classified as a permanent failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_NoSmsConfig_ReturnsPermanent()
|
||||
{
|
||||
@@ -367,6 +405,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.Contains("SMS configuration", outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that an incomplete configuration missing the auth token is classified as a permanent failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_IncompleteConfig_MissingAuthToken_ReturnsPermanent()
|
||||
{
|
||||
@@ -385,6 +425,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.Contains("incomplete", outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that an incomplete configuration with neither a from number nor a messaging service SID is classified as a permanent failure.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_IncompleteConfig_NoFromAndNoMessagingServiceSid_ReturnsPermanent()
|
||||
{
|
||||
@@ -407,6 +449,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.Contains("incomplete", outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that delivery defaults to the Twilio base URL when no API base URL is configured.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_DefaultsToTwilioBaseUrl_WhenApiBaseUrlAbsent()
|
||||
{
|
||||
@@ -426,6 +470,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.StartsWith("https://api.twilio.com/2010-04-01/Accounts/", request.RequestUri!.ToString());
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the auth token never appears in a returned error.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_AuthToken_NeverAppearsInReturnedError()
|
||||
{
|
||||
@@ -457,6 +503,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.DoesNotContain(base64Credential, outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the auth token never appears on a transport exception.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_AuthToken_NeverAppearsOnTransportException()
|
||||
{
|
||||
@@ -473,6 +521,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.DoesNotContain(AuthToken, outcome.Error);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a long message body is truncated to the maximum message length.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_LongBody_TruncatedToMaxMessageLength()
|
||||
{
|
||||
@@ -495,6 +545,8 @@ public class SmsNotificationDeliveryAdapterTests
|
||||
Assert.DoesNotContain(new string('x', 100), body);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that caller cancellation propagates out of delivery.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deliver_CallerCancellation_Propagates()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user