From e07f5463187ba02863e61f17eb5600e97ba6095e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Tore=20Gjerde?= Date: Wed, 10 Jul 2024 15:48:36 +0200 Subject: [PATCH] Don't generate PDF receipt for skipped payments. (#712) --- .../Payment/Services/IPaymentService.cs | 4 +- .../Payment/Services/PaymentService.cs | 7 ++- .../ProcessTasks/PaymentProcessTask.cs | 8 +++- .../Features/Payment/PaymentServiceTests.cs | 31 ++---------- .../ProcessTasks/PaymentProcessTaskTests.cs | 48 ++++++++++++++++--- 5 files changed, 60 insertions(+), 38 deletions(-) diff --git a/src/Altinn.App.Core/Features/Payment/Services/IPaymentService.cs b/src/Altinn.App.Core/Features/Payment/Services/IPaymentService.cs index 4ac5528ec..3ca181f60 100644 --- a/src/Altinn.App.Core/Features/Payment/Services/IPaymentService.cs +++ b/src/Altinn.App.Core/Features/Payment/Services/IPaymentService.cs @@ -28,9 +28,9 @@ Task CheckAndStorePaymentStatus( ); /// - /// Check our internal state to see if payment is complete. + /// Get our internal payment status. Will only check the local status and will not get updated status from the payment provider. /// - Task IsPaymentCompleted(Instance instance, ValidAltinnPaymentConfiguration paymentConfiguration); + Task GetPaymentStatus(Instance instance, ValidAltinnPaymentConfiguration paymentConfiguration); /// /// Cancel payment with payment processor and delete internal payment information. diff --git a/src/Altinn.App.Core/Features/Payment/Services/PaymentService.cs b/src/Altinn.App.Core/Features/Payment/Services/PaymentService.cs index 7486f966f..d6b7ec867 100644 --- a/src/Altinn.App.Core/Features/Payment/Services/PaymentService.cs +++ b/src/Altinn.App.Core/Features/Payment/Services/PaymentService.cs @@ -198,7 +198,10 @@ await _dataService.UpdateJsonObject( } /// - public async Task IsPaymentCompleted(Instance instance, ValidAltinnPaymentConfiguration paymentConfiguration) + public async Task GetPaymentStatus( + Instance instance, + ValidAltinnPaymentConfiguration paymentConfiguration + ) { string dataTypeId = paymentConfiguration.PaymentDataType; (Guid _, PaymentInformation? paymentInformation) = await _dataService.GetByType( @@ -211,7 +214,7 @@ public async Task IsPaymentCompleted(Instance instance, ValidAltinnPayment throw new PaymentException("Payment information not found."); } - return paymentInformation.Status is PaymentStatus.Paid or PaymentStatus.Skipped; + return paymentInformation.Status; } /// diff --git a/src/Altinn.App.Core/Internal/Process/ProcessTasks/PaymentProcessTask.cs b/src/Altinn.App.Core/Internal/Process/ProcessTasks/PaymentProcessTask.cs index a940bb453..7829742e7 100644 --- a/src/Altinn.App.Core/Internal/Process/ProcessTasks/PaymentProcessTask.cs +++ b/src/Altinn.App.Core/Internal/Process/ProcessTasks/PaymentProcessTask.cs @@ -1,4 +1,5 @@ using Altinn.App.Core.Features.Payment.Exceptions; +using Altinn.App.Core.Features.Payment.Models; using Altinn.App.Core.Features.Payment.Services; using Altinn.App.Core.Internal.App; using Altinn.App.Core.Internal.Data; @@ -52,7 +53,12 @@ public async Task End(string taskId, Instance instance) { AltinnPaymentConfiguration paymentConfiguration = GetAltinnPaymentConfiguration(taskId); - if (!await _paymentService.IsPaymentCompleted(instance, paymentConfiguration.Validate())) + PaymentStatus paymentStatus = await _paymentService.GetPaymentStatus(instance, paymentConfiguration.Validate()); + + if (paymentStatus == PaymentStatus.Skipped) + return; + + if (paymentStatus != PaymentStatus.Paid) throw new PaymentException("The payment is not completed."); Stream pdfStream = await _pdfService.GeneratePdf(instance, taskId, CancellationToken.None); diff --git a/test/Altinn.App.Core.Tests/Features/Payment/PaymentServiceTests.cs b/test/Altinn.App.Core.Tests/Features/Payment/PaymentServiceTests.cs index d5f9d64a6..55221087b 100644 --- a/test/Altinn.App.Core.Tests/Features/Payment/PaymentServiceTests.cs +++ b/test/Altinn.App.Core.Tests/Features/Payment/PaymentServiceTests.cs @@ -459,14 +459,14 @@ public async Task IsPaymentCompleted_ShouldThrowPaymentException_WhenPaymentInfo .ReturnsAsync((Guid.NewGuid(), null)); // Act - Func act = async () => await _paymentService.IsPaymentCompleted(instance, paymentConfiguration); + Func act = async () => await _paymentService.GetPaymentStatus(instance, paymentConfiguration); // Assert await act.Should().ThrowAsync().WithMessage("Payment information not found."); } [Fact] - public async Task IsPaymentCompleted_ShouldReturnTrue_WhenPaymentStatusIsPaidOrSkipped() + public async Task GetPaymentStatus_ShouldReturn_CorrectStatus() { // Arrange Instance instance = CreateInstance(); @@ -483,33 +483,10 @@ public async Task IsPaymentCompleted_ShouldReturnTrue_WhenPaymentStatusIsPaidOrS .ReturnsAsync((Guid.NewGuid(), paymentInformation)); // Act - bool result = await _paymentService.IsPaymentCompleted(instance, paymentConfiguration); + PaymentStatus result = await _paymentService.GetPaymentStatus(instance, paymentConfiguration); // Assert - result.Should().BeTrue(); - } - - [Fact] - public async Task IsPaymentCompleted_ShouldReturnFalse_WhenPaymentStatusIsNotPaidOrSkipped() - { - // Arrange - Instance instance = CreateInstance(); - ValidAltinnPaymentConfiguration paymentConfiguration = CreatePaymentConfiguration(); - PaymentInformation paymentInformation = CreatePaymentInformation(); - - string paymentDataType = - paymentConfiguration.PaymentDataType - ?? throw new Exception("PaymentDataType should not be null. Fix test."); - - _dataService - .Setup(ds => ds.GetByType(instance, paymentDataType)) - .ReturnsAsync((Guid.NewGuid(), paymentInformation)); - - // Act - var result = await _paymentService.IsPaymentCompleted(instance, paymentConfiguration); - - // Assert - result.Should().BeFalse(); + result.Should().Be(PaymentStatus.Paid); } private static PaymentInformation CreatePaymentInformation() diff --git a/test/Altinn.App.Core.Tests/Internal/Process/ProcessTasks/PaymentProcessTaskTests.cs b/test/Altinn.App.Core.Tests/Internal/Process/ProcessTasks/PaymentProcessTaskTests.cs index e04eccf89..a162dd95f 100644 --- a/test/Altinn.App.Core.Tests/Internal/Process/ProcessTasks/PaymentProcessTaskTests.cs +++ b/test/Altinn.App.Core.Tests/Internal/Process/ProcessTasks/PaymentProcessTaskTests.cs @@ -1,4 +1,5 @@ using Altinn.App.Core.Features.Payment.Exceptions; +using Altinn.App.Core.Features.Payment.Models; using Altinn.App.Core.Features.Payment.Services; using Altinn.App.Core.Internal.App; using Altinn.App.Core.Internal.Data; @@ -69,8 +70,8 @@ public async Task End_PaymentCompleted_ShouldGeneratePdfReceipt() _processReaderMock.Setup(x => x.GetAltinnTaskExtension(It.IsAny())).Returns(altinnTaskExtension); _paymentServiceMock - .Setup(x => x.IsPaymentCompleted(It.IsAny(), It.IsAny())) - .ReturnsAsync(true); + .Setup(x => x.GetPaymentStatus(It.IsAny(), It.IsAny())) + .ReturnsAsync(PaymentStatus.Paid); // Act await _paymentProcessTask.End(taskId, instance); @@ -89,6 +90,41 @@ public async Task End_PaymentCompleted_ShouldGeneratePdfReceipt() ); } + [Fact] + public async Task End_PaymentSkipped_ShouldNotGeneratePdfReceipt() + { + Instance instance = CreateInstance(); + string taskId = instance.Process.CurrentTask.ElementId; + + var altinnTaskExtension = new AltinnTaskExtension { PaymentConfiguration = CreatePaymentConfiguration() }; + ValidAltinnPaymentConfiguration validPaymentConfiguration = + altinnTaskExtension.PaymentConfiguration.Validate(); + + _processReaderMock.Setup(x => x.GetAltinnTaskExtension(It.IsAny())).Returns(altinnTaskExtension); + + _paymentServiceMock + .Setup(x => x.GetPaymentStatus(It.IsAny(), It.IsAny())) + .ReturnsAsync(PaymentStatus.Skipped); + + // Act + await _paymentProcessTask.End(taskId, instance); + + // Assert + _pdfServiceMock.Verify(x => x.GeneratePdf(instance, taskId, CancellationToken.None), Times.Never); + _dataClientMock.Verify( + x => + x.InsertBinaryData( + instance.Id, + validPaymentConfiguration.PaymentReceiptPdfDataType, + "application/pdf", + "Betalingskvittering.pdf", + It.IsAny(), + taskId + ), + Times.Never + ); + } + [Fact] public async Task End_PaymentNotCompleted_ShouldThrowException() { @@ -102,8 +138,8 @@ public async Task End_PaymentNotCompleted_ShouldThrowException() _processReaderMock.Setup(x => x.GetAltinnTaskExtension(It.IsAny())).Returns(altinnTaskExtension); _paymentServiceMock - .Setup(x => x.IsPaymentCompleted(It.IsAny(), It.IsAny())) - .ReturnsAsync(false); + .Setup(x => x.GetPaymentStatus(It.IsAny(), It.IsAny())) + .ReturnsAsync(PaymentStatus.Created); // Act and assert _pdfServiceMock.Verify(x => x.GeneratePdf(instance, taskId, CancellationToken.None), Times.Never); @@ -179,8 +215,8 @@ public async Task End_ValidConfiguration_ShouldNotThrow() .Returns(new AltinnTaskExtension { PaymentConfiguration = CreatePaymentConfiguration() }); _paymentServiceMock - .Setup(ps => ps.IsPaymentCompleted(It.IsAny(), It.IsAny())) - .ReturnsAsync(true); + .Setup(ps => ps.GetPaymentStatus(It.IsAny(), It.IsAny())) + .ReturnsAsync(PaymentStatus.Paid); using var memoryStream = new MemoryStream(); _pdfServiceMock