Skip to content

Commit

Permalink
Don't generate PDF receipt for skipped payments. (#712)
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorntore authored Jul 10, 2024
1 parent ee4f848 commit e07f546
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ Task<PaymentInformation> CheckAndStorePaymentStatus(
);

/// <summary>
/// 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.
/// </summary>
Task<bool> IsPaymentCompleted(Instance instance, ValidAltinnPaymentConfiguration paymentConfiguration);
Task<PaymentStatus> GetPaymentStatus(Instance instance, ValidAltinnPaymentConfiguration paymentConfiguration);

/// <summary>
/// Cancel payment with payment processor and delete internal payment information.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,10 @@ await _dataService.UpdateJsonObject(
}

/// <inheritdoc/>
public async Task<bool> IsPaymentCompleted(Instance instance, ValidAltinnPaymentConfiguration paymentConfiguration)
public async Task<PaymentStatus> GetPaymentStatus(
Instance instance,
ValidAltinnPaymentConfiguration paymentConfiguration
)
{
string dataTypeId = paymentConfiguration.PaymentDataType;
(Guid _, PaymentInformation? paymentInformation) = await _dataService.GetByType<PaymentInformation>(
Expand All @@ -211,7 +214,7 @@ public async Task<bool> IsPaymentCompleted(Instance instance, ValidAltinnPayment
throw new PaymentException("Payment information not found.");
}

return paymentInformation.Status is PaymentStatus.Paid or PaymentStatus.Skipped;
return paymentInformation.Status;
}

/// <inheritdoc/>
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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);
Expand Down
31 changes: 4 additions & 27 deletions test/Altinn.App.Core.Tests/Features/Payment/PaymentServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -459,14 +459,14 @@ public async Task IsPaymentCompleted_ShouldThrowPaymentException_WhenPaymentInfo
.ReturnsAsync((Guid.NewGuid(), null));

// Act
Func<Task> act = async () => await _paymentService.IsPaymentCompleted(instance, paymentConfiguration);
Func<Task> act = async () => await _paymentService.GetPaymentStatus(instance, paymentConfiguration);

// Assert
await act.Should().ThrowAsync<PaymentException>().WithMessage("Payment information not found.");
}

[Fact]
public async Task IsPaymentCompleted_ShouldReturnTrue_WhenPaymentStatusIsPaidOrSkipped()
public async Task GetPaymentStatus_ShouldReturn_CorrectStatus()
{
// Arrange
Instance instance = CreateInstance();
Expand All @@ -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<PaymentInformation>(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()
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -69,8 +70,8 @@ public async Task End_PaymentCompleted_ShouldGeneratePdfReceipt()
_processReaderMock.Setup(x => x.GetAltinnTaskExtension(It.IsAny<string>())).Returns(altinnTaskExtension);

_paymentServiceMock
.Setup(x => x.IsPaymentCompleted(It.IsAny<Instance>(), It.IsAny<ValidAltinnPaymentConfiguration>()))
.ReturnsAsync(true);
.Setup(x => x.GetPaymentStatus(It.IsAny<Instance>(), It.IsAny<ValidAltinnPaymentConfiguration>()))
.ReturnsAsync(PaymentStatus.Paid);

// Act
await _paymentProcessTask.End(taskId, instance);
Expand All @@ -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<string>())).Returns(altinnTaskExtension);

_paymentServiceMock
.Setup(x => x.GetPaymentStatus(It.IsAny<Instance>(), It.IsAny<ValidAltinnPaymentConfiguration>()))
.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<Stream>(),
taskId
),
Times.Never
);
}

[Fact]
public async Task End_PaymentNotCompleted_ShouldThrowException()
{
Expand All @@ -102,8 +138,8 @@ public async Task End_PaymentNotCompleted_ShouldThrowException()
_processReaderMock.Setup(x => x.GetAltinnTaskExtension(It.IsAny<string>())).Returns(altinnTaskExtension);

_paymentServiceMock
.Setup(x => x.IsPaymentCompleted(It.IsAny<Instance>(), It.IsAny<ValidAltinnPaymentConfiguration>()))
.ReturnsAsync(false);
.Setup(x => x.GetPaymentStatus(It.IsAny<Instance>(), It.IsAny<ValidAltinnPaymentConfiguration>()))
.ReturnsAsync(PaymentStatus.Created);

// Act and assert
_pdfServiceMock.Verify(x => x.GeneratePdf(instance, taskId, CancellationToken.None), Times.Never);
Expand Down Expand Up @@ -179,8 +215,8 @@ public async Task End_ValidConfiguration_ShouldNotThrow()
.Returns(new AltinnTaskExtension { PaymentConfiguration = CreatePaymentConfiguration() });

_paymentServiceMock
.Setup(ps => ps.IsPaymentCompleted(It.IsAny<Instance>(), It.IsAny<ValidAltinnPaymentConfiguration>()))
.ReturnsAsync(true);
.Setup(ps => ps.GetPaymentStatus(It.IsAny<Instance>(), It.IsAny<ValidAltinnPaymentConfiguration>()))
.ReturnsAsync(PaymentStatus.Paid);

using var memoryStream = new MemoryStream();
_pdfServiceMock
Expand Down

0 comments on commit e07f546

Please sign in to comment.