From a10f917084e988dd3669f3095049383c42d2fc1a Mon Sep 17 00:00:00 2001 From: TekH Date: Thu, 16 Apr 2026 10:40:34 +0200 Subject: [PATCH] Add tests for batch duplicate guard in rec action invoke Added InvokeBatchDuplicateGuardTests to verify that invoking batch rec actions with an existing BatchId throws BadRequestException, while using a new BatchId does not trigger the duplicate guard. Tests use MediatR ISender and real database data for integration coverage. Added necessary using directives. --- .../InvokeBatchDuplicateGuardTests.cs | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 tests/ReC.Tests/Application/RecActions/InvokeBatchDuplicateGuardTests.cs diff --git a/tests/ReC.Tests/Application/RecActions/InvokeBatchDuplicateGuardTests.cs b/tests/ReC.Tests/Application/RecActions/InvokeBatchDuplicateGuardTests.cs new file mode 100644 index 0000000..41a0475 --- /dev/null +++ b/tests/ReC.Tests/Application/RecActions/InvokeBatchDuplicateGuardTests.cs @@ -0,0 +1,87 @@ +using System.Linq; +using System.Threading.Tasks; +using DigitalData.Core.Exceptions; +using MediatR; +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; +using ReC.Application.RecActions.Commands; +using ReC.Application.Results.Queries; + +namespace ReC.Tests.Application.RecActions; + +[TestFixture] +public class InvokeBatchDuplicateGuardTests : RecApplicationTestBase +{ + private const long ProfileId = 3; + + private (ISender Sender, IServiceScope Scope) CreateScopedSender() + { + var scope = ServiceProvider.CreateScope(); + var sender = scope.ServiceProvider.GetRequiredService(); + return (sender, scope); + } + + [Test] + public async Task Invoke_with_existing_batchId_throws_BadRequestException() + { + var (sender, scope) = CreateScopedSender(); + using var _ = scope; + + // Arrange: read an existing result to get a real BatchId from the database + var results = await sender.Send(new ReadResultViewQuery + { + ProfileId = ProfileId, + IncludeAction = false, + Last = true + }); + + var existingBatchId = results.FirstOrDefault()?.BatchId; + Assert.That(existingBatchId, Is.Not.Null.And.Not.Empty, + $"No results with a BatchId found for ProfileId {ProfileId}. Ensure test data exists in the database."); + + // Act & Assert: invoking with the same BatchId should throw + var ex = Assert.ThrowsAsync(async () => + await sender.Send(new InvokeBatchRecActionViewsCommand + { + ProfileId = ProfileId, + References = new InvokeReferences + { + BatchId = existingBatchId! + } + })); + + Assert.That(ex!.Message, Does.Contain(existingBatchId!)); + } + + [Test] + public void Invoke_with_new_batchId_does_not_throw_duplicate_guard() + { + var (sender, scope) = CreateScopedSender(); + using var _ = scope; + + var uniqueBatchId = $"test-{System.Guid.NewGuid():N}"; + + // This should NOT throw BadRequestException for duplicate BatchId. + // It may throw other exceptions (e.g., no actions found, endpoint errors), + // but the duplicate guard should pass. + try + { + sender.Send(new InvokeBatchRecActionViewsCommand + { + ProfileId = ProfileId, + References = new InvokeReferences + { + BatchId = uniqueBatchId + } + }).GetAwaiter().GetResult(); + } + catch (BadRequestException badReq) when (badReq.Message.Contains("already results associated")) + { + Assert.Fail("Duplicate guard should not trigger for a unique BatchId."); + } + catch + { + // Other exceptions (endpoint errors, etc.) are acceptable + } + } +}