2024-03-29 16:18:10 +01:00
|
|
|
|
using Bit.Api.Billing.Controllers;
|
2024-06-03 17:00:52 +02:00
|
|
|
|
using Bit.Api.Billing.Models.Requests;
|
2024-04-16 19:55:00 +02:00
|
|
|
|
using Bit.Api.Billing.Models.Responses;
|
2024-03-29 16:18:10 +01:00
|
|
|
|
using Bit.Core;
|
2024-06-03 17:00:52 +02:00
|
|
|
|
using Bit.Core.AdminConsole.Entities.Provider;
|
|
|
|
|
using Bit.Core.AdminConsole.Enums.Provider;
|
|
|
|
|
using Bit.Core.AdminConsole.Repositories;
|
|
|
|
|
using Bit.Core.Billing.Constants;
|
2024-03-29 16:18:10 +01:00
|
|
|
|
using Bit.Core.Billing.Models;
|
2024-05-23 16:17:00 +02:00
|
|
|
|
using Bit.Core.Billing.Services;
|
2024-03-29 16:18:10 +01:00
|
|
|
|
using Bit.Core.Context;
|
|
|
|
|
using Bit.Core.Enums;
|
|
|
|
|
using Bit.Core.Services;
|
|
|
|
|
using Bit.Core.Utilities;
|
|
|
|
|
using Bit.Test.Common.AutoFixture;
|
|
|
|
|
using Bit.Test.Common.AutoFixture.Attributes;
|
|
|
|
|
using Microsoft.AspNetCore.Http.HttpResults;
|
|
|
|
|
using NSubstitute;
|
|
|
|
|
using NSubstitute.ReturnsExtensions;
|
|
|
|
|
using Stripe;
|
|
|
|
|
using Xunit;
|
|
|
|
|
|
|
|
|
|
namespace Bit.Api.Test.Billing.Controllers;
|
|
|
|
|
|
|
|
|
|
[ControllerCustomize(typeof(ProviderBillingController))]
|
|
|
|
|
[SutProviderCustomize]
|
|
|
|
|
public class ProviderBillingControllerTests
|
|
|
|
|
{
|
2024-06-05 19:33:28 +02:00
|
|
|
|
#region GetInvoices
|
|
|
|
|
|
|
|
|
|
[Theory, BitAutoData]
|
|
|
|
|
public async Task GetInvoices_Ok(
|
|
|
|
|
Provider provider,
|
|
|
|
|
SutProvider<ProviderBillingController> sutProvider)
|
|
|
|
|
{
|
|
|
|
|
ConfigureStableInputs(provider, sutProvider);
|
|
|
|
|
|
|
|
|
|
var invoices = new List<Invoice>
|
|
|
|
|
{
|
|
|
|
|
new ()
|
|
|
|
|
{
|
|
|
|
|
Created = new DateTime(2024, 7, 1),
|
|
|
|
|
Status = "draft",
|
|
|
|
|
Total = 100000,
|
|
|
|
|
HostedInvoiceUrl = "https://example.com/invoice/3",
|
|
|
|
|
InvoicePdf = "https://example.com/invoice/3/pdf"
|
|
|
|
|
},
|
|
|
|
|
new ()
|
|
|
|
|
{
|
|
|
|
|
Created = new DateTime(2024, 6, 1),
|
|
|
|
|
Number = "2",
|
|
|
|
|
Status = "open",
|
|
|
|
|
Total = 100000,
|
|
|
|
|
HostedInvoiceUrl = "https://example.com/invoice/2",
|
|
|
|
|
InvoicePdf = "https://example.com/invoice/2/pdf"
|
|
|
|
|
},
|
|
|
|
|
new ()
|
|
|
|
|
{
|
|
|
|
|
Created = new DateTime(2024, 5, 1),
|
|
|
|
|
Number = "1",
|
|
|
|
|
Status = "paid",
|
|
|
|
|
Total = 100000,
|
|
|
|
|
HostedInvoiceUrl = "https://example.com/invoice/1",
|
|
|
|
|
InvoicePdf = "https://example.com/invoice/1/pdf"
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
sutProvider.GetDependency<ISubscriberService>().GetInvoices(provider).Returns(invoices);
|
|
|
|
|
|
|
|
|
|
var result = await sutProvider.Sut.GetInvoicesAsync(provider.Id);
|
|
|
|
|
|
|
|
|
|
Assert.IsType<Ok<InvoicesResponse>>(result);
|
|
|
|
|
|
|
|
|
|
var response = ((Ok<InvoicesResponse>)result).Value;
|
|
|
|
|
|
|
|
|
|
Assert.Equal(2, response.Invoices.Count);
|
|
|
|
|
|
|
|
|
|
var openInvoice = response.Invoices.FirstOrDefault(i => i.Status == "open");
|
|
|
|
|
|
|
|
|
|
Assert.NotNull(openInvoice);
|
|
|
|
|
Assert.Equal(new DateTime(2024, 6, 1), openInvoice.Date);
|
|
|
|
|
Assert.Equal("2", openInvoice.Number);
|
|
|
|
|
Assert.Equal(1000, openInvoice.Total);
|
|
|
|
|
Assert.Equal("https://example.com/invoice/2", openInvoice.Url);
|
|
|
|
|
Assert.Equal("https://example.com/invoice/2/pdf", openInvoice.PdfUrl);
|
|
|
|
|
|
|
|
|
|
var paidInvoice = response.Invoices.FirstOrDefault(i => i.Status == "paid");
|
|
|
|
|
Assert.NotNull(paidInvoice);
|
|
|
|
|
Assert.Equal(new DateTime(2024, 5, 1), paidInvoice.Date);
|
|
|
|
|
Assert.Equal("1", paidInvoice.Number);
|
|
|
|
|
Assert.Equal(1000, paidInvoice.Total);
|
|
|
|
|
Assert.Equal("https://example.com/invoice/1", paidInvoice.Url);
|
|
|
|
|
Assert.Equal("https://example.com/invoice/1/pdf", paidInvoice.PdfUrl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region GetPaymentInformationAsync
|
|
|
|
|
|
|
|
|
|
[Theory, BitAutoData]
|
|
|
|
|
public async Task GetPaymentInformation_PaymentInformationNull_NotFound(
|
|
|
|
|
Provider provider,
|
|
|
|
|
SutProvider<ProviderBillingController> sutProvider)
|
|
|
|
|
{
|
|
|
|
|
ConfigureStableInputs(provider, sutProvider);
|
|
|
|
|
|
|
|
|
|
sutProvider.GetDependency<ISubscriberService>().GetPaymentInformation(provider).ReturnsNull();
|
|
|
|
|
|
|
|
|
|
var result = await sutProvider.Sut.GetSubscriptionAsync(provider.Id);
|
|
|
|
|
|
|
|
|
|
Assert.IsType<NotFound>(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Theory, BitAutoData]
|
|
|
|
|
public async Task GetPaymentInformation_Ok(
|
|
|
|
|
Provider provider,
|
|
|
|
|
SutProvider<ProviderBillingController> sutProvider)
|
|
|
|
|
{
|
|
|
|
|
ConfigureStableInputs(provider, sutProvider);
|
|
|
|
|
|
|
|
|
|
var maskedPaymentMethod = new MaskedPaymentMethodDTO(PaymentMethodType.Card, "VISA *1234", false);
|
|
|
|
|
|
|
|
|
|
var taxInformation =
|
|
|
|
|
new TaxInformationDTO("US", "12345", "123456789", "123 Example St.", null, "Example Town", "NY");
|
|
|
|
|
|
|
|
|
|
sutProvider.GetDependency<ISubscriberService>().GetPaymentInformation(provider).Returns(new PaymentInformationDTO(
|
|
|
|
|
100,
|
|
|
|
|
maskedPaymentMethod,
|
|
|
|
|
taxInformation));
|
|
|
|
|
|
|
|
|
|
var result = await sutProvider.Sut.GetPaymentInformationAsync(provider.Id);
|
|
|
|
|
|
|
|
|
|
Assert.IsType<Ok<PaymentInformationResponse>>(result);
|
|
|
|
|
|
|
|
|
|
var response = ((Ok<PaymentInformationResponse>)result).Value;
|
|
|
|
|
|
|
|
|
|
Assert.Equal(100, response.AccountCredit);
|
|
|
|
|
Assert.Equal(maskedPaymentMethod.Description, response.PaymentMethod.Description);
|
|
|
|
|
Assert.Equal(taxInformation.TaxId, response.TaxInformation.TaxId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region GetPaymentMethodAsync
|
|
|
|
|
|
|
|
|
|
[Theory, BitAutoData]
|
|
|
|
|
public async Task GetPaymentMethod_PaymentMethodNull_NotFound(
|
|
|
|
|
Provider provider,
|
|
|
|
|
SutProvider<ProviderBillingController> sutProvider)
|
|
|
|
|
{
|
|
|
|
|
ConfigureStableInputs(provider, sutProvider);
|
|
|
|
|
|
|
|
|
|
sutProvider.GetDependency<ISubscriberService>().GetPaymentMethod(provider).ReturnsNull();
|
|
|
|
|
|
|
|
|
|
var result = await sutProvider.Sut.GetSubscriptionAsync(provider.Id);
|
|
|
|
|
|
|
|
|
|
Assert.IsType<NotFound>(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Theory, BitAutoData]
|
|
|
|
|
public async Task GetPaymentMethod_Ok(
|
|
|
|
|
Provider provider,
|
|
|
|
|
SutProvider<ProviderBillingController> sutProvider)
|
|
|
|
|
{
|
|
|
|
|
ConfigureStableInputs(provider, sutProvider);
|
|
|
|
|
|
|
|
|
|
sutProvider.GetDependency<ISubscriberService>().GetPaymentMethod(provider).Returns(new MaskedPaymentMethodDTO(
|
|
|
|
|
PaymentMethodType.Card, "Description", false));
|
|
|
|
|
|
|
|
|
|
var result = await sutProvider.Sut.GetPaymentMethodAsync(provider.Id);
|
|
|
|
|
|
|
|
|
|
Assert.IsType<Ok<MaskedPaymentMethodResponse>>(result);
|
|
|
|
|
|
|
|
|
|
var response = ((Ok<MaskedPaymentMethodResponse>)result).Value;
|
|
|
|
|
|
|
|
|
|
Assert.Equal(PaymentMethodType.Card, response.Type);
|
|
|
|
|
Assert.Equal("Description", response.Description);
|
|
|
|
|
Assert.False(response.NeedsVerification);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2024-06-03 17:00:52 +02:00
|
|
|
|
#region GetSubscriptionAsync
|
2024-03-29 16:18:10 +01:00
|
|
|
|
[Theory, BitAutoData]
|
|
|
|
|
public async Task GetSubscriptionAsync_FFDisabled_NotFound(
|
|
|
|
|
Guid providerId,
|
|
|
|
|
SutProvider<ProviderBillingController> sutProvider)
|
|
|
|
|
{
|
|
|
|
|
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
|
|
|
|
.Returns(false);
|
|
|
|
|
|
|
|
|
|
var result = await sutProvider.Sut.GetSubscriptionAsync(providerId);
|
|
|
|
|
|
|
|
|
|
Assert.IsType<NotFound>(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Theory, BitAutoData]
|
2024-06-03 17:00:52 +02:00
|
|
|
|
public async Task GetSubscriptionAsync_NullProvider_NotFound(
|
2024-03-29 16:18:10 +01:00
|
|
|
|
Guid providerId,
|
|
|
|
|
SutProvider<ProviderBillingController> sutProvider)
|
|
|
|
|
{
|
|
|
|
|
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
|
|
|
|
.Returns(true);
|
|
|
|
|
|
2024-06-03 17:00:52 +02:00
|
|
|
|
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(providerId).ReturnsNull();
|
2024-03-29 16:18:10 +01:00
|
|
|
|
|
|
|
|
|
var result = await sutProvider.Sut.GetSubscriptionAsync(providerId);
|
|
|
|
|
|
2024-06-03 17:00:52 +02:00
|
|
|
|
Assert.IsType<NotFound>(result);
|
2024-03-29 16:18:10 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Theory, BitAutoData]
|
2024-06-03 17:00:52 +02:00
|
|
|
|
public async Task GetSubscriptionAsync_NotProviderAdmin_Unauthorized(
|
|
|
|
|
Provider provider,
|
2024-03-29 16:18:10 +01:00
|
|
|
|
SutProvider<ProviderBillingController> sutProvider)
|
|
|
|
|
{
|
|
|
|
|
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
|
|
|
|
.Returns(true);
|
|
|
|
|
|
2024-06-03 17:00:52 +02:00
|
|
|
|
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(provider.Id).Returns(provider);
|
2024-03-29 16:18:10 +01:00
|
|
|
|
|
2024-06-03 17:00:52 +02:00
|
|
|
|
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(provider.Id)
|
|
|
|
|
.Returns(false);
|
2024-03-29 16:18:10 +01:00
|
|
|
|
|
2024-06-03 17:00:52 +02:00
|
|
|
|
var result = await sutProvider.Sut.GetSubscriptionAsync(provider.Id);
|
2024-03-29 16:18:10 +01:00
|
|
|
|
|
2024-06-03 17:00:52 +02:00
|
|
|
|
Assert.IsType<UnauthorizedHttpResult>(result);
|
2024-03-29 16:18:10 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Theory, BitAutoData]
|
2024-06-03 17:00:52 +02:00
|
|
|
|
public async Task GetSubscriptionAsync_ProviderNotBillable_Unauthorized(
|
|
|
|
|
Provider provider,
|
2024-03-29 16:18:10 +01:00
|
|
|
|
SutProvider<ProviderBillingController> sutProvider)
|
|
|
|
|
{
|
|
|
|
|
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
|
|
|
|
.Returns(true);
|
|
|
|
|
|
2024-06-03 17:00:52 +02:00
|
|
|
|
provider.Type = ProviderType.Reseller;
|
|
|
|
|
provider.Status = ProviderStatusType.Created;
|
|
|
|
|
|
|
|
|
|
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(provider.Id).Returns(provider);
|
2024-03-29 16:18:10 +01:00
|
|
|
|
|
2024-06-03 17:00:52 +02:00
|
|
|
|
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(provider.Id)
|
|
|
|
|
.Returns(false);
|
|
|
|
|
|
|
|
|
|
var result = await sutProvider.Sut.GetSubscriptionAsync(provider.Id);
|
|
|
|
|
|
|
|
|
|
Assert.IsType<UnauthorizedHttpResult>(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Theory, BitAutoData]
|
|
|
|
|
public async Task GetSubscriptionAsync_NullConsolidatedBillingSubscription_NotFound(
|
|
|
|
|
Provider provider,
|
|
|
|
|
SutProvider<ProviderBillingController> sutProvider)
|
|
|
|
|
{
|
|
|
|
|
ConfigureStableInputs(provider, sutProvider);
|
|
|
|
|
|
|
|
|
|
sutProvider.GetDependency<IProviderBillingService>().GetConsolidatedBillingSubscription(provider).ReturnsNull();
|
|
|
|
|
|
|
|
|
|
var result = await sutProvider.Sut.GetSubscriptionAsync(provider.Id);
|
|
|
|
|
|
|
|
|
|
Assert.IsType<NotFound>(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Theory, BitAutoData]
|
|
|
|
|
public async Task GetSubscriptionAsync_Ok(
|
|
|
|
|
Provider provider,
|
|
|
|
|
SutProvider<ProviderBillingController> sutProvider)
|
|
|
|
|
{
|
|
|
|
|
ConfigureStableInputs(provider, sutProvider);
|
|
|
|
|
|
|
|
|
|
var configuredProviderPlans = new List<ConfiguredProviderPlanDTO>
|
2024-03-29 16:18:10 +01:00
|
|
|
|
{
|
2024-06-03 17:00:52 +02:00
|
|
|
|
new (Guid.NewGuid(), provider.Id, PlanType.TeamsMonthly, 50, 10, 30),
|
|
|
|
|
new (Guid.NewGuid(), provider.Id , PlanType.EnterpriseMonthly, 100, 0, 90)
|
2024-03-29 16:18:10 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var subscription = new Subscription
|
|
|
|
|
{
|
|
|
|
|
Status = "active",
|
|
|
|
|
CurrentPeriodEnd = new DateTime(2025, 1, 1),
|
|
|
|
|
Customer = new Customer { Discount = new Discount { Coupon = new Coupon { PercentOff = 10 } } }
|
|
|
|
|
};
|
|
|
|
|
|
2024-06-06 16:54:08 +02:00
|
|
|
|
DateTime? SuspensionDate = new DateTime();
|
|
|
|
|
DateTime? UnpaidPeriodEndDate = new DateTime();
|
|
|
|
|
var gracePeriod = 30;
|
2024-06-03 17:00:52 +02:00
|
|
|
|
var consolidatedBillingSubscription = new ConsolidatedBillingSubscriptionDTO(
|
|
|
|
|
configuredProviderPlans,
|
2024-06-06 16:54:08 +02:00
|
|
|
|
subscription,
|
|
|
|
|
SuspensionDate,
|
|
|
|
|
UnpaidPeriodEndDate);
|
2024-03-29 16:18:10 +01:00
|
|
|
|
|
2024-06-03 17:00:52 +02:00
|
|
|
|
sutProvider.GetDependency<IProviderBillingService>().GetConsolidatedBillingSubscription(provider)
|
|
|
|
|
.Returns(consolidatedBillingSubscription);
|
2024-03-29 16:18:10 +01:00
|
|
|
|
|
2024-06-03 17:00:52 +02:00
|
|
|
|
var result = await sutProvider.Sut.GetSubscriptionAsync(provider.Id);
|
2024-03-29 16:18:10 +01:00
|
|
|
|
|
2024-06-03 17:00:52 +02:00
|
|
|
|
Assert.IsType<Ok<ConsolidatedBillingSubscriptionResponse>>(result);
|
2024-03-29 16:18:10 +01:00
|
|
|
|
|
2024-06-03 17:00:52 +02:00
|
|
|
|
var response = ((Ok<ConsolidatedBillingSubscriptionResponse>)result).Value;
|
2024-03-29 16:18:10 +01:00
|
|
|
|
|
2024-06-03 17:00:52 +02:00
|
|
|
|
Assert.Equal(response.Status, subscription.Status);
|
|
|
|
|
Assert.Equal(response.CurrentPeriodEndDate, subscription.CurrentPeriodEnd);
|
|
|
|
|
Assert.Equal(response.DiscountPercentage, subscription.Customer!.Discount!.Coupon!.PercentOff);
|
2024-06-06 16:54:08 +02:00
|
|
|
|
Assert.Equal(response.CollectionMethod, subscription.CollectionMethod);
|
|
|
|
|
Assert.Equal(response.UnpaidPeriodEndDate, UnpaidPeriodEndDate);
|
|
|
|
|
Assert.Equal(response.GracePeriod, gracePeriod);
|
|
|
|
|
Assert.Equal(response.SuspensionDate, SuspensionDate);
|
2024-03-29 16:18:10 +01:00
|
|
|
|
|
|
|
|
|
var teamsPlan = StaticStore.GetPlan(PlanType.TeamsMonthly);
|
2024-06-03 17:00:52 +02:00
|
|
|
|
var providerTeamsPlan = response.Plans.FirstOrDefault(plan => plan.PlanName == teamsPlan.Name);
|
2024-03-29 16:18:10 +01:00
|
|
|
|
Assert.NotNull(providerTeamsPlan);
|
|
|
|
|
Assert.Equal(50, providerTeamsPlan.SeatMinimum);
|
|
|
|
|
Assert.Equal(10, providerTeamsPlan.PurchasedSeats);
|
|
|
|
|
Assert.Equal(30, providerTeamsPlan.AssignedSeats);
|
|
|
|
|
Assert.Equal(60 * teamsPlan.PasswordManager.SeatPrice, providerTeamsPlan.Cost);
|
|
|
|
|
Assert.Equal("Monthly", providerTeamsPlan.Cadence);
|
|
|
|
|
|
|
|
|
|
var enterprisePlan = StaticStore.GetPlan(PlanType.EnterpriseMonthly);
|
2024-06-03 17:00:52 +02:00
|
|
|
|
var providerEnterprisePlan = response.Plans.FirstOrDefault(plan => plan.PlanName == enterprisePlan.Name);
|
2024-03-29 16:18:10 +01:00
|
|
|
|
Assert.NotNull(providerEnterprisePlan);
|
|
|
|
|
Assert.Equal(100, providerEnterprisePlan.SeatMinimum);
|
|
|
|
|
Assert.Equal(0, providerEnterprisePlan.PurchasedSeats);
|
|
|
|
|
Assert.Equal(90, providerEnterprisePlan.AssignedSeats);
|
|
|
|
|
Assert.Equal(100 * enterprisePlan.PasswordManager.SeatPrice, providerEnterprisePlan.Cost);
|
|
|
|
|
Assert.Equal("Monthly", providerEnterprisePlan.Cadence);
|
|
|
|
|
}
|
2024-06-03 17:00:52 +02:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region GetTaxInformationAsync
|
|
|
|
|
|
|
|
|
|
[Theory, BitAutoData]
|
|
|
|
|
public async Task GetTaxInformation_TaxInformationNull_NotFound(
|
|
|
|
|
Provider provider,
|
|
|
|
|
SutProvider<ProviderBillingController> sutProvider)
|
|
|
|
|
{
|
|
|
|
|
ConfigureStableInputs(provider, sutProvider);
|
|
|
|
|
|
|
|
|
|
sutProvider.GetDependency<ISubscriberService>().GetTaxInformation(provider).ReturnsNull();
|
|
|
|
|
|
|
|
|
|
var result = await sutProvider.Sut.GetSubscriptionAsync(provider.Id);
|
|
|
|
|
|
|
|
|
|
Assert.IsType<NotFound>(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Theory, BitAutoData]
|
|
|
|
|
public async Task GetTaxInformation_Ok(
|
|
|
|
|
Provider provider,
|
|
|
|
|
SutProvider<ProviderBillingController> sutProvider)
|
|
|
|
|
{
|
|
|
|
|
ConfigureStableInputs(provider, sutProvider);
|
|
|
|
|
|
|
|
|
|
sutProvider.GetDependency<ISubscriberService>().GetTaxInformation(provider).Returns(new TaxInformationDTO(
|
|
|
|
|
"US",
|
|
|
|
|
"12345",
|
|
|
|
|
"123456789",
|
|
|
|
|
"123 Example St.",
|
|
|
|
|
null,
|
|
|
|
|
"Example Town",
|
|
|
|
|
"NY"));
|
|
|
|
|
|
|
|
|
|
var result = await sutProvider.Sut.GetTaxInformationAsync(provider.Id);
|
|
|
|
|
|
|
|
|
|
Assert.IsType<Ok<TaxInformationResponse>>(result);
|
|
|
|
|
|
|
|
|
|
var response = ((Ok<TaxInformationResponse>)result).Value;
|
|
|
|
|
|
|
|
|
|
Assert.Equal("US", response.Country);
|
|
|
|
|
Assert.Equal("12345", response.PostalCode);
|
|
|
|
|
Assert.Equal("123456789", response.TaxId);
|
|
|
|
|
Assert.Equal("123 Example St.", response.Line1);
|
|
|
|
|
Assert.Null(response.Line2);
|
|
|
|
|
Assert.Equal("Example Town", response.City);
|
|
|
|
|
Assert.Equal("NY", response.State);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region UpdatePaymentMethodAsync
|
|
|
|
|
|
|
|
|
|
[Theory, BitAutoData]
|
|
|
|
|
public async Task UpdatePaymentMethod_Ok(
|
|
|
|
|
Provider provider,
|
|
|
|
|
TokenizedPaymentMethodRequestBody requestBody,
|
|
|
|
|
SutProvider<ProviderBillingController> sutProvider)
|
|
|
|
|
{
|
|
|
|
|
ConfigureStableInputs(provider, sutProvider);
|
|
|
|
|
|
|
|
|
|
await sutProvider.Sut.UpdatePaymentMethodAsync(provider.Id, requestBody);
|
|
|
|
|
|
|
|
|
|
await sutProvider.GetDependency<ISubscriberService>().Received(1).UpdatePaymentMethod(
|
|
|
|
|
provider, Arg.Is<TokenizedPaymentMethodDTO>(
|
|
|
|
|
options => options.Type == requestBody.Type && options.Token == requestBody.Token));
|
|
|
|
|
|
|
|
|
|
await sutProvider.GetDependency<IStripeAdapter>().Received(1).SubscriptionUpdateAsync(
|
|
|
|
|
provider.GatewaySubscriptionId, Arg.Is<SubscriptionUpdateOptions>(
|
|
|
|
|
options => options.CollectionMethod == StripeConstants.CollectionMethod.ChargeAutomatically));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region UpdateTaxInformationAsync
|
|
|
|
|
|
|
|
|
|
[Theory, BitAutoData]
|
|
|
|
|
public async Task UpdateTaxInformation_Ok(
|
|
|
|
|
Provider provider,
|
|
|
|
|
TaxInformationRequestBody requestBody,
|
|
|
|
|
SutProvider<ProviderBillingController> sutProvider)
|
|
|
|
|
{
|
|
|
|
|
ConfigureStableInputs(provider, sutProvider);
|
|
|
|
|
|
|
|
|
|
await sutProvider.Sut.UpdateTaxInformationAsync(provider.Id, requestBody);
|
|
|
|
|
|
|
|
|
|
await sutProvider.GetDependency<ISubscriberService>().Received(1).UpdateTaxInformation(
|
|
|
|
|
provider, Arg.Is<TaxInformationDTO>(
|
|
|
|
|
options =>
|
|
|
|
|
options.Country == requestBody.Country &&
|
|
|
|
|
options.PostalCode == requestBody.PostalCode &&
|
|
|
|
|
options.TaxId == requestBody.TaxId &&
|
|
|
|
|
options.Line1 == requestBody.Line1 &&
|
|
|
|
|
options.Line2 == requestBody.Line2 &&
|
|
|
|
|
options.City == requestBody.City &&
|
|
|
|
|
options.State == requestBody.State));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region VerifyBankAccount
|
|
|
|
|
|
|
|
|
|
[Theory, BitAutoData]
|
|
|
|
|
public async Task VerifyBankAccount_Ok(
|
|
|
|
|
Provider provider,
|
|
|
|
|
VerifyBankAccountRequestBody requestBody,
|
|
|
|
|
SutProvider<ProviderBillingController> sutProvider)
|
|
|
|
|
{
|
|
|
|
|
ConfigureStableInputs(provider, sutProvider);
|
|
|
|
|
|
|
|
|
|
var result = await sutProvider.Sut.VerifyBankAccountAsync(provider.Id, requestBody);
|
|
|
|
|
|
|
|
|
|
Assert.IsType<Ok>(result);
|
|
|
|
|
|
|
|
|
|
await sutProvider.GetDependency<ISubscriberService>().Received(1).VerifyBankAccount(
|
|
|
|
|
provider,
|
|
|
|
|
(requestBody.Amount1, requestBody.Amount2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
private static void ConfigureStableInputs(
|
|
|
|
|
Provider provider,
|
|
|
|
|
SutProvider<ProviderBillingController> sutProvider)
|
|
|
|
|
{
|
|
|
|
|
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
|
|
|
|
.Returns(true);
|
|
|
|
|
|
|
|
|
|
provider.Type = ProviderType.Msp;
|
|
|
|
|
provider.Status = ProviderStatusType.Billable;
|
|
|
|
|
|
|
|
|
|
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(provider.Id).Returns(provider);
|
|
|
|
|
|
|
|
|
|
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(provider.Id)
|
|
|
|
|
.Returns(true);
|
|
|
|
|
}
|
2024-03-29 16:18:10 +01:00
|
|
|
|
}
|