diff --git a/EnvelopeGenerator.Application/Common/Extensions/MediatorExtensions.cs b/EnvelopeGenerator.Application/Common/Extensions/MediatorExtensions.cs index b0a09668..9a6a35dc 100644 --- a/EnvelopeGenerator.Application/Common/Extensions/MediatorExtensions.cs +++ b/EnvelopeGenerator.Application/Common/Extensions/MediatorExtensions.cs @@ -15,16 +15,16 @@ public static class MediatorExtensions /// /// The expected response type. /// The exception type to throw. - /// The mediator instance. + /// The mediator instance. /// The MediatR request whose response may be null. /// A factory that creates the exception to throw when the response is absent. /// Cancellation token. /// A guaranteed non-null . /// The exception produced by . - public static async Task SendOrThrowAsync(this IMediator mediator, IRequest request, Func exceptionFactory, CancellationToken cancel = default) + public static async Task GetOrThrow(this ISender sender, IRequest request, Func exceptionFactory, CancellationToken cancel = default) where TException : Exception { - if (await mediator.Send(request, cancel) is TResponse res) + if (await sender.Send(request, cancel) is TResponse res) { if (res is not string && res is IEnumerable enumerable && !enumerable.Cast().Any()) throw exceptionFactory(); @@ -39,16 +39,16 @@ public static class MediatorExtensions /// Sends a request via MediatR and throws when the response is null or an empty collection. /// /// The expected response type. - /// The mediator instance. + /// The mediator instance. /// The MediatR request whose response may be null. /// Optional message for the . /// Cancellation token. /// A guaranteed non-null . /// Thrown when the response is null or an empty collection. - public static async Task SendOrNotFoundAsync(this IMediator mediator, IRequest request, string? exceptionMessage, CancellationToken cancel = default) - => await mediator.SendOrThrowAsync(request, () => new NotFoundException(exceptionMessage ?? $"The requested resource of type {typeof(TResponse).Name} was not found."), cancel); + public static async Task GetOrThrow(this ISender sender, IRequest request, string? exceptionMessage, CancellationToken cancel = default) + => await sender.GetOrThrow(request, () => new NotFoundException(exceptionMessage ?? $"The requested resource of type {typeof(TResponse).Name} was not found."), cancel); - /// - public static async Task SendOrNotFoundAsync(this IMediator mediator, IRequest request, CancellationToken cancel = default) - => await mediator.SendOrNotFoundAsync(request, null, cancel); + /// + public static async Task GetOrThrow(this ISender sender, IRequest request, CancellationToken cancel = default) + => await sender.GetOrThrow(request, null, cancel); } \ No newline at end of file diff --git a/EnvelopeGenerator.Tests/Application/MediatorExtensionsTests.cs b/EnvelopeGenerator.Tests/Application/MediatorExtensionsTests.cs index ca28f61e..bec0c4a1 100644 --- a/EnvelopeGenerator.Tests/Application/MediatorExtensionsTests.cs +++ b/EnvelopeGenerator.Tests/Application/MediatorExtensionsTests.cs @@ -12,13 +12,13 @@ public class MediatorExtensionsTests private sealed class StubRequest : IRequest { } /// - /// Minimal stub that returns a pre-configured response for any call. + /// Minimal stub that returns a pre-configured response for any call. /// - private sealed class StubMediator : IMediator + private sealed class StubSender : ISender { private readonly object? _response; - public StubMediator(object? response) => _response = response; + public StubSender(object? response) => _response = response; public Task Send(IRequest request, CancellationToken cancellationToken = default) { @@ -43,214 +43,208 @@ public class MediatorExtensionsTests public IAsyncEnumerable CreateStream(object request, CancellationToken cancellationToken = default) => throw new NotImplementedException(); - - public Task Publish(object notification, CancellationToken cancellationToken = default) - => Task.CompletedTask; - - public Task Publish(TNotification notification, CancellationToken cancellationToken = default) where TNotification : INotification - => Task.CompletedTask; } - private static IMediator CreateMediator(T? response) => new StubMediator(response); + private static ISender CreateSender(T? response) => new StubSender(response); #endregion - #region SendOrThrowAsync — non-null scalar + #region GetOrThrow — non-null scalar [Test] - public async Task SendOrThrowAsync_WithNonNullResponse_ReturnsResponse() + public async Task GetOrThrow_WithNonNullResponse_ReturnsResponse() { - var mediator = CreateMediator("hello"); + var sender = CreateSender("hello"); var request = new StubRequest(); - var result = await mediator.SendOrThrowAsync(request, () => new InvalidOperationException()); + var result = await sender.GetOrThrow(request, () => new InvalidOperationException()); Assert.That(result, Is.EqualTo("hello")); } #endregion - #region SendOrThrowAsync — null response + #region GetOrThrow — null response [Test] - public void SendOrThrowAsync_WithNullResponse_ThrowsCustomException() + public void GetOrThrow_WithNullResponse_ThrowsCustomException() { - var mediator = CreateMediator(null); + var sender = CreateSender(null); var request = new StubRequest(); var ex = Assert.ThrowsAsync( - () => mediator.SendOrThrowAsync(request, () => new InvalidOperationException("custom"))); + () => sender.GetOrThrow(request, () => new InvalidOperationException("custom"))); Assert.That(ex!.Message, Is.EqualTo("custom")); } #endregion - #region SendOrThrowAsync — empty collection + #region GetOrThrow — empty collection [Test] - public void SendOrThrowAsync_WithEmptyList_ThrowsCustomException() + public void GetOrThrow_WithEmptyList_ThrowsCustomException() { - var mediator = CreateMediator>(new List()); + var sender = CreateSender>(new List()); var request = new StubRequest?>(); Assert.ThrowsAsync( - () => mediator.SendOrThrowAsync(request, () => new ArgumentException("empty"))); + () => sender.GetOrThrow(request, () => new ArgumentException("empty"))); } #endregion - #region SendOrThrowAsync — non-empty collection + #region GetOrThrow — non-empty collection [Test] - public async Task SendOrThrowAsync_WithNonEmptyList_ReturnsResponse() + public async Task GetOrThrow_WithNonEmptyList_ReturnsResponse() { var expected = new List { 1, 2 }; - var mediator = CreateMediator>(expected); + var sender = CreateSender>(expected); var request = new StubRequest?>(); - var result = await mediator.SendOrThrowAsync(request, () => new InvalidOperationException()); + var result = await sender.GetOrThrow(request, () => new InvalidOperationException()); Assert.That(result, Is.EqualTo(expected)); } #endregion - #region SendOrThrowAsync — string edge case (string implements IEnumerable) + #region GetOrThrow — string edge case (string implements IEnumerable) [Test] - public async Task SendOrThrowAsync_WithEmptyString_ReturnsEmptyString() + public async Task GetOrThrow_WithEmptyString_ReturnsEmptyString() { - var mediator = CreateMediator(""); + var sender = CreateSender(""); var request = new StubRequest(); - var result = await mediator.SendOrThrowAsync(request, () => new InvalidOperationException("should not throw")); + var result = await sender.GetOrThrow(request, () => new InvalidOperationException("should not throw")); Assert.That(result, Is.EqualTo("")); } #endregion - #region SendOrNotFoundAsync — non-null scalar + #region GetOrThrow (NotFoundException) — non-null scalar [Test] - public async Task SendOrNotFoundAsync_WithNonNullResponse_ReturnsResponse() + public async Task GetOrThrow_NotFound_WithNonNullResponse_ReturnsResponse() { - var mediator = CreateMediator("hello"); + var sender = CreateSender("hello"); var request = new StubRequest(); - var result = await mediator.SendOrNotFoundAsync(request); + var result = await sender.GetOrThrow(request); Assert.That(result, Is.EqualTo("hello")); } [Test] - public async Task SendOrNotFoundAsync_WithExceptionMessage_AndNonNullResponse_ReturnsResponse() + public async Task GetOrThrow_NotFound_WithExceptionMessage_AndNonNullResponse_ReturnsResponse() { - var mediator = CreateMediator(42); + var sender = CreateSender(42); var request = new StubRequest(); - var result = await mediator.SendOrNotFoundAsync(request, "not found", CancellationToken.None); + var result = await sender.GetOrThrow(request, "not found", CancellationToken.None); Assert.That(result, Is.EqualTo(42)); } #endregion - #region SendOrNotFoundAsync — null response + #region GetOrThrow (NotFoundException) — null response [Test] - public void SendOrNotFoundAsync_WithNullResponse_ThrowsNotFoundException() + public void GetOrThrow_NotFound_WithNullResponse_ThrowsNotFoundException() { - var mediator = CreateMediator(null); + var sender = CreateSender(null); var request = new StubRequest(); - Assert.ThrowsAsync(() => mediator.SendOrNotFoundAsync(request)); + Assert.ThrowsAsync(() => sender.GetOrThrow(request)); } [Test] - public void SendOrNotFoundAsync_WithNullResponse_AndCustomMessage_ThrowsNotFoundExceptionWithMessage() + public void GetOrThrow_NotFound_WithNullResponse_AndCustomMessage_ContainsMessage() { const string message = "Entity not found"; - var mediator = CreateMediator(null); + var sender = CreateSender(null); var request = new StubRequest(); var ex = Assert.ThrowsAsync( - () => mediator.SendOrNotFoundAsync(request, message, CancellationToken.None)); + () => sender.GetOrThrow(request, message, CancellationToken.None)); Assert.That(ex!.Message, Does.Contain(message)); } [Test] - public void SendOrNotFoundAsync_WithNullResponse_HasDefaultMessage() + public void GetOrThrow_NotFound_WithNullResponse_HasDefaultMessageWithTypeName() { - var mediator = CreateMediator(null); + var sender = CreateSender(null); var request = new StubRequest(); - var ex = Assert.ThrowsAsync(() => mediator.SendOrNotFoundAsync(request)); + var ex = Assert.ThrowsAsync(() => sender.GetOrThrow(request)); Assert.That(ex!.Message, Does.Contain(nameof(String))); } #endregion - #region SendOrNotFoundAsync — empty collection + #region GetOrThrow (NotFoundException) — empty collection [Test] - public void SendOrNotFoundAsync_WithEmptyList_ThrowsNotFoundException() + public void GetOrThrow_NotFound_WithEmptyList_ThrowsNotFoundException() { - var mediator = CreateMediator>(new List()); + var sender = CreateSender>(new List()); var request = new StubRequest?>(); - Assert.ThrowsAsync(() => mediator.SendOrNotFoundAsync(request)); + Assert.ThrowsAsync(() => sender.GetOrThrow(request)); } [Test] - public void SendOrNotFoundAsync_WithEmptyArray_ThrowsNotFoundException() + public void GetOrThrow_NotFound_WithEmptyArray_ThrowsNotFoundException() { - var mediator = CreateMediator(Array.Empty()); + var sender = CreateSender(Array.Empty()); var request = new StubRequest(); - Assert.ThrowsAsync(() => mediator.SendOrNotFoundAsync(request)); + Assert.ThrowsAsync(() => sender.GetOrThrow(request)); } [Test] - public void SendOrNotFoundAsync_WithEmptyCollection_AndCustomMessage_ThrowsNotFoundExceptionWithMessage() + public void GetOrThrow_NotFound_WithEmptyCollection_AndCustomMessage_ContainsMessage() { const string message = "No items found"; - var mediator = CreateMediator>(new List()); + var sender = CreateSender>(new List()); var request = new StubRequest?>(); var ex = Assert.ThrowsAsync( - () => mediator.SendOrNotFoundAsync(request, message, CancellationToken.None)); + () => sender.GetOrThrow(request, message, CancellationToken.None)); Assert.That(ex!.Message, Does.Contain(message)); } #endregion - #region SendOrNotFoundAsync — non-empty collection + #region GetOrThrow (NotFoundException) — non-empty collection [Test] - public async Task SendOrNotFoundAsync_WithNonEmptyList_ReturnsResponse() + public async Task GetOrThrow_NotFound_WithNonEmptyList_ReturnsResponse() { var expected = new List { "a", "b" }; - var mediator = CreateMediator>(expected); + var sender = CreateSender>(expected); var request = new StubRequest?>(); - var result = await mediator.SendOrNotFoundAsync(request); + var result = await sender.GetOrThrow(request); Assert.That(result, Is.EqualTo(expected)); } [Test] - public async Task SendOrNotFoundAsync_WithNonEmptyArray_ReturnsResponse() + public async Task GetOrThrow_NotFound_WithNonEmptyArray_ReturnsResponse() { var expected = new[] { 1, 2, 3 }; - var mediator = CreateMediator(expected); + var sender = CreateSender(expected); var request = new StubRequest(); - var result = await mediator.SendOrNotFoundAsync(request); + var result = await sender.GetOrThrow(request); Assert.That(result, Is.EqualTo(expected)); } @@ -260,27 +254,27 @@ public class MediatorExtensionsTests #region CancellationToken [Test] - public void SendOrThrowAsync_WithCancelledToken_ThrowsOperationCanceledException() + public void GetOrThrow_WithCancelledToken_ThrowsOperationCanceledException() { - var mediator = CreateMediator("value"); + var sender = CreateSender("value"); var request = new StubRequest(); var cts = new CancellationTokenSource(); cts.Cancel(); Assert.ThrowsAsync( - () => mediator.SendOrThrowAsync(request, () => new InvalidOperationException(), cts.Token)); + () => sender.GetOrThrow(request, () => new InvalidOperationException(), cts.Token)); } [Test] - public void SendOrNotFoundAsync_WithCancelledToken_ThrowsOperationCanceledException() + public void GetOrThrow_NotFound_WithCancelledToken_ThrowsOperationCanceledException() { - var mediator = CreateMediator("value"); + var sender = CreateSender("value"); var request = new StubRequest(); var cts = new CancellationTokenSource(); cts.Cancel(); Assert.ThrowsAsync( - () => mediator.SendOrNotFoundAsync(request, cts.Token)); + () => sender.GetOrThrow(request, cts.Token)); } #endregion