2019-01-14 22:43:29 +01:00
|
|
|
using System;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using BTCPayServer.Controllers;
|
2021-12-16 17:37:19 +01:00
|
|
|
using BTCPayServer.Data;
|
2019-01-14 22:43:29 +01:00
|
|
|
using BTCPayServer.Models.PaymentRequestViewModels;
|
|
|
|
using BTCPayServer.Services.Invoices;
|
2020-08-04 07:55:13 +02:00
|
|
|
using BTCPayServer.Services.PaymentRequests;
|
2019-01-14 22:43:29 +01:00
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
using NBitpayClient;
|
|
|
|
using Xunit;
|
|
|
|
using Xunit.Abstractions;
|
|
|
|
|
|
|
|
namespace BTCPayServer.Tests
|
|
|
|
{
|
2021-11-23 05:57:45 +01:00
|
|
|
[Collection(nameof(NonParallelizableCollectionDefinition))]
|
2021-11-22 09:16:08 +01:00
|
|
|
public class PaymentRequestTests : UnitTestBase
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
2021-11-22 09:16:08 +01:00
|
|
|
public PaymentRequestTests(ITestOutputHelper helper) : base(helper)
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
[Fact]
|
|
|
|
[Trait("Integration", "Integration")]
|
2019-10-07 09:04:25 +02:00
|
|
|
public async Task CanCreateViewUpdateAndDeletePaymentRequest()
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
2022-01-14 09:50:29 +01:00
|
|
|
using var tester = CreateServerTester();
|
|
|
|
await tester.StartAsync();
|
|
|
|
var user = tester.NewAccount();
|
|
|
|
await user.GrantAccessAsync();
|
|
|
|
user.RegisterDerivationScheme("BTC");
|
2019-01-14 22:43:29 +01:00
|
|
|
|
2022-01-14 09:50:29 +01:00
|
|
|
var user2 = tester.NewAccount();
|
2021-12-31 08:59:02 +01:00
|
|
|
|
2022-01-14 09:50:29 +01:00
|
|
|
await user2.GrantAccessAsync();
|
2019-01-14 22:43:29 +01:00
|
|
|
|
2022-01-14 09:50:29 +01:00
|
|
|
var paymentRequestController = user.GetController<UIPaymentRequestController>();
|
|
|
|
var guestpaymentRequestController = user2.GetController<UIPaymentRequestController>();
|
2019-01-14 22:43:29 +01:00
|
|
|
|
2022-01-14 09:50:29 +01:00
|
|
|
var request = new UpdatePaymentRequestViewModel
|
|
|
|
{
|
|
|
|
Title = "original juice",
|
|
|
|
Currency = "BTC",
|
|
|
|
Amount = 1,
|
|
|
|
StoreId = user.StoreId,
|
|
|
|
Description = "description"
|
|
|
|
};
|
|
|
|
var id = Assert
|
|
|
|
.IsType<RedirectToActionResult>(await paymentRequestController.EditPaymentRequest(null, request))
|
|
|
|
.RouteValues.Values.Last().ToString();
|
|
|
|
|
|
|
|
paymentRequestController.HttpContext.SetPaymentRequestData(new PaymentRequestData { Id = id, StoreDataId = request.StoreId });
|
|
|
|
|
|
|
|
// Permission guard for guests editing
|
|
|
|
Assert
|
|
|
|
.IsType<NotFoundResult>(guestpaymentRequestController.EditPaymentRequest(user.StoreId, id));
|
|
|
|
|
|
|
|
request.Title = "update";
|
|
|
|
Assert.IsType<RedirectToActionResult>(await paymentRequestController.EditPaymentRequest(id, request));
|
|
|
|
|
|
|
|
Assert.Equal(request.Title,
|
|
|
|
Assert.IsType<ViewPaymentRequestViewModel>(Assert
|
|
|
|
.IsType<ViewResult>(await paymentRequestController.ViewPaymentRequest(id)).Model).Title);
|
2019-01-14 22:43:29 +01:00
|
|
|
|
2022-01-14 09:50:29 +01:00
|
|
|
Assert.False(string.IsNullOrEmpty(id));
|
2021-12-31 08:59:02 +01:00
|
|
|
|
2022-01-14 09:50:29 +01:00
|
|
|
Assert.IsType<ViewPaymentRequestViewModel>(Assert
|
|
|
|
.IsType<ViewResult>(await paymentRequestController.ViewPaymentRequest(id)).Model);
|
2019-01-14 22:43:29 +01:00
|
|
|
|
2022-01-14 09:50:29 +01:00
|
|
|
// Archive
|
|
|
|
Assert
|
|
|
|
.IsType<RedirectToActionResult>(await paymentRequestController.TogglePaymentRequestArchival(id));
|
|
|
|
Assert.True(Assert
|
|
|
|
.IsType<ViewPaymentRequestViewModel>(Assert
|
|
|
|
.IsType<ViewResult>(await paymentRequestController.ViewPaymentRequest(id)).Model).Archived);
|
2020-06-28 10:55:27 +02:00
|
|
|
|
2022-01-14 09:50:29 +01:00
|
|
|
Assert.Empty(Assert
|
|
|
|
.IsType<ListPaymentRequestsViewModel>(Assert
|
|
|
|
.IsType<ViewResult>(await paymentRequestController.GetPaymentRequests(user.StoreId)).Model).Items);
|
2019-01-14 22:43:29 +01:00
|
|
|
|
2022-01-14 09:50:29 +01:00
|
|
|
// Unarchive
|
|
|
|
Assert
|
|
|
|
.IsType<RedirectToActionResult>(await paymentRequestController.TogglePaymentRequestArchival(id));
|
2019-01-14 22:43:29 +01:00
|
|
|
|
2022-01-14 09:50:29 +01:00
|
|
|
Assert.False(Assert
|
|
|
|
.IsType<ViewPaymentRequestViewModel>(Assert
|
|
|
|
.IsType<ViewResult>(await paymentRequestController.ViewPaymentRequest(id)).Model).Archived);
|
|
|
|
|
|
|
|
Assert.Single(Assert
|
|
|
|
.IsType<ListPaymentRequestsViewModel>(Assert
|
|
|
|
.IsType<ViewResult>(await paymentRequestController.GetPaymentRequests(user.StoreId)).Model).Items);
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
|
2019-04-05 09:28:18 +02:00
|
|
|
[Fact(Timeout = 60 * 2 * 1000)]
|
2019-01-14 22:43:29 +01:00
|
|
|
[Trait("Integration", "Integration")]
|
|
|
|
public async Task CanPayPaymentRequestWhenPossible()
|
|
|
|
{
|
2022-01-14 09:50:29 +01:00
|
|
|
using var tester = CreateServerTester();
|
|
|
|
await tester.StartAsync();
|
|
|
|
var user = tester.NewAccount();
|
|
|
|
await user.GrantAccessAsync();
|
|
|
|
user.RegisterDerivationScheme("BTC");
|
|
|
|
|
|
|
|
var paymentRequestController = user.GetController<UIPaymentRequestController>();
|
|
|
|
|
|
|
|
Assert.IsType<NotFoundResult>(
|
|
|
|
await paymentRequestController.PayPaymentRequest(Guid.NewGuid().ToString()));
|
|
|
|
|
|
|
|
|
|
|
|
var request = new UpdatePaymentRequestViewModel()
|
2019-01-14 22:43:29 +01:00
|
|
|
{
|
2022-01-14 09:50:29 +01:00
|
|
|
Title = "original juice",
|
|
|
|
Currency = "BTC",
|
|
|
|
Amount = 1,
|
|
|
|
StoreId = user.StoreId,
|
|
|
|
Description = "description"
|
|
|
|
};
|
|
|
|
var response = Assert
|
|
|
|
.IsType<RedirectToActionResult>(paymentRequestController.EditPaymentRequest(null, request).Result)
|
|
|
|
.RouteValues.Last();
|
|
|
|
|
|
|
|
var invoiceId = Assert
|
|
|
|
.IsType<OkObjectResult>(
|
|
|
|
await paymentRequestController.PayPaymentRequest(response.Value.ToString(), false)).Value
|
|
|
|
.ToString();
|
|
|
|
|
|
|
|
var actionResult = Assert
|
|
|
|
.IsType<RedirectToActionResult>(
|
|
|
|
await paymentRequestController.PayPaymentRequest(response.Value.ToString()));
|
|
|
|
|
|
|
|
Assert.Equal("Checkout", actionResult.ActionName);
|
|
|
|
Assert.Equal("UIInvoice", actionResult.ControllerName);
|
|
|
|
Assert.Contains(actionResult.RouteValues,
|
|
|
|
pair => pair.Key == "Id" && pair.Value.ToString() == invoiceId);
|
|
|
|
|
|
|
|
var invoice = user.BitPay.GetInvoice(invoiceId, Facade.Merchant);
|
|
|
|
Assert.Equal(1, invoice.Price);
|
|
|
|
|
|
|
|
request = new UpdatePaymentRequestViewModel()
|
|
|
|
{
|
|
|
|
Title = "original juice with expiry",
|
|
|
|
Currency = "BTC",
|
|
|
|
Amount = 1,
|
|
|
|
ExpiryDate = DateTime.Today.Subtract(TimeSpan.FromDays(2)),
|
|
|
|
StoreId = user.StoreId,
|
|
|
|
Description = "description"
|
|
|
|
};
|
|
|
|
|
|
|
|
response = Assert
|
|
|
|
.IsType<RedirectToActionResult>(paymentRequestController.EditPaymentRequest(null, request).Result)
|
|
|
|
.RouteValues.Last();
|
|
|
|
|
|
|
|
Assert
|
|
|
|
.IsType<BadRequestObjectResult>(
|
|
|
|
await paymentRequestController.PayPaymentRequest(response.Value.ToString(), false));
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
2020-06-28 10:55:27 +02:00
|
|
|
|
2019-05-07 10:26:40 +02:00
|
|
|
[Fact(Timeout = 60 * 2 * 1000)]
|
|
|
|
[Trait("Integration", "Integration")]
|
|
|
|
public async Task CanCancelPaymentWhenPossible()
|
|
|
|
{
|
2022-01-14 09:50:29 +01:00
|
|
|
using var tester = CreateServerTester();
|
|
|
|
await tester.StartAsync();
|
|
|
|
var user = tester.NewAccount();
|
|
|
|
user.GrantAccess();
|
|
|
|
user.RegisterDerivationScheme("BTC");
|
|
|
|
|
|
|
|
var paymentRequestController = user.GetController<UIPaymentRequestController>();
|
|
|
|
|
|
|
|
Assert.IsType<NotFoundResult>(await
|
|
|
|
paymentRequestController.CancelUnpaidPendingInvoice(Guid.NewGuid().ToString(), false));
|
|
|
|
|
|
|
|
var request = new UpdatePaymentRequestViewModel()
|
|
|
|
{
|
|
|
|
Title = "original juice",
|
|
|
|
Currency = "BTC",
|
|
|
|
Amount = 1,
|
|
|
|
StoreId = user.StoreId,
|
|
|
|
Description = "description"
|
|
|
|
};
|
|
|
|
var response = Assert
|
|
|
|
.IsType<RedirectToActionResult>(paymentRequestController.EditPaymentRequest(null, request).Result)
|
|
|
|
.RouteValues.Last();
|
|
|
|
var invoiceId = response.Value.ToString();
|
|
|
|
await paymentRequestController.PayPaymentRequest(invoiceId, false);
|
|
|
|
Assert.IsType<BadRequestObjectResult>(await
|
|
|
|
paymentRequestController.CancelUnpaidPendingInvoice(invoiceId, false));
|
|
|
|
|
|
|
|
request.AllowCustomPaymentAmounts = true;
|
|
|
|
|
|
|
|
response = Assert
|
|
|
|
.IsType<RedirectToActionResult>(paymentRequestController.EditPaymentRequest(null, request).Result)
|
|
|
|
.RouteValues.Last();
|
|
|
|
|
|
|
|
var paymentRequestId = response.Value.ToString();
|
|
|
|
|
|
|
|
invoiceId = Assert
|
|
|
|
.IsType<OkObjectResult>(await paymentRequestController.PayPaymentRequest(paymentRequestId, false))
|
|
|
|
.Value
|
|
|
|
.ToString();
|
|
|
|
|
|
|
|
var actionResult = Assert
|
|
|
|
.IsType<RedirectToActionResult>(
|
|
|
|
await paymentRequestController.PayPaymentRequest(response.Value.ToString()));
|
|
|
|
|
|
|
|
Assert.Equal("Checkout", actionResult.ActionName);
|
|
|
|
Assert.Equal("UIInvoice", actionResult.ControllerName);
|
|
|
|
Assert.Contains(actionResult.RouteValues,
|
|
|
|
pair => pair.Key == "Id" && pair.Value.ToString() == invoiceId);
|
|
|
|
|
|
|
|
var invoice = user.BitPay.GetInvoice(invoiceId, Facade.Merchant);
|
|
|
|
Assert.Equal(InvoiceState.ToString(InvoiceStatusLegacy.New), invoice.Status);
|
|
|
|
Assert.IsType<OkObjectResult>(await
|
|
|
|
paymentRequestController.CancelUnpaidPendingInvoice(paymentRequestId, false));
|
|
|
|
|
|
|
|
invoice = user.BitPay.GetInvoice(invoiceId, Facade.Merchant);
|
|
|
|
Assert.Equal(InvoiceState.ToString(InvoiceStatusLegacy.Invalid), invoice.Status);
|
|
|
|
|
|
|
|
Assert.IsType<BadRequestObjectResult>(await
|
|
|
|
paymentRequestController.CancelUnpaidPendingInvoice(paymentRequestId, false));
|
|
|
|
|
|
|
|
invoiceId = Assert
|
|
|
|
.IsType<OkObjectResult>(await paymentRequestController.PayPaymentRequest(paymentRequestId, false))
|
|
|
|
.Value
|
|
|
|
.ToString();
|
|
|
|
|
|
|
|
await user.BitPay.GetInvoiceAsync(invoiceId, Facade.Merchant);
|
|
|
|
|
|
|
|
//a hack to generate invoices for the payment request is to manually create an invoice with an order id that matches:
|
|
|
|
user.BitPay.CreateInvoice(new Invoice(1, "USD")
|
2019-05-07 10:26:40 +02:00
|
|
|
{
|
2022-01-14 09:50:29 +01:00
|
|
|
OrderId = PaymentRequestRepository.GetOrderIdForPaymentRequest(paymentRequestId)
|
|
|
|
});
|
|
|
|
//shouldn't crash
|
|
|
|
await paymentRequestController.ViewPaymentRequest(paymentRequestId);
|
|
|
|
await paymentRequestController.CancelUnpaidPendingInvoice(paymentRequestId);
|
2019-05-07 10:26:40 +02:00
|
|
|
}
|
2019-01-14 22:43:29 +01:00
|
|
|
}
|
|
|
|
}
|