mirror of
https://github.com/bitwarden/server
synced 2026-01-05 10:03:23 +00:00
[PM-24616] refactor stripe adapter (#6527)
* move billing services+tests to billing namespaces * reorganized methods in file and added comment headers * renamed StripeAdapter methods for better clarity * clean up redundant qualifiers * Upgrade Stripe.net to v48.4.0 * Update PreviewTaxAmountCommand * Remove unused UpcomingInvoiceOptionExtensions * Added SubscriptionExtensions with GetCurrentPeriodEnd * Update PremiumUserBillingService * Update OrganizationBillingService * Update GetOrganizationWarningsQuery * Update BillingHistoryInfo * Update SubscriptionInfo * Remove unused Sql Billing folder * Update StripeAdapter * Update StripePaymentService * Update InvoiceCreatedHandler * Update PaymentFailedHandler * Update PaymentSucceededHandler * Update ProviderEventService * Update StripeEventUtilityService * Update SubscriptionDeletedHandler * Update SubscriptionUpdatedHandler * Update UpcomingInvoiceHandler * Update ProviderSubscriptionResponse * Remove unused Stripe Subscriptions Admin Tool * Update RemoveOrganizationFromProviderCommand * Update ProviderBillingService * Update RemoveOrganizatinoFromProviderCommandTests * Update PreviewTaxAmountCommandTests * Update GetCloudOrganizationLicenseQueryTests * Update GetOrganizationWarningsQueryTests * Update StripePaymentServiceTests * Update ProviderBillingControllerTests * Update ProviderEventServiceTests * Update SubscriptionDeletedHandlerTests * Update SubscriptionUpdatedHandlerTests * Resolve Billing test failures I completely removed tests for the StripeEventService as they were using a system I setup a while back that read JSON files of the Stripe event structure. I did not anticipate how frequently these structures would change with each API version and the cost of trying to update these specific JSON files to test a very static data retrieval service far outweigh the benefit. * Resolve Core test failures * Run dotnet format * Remove unused provider migration * Fixed failing tests * Run dotnet format * Replace the old webhook secret key with new one (#6223) * Fix compilation failures in additions * Run dotnet format * Bump Stripe API version * Fix recent addition: CreatePremiumCloudHostedSubscriptionCommand * Fix new code in main according to Stripe update * Fix InvoiceExtensions * Bump SDK version to match API Version * cleanup * fixing items missed after the merge * use expression body for all simple returns * forgot fixes, format, and pr feedback * claude pr feedback * pr feedback and cleanup * more claude feedback --------- Co-authored-by: Alex Morask <amorask@bitwarden.com> Co-authored-by: cyprain-okeke <108260115+cyprain-okeke@users.noreply.github.com>
This commit is contained in:
@@ -28,7 +28,7 @@ public class AccountsControllerTests : IDisposable
|
||||
|
||||
private readonly IUserService _userService;
|
||||
private readonly IFeatureService _featureService;
|
||||
private readonly IPaymentService _paymentService;
|
||||
private readonly IStripePaymentService _paymentService;
|
||||
private readonly ITwoFactorIsEnabledQuery _twoFactorIsEnabledQuery;
|
||||
private readonly IUserAccountKeysQuery _userAccountKeysQuery;
|
||||
private readonly ILicensingService _licensingService;
|
||||
@@ -39,7 +39,7 @@ public class AccountsControllerTests : IDisposable
|
||||
{
|
||||
_userService = Substitute.For<IUserService>();
|
||||
_featureService = Substitute.For<IFeatureService>();
|
||||
_paymentService = Substitute.For<IPaymentService>();
|
||||
_paymentService = Substitute.For<IStripePaymentService>();
|
||||
_twoFactorIsEnabledQuery = Substitute.For<ITwoFactorIsEnabledQuery>();
|
||||
_userAccountKeysQuery = Substitute.For<IUserAccountKeysQuery>();
|
||||
_licensingService = Substitute.For<ILicensingService>();
|
||||
|
||||
@@ -3,9 +3,9 @@ using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Billing.Models;
|
||||
using Bit.Core.Billing.Organizations.Models;
|
||||
using Bit.Core.Billing.Organizations.Services;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
@@ -103,7 +103,7 @@ public class OrganizationBillingControllerTests
|
||||
// Manually create a BillingHistoryInfo object to avoid requiring AutoFixture to create HttpResponseHeaders
|
||||
var billingInfo = new BillingHistoryInfo();
|
||||
|
||||
sutProvider.GetDependency<IPaymentService>().GetBillingHistoryAsync(organization).Returns(billingInfo);
|
||||
sutProvider.GetDependency<IStripePaymentService>().GetBillingHistoryAsync(organization).Returns(billingInfo);
|
||||
|
||||
// Act
|
||||
var result = await sutProvider.Sut.GetHistoryAsync(organizationId);
|
||||
|
||||
@@ -37,7 +37,7 @@ public class OrganizationsControllerTests : IDisposable
|
||||
private readonly IOrganizationRepository _organizationRepository;
|
||||
private readonly IOrganizationService _organizationService;
|
||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||
private readonly IPaymentService _paymentService;
|
||||
private readonly IStripePaymentService _paymentService;
|
||||
private readonly ISsoConfigRepository _ssoConfigRepository;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IGetCloudOrganizationLicenseQuery _getCloudOrganizationLicenseQuery;
|
||||
@@ -59,7 +59,7 @@ public class OrganizationsControllerTests : IDisposable
|
||||
_organizationRepository = Substitute.For<IOrganizationRepository>();
|
||||
_organizationService = Substitute.For<IOrganizationService>();
|
||||
_organizationUserRepository = Substitute.For<IOrganizationUserRepository>();
|
||||
_paymentService = Substitute.For<IPaymentService>();
|
||||
_paymentService = Substitute.For<IStripePaymentService>();
|
||||
Substitute.For<IPolicyRepository>();
|
||||
_ssoConfigRepository = Substitute.For<ISsoConfigRepository>();
|
||||
Substitute.For<ISsoConfigService>();
|
||||
|
||||
@@ -10,10 +10,10 @@ using Bit.Core.Billing.Pricing;
|
||||
using Bit.Core.Billing.Providers.Entities;
|
||||
using Bit.Core.Billing.Providers.Repositories;
|
||||
using Bit.Core.Billing.Providers.Services;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Models.Api;
|
||||
using Bit.Core.Models.BitStripe;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Test.Billing.Mocks;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
@@ -121,7 +121,7 @@ public class ProviderBillingControllerTests
|
||||
}
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().InvoiceListAsync(Arg.Is<StripeInvoiceListOptions>(
|
||||
sutProvider.GetDependency<IStripeAdapter>().ListInvoicesAsync(Arg.Is<StripeInvoiceListOptions>(
|
||||
options =>
|
||||
options.Customer == provider.GatewayCustomerId)).Returns(invoices);
|
||||
|
||||
@@ -301,7 +301,7 @@ public class ProviderBillingControllerTests
|
||||
Status = "unpaid"
|
||||
};
|
||||
|
||||
stripeAdapter.SubscriptionGetAsync(provider.GatewaySubscriptionId, Arg.Is<SubscriptionGetOptions>(
|
||||
stripeAdapter.GetSubscriptionAsync(provider.GatewaySubscriptionId, Arg.Is<SubscriptionGetOptions>(
|
||||
options =>
|
||||
options.Expand.Contains("customer.tax_ids") &&
|
||||
options.Expand.Contains("discounts") &&
|
||||
@@ -318,7 +318,7 @@ public class ProviderBillingControllerTests
|
||||
Attempted = true
|
||||
};
|
||||
|
||||
stripeAdapter.InvoiceSearchAsync(Arg.Is<InvoiceSearchOptions>(
|
||||
stripeAdapter.SearchInvoiceAsync(Arg.Is<InvoiceSearchOptions>(
|
||||
options => options.Query == $"subscription:'{subscription.Id}' status:'open'"))
|
||||
.Returns([overdueInvoice]);
|
||||
|
||||
@@ -351,7 +351,7 @@ public class ProviderBillingControllerTests
|
||||
var plan = MockPlans.Get(providerPlan.PlanType);
|
||||
sutProvider.GetDependency<IPricingClient>().GetPlanOrThrow(providerPlan.PlanType).Returns(plan);
|
||||
var priceId = ProviderPriceAdapter.GetPriceId(provider, subscription, providerPlan.PlanType);
|
||||
sutProvider.GetDependency<IStripeAdapter>().PriceGetAsync(priceId)
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetPriceAsync(priceId)
|
||||
.Returns(new Price
|
||||
{
|
||||
UnitAmountDecimal = plan.PasswordManager.ProviderPortalSeatPrice * 100
|
||||
@@ -459,13 +459,13 @@ public class ProviderBillingControllerTests
|
||||
Status = "active"
|
||||
};
|
||||
|
||||
stripeAdapter.SubscriptionGetAsync(provider.GatewaySubscriptionId, Arg.Is<SubscriptionGetOptions>(
|
||||
stripeAdapter.GetSubscriptionAsync(provider.GatewaySubscriptionId, Arg.Is<SubscriptionGetOptions>(
|
||||
options =>
|
||||
options.Expand.Contains("customer.tax_ids") &&
|
||||
options.Expand.Contains("discounts") &&
|
||||
options.Expand.Contains("test_clock"))).Returns(subscription);
|
||||
|
||||
stripeAdapter.InvoiceSearchAsync(Arg.Is<InvoiceSearchOptions>(
|
||||
stripeAdapter.SearchInvoiceAsync(Arg.Is<InvoiceSearchOptions>(
|
||||
options => options.Query == $"subscription:'{subscription.Id}' status:'open'"))
|
||||
.Returns([]);
|
||||
|
||||
@@ -498,7 +498,7 @@ public class ProviderBillingControllerTests
|
||||
var plan = MockPlans.Get(providerPlan.PlanType);
|
||||
sutProvider.GetDependency<IPricingClient>().GetPlanOrThrow(providerPlan.PlanType).Returns(plan);
|
||||
var priceId = ProviderPriceAdapter.GetPriceId(provider, subscription, providerPlan.PlanType);
|
||||
sutProvider.GetDependency<IStripeAdapter>().PriceGetAsync(priceId)
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetPriceAsync(priceId)
|
||||
.Returns(new Price
|
||||
{
|
||||
UnitAmountDecimal = plan.PasswordManager.ProviderPortalSeatPrice * 100
|
||||
|
||||
@@ -31,7 +31,7 @@ public class BitPayControllerTests
|
||||
private readonly IUserRepository _userRepository = Substitute.For<IUserRepository>();
|
||||
private readonly IProviderRepository _providerRepository = Substitute.For<IProviderRepository>();
|
||||
private readonly IMailService _mailService = Substitute.For<IMailService>();
|
||||
private readonly IPaymentService _paymentService = Substitute.For<IPaymentService>();
|
||||
private readonly IStripePaymentService _paymentService = Substitute.For<IStripePaymentService>();
|
||||
|
||||
private readonly IPremiumUserBillingService _premiumUserBillingService =
|
||||
Substitute.For<IPremiumUserBillingService>();
|
||||
|
||||
@@ -28,7 +28,7 @@ public class PayPalControllerTests(ITestOutputHelper testOutputHelper)
|
||||
private readonly IOptions<BillingSettings> _billingSettings = Substitute.For<IOptions<BillingSettings>>();
|
||||
private readonly IMailService _mailService = Substitute.For<IMailService>();
|
||||
private readonly IOrganizationRepository _organizationRepository = Substitute.For<IOrganizationRepository>();
|
||||
private readonly IPaymentService _paymentService = Substitute.For<IPaymentService>();
|
||||
private readonly IStripePaymentService _paymentService = Substitute.For<IStripePaymentService>();
|
||||
private readonly ITransactionRepository _transactionRepository = Substitute.For<ITransactionRepository>();
|
||||
private readonly IUserRepository _userRepository = Substitute.For<IUserRepository>();
|
||||
private readonly IProviderRepository _providerRepository = Substitute.For<IProviderRepository>();
|
||||
|
||||
@@ -4,8 +4,8 @@ using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Entities.Provider;
|
||||
using Bit.Core.AdminConsole.Repositories;
|
||||
using Bit.Core.Billing.Caches;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using NSubstitute;
|
||||
using Stripe;
|
||||
using Xunit;
|
||||
@@ -61,7 +61,7 @@ public class SetupIntentSucceededHandlerTests
|
||||
|
||||
// Assert
|
||||
await _setupIntentCache.DidNotReceiveWithAnyArgs().GetSubscriberIdForSetupIntent(Arg.Any<string>());
|
||||
await _stripeAdapter.DidNotReceiveWithAnyArgs().PaymentMethodAttachAsync(
|
||||
await _stripeAdapter.DidNotReceiveWithAnyArgs().AttachPaymentMethodAsync(
|
||||
Arg.Any<string>(), Arg.Any<PaymentMethodAttachOptions>());
|
||||
await _pushNotificationAdapter.DidNotReceiveWithAnyArgs().NotifyBankAccountVerifiedAsync(Arg.Any<Organization>());
|
||||
await _pushNotificationAdapter.DidNotReceiveWithAnyArgs().NotifyBankAccountVerifiedAsync(Arg.Any<Provider>());
|
||||
@@ -86,7 +86,7 @@ public class SetupIntentSucceededHandlerTests
|
||||
await _handler.HandleAsync(_mockEvent);
|
||||
|
||||
// Assert
|
||||
await _stripeAdapter.DidNotReceiveWithAnyArgs().PaymentMethodAttachAsync(
|
||||
await _stripeAdapter.DidNotReceiveWithAnyArgs().AttachPaymentMethodAsync(
|
||||
Arg.Any<string>(), Arg.Any<PaymentMethodAttachOptions>());
|
||||
await _pushNotificationAdapter.DidNotReceiveWithAnyArgs().NotifyBankAccountVerifiedAsync(Arg.Any<Organization>());
|
||||
await _pushNotificationAdapter.DidNotReceiveWithAnyArgs().NotifyBankAccountVerifiedAsync(Arg.Any<Provider>());
|
||||
@@ -116,7 +116,7 @@ public class SetupIntentSucceededHandlerTests
|
||||
await _handler.HandleAsync(_mockEvent);
|
||||
|
||||
// Assert
|
||||
await _stripeAdapter.Received(1).PaymentMethodAttachAsync(
|
||||
await _stripeAdapter.Received(1).AttachPaymentMethodAsync(
|
||||
"pm_test",
|
||||
Arg.Is<PaymentMethodAttachOptions>(o => o.Customer == organization.GatewayCustomerId));
|
||||
|
||||
@@ -151,7 +151,7 @@ public class SetupIntentSucceededHandlerTests
|
||||
await _handler.HandleAsync(_mockEvent);
|
||||
|
||||
// Assert
|
||||
await _stripeAdapter.Received(1).PaymentMethodAttachAsync(
|
||||
await _stripeAdapter.Received(1).AttachPaymentMethodAsync(
|
||||
"pm_test",
|
||||
Arg.Is<PaymentMethodAttachOptions>(o => o.Customer == provider.GatewayCustomerId));
|
||||
|
||||
@@ -183,7 +183,7 @@ public class SetupIntentSucceededHandlerTests
|
||||
await _handler.HandleAsync(_mockEvent);
|
||||
|
||||
// Assert
|
||||
await _stripeAdapter.DidNotReceiveWithAnyArgs().PaymentMethodAttachAsync(
|
||||
await _stripeAdapter.DidNotReceiveWithAnyArgs().AttachPaymentMethodAsync(
|
||||
Arg.Any<string>(), Arg.Any<PaymentMethodAttachOptions>());
|
||||
await _pushNotificationAdapter.DidNotReceiveWithAnyArgs().NotifyBankAccountVerifiedAsync(Arg.Any<Organization>());
|
||||
await _pushNotificationAdapter.DidNotReceiveWithAnyArgs().NotifyBankAccountVerifiedAsync(Arg.Any<Provider>());
|
||||
@@ -216,7 +216,7 @@ public class SetupIntentSucceededHandlerTests
|
||||
await _handler.HandleAsync(_mockEvent);
|
||||
|
||||
// Assert
|
||||
await _stripeAdapter.DidNotReceiveWithAnyArgs().PaymentMethodAttachAsync(
|
||||
await _stripeAdapter.DidNotReceiveWithAnyArgs().AttachPaymentMethodAsync(
|
||||
Arg.Any<string>(), Arg.Any<PaymentMethodAttachOptions>());
|
||||
await _pushNotificationAdapter.DidNotReceiveWithAnyArgs().NotifyBankAccountVerifiedAsync(Arg.Any<Organization>());
|
||||
await _pushNotificationAdapter.DidNotReceiveWithAnyArgs().NotifyBankAccountVerifiedAsync(Arg.Any<Provider>());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Bit.Core.AdminConsole.Models.Business;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Import;
|
||||
using Bit.Core.Auth.Models.Business.Tokenables;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
@@ -57,7 +58,7 @@ public class ImportOrganizationUsersAndGroupsCommandTests
|
||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||
SetupOrgUserRepositoryCreateManyAsyncMock(organizationUserRepository);
|
||||
|
||||
sutProvider.GetDependency<IPaymentService>().HasSecretsManagerStandalone(org).Returns(true);
|
||||
sutProvider.GetDependency<IStripePaymentService>().HasSecretsManagerStandalone(org).Returns(true);
|
||||
sutProvider.GetDependency<IOrganizationUserRepository>().GetManyDetailsByOrganizationAsync(org.Id).Returns(existingUsers);
|
||||
sutProvider.GetDependency<IOrganizationRepository>().GetOccupiedSeatCountByOrganizationIdAsync(org.Id).Returns(
|
||||
new OrganizationSeatCounts
|
||||
|
||||
@@ -3,11 +3,11 @@ using Bit.Core.AdminConsole.Models.Business;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation;
|
||||
using Bit.Core.AdminConsole.Utilities.Validation;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Test.Billing.Mocks.Plans;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
@@ -50,7 +50,7 @@ public class InviteOrganizationUsersValidatorTests
|
||||
OccupiedSmSeats = 9
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IPaymentService>()
|
||||
sutProvider.GetDependency<IStripePaymentService>()
|
||||
.HasSecretsManagerStandalone(request.InviteOrganization)
|
||||
.Returns(true);
|
||||
|
||||
@@ -96,7 +96,7 @@ public class InviteOrganizationUsersValidatorTests
|
||||
OccupiedSmSeats = 9
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IPaymentService>()
|
||||
sutProvider.GetDependency<IStripePaymentService>()
|
||||
.HasSecretsManagerStandalone(request.InviteOrganization)
|
||||
.Returns(true);
|
||||
|
||||
@@ -140,7 +140,7 @@ public class InviteOrganizationUsersValidatorTests
|
||||
OccupiedSmSeats = 4
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IPaymentService>()
|
||||
sutProvider.GetDependency<IStripePaymentService>()
|
||||
.HasSecretsManagerStandalone(request.InviteOrganization)
|
||||
.Returns(true);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Organizations;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Repositories;
|
||||
@@ -172,7 +173,7 @@ public class ResellerClientOrganizationSignUpCommandTests
|
||||
|
||||
private static async Task AssertCleanupIsPerformed(SutProvider<ResellerClientOrganizationSignUpCommand> sutProvider)
|
||||
{
|
||||
await sutProvider.GetDependency<IPaymentService>()
|
||||
await sutProvider.GetDependency<IStripePaymentService>()
|
||||
.Received(1)
|
||||
.CancelAndRecoverChargesAsync(Arg.Any<Organization>());
|
||||
await sutProvider.GetDependency<IOrganizationRepository>()
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
using Bit.Core.AdminConsole.Models.Data.Organizations;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Organizations;
|
||||
using Bit.Core.Billing.Enums;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Models.StaticStore;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Test.Billing.Mocks.Plans;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
@@ -28,7 +28,7 @@ public class UpdateOrganizationSubscriptionCommandTests
|
||||
// Act
|
||||
await sutProvider.Sut.UpdateOrganizationSubscriptionAsync(subscriptionsToUpdate);
|
||||
|
||||
await sutProvider.GetDependency<IPaymentService>()
|
||||
await sutProvider.GetDependency<IStripePaymentService>()
|
||||
.DidNotReceive()
|
||||
.AdjustSeatsAsync(Arg.Any<Organization>(), Arg.Any<Plan>(), Arg.Any<int>());
|
||||
|
||||
@@ -53,7 +53,7 @@ public class UpdateOrganizationSubscriptionCommandTests
|
||||
// Act
|
||||
await sutProvider.Sut.UpdateOrganizationSubscriptionAsync(subscriptionsToUpdate);
|
||||
|
||||
await sutProvider.GetDependency<IPaymentService>()
|
||||
await sutProvider.GetDependency<IStripePaymentService>()
|
||||
.Received(1)
|
||||
.AdjustSeatsAsync(
|
||||
Arg.Is<Organization>(x => x.Id == organization.Id),
|
||||
@@ -81,7 +81,7 @@ public class UpdateOrganizationSubscriptionCommandTests
|
||||
OrganizationSubscriptionUpdate[] subscriptionsToUpdate =
|
||||
[new() { Organization = organization, Plan = new Enterprise2023Plan(true) }];
|
||||
|
||||
sutProvider.GetDependency<IPaymentService>()
|
||||
sutProvider.GetDependency<IStripePaymentService>()
|
||||
.AdjustSeatsAsync(
|
||||
Arg.Is<Organization>(x => x.Id == organization.Id),
|
||||
Arg.Is<Plan>(x => x.Type == organization.PlanType),
|
||||
@@ -115,7 +115,7 @@ public class UpdateOrganizationSubscriptionCommandTests
|
||||
new() { Organization = failedOrganization, Plan = new Enterprise2023Plan(true) }
|
||||
];
|
||||
|
||||
sutProvider.GetDependency<IPaymentService>()
|
||||
sutProvider.GetDependency<IStripePaymentService>()
|
||||
.AdjustSeatsAsync(
|
||||
Arg.Is<Organization>(x => x.Id == failedOrganization.Id),
|
||||
Arg.Is<Plan>(x => x.Type == failedOrganization.PlanType),
|
||||
@@ -124,7 +124,7 @@ public class UpdateOrganizationSubscriptionCommandTests
|
||||
// Act
|
||||
await sutProvider.Sut.UpdateOrganizationSubscriptionAsync(subscriptionsToUpdate);
|
||||
|
||||
await sutProvider.GetDependency<IPaymentService>()
|
||||
await sutProvider.GetDependency<IStripePaymentService>()
|
||||
.Received(1)
|
||||
.AdjustSeatsAsync(
|
||||
Arg.Is<Organization>(x => x.Id == successfulOrganization.Id),
|
||||
|
||||
@@ -9,6 +9,7 @@ using Bit.Core.AdminConsole.Repositories;
|
||||
using Bit.Core.Auth.Models.Business.Tokenables;
|
||||
using Bit.Core.Billing.Enums;
|
||||
using Bit.Core.Billing.Pricing;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
@@ -1142,7 +1143,7 @@ public class OrganizationServiceTests
|
||||
.GetByIdentifierAsync(Arg.Is<string>(id => id == organization.Identifier));
|
||||
await stripeAdapter
|
||||
.Received(1)
|
||||
.CustomerUpdateAsync(
|
||||
.UpdateCustomerAsync(
|
||||
Arg.Is<string>(id => id == organization.GatewayCustomerId),
|
||||
Arg.Is<CustomerUpdateOptions>(options => options.Email == requestOptionsReturned.Email
|
||||
&& options.Description == requestOptionsReturned.Description
|
||||
@@ -1182,7 +1183,7 @@ public class OrganizationServiceTests
|
||||
.GetByIdentifierAsync(Arg.Is<string>(id => id == organization.Identifier));
|
||||
await stripeAdapter
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>());
|
||||
.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>());
|
||||
await organizationRepository
|
||||
.Received(1)
|
||||
.ReplaceAsync(Arg.Is<Organization>(org => org == organization));
|
||||
|
||||
@@ -4,7 +4,7 @@ using Bit.Core.Billing.Organizations.Commands;
|
||||
using Bit.Core.Billing.Organizations.Models;
|
||||
using Bit.Core.Billing.Payment.Models;
|
||||
using Bit.Core.Billing.Pricing;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Test.Billing.Mocks.Plans;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NSubstitute;
|
||||
@@ -58,7 +58,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 5500
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(purchase, billingAddress);
|
||||
|
||||
@@ -68,7 +68,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(55.00m, total);
|
||||
|
||||
// Verify the correct Stripe API call for sponsored subscription
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "US" &&
|
||||
@@ -116,7 +116,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 8250
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(purchase, billingAddress);
|
||||
|
||||
@@ -126,7 +126,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(82.50m, total);
|
||||
|
||||
// Verify the correct Stripe API call for standalone secrets manager
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "CA" &&
|
||||
@@ -179,7 +179,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 12200
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(purchase, billingAddress);
|
||||
|
||||
@@ -189,7 +189,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(122.00m, total);
|
||||
|
||||
// Verify the correct Stripe API call for comprehensive purchase with storage and service accounts
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "GB" &&
|
||||
@@ -240,7 +240,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 3300
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(purchase, billingAddress);
|
||||
|
||||
@@ -250,7 +250,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(33.00m, total);
|
||||
|
||||
// Verify the correct Stripe API call for Families tier (non-seat-based plan)
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "US" &&
|
||||
@@ -292,7 +292,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 2700
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(purchase, billingAddress);
|
||||
|
||||
@@ -302,7 +302,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(27.00m, total);
|
||||
|
||||
// Verify the correct Stripe API call for business use in non-US country (tax exempt reverse)
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "DE" &&
|
||||
@@ -345,7 +345,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 12100
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(purchase, billingAddress);
|
||||
|
||||
@@ -355,7 +355,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(121.00m, total);
|
||||
|
||||
// Verify the correct Stripe API call for Spanish NIF that adds both Spanish NIF and EU VAT tax IDs
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "ES" &&
|
||||
@@ -405,7 +405,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 1320
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(organization, planChange, billingAddress);
|
||||
|
||||
@@ -415,7 +415,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(13.20m, total);
|
||||
|
||||
// Verify the correct Stripe API call for free organization upgrade to Teams
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "US" &&
|
||||
@@ -458,7 +458,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 4400
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(organization, planChange, billingAddress);
|
||||
|
||||
@@ -468,7 +468,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(44.00m, total);
|
||||
|
||||
// Verify the correct Stripe API call for free organization upgrade to Families (no SM for Families)
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "CA" &&
|
||||
@@ -522,7 +522,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Customer = new Customer { Discount = null }
|
||||
};
|
||||
|
||||
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
|
||||
var invoice = new Invoice
|
||||
{
|
||||
@@ -534,7 +534,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 9900
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(organization, planChange, billingAddress);
|
||||
|
||||
@@ -543,7 +543,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(9.00m, tax);
|
||||
Assert.Equal(99.00m, total);
|
||||
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "US" &&
|
||||
@@ -597,7 +597,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Customer = new Customer { Discount = null }
|
||||
};
|
||||
|
||||
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
|
||||
var invoice = new Invoice
|
||||
{
|
||||
@@ -609,7 +609,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 13200
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(organization, planChange, billingAddress);
|
||||
|
||||
@@ -618,7 +618,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(12.00m, tax);
|
||||
Assert.Equal(132.00m, total);
|
||||
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "US" &&
|
||||
@@ -661,7 +661,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 8800
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(organization, planChange, billingAddress);
|
||||
|
||||
@@ -671,7 +671,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(88.00m, total);
|
||||
|
||||
// Verify the correct Stripe API call for free organization with SM to Enterprise
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "GB" &&
|
||||
@@ -730,7 +730,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Customer = new Customer { Discount = null }
|
||||
};
|
||||
|
||||
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
|
||||
var invoice = new Invoice
|
||||
{
|
||||
@@ -738,7 +738,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 16500
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(organization, planChange, billingAddress);
|
||||
|
||||
@@ -748,7 +748,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(165.00m, total);
|
||||
|
||||
// Verify the correct Stripe API call for existing subscription upgrade
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "DE" &&
|
||||
@@ -814,7 +814,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
}
|
||||
};
|
||||
|
||||
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
|
||||
var invoice = new Invoice
|
||||
{
|
||||
@@ -822,7 +822,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 6600
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(organization, planChange, billingAddress);
|
||||
|
||||
@@ -832,7 +832,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(66.00m, total);
|
||||
|
||||
// Verify the correct Stripe API call preserves existing discount
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "US" &&
|
||||
@@ -876,8 +876,8 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal("Organization does not have a subscription.", badRequest.Response);
|
||||
|
||||
// Verify no Stripe API calls were made
|
||||
await _stripeAdapter.DidNotReceive().InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>());
|
||||
await _stripeAdapter.DidNotReceive().SubscriptionGetAsync(Arg.Any<string>(), Arg.Any<SubscriptionGetOptions>());
|
||||
await _stripeAdapter.DidNotReceive().CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>());
|
||||
await _stripeAdapter.DidNotReceive().GetSubscriptionAsync(Arg.Any<string>(), Arg.Any<SubscriptionGetOptions>());
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -919,7 +919,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Customer = customer
|
||||
};
|
||||
|
||||
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
|
||||
var invoice = new Invoice
|
||||
{
|
||||
@@ -927,7 +927,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 6600
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(organization, update);
|
||||
|
||||
@@ -937,7 +937,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(66.00m, total);
|
||||
|
||||
// Verify the correct Stripe API call for PM seats only
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "US" &&
|
||||
@@ -984,7 +984,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Customer = customer
|
||||
};
|
||||
|
||||
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
|
||||
var invoice = new Invoice
|
||||
{
|
||||
@@ -992,7 +992,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 13200
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(organization, update);
|
||||
|
||||
@@ -1002,7 +1002,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(132.00m, total);
|
||||
|
||||
// Verify the correct Stripe API call for PM seats + storage
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "CA" &&
|
||||
@@ -1051,7 +1051,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Customer = customer
|
||||
};
|
||||
|
||||
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
|
||||
var invoice = new Invoice
|
||||
{
|
||||
@@ -1059,7 +1059,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 8800
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(organization, update);
|
||||
|
||||
@@ -1069,7 +1069,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(88.00m, total);
|
||||
|
||||
// Verify the correct Stripe API call for SM seats only
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "DE" &&
|
||||
@@ -1119,7 +1119,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Customer = customer
|
||||
};
|
||||
|
||||
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
|
||||
var invoice = new Invoice
|
||||
{
|
||||
@@ -1127,7 +1127,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 16500
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(organization, update);
|
||||
|
||||
@@ -1137,7 +1137,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(165.00m, total);
|
||||
|
||||
// Verify the correct Stripe API call for SM seats + service accounts with tax ID
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "GB" &&
|
||||
@@ -1200,7 +1200,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Customer = customer
|
||||
};
|
||||
|
||||
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
|
||||
var invoice = new Invoice
|
||||
{
|
||||
@@ -1208,7 +1208,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 27500
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(organization, update);
|
||||
|
||||
@@ -1218,7 +1218,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(275.00m, total);
|
||||
|
||||
// Verify the correct Stripe API call for comprehensive update with discount and Spanish tax ID
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "ES" &&
|
||||
@@ -1276,7 +1276,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Customer = customer
|
||||
};
|
||||
|
||||
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
|
||||
var invoice = new Invoice
|
||||
{
|
||||
@@ -1284,7 +1284,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 5500
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(organization, update);
|
||||
|
||||
@@ -1294,7 +1294,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(55.00m, total);
|
||||
|
||||
// Verify the correct Stripe API call for Families tier (personal usage, no business tax exemption)
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "AU" &&
|
||||
@@ -1334,8 +1334,8 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal("Organization does not have a subscription.", badRequest.Response);
|
||||
|
||||
// Verify no Stripe API calls were made
|
||||
await _stripeAdapter.DidNotReceive().InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>());
|
||||
await _stripeAdapter.DidNotReceive().SubscriptionGetAsync(Arg.Any<string>(), Arg.Any<SubscriptionGetOptions>());
|
||||
await _stripeAdapter.DidNotReceive().CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>());
|
||||
await _stripeAdapter.DidNotReceive().GetSubscriptionAsync(Arg.Any<string>(), Arg.Any<SubscriptionGetOptions>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -1378,7 +1378,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Customer = customer
|
||||
};
|
||||
|
||||
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
|
||||
|
||||
var invoice = new Invoice
|
||||
{
|
||||
@@ -1386,7 +1386,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Total = 3300
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(organization, update);
|
||||
|
||||
@@ -1396,7 +1396,7 @@ public class PreviewOrganizationTaxCommandTests
|
||||
Assert.Equal(33.00m, total);
|
||||
|
||||
// Verify only PM seats are included (storage=0 excluded, SM seats=0 so entire SM excluded)
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "US" &&
|
||||
|
||||
@@ -8,7 +8,6 @@ using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.Platform.Installations;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Test.AutoFixture;
|
||||
using Bit.Core.Test.Billing.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
@@ -59,7 +58,7 @@ public class GetCloudOrganizationLicenseQueryTests
|
||||
{
|
||||
installation.Enabled = true;
|
||||
sutProvider.GetDependency<IInstallationRepository>().GetByIdAsync(installationId).Returns(installation);
|
||||
sutProvider.GetDependency<IPaymentService>().GetSubscriptionAsync(organization).Returns(subInfo);
|
||||
sutProvider.GetDependency<IStripePaymentService>().GetSubscriptionAsync(organization).Returns(subInfo);
|
||||
sutProvider.GetDependency<ILicensingService>().SignLicense(Arg.Any<ILicense>()).Returns(licenseSignature);
|
||||
|
||||
var result = await sutProvider.Sut.GetLicenseAsync(organization, installationId);
|
||||
@@ -80,7 +79,7 @@ public class GetCloudOrganizationLicenseQueryTests
|
||||
{
|
||||
installation.Enabled = true;
|
||||
sutProvider.GetDependency<IInstallationRepository>().GetByIdAsync(installationId).Returns(installation);
|
||||
sutProvider.GetDependency<IPaymentService>().GetSubscriptionAsync(organization).Returns(subInfo);
|
||||
sutProvider.GetDependency<IStripePaymentService>().GetSubscriptionAsync(organization).Returns(subInfo);
|
||||
sutProvider.GetDependency<ILicensingService>().SignLicense(Arg.Any<ILicense>()).Returns(licenseSignature);
|
||||
sutProvider.GetDependency<ILicensingService>()
|
||||
.CreateOrganizationTokenAsync(organization, installationId, subInfo)
|
||||
@@ -119,7 +118,7 @@ public class GetCloudOrganizationLicenseQueryTests
|
||||
installation.Enabled = true;
|
||||
sutProvider.GetDependency<IInstallationRepository>().GetByIdAsync(installationId).Returns(installation);
|
||||
sutProvider.GetDependency<IProviderRepository>().GetByOrganizationIdAsync(organization.Id).Returns(provider);
|
||||
sutProvider.GetDependency<IPaymentService>().GetSubscriptionAsync(provider).Returns(subInfo);
|
||||
sutProvider.GetDependency<IStripePaymentService>().GetSubscriptionAsync(provider).Returns(subInfo);
|
||||
sutProvider.GetDependency<ILicensingService>().SignLicense(Arg.Any<ILicense>()).Returns(licenseSignature);
|
||||
|
||||
var result = await sutProvider.Sut.GetLicenseAsync(organization, installationId);
|
||||
|
||||
@@ -8,7 +8,6 @@ using Bit.Core.Billing.Organizations.Queries;
|
||||
using Bit.Core.Billing.Payment.Queries;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using NSubstitute;
|
||||
@@ -382,7 +381,7 @@ public class GetOrganizationWarningsQueryTests
|
||||
|
||||
var dueDate = now.AddDays(-10);
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().InvoiceSearchAsync(Arg.Is<InvoiceSearchOptions>(options =>
|
||||
sutProvider.GetDependency<IStripeAdapter>().SearchInvoiceAsync(Arg.Is<InvoiceSearchOptions>(options =>
|
||||
options.Query == $"subscription:'{subscriptionId}' status:'open'")).Returns([
|
||||
new Invoice { DueDate = dueDate, Created = dueDate.AddDays(-30) }
|
||||
]);
|
||||
@@ -542,7 +541,7 @@ public class GetOrganizationWarningsQueryTests
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
|
||||
.ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
|
||||
.Returns(new StripeList<Registration>
|
||||
{
|
||||
Data = new List<Registration>
|
||||
@@ -583,7 +582,7 @@ public class GetOrganizationWarningsQueryTests
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
|
||||
.ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
|
||||
.Returns(new StripeList<Registration>
|
||||
{
|
||||
Data = new List<Registration>
|
||||
@@ -635,7 +634,7 @@ public class GetOrganizationWarningsQueryTests
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
|
||||
.ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
|
||||
.Returns(new StripeList<Registration>
|
||||
{
|
||||
Data = new List<Registration>
|
||||
@@ -687,7 +686,7 @@ public class GetOrganizationWarningsQueryTests
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
|
||||
.ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
|
||||
.Returns(new StripeList<Registration>
|
||||
{
|
||||
Data = new List<Registration>
|
||||
@@ -739,7 +738,7 @@ public class GetOrganizationWarningsQueryTests
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
|
||||
.ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
|
||||
.Returns(new StripeList<Registration>
|
||||
{
|
||||
Data = new List<Registration>
|
||||
@@ -785,7 +784,7 @@ public class GetOrganizationWarningsQueryTests
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
|
||||
.ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
|
||||
.Returns(new StripeList<Registration>
|
||||
{
|
||||
Data = new List<Registration>
|
||||
|
||||
@@ -4,7 +4,6 @@ using Bit.Core.Billing.Enums;
|
||||
using Bit.Core.Billing.Payment.Commands;
|
||||
using Bit.Core.Billing.Payment.Models;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Test.Billing.Extensions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NSubstitute;
|
||||
@@ -73,7 +72,7 @@ public class UpdateBillingAddressCommandTests
|
||||
}
|
||||
};
|
||||
|
||||
_stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
|
||||
_stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
|
||||
options.Address.Matches(input) &&
|
||||
options.HasExpansions("subscriptions")
|
||||
)).Returns(customer);
|
||||
@@ -84,7 +83,7 @@ public class UpdateBillingAddressCommandTests
|
||||
var output = result.AsT0;
|
||||
Assert.Equivalent(input, output);
|
||||
|
||||
await _stripeAdapter.Received(1).SubscriptionUpdateAsync(organization.GatewaySubscriptionId,
|
||||
await _stripeAdapter.Received(1).UpdateSubscriptionAsync(organization.GatewaySubscriptionId,
|
||||
Arg.Is<SubscriptionUpdateOptions>(options => options.AutomaticTax.Enabled == true));
|
||||
}
|
||||
|
||||
@@ -131,7 +130,7 @@ public class UpdateBillingAddressCommandTests
|
||||
}
|
||||
};
|
||||
|
||||
_stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
|
||||
_stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
|
||||
options.Address.Matches(input) &&
|
||||
options.HasExpansions("subscriptions")
|
||||
)).Returns(customer);
|
||||
@@ -144,7 +143,7 @@ public class UpdateBillingAddressCommandTests
|
||||
|
||||
await _subscriberService.Received(1).CreateStripeCustomer(organization);
|
||||
|
||||
await _stripeAdapter.Received(1).SubscriptionUpdateAsync(organization.GatewaySubscriptionId,
|
||||
await _stripeAdapter.Received(1).UpdateSubscriptionAsync(organization.GatewaySubscriptionId,
|
||||
Arg.Is<SubscriptionUpdateOptions>(options => options.AutomaticTax.Enabled == true));
|
||||
}
|
||||
|
||||
@@ -192,7 +191,7 @@ public class UpdateBillingAddressCommandTests
|
||||
}
|
||||
};
|
||||
|
||||
_stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
|
||||
_stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
|
||||
options.Address.Matches(input) &&
|
||||
options.HasExpansions("subscriptions", "tax_ids") &&
|
||||
options.TaxExempt == TaxExempt.None
|
||||
@@ -204,7 +203,7 @@ public class UpdateBillingAddressCommandTests
|
||||
var output = result.AsT0;
|
||||
Assert.Equivalent(input, output);
|
||||
|
||||
await _stripeAdapter.Received(1).SubscriptionUpdateAsync(organization.GatewaySubscriptionId,
|
||||
await _stripeAdapter.Received(1).UpdateSubscriptionAsync(organization.GatewaySubscriptionId,
|
||||
Arg.Is<SubscriptionUpdateOptions>(options => options.AutomaticTax.Enabled == true));
|
||||
}
|
||||
|
||||
@@ -260,7 +259,7 @@ public class UpdateBillingAddressCommandTests
|
||||
}
|
||||
};
|
||||
|
||||
_stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
|
||||
_stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
|
||||
options.Address.Matches(input) &&
|
||||
options.HasExpansions("subscriptions", "tax_ids") &&
|
||||
options.TaxExempt == TaxExempt.None
|
||||
@@ -272,10 +271,10 @@ public class UpdateBillingAddressCommandTests
|
||||
var output = result.AsT0;
|
||||
Assert.Equivalent(input, output);
|
||||
|
||||
await _stripeAdapter.Received(1).SubscriptionUpdateAsync(organization.GatewaySubscriptionId,
|
||||
await _stripeAdapter.Received(1).UpdateSubscriptionAsync(organization.GatewaySubscriptionId,
|
||||
Arg.Is<SubscriptionUpdateOptions>(options => options.AutomaticTax.Enabled == true));
|
||||
|
||||
await _stripeAdapter.Received(1).TaxIdDeleteAsync(customer.Id, "tax_id_123");
|
||||
await _stripeAdapter.Received(1).DeleteTaxIdAsync(customer.Id, "tax_id_123");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -322,7 +321,7 @@ public class UpdateBillingAddressCommandTests
|
||||
}
|
||||
};
|
||||
|
||||
_stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
|
||||
_stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
|
||||
options.Address.Matches(input) &&
|
||||
options.HasExpansions("subscriptions", "tax_ids") &&
|
||||
options.TaxExempt == TaxExempt.Reverse
|
||||
@@ -334,7 +333,7 @@ public class UpdateBillingAddressCommandTests
|
||||
var output = result.AsT0;
|
||||
Assert.Equivalent(input, output);
|
||||
|
||||
await _stripeAdapter.Received(1).SubscriptionUpdateAsync(organization.GatewaySubscriptionId,
|
||||
await _stripeAdapter.Received(1).UpdateSubscriptionAsync(organization.GatewaySubscriptionId,
|
||||
Arg.Is<SubscriptionUpdateOptions>(options => options.AutomaticTax.Enabled == true));
|
||||
}
|
||||
|
||||
@@ -384,14 +383,14 @@ public class UpdateBillingAddressCommandTests
|
||||
}
|
||||
};
|
||||
|
||||
_stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
|
||||
_stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
|
||||
options.Address.Matches(input) &&
|
||||
options.HasExpansions("subscriptions", "tax_ids") &&
|
||||
options.TaxExempt == TaxExempt.Reverse
|
||||
)).Returns(customer);
|
||||
|
||||
_stripeAdapter
|
||||
.TaxIdCreateAsync(customer.Id,
|
||||
.CreateTaxIdAsync(customer.Id,
|
||||
Arg.Is<TaxIdCreateOptions>(options => options.Type == TaxIdType.EUVAT))
|
||||
.Returns(new TaxId { Type = TaxIdType.EUVAT, Value = "ESA12345678" });
|
||||
|
||||
@@ -401,10 +400,10 @@ public class UpdateBillingAddressCommandTests
|
||||
var output = result.AsT0;
|
||||
Assert.Equivalent(input with { TaxId = new TaxID(TaxIdType.EUVAT, "ESA12345678") }, output);
|
||||
|
||||
await _stripeAdapter.Received(1).SubscriptionUpdateAsync(organization.GatewaySubscriptionId,
|
||||
await _stripeAdapter.Received(1).UpdateSubscriptionAsync(organization.GatewaySubscriptionId,
|
||||
Arg.Is<SubscriptionUpdateOptions>(options => options.AutomaticTax.Enabled == true));
|
||||
|
||||
await _stripeAdapter.Received(1).TaxIdCreateAsync(organization.GatewayCustomerId, Arg.Is<TaxIdCreateOptions>(
|
||||
await _stripeAdapter.Received(1).CreateTaxIdAsync(organization.GatewayCustomerId, Arg.Is<TaxIdCreateOptions>(
|
||||
options => options.Type == TaxIdType.SpanishNIF &&
|
||||
options.Value == input.TaxId.Value));
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ using Bit.Core.Billing.Constants;
|
||||
using Bit.Core.Billing.Payment.Commands;
|
||||
using Bit.Core.Billing.Payment.Models;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Test.Billing.Extensions;
|
||||
using Braintree;
|
||||
@@ -82,7 +81,7 @@ public class UpdatePaymentMethodCommandTests
|
||||
Status = "requires_action"
|
||||
};
|
||||
|
||||
_stripeAdapter.SetupIntentList(Arg.Is<SetupIntentListOptions>(options =>
|
||||
_stripeAdapter.ListSetupIntentsAsync(Arg.Is<SetupIntentListOptions>(options =>
|
||||
options.PaymentMethod == token && options.HasExpansions("data.payment_method"))).Returns([setupIntent]);
|
||||
|
||||
var result = await _command.Run(organization,
|
||||
@@ -144,7 +143,7 @@ public class UpdatePaymentMethodCommandTests
|
||||
Status = "requires_action"
|
||||
};
|
||||
|
||||
_stripeAdapter.SetupIntentList(Arg.Is<SetupIntentListOptions>(options =>
|
||||
_stripeAdapter.ListSetupIntentsAsync(Arg.Is<SetupIntentListOptions>(options =>
|
||||
options.PaymentMethod == token && options.HasExpansions("data.payment_method"))).Returns([setupIntent]);
|
||||
|
||||
var result = await _command.Run(organization,
|
||||
@@ -213,7 +212,7 @@ public class UpdatePaymentMethodCommandTests
|
||||
Status = "requires_action"
|
||||
};
|
||||
|
||||
_stripeAdapter.SetupIntentList(Arg.Is<SetupIntentListOptions>(options =>
|
||||
_stripeAdapter.ListSetupIntentsAsync(Arg.Is<SetupIntentListOptions>(options =>
|
||||
options.PaymentMethod == token && options.HasExpansions("data.payment_method"))).Returns([setupIntent]);
|
||||
|
||||
var result = await _command.Run(organization,
|
||||
@@ -232,7 +231,7 @@ public class UpdatePaymentMethodCommandTests
|
||||
Assert.Equal("https://example.com", maskedBankAccount.HostedVerificationUrl);
|
||||
|
||||
await _setupIntentCache.Received(1).Set(organization.Id, setupIntent.Id);
|
||||
await _stripeAdapter.Received(1).CustomerUpdateAsync(customer.Id, Arg.Is<CustomerUpdateOptions>(options =>
|
||||
await _stripeAdapter.Received(1).UpdateCustomerAsync(customer.Id, Arg.Is<CustomerUpdateOptions>(options =>
|
||||
options.Metadata[MetadataKeys.BraintreeCustomerId] == string.Empty &&
|
||||
options.Metadata[MetadataKeys.RetiredBraintreeCustomerId] == "braintree_customer_id"));
|
||||
}
|
||||
@@ -262,7 +261,7 @@ public class UpdatePaymentMethodCommandTests
|
||||
const string token = "TOKEN";
|
||||
|
||||
_stripeAdapter
|
||||
.PaymentMethodAttachAsync(token,
|
||||
.AttachPaymentMethodAsync(token,
|
||||
Arg.Is<PaymentMethodAttachOptions>(options => options.Customer == customer.Id))
|
||||
.Returns(new PaymentMethod
|
||||
{
|
||||
@@ -291,7 +290,7 @@ public class UpdatePaymentMethodCommandTests
|
||||
Assert.Equal("9999", maskedCard.Last4);
|
||||
Assert.Equal("01/2028", maskedCard.Expiration);
|
||||
|
||||
await _stripeAdapter.Received(1).CustomerUpdateAsync(customer.Id,
|
||||
await _stripeAdapter.Received(1).UpdateCustomerAsync(customer.Id,
|
||||
Arg.Is<CustomerUpdateOptions>(options => options.InvoiceSettings.DefaultPaymentMethod == token));
|
||||
}
|
||||
|
||||
@@ -315,7 +314,7 @@ public class UpdatePaymentMethodCommandTests
|
||||
const string token = "TOKEN";
|
||||
|
||||
_stripeAdapter
|
||||
.PaymentMethodAttachAsync(token,
|
||||
.AttachPaymentMethodAsync(token,
|
||||
Arg.Is<PaymentMethodAttachOptions>(options => options.Customer == customer.Id))
|
||||
.Returns(new PaymentMethod
|
||||
{
|
||||
@@ -344,10 +343,10 @@ public class UpdatePaymentMethodCommandTests
|
||||
Assert.Equal("9999", maskedCard.Last4);
|
||||
Assert.Equal("01/2028", maskedCard.Expiration);
|
||||
|
||||
await _stripeAdapter.Received(1).CustomerUpdateAsync(customer.Id,
|
||||
await _stripeAdapter.Received(1).UpdateCustomerAsync(customer.Id,
|
||||
Arg.Is<CustomerUpdateOptions>(options => options.InvoiceSettings.DefaultPaymentMethod == token));
|
||||
|
||||
await _stripeAdapter.Received(1).CustomerUpdateAsync(customer.Id,
|
||||
await _stripeAdapter.Received(1).UpdateCustomerAsync(customer.Id,
|
||||
Arg.Is<CustomerUpdateOptions>(options => options.Address.Country == "US" && options.Address.PostalCode == "12345"));
|
||||
}
|
||||
|
||||
@@ -468,7 +467,7 @@ public class UpdatePaymentMethodCommandTests
|
||||
var maskedPayPalAccount = maskedPaymentMethod.AsT2;
|
||||
Assert.Equal("user@gmail.com", maskedPayPalAccount.Email);
|
||||
|
||||
await _stripeAdapter.Received(1).CustomerUpdateAsync(customer.Id,
|
||||
await _stripeAdapter.Received(1).UpdateCustomerAsync(customer.Id,
|
||||
Arg.Is<CustomerUpdateOptions>(options =>
|
||||
options.Metadata[MetadataKeys.BraintreeCustomerId] == "braintree_customer_id"));
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ using Bit.Core.Billing.Caches;
|
||||
using Bit.Core.Billing.Constants;
|
||||
using Bit.Core.Billing.Payment.Queries;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Test.Billing.Extensions;
|
||||
using Braintree;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -166,7 +165,7 @@ public class GetPaymentMethodQueryTests
|
||||
_setupIntentCache.GetSetupIntentIdForSubscriber(organization.Id).Returns("seti_123");
|
||||
|
||||
_stripeAdapter
|
||||
.SetupIntentGet("seti_123",
|
||||
.GetSetupIntentAsync("seti_123",
|
||||
Arg.Is<SetupIntentGetOptions>(options => options.HasExpansions("payment_method"))).Returns(
|
||||
new SetupIntent
|
||||
{
|
||||
|
||||
@@ -3,7 +3,6 @@ using Bit.Core.Billing.Caches;
|
||||
using Bit.Core.Billing.Constants;
|
||||
using Bit.Core.Billing.Payment.Queries;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Test.Billing.Extensions;
|
||||
using NSubstitute;
|
||||
using NSubstitute.ReturnsExtensions;
|
||||
@@ -57,7 +56,7 @@ public class HasPaymentMethodQueryTests
|
||||
_setupIntentCache.GetSetupIntentIdForSubscriber(organization.Id).Returns("seti_123");
|
||||
|
||||
_stripeAdapter
|
||||
.SetupIntentGet("seti_123",
|
||||
.GetSetupIntentAsync("seti_123",
|
||||
Arg.Is<SetupIntentGetOptions>(options => options.HasExpansions("payment_method")))
|
||||
.Returns(new SetupIntent
|
||||
{
|
||||
@@ -162,7 +161,7 @@ public class HasPaymentMethodQueryTests
|
||||
_setupIntentCache.GetSetupIntentIdForSubscriber(organization.Id).Returns("seti_123");
|
||||
|
||||
_stripeAdapter
|
||||
.SetupIntentGet("seti_123",
|
||||
.GetSetupIntentAsync("seti_123",
|
||||
Arg.Is<SetupIntentGetOptions>(options => options.HasExpansions("payment_method")))
|
||||
.Returns(new SetupIntent
|
||||
{
|
||||
@@ -246,7 +245,7 @@ public class HasPaymentMethodQueryTests
|
||||
_setupIntentCache.GetSetupIntentIdForSubscriber(organization.Id).Returns("seti_123");
|
||||
|
||||
_stripeAdapter
|
||||
.SetupIntentGet("seti_123",
|
||||
.GetSetupIntentAsync("seti_123",
|
||||
Arg.Is<SetupIntentGetOptions>(options => options.HasExpansions("payment_method")))
|
||||
.Returns(new SetupIntent
|
||||
{
|
||||
|
||||
@@ -146,11 +146,11 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
var mockSetupIntent = Substitute.For<SetupIntent>();
|
||||
mockSetupIntent.Id = "seti_123";
|
||||
|
||||
_stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_stripeAdapter.SetupIntentList(Arg.Any<SetupIntentListOptions>()).Returns(Task.FromResult(new List<SetupIntent> { mockSetupIntent }));
|
||||
_stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_stripeAdapter.ListSetupIntentsAsync(Arg.Any<SetupIntentListOptions>()).Returns(Task.FromResult(new List<SetupIntent> { mockSetupIntent }));
|
||||
_subscriberService.GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>()).Returns(mockCustomer);
|
||||
|
||||
// Act
|
||||
@@ -158,8 +158,8 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
|
||||
// Assert
|
||||
Assert.True(result.IsT0);
|
||||
await _stripeAdapter.Received(1).CustomerCreateAsync(Arg.Any<CustomerCreateOptions>());
|
||||
await _stripeAdapter.Received(1).SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
await _stripeAdapter.Received(1).CreateCustomerAsync(Arg.Any<CustomerCreateOptions>());
|
||||
await _stripeAdapter.Received(1).CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
await _userService.Received(1).SaveUserAsync(user);
|
||||
await _pushNotificationService.Received(1).PushSyncVaultAsync(user.Id);
|
||||
}
|
||||
@@ -200,10 +200,10 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
|
||||
var mockInvoice = Substitute.For<Invoice>();
|
||||
|
||||
_stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_subscriberService.GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>()).Returns(mockCustomer);
|
||||
|
||||
// Act
|
||||
@@ -211,8 +211,8 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
|
||||
// Assert
|
||||
Assert.True(result.IsT0);
|
||||
await _stripeAdapter.Received(1).CustomerCreateAsync(Arg.Any<CustomerCreateOptions>());
|
||||
await _stripeAdapter.Received(1).SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
await _stripeAdapter.Received(1).CreateCustomerAsync(Arg.Any<CustomerCreateOptions>());
|
||||
await _stripeAdapter.Received(1).CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
await _userService.Received(1).SaveUserAsync(user);
|
||||
await _pushNotificationService.Received(1).PushSyncVaultAsync(user.Id);
|
||||
}
|
||||
@@ -243,10 +243,10 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
|
||||
var mockInvoice = Substitute.For<Invoice>();
|
||||
|
||||
_stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_subscriberService.GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>()).Returns(mockCustomer);
|
||||
_subscriberService.CreateBraintreeCustomer(Arg.Any<User>(), Arg.Any<string>()).Returns("bt_customer_123");
|
||||
|
||||
@@ -255,8 +255,8 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
|
||||
// Assert
|
||||
Assert.True(result.IsT0);
|
||||
await _stripeAdapter.Received(1).CustomerCreateAsync(Arg.Any<CustomerCreateOptions>());
|
||||
await _stripeAdapter.Received(1).SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
await _stripeAdapter.Received(1).CreateCustomerAsync(Arg.Any<CustomerCreateOptions>());
|
||||
await _stripeAdapter.Received(1).CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
await _subscriberService.Received(1).CreateBraintreeCustomer(user, paymentMethod.Token);
|
||||
await _userService.Received(1).SaveUserAsync(user);
|
||||
await _pushNotificationService.Received(1).PushSyncVaultAsync(user.Id);
|
||||
@@ -299,10 +299,10 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
|
||||
var mockInvoice = Substitute.For<Invoice>();
|
||||
|
||||
_stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_subscriberService.GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>()).Returns(mockCustomer);
|
||||
|
||||
// Act
|
||||
@@ -356,8 +356,8 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
// Mock that the user has a payment method (this is the key difference from the credit purchase case)
|
||||
_hasPaymentMethodQuery.Run(Arg.Any<User>()).Returns(true);
|
||||
_subscriberService.GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
|
||||
// Act
|
||||
var result = await _command.Run(user, paymentMethod, billingAddress, 0);
|
||||
@@ -365,7 +365,7 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
// Assert
|
||||
Assert.True(result.IsT0);
|
||||
await _subscriberService.Received(1).GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>());
|
||||
await _stripeAdapter.DidNotReceive().CustomerCreateAsync(Arg.Any<CustomerCreateOptions>());
|
||||
await _stripeAdapter.DidNotReceive().CreateCustomerAsync(Arg.Any<CustomerCreateOptions>());
|
||||
await _updatePaymentMethodCommand.DidNotReceive().Run(Arg.Any<User>(), Arg.Any<TokenizedPaymentMethod>(), Arg.Any<BillingAddress>());
|
||||
}
|
||||
|
||||
@@ -415,8 +415,8 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
_updatePaymentMethodCommand.Run(Arg.Any<User>(), Arg.Any<TokenizedPaymentMethod>(), Arg.Any<BillingAddress>())
|
||||
.Returns(mockMaskedPaymentMethod);
|
||||
_subscriberService.GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
|
||||
// Act
|
||||
var result = await _command.Run(user, paymentMethod, billingAddress, 0);
|
||||
@@ -428,9 +428,9 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
// Verify GetCustomerOrThrow was called after updating payment method
|
||||
await _subscriberService.Received(1).GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>());
|
||||
// Verify no new customer was created
|
||||
await _stripeAdapter.DidNotReceive().CustomerCreateAsync(Arg.Any<CustomerCreateOptions>());
|
||||
await _stripeAdapter.DidNotReceive().CreateCustomerAsync(Arg.Any<CustomerCreateOptions>());
|
||||
// Verify subscription was created
|
||||
await _stripeAdapter.Received(1).SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
await _stripeAdapter.Received(1).CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
// Verify user was updated correctly
|
||||
Assert.True(user.Premium);
|
||||
await _userService.Received(1).SaveUserAsync(user);
|
||||
@@ -474,10 +474,10 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
|
||||
var mockInvoice = Substitute.For<Invoice>();
|
||||
|
||||
_stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_subscriberService.CreateBraintreeCustomer(Arg.Any<User>(), Arg.Any<string>()).Returns("bt_customer_123");
|
||||
|
||||
// Act
|
||||
@@ -525,10 +525,10 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
|
||||
var mockInvoice = Substitute.For<Invoice>();
|
||||
|
||||
_stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_subscriberService.GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>()).Returns(mockCustomer);
|
||||
|
||||
// Act
|
||||
@@ -577,10 +577,10 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
|
||||
var mockInvoice = Substitute.For<Invoice>();
|
||||
|
||||
_stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_subscriberService.CreateBraintreeCustomer(Arg.Any<User>(), Arg.Any<string>()).Returns("bt_customer_123");
|
||||
|
||||
// Act
|
||||
@@ -628,13 +628,13 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
|
||||
var mockInvoice = Substitute.For<Invoice>();
|
||||
|
||||
_stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_subscriberService.GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>()).Returns(mockCustomer);
|
||||
|
||||
_stripeAdapter.SetupIntentList(Arg.Any<SetupIntentListOptions>())
|
||||
_stripeAdapter.ListSetupIntentsAsync(Arg.Any<SetupIntentListOptions>())
|
||||
.Returns(Task.FromResult(new List<SetupIntent>())); // Empty list - no setup intent found
|
||||
|
||||
// Act
|
||||
@@ -681,8 +681,8 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
var mockInvoice = Substitute.For<Invoice>();
|
||||
|
||||
_subscriberService.GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
|
||||
|
||||
// Act
|
||||
var result = await _command.Run(user, paymentMethod, billingAddress, 0);
|
||||
@@ -690,7 +690,7 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
// Assert
|
||||
Assert.True(result.IsT0);
|
||||
await _subscriberService.Received(1).GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>());
|
||||
await _stripeAdapter.DidNotReceive().CustomerCreateAsync(Arg.Any<CustomerCreateOptions>());
|
||||
await _stripeAdapter.DidNotReceive().CreateCustomerAsync(Arg.Any<CustomerCreateOptions>());
|
||||
Assert.True(user.Premium);
|
||||
Assert.Equal(mockSubscription.GetCurrentPeriodEnd(), user.PremiumExpirationDate);
|
||||
}
|
||||
@@ -716,8 +716,8 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
Assert.True(result.IsT3); // Assuming T3 is the Unhandled result
|
||||
Assert.IsType<BillingException>(result.AsT3.Exception);
|
||||
// Verify no customer was created or subscription attempted
|
||||
await _stripeAdapter.DidNotReceive().CustomerCreateAsync(Arg.Any<CustomerCreateOptions>());
|
||||
await _stripeAdapter.DidNotReceive().SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
await _stripeAdapter.DidNotReceive().CreateCustomerAsync(Arg.Any<CustomerCreateOptions>());
|
||||
await _stripeAdapter.DidNotReceive().CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
await _userService.DidNotReceive().SaveUserAsync(Arg.Any<User>());
|
||||
}
|
||||
|
||||
@@ -767,8 +767,8 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
]
|
||||
};
|
||||
|
||||
_stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
_stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
|
||||
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
|
||||
|
||||
// Act
|
||||
var result = await _command.Run(user, paymentMethod, billingAddress, additionalStorage);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Bit.Core.Billing.Payment.Models;
|
||||
using Bit.Core.Billing.Premium.Commands;
|
||||
using Bit.Core.Billing.Pricing;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NSubstitute;
|
||||
using Stripe;
|
||||
@@ -50,7 +50,7 @@ public class PreviewPremiumTaxCommandTests
|
||||
Total = 3300
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(0, billingAddress);
|
||||
|
||||
@@ -59,7 +59,7 @@ public class PreviewPremiumTaxCommandTests
|
||||
Assert.Equal(3.00m, tax);
|
||||
Assert.Equal(33.00m, total);
|
||||
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "US" &&
|
||||
@@ -84,7 +84,7 @@ public class PreviewPremiumTaxCommandTests
|
||||
Total = 5500
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(5, billingAddress);
|
||||
|
||||
@@ -93,7 +93,7 @@ public class PreviewPremiumTaxCommandTests
|
||||
Assert.Equal(5.00m, tax);
|
||||
Assert.Equal(55.00m, total);
|
||||
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "CA" &&
|
||||
@@ -120,7 +120,7 @@ public class PreviewPremiumTaxCommandTests
|
||||
Total = 2750
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(0, billingAddress);
|
||||
|
||||
@@ -129,7 +129,7 @@ public class PreviewPremiumTaxCommandTests
|
||||
Assert.Equal(2.50m, tax);
|
||||
Assert.Equal(27.50m, total);
|
||||
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "GB" &&
|
||||
@@ -154,7 +154,7 @@ public class PreviewPremiumTaxCommandTests
|
||||
Total = 8800
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(20, billingAddress);
|
||||
|
||||
@@ -163,7 +163,7 @@ public class PreviewPremiumTaxCommandTests
|
||||
Assert.Equal(8.00m, tax);
|
||||
Assert.Equal(88.00m, total);
|
||||
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "DE" &&
|
||||
@@ -190,7 +190,7 @@ public class PreviewPremiumTaxCommandTests
|
||||
Total = 4950
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(10, billingAddress);
|
||||
|
||||
@@ -199,7 +199,7 @@ public class PreviewPremiumTaxCommandTests
|
||||
Assert.Equal(4.50m, tax);
|
||||
Assert.Equal(49.50m, total);
|
||||
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "AU" &&
|
||||
@@ -226,7 +226,7 @@ public class PreviewPremiumTaxCommandTests
|
||||
Total = 3000
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(0, billingAddress);
|
||||
|
||||
@@ -235,7 +235,7 @@ public class PreviewPremiumTaxCommandTests
|
||||
Assert.Equal(0.00m, tax);
|
||||
Assert.Equal(30.00m, total);
|
||||
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "US" &&
|
||||
@@ -260,7 +260,7 @@ public class PreviewPremiumTaxCommandTests
|
||||
Total = 6600
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(-5, billingAddress);
|
||||
|
||||
@@ -269,7 +269,7 @@ public class PreviewPremiumTaxCommandTests
|
||||
Assert.Equal(6.00m, tax);
|
||||
Assert.Equal(66.00m, total);
|
||||
|
||||
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.Currency == "usd" &&
|
||||
options.CustomerDetails.Address.Country == "FR" &&
|
||||
@@ -295,7 +295,7 @@ public class PreviewPremiumTaxCommandTests
|
||||
Total = 3123 // $31.23
|
||||
};
|
||||
|
||||
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
|
||||
|
||||
var result = await _command.Run(0, billingAddress);
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ using Bit.Core.Billing.Pricing;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Test.Billing.Mocks;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
@@ -179,7 +178,7 @@ public class OrganizationBillingServiceTests
|
||||
|
||||
SubscriptionCreateOptions capturedOptions = null;
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionCreateAsync(Arg.Do<SubscriptionCreateOptions>(options => capturedOptions = options))
|
||||
.CreateSubscriptionAsync(Arg.Do<SubscriptionCreateOptions>(options => capturedOptions = options))
|
||||
.Returns(new Subscription
|
||||
{
|
||||
Id = "sub_test123",
|
||||
@@ -196,7 +195,7 @@ public class OrganizationBillingServiceTests
|
||||
// Assert
|
||||
await sutProvider.GetDependency<IStripeAdapter>()
|
||||
.Received(1)
|
||||
.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
|
||||
Assert.NotNull(capturedOptions);
|
||||
Assert.Equal(7, capturedOptions.TrialPeriodDays);
|
||||
@@ -255,7 +254,7 @@ public class OrganizationBillingServiceTests
|
||||
|
||||
SubscriptionCreateOptions capturedOptions = null;
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionCreateAsync(Arg.Do<SubscriptionCreateOptions>(options => capturedOptions = options))
|
||||
.CreateSubscriptionAsync(Arg.Do<SubscriptionCreateOptions>(options => capturedOptions = options))
|
||||
.Returns(new Subscription
|
||||
{
|
||||
Id = "sub_test123",
|
||||
@@ -272,7 +271,7 @@ public class OrganizationBillingServiceTests
|
||||
// Assert
|
||||
await sutProvider.GetDependency<IStripeAdapter>()
|
||||
.Received(1)
|
||||
.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
|
||||
Assert.NotNull(capturedOptions);
|
||||
Assert.Equal(0, capturedOptions.TrialPeriodDays);
|
||||
@@ -329,7 +328,7 @@ public class OrganizationBillingServiceTests
|
||||
|
||||
SubscriptionCreateOptions capturedOptions = null;
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionCreateAsync(Arg.Do<SubscriptionCreateOptions>(options => capturedOptions = options))
|
||||
.CreateSubscriptionAsync(Arg.Do<SubscriptionCreateOptions>(options => capturedOptions = options))
|
||||
.Returns(new Subscription
|
||||
{
|
||||
Id = "sub_test123",
|
||||
@@ -346,7 +345,7 @@ public class OrganizationBillingServiceTests
|
||||
// Assert
|
||||
await sutProvider.GetDependency<IStripeAdapter>()
|
||||
.Received(1)
|
||||
.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
|
||||
Assert.NotNull(capturedOptions);
|
||||
Assert.Equal(7, capturedOptions.TrialPeriodDays);
|
||||
@@ -364,7 +363,7 @@ public class OrganizationBillingServiceTests
|
||||
|
||||
CustomerUpdateOptions capturedOptions = null;
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.CustomerUpdateAsync(
|
||||
.UpdateCustomerAsync(
|
||||
Arg.Is<string>(id => id == organization.GatewayCustomerId),
|
||||
Arg.Do<CustomerUpdateOptions>(options => capturedOptions = options))
|
||||
.Returns(new Customer());
|
||||
@@ -375,7 +374,7 @@ public class OrganizationBillingServiceTests
|
||||
// Assert
|
||||
await sutProvider.GetDependency<IStripeAdapter>()
|
||||
.Received(1)
|
||||
.CustomerUpdateAsync(
|
||||
.UpdateCustomerAsync(
|
||||
organization.GatewayCustomerId,
|
||||
Arg.Any<CustomerUpdateOptions>());
|
||||
|
||||
@@ -401,7 +400,7 @@ public class OrganizationBillingServiceTests
|
||||
|
||||
CustomerUpdateOptions capturedOptions = null;
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.CustomerUpdateAsync(
|
||||
.UpdateCustomerAsync(
|
||||
Arg.Is<string>(id => id == organization.GatewayCustomerId),
|
||||
Arg.Do<CustomerUpdateOptions>(options => capturedOptions = options))
|
||||
.Returns(new Customer());
|
||||
@@ -412,7 +411,7 @@ public class OrganizationBillingServiceTests
|
||||
// Assert
|
||||
await sutProvider.GetDependency<IStripeAdapter>()
|
||||
.Received(1)
|
||||
.CustomerUpdateAsync(
|
||||
.UpdateCustomerAsync(
|
||||
organization.GatewayCustomerId,
|
||||
Arg.Any<CustomerUpdateOptions>());
|
||||
|
||||
@@ -445,6 +444,6 @@ public class OrganizationBillingServiceTests
|
||||
|
||||
await sutProvider.GetDependency<IStripeAdapter>()
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>());
|
||||
.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Billing.Services.Implementations;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.BitStripe;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using NSubstitute;
|
||||
using Stripe;
|
||||
using Xunit;
|
||||
@@ -19,7 +19,7 @@ public class PaymentHistoryServiceTests
|
||||
var subscriber = new Organization { GatewayCustomerId = "cus_id", GatewaySubscriptionId = "sub_id" };
|
||||
var invoices = new List<Invoice> { new() { Id = "in_id" } };
|
||||
var stripeAdapter = Substitute.For<IStripeAdapter>();
|
||||
stripeAdapter.InvoiceListAsync(Arg.Any<StripeInvoiceListOptions>()).Returns(invoices);
|
||||
stripeAdapter.ListInvoicesAsync(Arg.Any<StripeInvoiceListOptions>()).Returns(invoices);
|
||||
var transactionRepository = Substitute.For<ITransactionRepository>();
|
||||
var paymentHistoryService = new PaymentHistoryService(stripeAdapter, transactionRepository);
|
||||
|
||||
@@ -29,7 +29,7 @@ public class PaymentHistoryServiceTests
|
||||
// Assert
|
||||
Assert.NotEmpty(result);
|
||||
Assert.Single(result);
|
||||
await stripeAdapter.Received(1).InvoiceListAsync(Arg.Any<StripeInvoiceListOptions>());
|
||||
await stripeAdapter.Received(1).ListInvoicesAsync(Arg.Any<StripeInvoiceListOptions>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
using Bit.Core.Billing.Constants;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Billing.Services.Implementations;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using NSubstitute;
|
||||
@@ -49,7 +50,7 @@ public class StripePaymentServiceTests
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionGetAsync(
|
||||
.GetSubscriptionAsync(
|
||||
subscriber.GatewaySubscriptionId,
|
||||
Arg.Any<SubscriptionGetOptions>())
|
||||
.Returns(subscription);
|
||||
@@ -100,7 +101,7 @@ public class StripePaymentServiceTests
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionGetAsync(
|
||||
.GetSubscriptionAsync(
|
||||
subscriber.GatewaySubscriptionId,
|
||||
Arg.Any<SubscriptionGetOptions>())
|
||||
.Returns(subscription);
|
||||
@@ -159,7 +160,7 @@ public class StripePaymentServiceTests
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionGetAsync(
|
||||
.GetSubscriptionAsync(
|
||||
subscriber.GatewaySubscriptionId,
|
||||
Arg.Any<SubscriptionGetOptions>())
|
||||
.Returns(subscription);
|
||||
@@ -198,7 +199,7 @@ public class StripePaymentServiceTests
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionGetAsync(
|
||||
.GetSubscriptionAsync(
|
||||
subscriber.GatewaySubscriptionId,
|
||||
Arg.Any<SubscriptionGetOptions>())
|
||||
.Returns(subscription);
|
||||
@@ -256,7 +257,7 @@ public class StripePaymentServiceTests
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionGetAsync(
|
||||
.GetSubscriptionAsync(
|
||||
subscriber.GatewaySubscriptionId,
|
||||
Arg.Any<SubscriptionGetOptions>())
|
||||
.Returns(subscription);
|
||||
@@ -295,7 +296,7 @@ public class StripePaymentServiceTests
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionGetAsync(
|
||||
.GetSubscriptionAsync(
|
||||
subscriber.GatewaySubscriptionId,
|
||||
Arg.Any<SubscriptionGetOptions>())
|
||||
.Returns(subscription);
|
||||
@@ -332,7 +333,7 @@ public class StripePaymentServiceTests
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionGetAsync(
|
||||
.GetSubscriptionAsync(
|
||||
subscriber.GatewaySubscriptionId,
|
||||
Arg.Any<SubscriptionGetOptions>())
|
||||
.Returns(subscription);
|
||||
@@ -367,7 +368,7 @@ public class StripePaymentServiceTests
|
||||
|
||||
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
|
||||
stripeAdapter
|
||||
.SubscriptionGetAsync(
|
||||
.GetSubscriptionAsync(
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<SubscriptionGetOptions>())
|
||||
.Returns(subscription);
|
||||
@@ -376,7 +377,7 @@ public class StripePaymentServiceTests
|
||||
await sutProvider.Sut.GetSubscriptionAsync(subscriber);
|
||||
|
||||
// Assert - Verify expand options are correct
|
||||
await stripeAdapter.Received(1).SubscriptionGetAsync(
|
||||
await stripeAdapter.Received(1).GetSubscriptionAsync(
|
||||
subscriber.GatewaySubscriptionId,
|
||||
Arg.Is<SubscriptionGetOptions>(o =>
|
||||
o.Expand.Contains("customer.discount.coupon.applies_to") &&
|
||||
@@ -405,6 +406,6 @@ public class StripePaymentServiceTests
|
||||
// Verify no Stripe API calls were made
|
||||
await sutProvider.GetDependency<IStripeAdapter>()
|
||||
.DidNotReceive()
|
||||
.SubscriptionGetAsync(Arg.Any<string>(), Arg.Any<SubscriptionGetOptions>());
|
||||
.GetSubscriptionAsync(Arg.Any<string>(), Arg.Any<SubscriptionGetOptions>());
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,10 @@ using Bit.Core.AdminConsole.Entities.Provider;
|
||||
using Bit.Core.Billing.Caches;
|
||||
using Bit.Core.Billing.Constants;
|
||||
using Bit.Core.Billing.Models;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Billing.Services.Implementations;
|
||||
using Bit.Core.Billing.Tax.Models;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
@@ -44,7 +44,7 @@ public class SubscriberServiceTests
|
||||
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
|
||||
|
||||
stripeAdapter
|
||||
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
|
||||
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
|
||||
.Returns(subscription);
|
||||
|
||||
await ThrowsBillingExceptionAsync(() =>
|
||||
@@ -52,11 +52,11 @@ public class SubscriberServiceTests
|
||||
|
||||
await stripeAdapter
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
.SubscriptionUpdateAsync(Arg.Any<string>(), Arg.Any<SubscriptionUpdateOptions>());
|
||||
.UpdateSubscriptionAsync(Arg.Any<string>(), Arg.Any<SubscriptionUpdateOptions>());
|
||||
|
||||
await stripeAdapter
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
.SubscriptionCancelAsync(Arg.Any<string>(), Arg.Any<SubscriptionCancelOptions>());
|
||||
.CancelSubscriptionAsync(Arg.Any<string>(), Arg.Any<SubscriptionCancelOptions>());
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
@@ -81,7 +81,7 @@ public class SubscriberServiceTests
|
||||
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
|
||||
|
||||
stripeAdapter
|
||||
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
|
||||
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
|
||||
.Returns(subscription);
|
||||
|
||||
var offboardingSurveyResponse = new OffboardingSurveyResponse
|
||||
@@ -95,12 +95,12 @@ public class SubscriberServiceTests
|
||||
|
||||
await stripeAdapter
|
||||
.Received(1)
|
||||
.SubscriptionUpdateAsync(subscriptionId, Arg.Is<SubscriptionUpdateOptions>(
|
||||
.UpdateSubscriptionAsync(subscriptionId, Arg.Is<SubscriptionUpdateOptions>(
|
||||
options => options.Metadata["cancellingUserId"] == userId.ToString()));
|
||||
|
||||
await stripeAdapter
|
||||
.Received(1)
|
||||
.SubscriptionCancelAsync(subscriptionId, Arg.Is<SubscriptionCancelOptions>(options =>
|
||||
.CancelSubscriptionAsync(subscriptionId, Arg.Is<SubscriptionCancelOptions>(options =>
|
||||
options.CancellationDetails.Comment == offboardingSurveyResponse.Feedback &&
|
||||
options.CancellationDetails.Feedback == offboardingSurveyResponse.Reason));
|
||||
}
|
||||
@@ -127,7 +127,7 @@ public class SubscriberServiceTests
|
||||
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
|
||||
|
||||
stripeAdapter
|
||||
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
|
||||
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
|
||||
.Returns(subscription);
|
||||
|
||||
var offboardingSurveyResponse = new OffboardingSurveyResponse
|
||||
@@ -141,11 +141,11 @@ public class SubscriberServiceTests
|
||||
|
||||
await stripeAdapter
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
.SubscriptionUpdateAsync(Arg.Any<string>(), Arg.Any<SubscriptionUpdateOptions>());
|
||||
.UpdateSubscriptionAsync(Arg.Any<string>(), Arg.Any<SubscriptionUpdateOptions>());
|
||||
|
||||
await stripeAdapter
|
||||
.Received(1)
|
||||
.SubscriptionCancelAsync(subscriptionId, Arg.Is<SubscriptionCancelOptions>(options =>
|
||||
.CancelSubscriptionAsync(subscriptionId, Arg.Is<SubscriptionCancelOptions>(options =>
|
||||
options.CancellationDetails.Comment == offboardingSurveyResponse.Feedback &&
|
||||
options.CancellationDetails.Feedback == offboardingSurveyResponse.Reason));
|
||||
}
|
||||
@@ -170,7 +170,7 @@ public class SubscriberServiceTests
|
||||
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
|
||||
|
||||
stripeAdapter
|
||||
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
|
||||
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
|
||||
.Returns(subscription);
|
||||
|
||||
var offboardingSurveyResponse = new OffboardingSurveyResponse
|
||||
@@ -184,7 +184,7 @@ public class SubscriberServiceTests
|
||||
|
||||
await stripeAdapter
|
||||
.Received(1)
|
||||
.SubscriptionUpdateAsync(subscriptionId, Arg.Is<SubscriptionUpdateOptions>(options =>
|
||||
.UpdateSubscriptionAsync(subscriptionId, Arg.Is<SubscriptionUpdateOptions>(options =>
|
||||
options.CancelAtPeriodEnd == true &&
|
||||
options.CancellationDetails.Comment == offboardingSurveyResponse.Feedback &&
|
||||
options.CancellationDetails.Feedback == offboardingSurveyResponse.Reason &&
|
||||
@@ -192,7 +192,7 @@ public class SubscriberServiceTests
|
||||
|
||||
await stripeAdapter
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
.SubscriptionCancelAsync(Arg.Any<string>(), Arg.Any<SubscriptionCancelOptions>());
|
||||
.CancelSubscriptionAsync(Arg.Any<string>(), Arg.Any<SubscriptionCancelOptions>());
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -223,7 +223,7 @@ public class SubscriberServiceTests
|
||||
SutProvider<SubscriberService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.CustomerGetAsync(organization.GatewayCustomerId)
|
||||
.GetCustomerAsync(organization.GatewayCustomerId)
|
||||
.ReturnsNull();
|
||||
|
||||
var customer = await sutProvider.Sut.GetCustomer(organization);
|
||||
@@ -237,7 +237,7 @@ public class SubscriberServiceTests
|
||||
SutProvider<SubscriberService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.CustomerGetAsync(organization.GatewayCustomerId)
|
||||
.GetCustomerAsync(organization.GatewayCustomerId)
|
||||
.ThrowsAsync<StripeException>();
|
||||
|
||||
var customer = await sutProvider.Sut.GetCustomer(organization);
|
||||
@@ -253,7 +253,7 @@ public class SubscriberServiceTests
|
||||
var customer = new Customer();
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.CustomerGetAsync(organization.GatewayCustomerId)
|
||||
.GetCustomerAsync(organization.GatewayCustomerId)
|
||||
.Returns(customer);
|
||||
|
||||
var gotCustomer = await sutProvider.Sut.GetCustomer(organization);
|
||||
@@ -287,7 +287,7 @@ public class SubscriberServiceTests
|
||||
SutProvider<SubscriberService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.CustomerGetAsync(organization.GatewayCustomerId)
|
||||
.GetCustomerAsync(organization.GatewayCustomerId)
|
||||
.ReturnsNull();
|
||||
|
||||
await ThrowsBillingExceptionAsync(async () => await sutProvider.Sut.GetCustomerOrThrow(organization));
|
||||
@@ -301,7 +301,7 @@ public class SubscriberServiceTests
|
||||
var stripeException = new StripeException();
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.CustomerGetAsync(organization.GatewayCustomerId)
|
||||
.GetCustomerAsync(organization.GatewayCustomerId)
|
||||
.ThrowsAsync(stripeException);
|
||||
|
||||
await ThrowsBillingExceptionAsync(
|
||||
@@ -318,7 +318,7 @@ public class SubscriberServiceTests
|
||||
var customer = new Customer();
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.CustomerGetAsync(organization.GatewayCustomerId)
|
||||
.GetCustomerAsync(organization.GatewayCustomerId)
|
||||
.Returns(customer);
|
||||
|
||||
var gotCustomer = await sutProvider.Sut.GetCustomerOrThrow(organization);
|
||||
@@ -351,7 +351,7 @@ public class SubscriberServiceTests
|
||||
}
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId,
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId,
|
||||
Arg.Is<CustomerGetOptions>(
|
||||
options => options.Expand.Contains("default_source") &&
|
||||
options.Expand.Contains("invoice_settings.default_payment_method")))
|
||||
@@ -388,7 +388,7 @@ public class SubscriberServiceTests
|
||||
}
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId,
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId,
|
||||
Arg.Is<CustomerGetOptions>(
|
||||
options => options.Expand.Contains("default_source") &&
|
||||
options.Expand.Contains("invoice_settings.default_payment_method")))
|
||||
@@ -442,7 +442,7 @@ public class SubscriberServiceTests
|
||||
}
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId,
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId,
|
||||
Arg.Is<CustomerGetOptions>(
|
||||
options => options.Expand.Contains("default_source") &&
|
||||
options.Expand.Contains("invoice_settings.default_payment_method")))
|
||||
@@ -478,7 +478,7 @@ public class SubscriberServiceTests
|
||||
}
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId,
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId,
|
||||
Arg.Is<CustomerGetOptions>(
|
||||
options => options.Expand.Contains("default_source") &&
|
||||
options.Expand.Contains("invoice_settings.default_payment_method")))
|
||||
@@ -498,7 +498,7 @@ public class SubscriberServiceTests
|
||||
{
|
||||
var customer = new Customer { Id = provider.GatewayCustomerId };
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId,
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId,
|
||||
Arg.Is<CustomerGetOptions>(options => options.Expand.Contains("default_source") &&
|
||||
options.Expand.Contains(
|
||||
"invoice_settings.default_payment_method")))
|
||||
@@ -521,7 +521,7 @@ public class SubscriberServiceTests
|
||||
|
||||
sutProvider.GetDependency<ISetupIntentCache>().GetSetupIntentIdForSubscriber(provider.Id).Returns(setupIntent.Id);
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().SetupIntentGet(setupIntent.Id,
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetSetupIntentAsync(setupIntent.Id,
|
||||
Arg.Is<SetupIntentGetOptions>(options => options.Expand.Contains("payment_method"))).Returns(setupIntent);
|
||||
|
||||
var paymentMethod = await sutProvider.Sut.GetPaymentSource(provider);
|
||||
@@ -541,7 +541,7 @@ public class SubscriberServiceTests
|
||||
DefaultSource = new BankAccount { Status = "verified", BankName = "Chase", Last4 = "9999" }
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId,
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId,
|
||||
Arg.Is<CustomerGetOptions>(options => options.Expand.Contains("default_source") &&
|
||||
options.Expand.Contains(
|
||||
"invoice_settings.default_payment_method")))
|
||||
@@ -564,7 +564,7 @@ public class SubscriberServiceTests
|
||||
DefaultSource = new Card { Brand = "Visa", Last4 = "9999", ExpMonth = 9, ExpYear = 2028 }
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId,
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId,
|
||||
Arg.Is<CustomerGetOptions>(options => options.Expand.Contains("default_source") &&
|
||||
options.Expand.Contains(
|
||||
"invoice_settings.default_payment_method")))
|
||||
@@ -596,7 +596,7 @@ public class SubscriberServiceTests
|
||||
}
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId,
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId,
|
||||
Arg.Is<CustomerGetOptions>(
|
||||
options => options.Expand.Contains("default_source") &&
|
||||
options.Expand.Contains("invoice_settings.default_payment_method")))
|
||||
@@ -636,7 +636,7 @@ public class SubscriberServiceTests
|
||||
SutProvider<SubscriberService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
|
||||
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
|
||||
.ReturnsNull();
|
||||
|
||||
var subscription = await sutProvider.Sut.GetSubscription(organization);
|
||||
@@ -650,7 +650,7 @@ public class SubscriberServiceTests
|
||||
SutProvider<SubscriberService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
|
||||
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
|
||||
.ThrowsAsync<StripeException>();
|
||||
|
||||
var subscription = await sutProvider.Sut.GetSubscription(organization);
|
||||
@@ -666,7 +666,7 @@ public class SubscriberServiceTests
|
||||
var subscription = new Subscription();
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
|
||||
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
|
||||
.Returns(subscription);
|
||||
|
||||
var gotSubscription = await sutProvider.Sut.GetSubscription(organization);
|
||||
@@ -698,7 +698,7 @@ public class SubscriberServiceTests
|
||||
SutProvider<SubscriberService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
|
||||
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
|
||||
.ReturnsNull();
|
||||
|
||||
await ThrowsBillingExceptionAsync(async () => await sutProvider.Sut.GetSubscriptionOrThrow(organization));
|
||||
@@ -712,7 +712,7 @@ public class SubscriberServiceTests
|
||||
var stripeException = new StripeException();
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
|
||||
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
|
||||
.ThrowsAsync(stripeException);
|
||||
|
||||
await ThrowsBillingExceptionAsync(
|
||||
@@ -729,7 +729,7 @@ public class SubscriberServiceTests
|
||||
var subscription = new Subscription();
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
|
||||
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
|
||||
.Returns(subscription);
|
||||
|
||||
var gotSubscription = await sutProvider.Sut.GetSubscriptionOrThrow(organization);
|
||||
@@ -760,7 +760,7 @@ public class SubscriberServiceTests
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.CustomerGetAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
|
||||
.GetCustomerAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
|
||||
.Returns(stripeCustomer);
|
||||
|
||||
var (braintreeGateway, customerGateway, paymentMethodGateway) = SetupBraintree(sutProvider.GetDependency<IBraintreeGateway>());
|
||||
@@ -795,7 +795,7 @@ public class SubscriberServiceTests
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.CustomerGetAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
|
||||
.GetCustomerAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
|
||||
.Returns(stripeCustomer);
|
||||
|
||||
var (_, customerGateway, paymentMethodGateway) = SetupBraintree(sutProvider.GetDependency<IBraintreeGateway>());
|
||||
@@ -832,7 +832,7 @@ public class SubscriberServiceTests
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.CustomerGetAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
|
||||
.GetCustomerAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
|
||||
.Returns(stripeCustomer);
|
||||
|
||||
var (_, customerGateway, paymentMethodGateway) = SetupBraintree(sutProvider.GetDependency<IBraintreeGateway>());
|
||||
@@ -887,7 +887,7 @@ public class SubscriberServiceTests
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.CustomerGetAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
|
||||
.GetCustomerAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
|
||||
.Returns(stripeCustomer);
|
||||
|
||||
var (_, customerGateway, paymentMethodGateway) = SetupBraintree(sutProvider.GetDependency<IBraintreeGateway>());
|
||||
@@ -946,21 +946,21 @@ public class SubscriberServiceTests
|
||||
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
|
||||
|
||||
stripeAdapter
|
||||
.CustomerGetAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
|
||||
.GetCustomerAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
|
||||
.Returns(stripeCustomer);
|
||||
|
||||
stripeAdapter
|
||||
.PaymentMethodListAutoPagingAsync(Arg.Any<PaymentMethodListOptions>())
|
||||
.ListPaymentMethodsAutoPagingAsync(Arg.Any<PaymentMethodListOptions>())
|
||||
.Returns(GetPaymentMethodsAsync(new List<PaymentMethod>()));
|
||||
|
||||
await sutProvider.Sut.RemovePaymentSource(organization);
|
||||
|
||||
await stripeAdapter.Received(1).BankAccountDeleteAsync(stripeCustomer.Id, bankAccountId);
|
||||
await stripeAdapter.Received(1).DeleteBankAccountAsync(stripeCustomer.Id, bankAccountId);
|
||||
|
||||
await stripeAdapter.Received(1).CardDeleteAsync(stripeCustomer.Id, cardId);
|
||||
await stripeAdapter.Received(1).DeleteCardAsync(stripeCustomer.Id, cardId);
|
||||
|
||||
await stripeAdapter.DidNotReceiveWithAnyArgs()
|
||||
.PaymentMethodDetachAsync(Arg.Any<string>(), Arg.Any<PaymentMethodDetachOptions>());
|
||||
.DetachPaymentMethodAsync(Arg.Any<string>(), Arg.Any<PaymentMethodDetachOptions>());
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
@@ -978,11 +978,11 @@ public class SubscriberServiceTests
|
||||
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
|
||||
|
||||
stripeAdapter
|
||||
.CustomerGetAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
|
||||
.GetCustomerAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
|
||||
.Returns(stripeCustomer);
|
||||
|
||||
stripeAdapter
|
||||
.PaymentMethodListAutoPagingAsync(Arg.Any<PaymentMethodListOptions>())
|
||||
.ListPaymentMethodsAutoPagingAsync(Arg.Any<PaymentMethodListOptions>())
|
||||
.Returns(GetPaymentMethodsAsync(new List<PaymentMethod>
|
||||
{
|
||||
new ()
|
||||
@@ -997,15 +997,15 @@ public class SubscriberServiceTests
|
||||
|
||||
await sutProvider.Sut.RemovePaymentSource(organization);
|
||||
|
||||
await stripeAdapter.DidNotReceiveWithAnyArgs().BankAccountDeleteAsync(Arg.Any<string>(), Arg.Any<string>());
|
||||
await stripeAdapter.DidNotReceiveWithAnyArgs().DeleteBankAccountAsync(Arg.Any<string>(), Arg.Any<string>());
|
||||
|
||||
await stripeAdapter.DidNotReceiveWithAnyArgs().CardDeleteAsync(Arg.Any<string>(), Arg.Any<string>());
|
||||
await stripeAdapter.DidNotReceiveWithAnyArgs().DeleteCardAsync(Arg.Any<string>(), Arg.Any<string>());
|
||||
|
||||
await stripeAdapter.Received(1)
|
||||
.PaymentMethodDetachAsync(bankAccountId);
|
||||
.DetachPaymentMethodAsync(bankAccountId);
|
||||
|
||||
await stripeAdapter.Received(1)
|
||||
.PaymentMethodDetachAsync(cardId);
|
||||
.DetachPaymentMethodAsync(cardId);
|
||||
}
|
||||
|
||||
private static async IAsyncEnumerable<PaymentMethod> GetPaymentMethodsAsync(
|
||||
@@ -1050,7 +1050,7 @@ public class SubscriberServiceTests
|
||||
Provider provider,
|
||||
SutProvider<SubscriberService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId)
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId)
|
||||
.Returns(new Customer());
|
||||
|
||||
await ThrowsBillingExceptionAsync(() =>
|
||||
@@ -1062,7 +1062,7 @@ public class SubscriberServiceTests
|
||||
Provider provider,
|
||||
SutProvider<SubscriberService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId)
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId)
|
||||
.Returns(new Customer());
|
||||
|
||||
await ThrowsBillingExceptionAsync(() =>
|
||||
@@ -1076,10 +1076,10 @@ public class SubscriberServiceTests
|
||||
{
|
||||
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
|
||||
|
||||
stripeAdapter.CustomerGetAsync(provider.GatewayCustomerId)
|
||||
stripeAdapter.GetCustomerAsync(provider.GatewayCustomerId)
|
||||
.Returns(new Customer());
|
||||
|
||||
stripeAdapter.SetupIntentList(Arg.Is<SetupIntentListOptions>(options => options.PaymentMethod == "TOKEN"))
|
||||
stripeAdapter.ListSetupIntentsAsync(Arg.Is<SetupIntentListOptions>(options => options.PaymentMethod == "TOKEN"))
|
||||
.Returns([new SetupIntent(), new SetupIntent()]);
|
||||
|
||||
await ThrowsBillingExceptionAsync(() =>
|
||||
@@ -1093,7 +1093,7 @@ public class SubscriberServiceTests
|
||||
{
|
||||
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
|
||||
|
||||
stripeAdapter.CustomerGetAsync(
|
||||
stripeAdapter.GetCustomerAsync(
|
||||
provider.GatewayCustomerId,
|
||||
Arg.Is<CustomerGetOptions>(p => p.Expand.Contains("tax") || p.Expand.Contains("tax_ids")))
|
||||
.Returns(new Customer
|
||||
@@ -1107,10 +1107,10 @@ public class SubscriberServiceTests
|
||||
|
||||
var matchingSetupIntent = new SetupIntent { Id = "setup_intent_1" };
|
||||
|
||||
stripeAdapter.SetupIntentList(Arg.Is<SetupIntentListOptions>(options => options.PaymentMethod == "TOKEN"))
|
||||
stripeAdapter.ListSetupIntentsAsync(Arg.Is<SetupIntentListOptions>(options => options.PaymentMethod == "TOKEN"))
|
||||
.Returns([matchingSetupIntent]);
|
||||
|
||||
stripeAdapter.CustomerListPaymentMethods(provider.GatewayCustomerId).Returns([
|
||||
stripeAdapter.ListCustomerPaymentMethodsAsync(provider.GatewayCustomerId).Returns([
|
||||
new PaymentMethod { Id = "payment_method_1" }
|
||||
]);
|
||||
|
||||
@@ -1119,12 +1119,12 @@ public class SubscriberServiceTests
|
||||
|
||||
await sutProvider.GetDependency<ISetupIntentCache>().Received(1).Set(provider.Id, "setup_intent_1");
|
||||
|
||||
await stripeAdapter.DidNotReceive().SetupIntentCancel(Arg.Any<string>(),
|
||||
await stripeAdapter.DidNotReceive().CancelSetupIntentAsync(Arg.Any<string>(),
|
||||
Arg.Any<SetupIntentCancelOptions>());
|
||||
|
||||
await stripeAdapter.Received(1).PaymentMethodDetachAsync("payment_method_1");
|
||||
await stripeAdapter.Received(1).DetachPaymentMethodAsync("payment_method_1");
|
||||
|
||||
await stripeAdapter.Received(1).CustomerUpdateAsync(provider.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(
|
||||
await stripeAdapter.Received(1).UpdateCustomerAsync(provider.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(
|
||||
options => options.Metadata[Core.Billing.Utilities.BraintreeCustomerIdKey] == null));
|
||||
}
|
||||
|
||||
@@ -1135,7 +1135,7 @@ public class SubscriberServiceTests
|
||||
{
|
||||
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
|
||||
|
||||
stripeAdapter.CustomerGetAsync(
|
||||
stripeAdapter.GetCustomerAsync(
|
||||
provider.GatewayCustomerId,
|
||||
Arg.Is<CustomerGetOptions>(p => p.Expand.Contains("tax") || p.Expand.Contains("tax_ids"))
|
||||
)
|
||||
@@ -1148,22 +1148,22 @@ public class SubscriberServiceTests
|
||||
}
|
||||
});
|
||||
|
||||
stripeAdapter.CustomerListPaymentMethods(provider.GatewayCustomerId).Returns([
|
||||
stripeAdapter.ListCustomerPaymentMethodsAsync(provider.GatewayCustomerId).Returns([
|
||||
new PaymentMethod { Id = "payment_method_1" }
|
||||
]);
|
||||
|
||||
await sutProvider.Sut.UpdatePaymentSource(provider,
|
||||
new TokenizedPaymentSource(PaymentMethodType.Card, "TOKEN"));
|
||||
|
||||
await stripeAdapter.DidNotReceive().SetupIntentCancel(Arg.Any<string>(),
|
||||
await stripeAdapter.DidNotReceive().CancelSetupIntentAsync(Arg.Any<string>(),
|
||||
Arg.Any<SetupIntentCancelOptions>());
|
||||
|
||||
await stripeAdapter.Received(1).PaymentMethodDetachAsync("payment_method_1");
|
||||
await stripeAdapter.Received(1).DetachPaymentMethodAsync("payment_method_1");
|
||||
|
||||
await stripeAdapter.Received(1).PaymentMethodAttachAsync("TOKEN", Arg.Is<PaymentMethodAttachOptions>(
|
||||
await stripeAdapter.Received(1).AttachPaymentMethodAsync("TOKEN", Arg.Is<PaymentMethodAttachOptions>(
|
||||
options => options.Customer == provider.GatewayCustomerId));
|
||||
|
||||
await stripeAdapter.Received(1).CustomerUpdateAsync(provider.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(
|
||||
await stripeAdapter.Received(1).UpdateCustomerAsync(provider.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(
|
||||
options =>
|
||||
options.InvoiceSettings.DefaultPaymentMethod == "TOKEN" &&
|
||||
options.Metadata[Core.Billing.Utilities.BraintreeCustomerIdKey] == null));
|
||||
@@ -1176,7 +1176,7 @@ public class SubscriberServiceTests
|
||||
{
|
||||
const string braintreeCustomerId = "braintree_customer_id";
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId)
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId)
|
||||
.Returns(new Customer
|
||||
{
|
||||
Id = provider.GatewayCustomerId,
|
||||
@@ -1202,7 +1202,7 @@ public class SubscriberServiceTests
|
||||
{
|
||||
const string braintreeCustomerId = "braintree_customer_id";
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId)
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId)
|
||||
.Returns(new Customer
|
||||
{
|
||||
Id = provider.GatewayCustomerId,
|
||||
@@ -1240,7 +1240,7 @@ public class SubscriberServiceTests
|
||||
{
|
||||
const string braintreeCustomerId = "braintree_customer_id";
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(
|
||||
provider.GatewayCustomerId,
|
||||
Arg.Is<CustomerGetOptions>(p => p.Expand.Contains("tax") || p.Expand.Contains("tax_ids")))
|
||||
.Returns(new Customer
|
||||
@@ -1294,7 +1294,7 @@ public class SubscriberServiceTests
|
||||
{
|
||||
const string braintreeCustomerId = "braintree_customer_id";
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(
|
||||
provider.GatewayCustomerId,
|
||||
Arg.Is<CustomerGetOptions>(p => p.Expand.Contains("tax") || p.Expand.Contains("tax_ids")))
|
||||
.Returns(new Customer
|
||||
@@ -1363,7 +1363,7 @@ public class SubscriberServiceTests
|
||||
{
|
||||
const string braintreeCustomerId = "braintree_customer_id";
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId)
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId)
|
||||
.Returns(new Customer
|
||||
{
|
||||
Id = provider.GatewayCustomerId
|
||||
@@ -1395,7 +1395,7 @@ public class SubscriberServiceTests
|
||||
new TokenizedPaymentSource(PaymentMethodType.PayPal, "TOKEN")));
|
||||
|
||||
await sutProvider.GetDependency<IStripeAdapter>().DidNotReceiveWithAnyArgs()
|
||||
.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>());
|
||||
.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>());
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
@@ -1405,7 +1405,7 @@ public class SubscriberServiceTests
|
||||
{
|
||||
const string braintreeCustomerId = "braintree_customer_id";
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(
|
||||
provider.GatewayCustomerId,
|
||||
Arg.Is<CustomerGetOptions>(p => p.Expand.Contains("tax") || p.Expand.Contains("tax_ids")))
|
||||
.Returns(new Customer
|
||||
@@ -1442,7 +1442,7 @@ public class SubscriberServiceTests
|
||||
await sutProvider.Sut.UpdatePaymentSource(provider,
|
||||
new TokenizedPaymentSource(PaymentMethodType.PayPal, "TOKEN"));
|
||||
|
||||
await sutProvider.GetDependency<IStripeAdapter>().Received(1).CustomerUpdateAsync(provider.GatewayCustomerId,
|
||||
await sutProvider.GetDependency<IStripeAdapter>().Received(1).UpdateCustomerAsync(provider.GatewayCustomerId,
|
||||
Arg.Is<CustomerUpdateOptions>(
|
||||
options => options.Metadata[Core.Billing.Utilities.BraintreeCustomerIdKey] == braintreeCustomerId));
|
||||
}
|
||||
@@ -1473,7 +1473,7 @@ public class SubscriberServiceTests
|
||||
|
||||
var customer = new Customer { Id = provider.GatewayCustomerId, TaxIds = new StripeList<TaxId> { Data = [new TaxId { Id = "tax_id_1", Type = "us_ein" }] } };
|
||||
|
||||
stripeAdapter.CustomerGetAsync(provider.GatewayCustomerId, Arg.Is<CustomerGetOptions>(
|
||||
stripeAdapter.GetCustomerAsync(provider.GatewayCustomerId, Arg.Is<CustomerGetOptions>(
|
||||
options => options.Expand.Contains("tax_ids"))).Returns(customer);
|
||||
|
||||
var taxInformation = new TaxInformation(
|
||||
@@ -1487,7 +1487,7 @@ public class SubscriberServiceTests
|
||||
"NY");
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.CustomerUpdateAsync(
|
||||
.UpdateCustomerAsync(
|
||||
Arg.Is<string>(p => p == provider.GatewayCustomerId),
|
||||
Arg.Is<CustomerUpdateOptions>(options =>
|
||||
options.Address.Country == "US" &&
|
||||
@@ -1522,12 +1522,12 @@ public class SubscriberServiceTests
|
||||
});
|
||||
|
||||
var subscription = new Subscription { Items = new StripeList<SubscriptionItem>() };
|
||||
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(Arg.Any<string>())
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetSubscriptionAsync(Arg.Any<string>())
|
||||
.Returns(subscription);
|
||||
|
||||
await sutProvider.Sut.UpdateTaxInformation(provider, taxInformation);
|
||||
|
||||
await stripeAdapter.Received(1).CustomerUpdateAsync(provider.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(
|
||||
await stripeAdapter.Received(1).UpdateCustomerAsync(provider.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(
|
||||
options =>
|
||||
options.Address.Country == taxInformation.Country &&
|
||||
options.Address.PostalCode == taxInformation.PostalCode &&
|
||||
@@ -1536,13 +1536,13 @@ public class SubscriberServiceTests
|
||||
options.Address.City == taxInformation.City &&
|
||||
options.Address.State == taxInformation.State));
|
||||
|
||||
await stripeAdapter.Received(1).TaxIdDeleteAsync(provider.GatewayCustomerId, "tax_id_1");
|
||||
await stripeAdapter.Received(1).DeleteTaxIdAsync(provider.GatewayCustomerId, "tax_id_1");
|
||||
|
||||
await stripeAdapter.Received(1).TaxIdCreateAsync(provider.GatewayCustomerId, Arg.Is<TaxIdCreateOptions>(
|
||||
await stripeAdapter.Received(1).CreateTaxIdAsync(provider.GatewayCustomerId, Arg.Is<TaxIdCreateOptions>(
|
||||
options => options.Type == "us_ein" &&
|
||||
options.Value == taxInformation.TaxId));
|
||||
|
||||
await stripeAdapter.Received(1).SubscriptionUpdateAsync(provider.GatewaySubscriptionId,
|
||||
await stripeAdapter.Received(1).UpdateSubscriptionAsync(provider.GatewaySubscriptionId,
|
||||
Arg.Is<SubscriptionUpdateOptions>(options => options.AutomaticTax.Enabled == true));
|
||||
}
|
||||
|
||||
@@ -1555,7 +1555,7 @@ public class SubscriberServiceTests
|
||||
|
||||
var customer = new Customer { Id = provider.GatewayCustomerId, TaxIds = new StripeList<TaxId> { Data = [new TaxId { Id = "tax_id_1", Type = "us_ein" }] } };
|
||||
|
||||
stripeAdapter.CustomerGetAsync(provider.GatewayCustomerId, Arg.Is<CustomerGetOptions>(
|
||||
stripeAdapter.GetCustomerAsync(provider.GatewayCustomerId, Arg.Is<CustomerGetOptions>(
|
||||
options => options.Expand.Contains("tax_ids"))).Returns(customer);
|
||||
|
||||
var taxInformation = new TaxInformation(
|
||||
@@ -1569,7 +1569,7 @@ public class SubscriberServiceTests
|
||||
"NY");
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.CustomerUpdateAsync(
|
||||
.UpdateCustomerAsync(
|
||||
Arg.Is<string>(p => p == provider.GatewayCustomerId),
|
||||
Arg.Is<CustomerUpdateOptions>(options =>
|
||||
options.Address.Country == "CA" &&
|
||||
@@ -1605,12 +1605,12 @@ public class SubscriberServiceTests
|
||||
});
|
||||
|
||||
var subscription = new Subscription { Items = new StripeList<SubscriptionItem>() };
|
||||
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(Arg.Any<string>())
|
||||
sutProvider.GetDependency<IStripeAdapter>().GetSubscriptionAsync(Arg.Any<string>())
|
||||
.Returns(subscription);
|
||||
|
||||
await sutProvider.Sut.UpdateTaxInformation(provider, taxInformation);
|
||||
|
||||
await stripeAdapter.Received(1).CustomerUpdateAsync(provider.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(
|
||||
await stripeAdapter.Received(1).UpdateCustomerAsync(provider.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(
|
||||
options =>
|
||||
options.Address.Country == taxInformation.Country &&
|
||||
options.Address.PostalCode == taxInformation.PostalCode &&
|
||||
@@ -1619,16 +1619,16 @@ public class SubscriberServiceTests
|
||||
options.Address.City == taxInformation.City &&
|
||||
options.Address.State == taxInformation.State));
|
||||
|
||||
await stripeAdapter.Received(1).TaxIdDeleteAsync(provider.GatewayCustomerId, "tax_id_1");
|
||||
await stripeAdapter.Received(1).DeleteTaxIdAsync(provider.GatewayCustomerId, "tax_id_1");
|
||||
|
||||
await stripeAdapter.Received(1).TaxIdCreateAsync(provider.GatewayCustomerId, Arg.Is<TaxIdCreateOptions>(
|
||||
await stripeAdapter.Received(1).CreateTaxIdAsync(provider.GatewayCustomerId, Arg.Is<TaxIdCreateOptions>(
|
||||
options => options.Type == "us_ein" &&
|
||||
options.Value == taxInformation.TaxId));
|
||||
|
||||
await stripeAdapter.Received(1).CustomerUpdateAsync(provider.GatewayCustomerId,
|
||||
await stripeAdapter.Received(1).UpdateCustomerAsync(provider.GatewayCustomerId,
|
||||
Arg.Is<CustomerUpdateOptions>(options => options.TaxExempt == StripeConstants.TaxExempt.Reverse));
|
||||
|
||||
await stripeAdapter.Received(1).SubscriptionUpdateAsync(provider.GatewaySubscriptionId,
|
||||
await stripeAdapter.Received(1).UpdateSubscriptionAsync(provider.GatewaySubscriptionId,
|
||||
Arg.Is<SubscriptionUpdateOptions>(options => options.AutomaticTax.Enabled == true));
|
||||
}
|
||||
|
||||
@@ -1655,7 +1655,7 @@ public class SubscriberServiceTests
|
||||
|
||||
Assert.True(result);
|
||||
await sutProvider.GetDependency<IStripeAdapter>().DidNotReceiveWithAnyArgs()
|
||||
.CustomerGetAsync(Arg.Any<string>());
|
||||
.GetCustomerAsync(Arg.Any<string>());
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
@@ -1669,7 +1669,7 @@ public class SubscriberServiceTests
|
||||
|
||||
Assert.True(result);
|
||||
await sutProvider.GetDependency<IStripeAdapter>().DidNotReceiveWithAnyArgs()
|
||||
.CustomerGetAsync(Arg.Any<string>());
|
||||
.GetCustomerAsync(Arg.Any<string>());
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
@@ -1678,12 +1678,12 @@ public class SubscriberServiceTests
|
||||
SutProvider<SubscriberService> sutProvider)
|
||||
{
|
||||
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
|
||||
stripeAdapter.CustomerGetAsync(organization.GatewayCustomerId).Returns(new Customer());
|
||||
stripeAdapter.GetCustomerAsync(organization.GatewayCustomerId).Returns(new Customer());
|
||||
|
||||
var result = await sutProvider.Sut.IsValidGatewayCustomerIdAsync(organization);
|
||||
|
||||
Assert.True(result);
|
||||
await stripeAdapter.Received(1).CustomerGetAsync(organization.GatewayCustomerId);
|
||||
await stripeAdapter.Received(1).GetCustomerAsync(organization.GatewayCustomerId);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
@@ -1693,12 +1693,12 @@ public class SubscriberServiceTests
|
||||
{
|
||||
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
|
||||
var stripeException = new StripeException { StripeError = new StripeError { Code = "resource_missing" } };
|
||||
stripeAdapter.CustomerGetAsync(organization.GatewayCustomerId).Throws(stripeException);
|
||||
stripeAdapter.GetCustomerAsync(organization.GatewayCustomerId).Throws(stripeException);
|
||||
|
||||
var result = await sutProvider.Sut.IsValidGatewayCustomerIdAsync(organization);
|
||||
|
||||
Assert.False(result);
|
||||
await stripeAdapter.Received(1).CustomerGetAsync(organization.GatewayCustomerId);
|
||||
await stripeAdapter.Received(1).GetCustomerAsync(organization.GatewayCustomerId);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -1724,7 +1724,7 @@ public class SubscriberServiceTests
|
||||
|
||||
Assert.True(result);
|
||||
await sutProvider.GetDependency<IStripeAdapter>().DidNotReceiveWithAnyArgs()
|
||||
.SubscriptionGetAsync(Arg.Any<string>());
|
||||
.GetSubscriptionAsync(Arg.Any<string>());
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
@@ -1738,7 +1738,7 @@ public class SubscriberServiceTests
|
||||
|
||||
Assert.True(result);
|
||||
await sutProvider.GetDependency<IStripeAdapter>().DidNotReceiveWithAnyArgs()
|
||||
.SubscriptionGetAsync(Arg.Any<string>());
|
||||
.GetSubscriptionAsync(Arg.Any<string>());
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
@@ -1747,12 +1747,12 @@ public class SubscriberServiceTests
|
||||
SutProvider<SubscriberService> sutProvider)
|
||||
{
|
||||
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
|
||||
stripeAdapter.SubscriptionGetAsync(organization.GatewaySubscriptionId).Returns(new Subscription());
|
||||
stripeAdapter.GetSubscriptionAsync(organization.GatewaySubscriptionId).Returns(new Subscription());
|
||||
|
||||
var result = await sutProvider.Sut.IsValidGatewaySubscriptionIdAsync(organization);
|
||||
|
||||
Assert.True(result);
|
||||
await stripeAdapter.Received(1).SubscriptionGetAsync(organization.GatewaySubscriptionId);
|
||||
await stripeAdapter.Received(1).GetSubscriptionAsync(organization.GatewaySubscriptionId);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
@@ -1762,12 +1762,12 @@ public class SubscriberServiceTests
|
||||
{
|
||||
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
|
||||
var stripeException = new StripeException { StripeError = new StripeError { Code = "resource_missing" } };
|
||||
stripeAdapter.SubscriptionGetAsync(organization.GatewaySubscriptionId).Throws(stripeException);
|
||||
stripeAdapter.GetSubscriptionAsync(organization.GatewaySubscriptionId).Throws(stripeException);
|
||||
|
||||
var result = await sutProvider.Sut.IsValidGatewaySubscriptionIdAsync(organization);
|
||||
|
||||
Assert.False(result);
|
||||
await stripeAdapter.Received(1).SubscriptionGetAsync(organization.GatewaySubscriptionId);
|
||||
await stripeAdapter.Received(1).GetSubscriptionAsync(organization.GatewaySubscriptionId);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -6,7 +6,6 @@ using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Billing.Subscriptions.Commands;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using NSubstitute;
|
||||
using Stripe;
|
||||
using Xunit;
|
||||
@@ -98,13 +97,13 @@ public class RestartSubscriptionCommandTests
|
||||
};
|
||||
|
||||
_subscriberService.GetSubscription(organization).Returns(existingSubscription);
|
||||
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(newSubscription);
|
||||
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(newSubscription);
|
||||
|
||||
var result = await _command.Run(organization);
|
||||
|
||||
Assert.True(result.IsT0);
|
||||
|
||||
await _stripeAdapter.Received(1).SubscriptionCreateAsync(Arg.Is((SubscriptionCreateOptions options) =>
|
||||
await _stripeAdapter.Received(1).CreateSubscriptionAsync(Arg.Is((SubscriptionCreateOptions options) =>
|
||||
options.AutomaticTax.Enabled == true &&
|
||||
options.CollectionMethod == CollectionMethod.ChargeAutomatically &&
|
||||
options.Customer == "cus_123" &&
|
||||
@@ -154,13 +153,13 @@ public class RestartSubscriptionCommandTests
|
||||
};
|
||||
|
||||
_subscriberService.GetSubscription(provider).Returns(existingSubscription);
|
||||
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(newSubscription);
|
||||
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(newSubscription);
|
||||
|
||||
var result = await _command.Run(provider);
|
||||
|
||||
Assert.True(result.IsT0);
|
||||
|
||||
await _stripeAdapter.Received(1).SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
await _stripeAdapter.Received(1).CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
|
||||
await _providerRepository.Received(1).ReplaceAsync(Arg.Is<Provider>(prov =>
|
||||
prov.Id == providerId &&
|
||||
@@ -199,13 +198,13 @@ public class RestartSubscriptionCommandTests
|
||||
};
|
||||
|
||||
_subscriberService.GetSubscription(user).Returns(existingSubscription);
|
||||
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(newSubscription);
|
||||
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(newSubscription);
|
||||
|
||||
var result = await _command.Run(user);
|
||||
|
||||
Assert.True(result.IsT0);
|
||||
|
||||
await _stripeAdapter.Received(1).SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
await _stripeAdapter.Received(1).CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
|
||||
|
||||
await _userRepository.Received(1).ReplaceAsync(Arg.Is<User>(u =>
|
||||
u.Id == userId &&
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
@@ -12,7 +13,7 @@ public abstract class CancelSponsorshipCommandTestsBase : FamiliesForEnterpriseT
|
||||
protected async Task AssertRemovedSponsoredPaymentAsync<T>(Organization sponsoredOrg,
|
||||
OrganizationSponsorship sponsorship, SutProvider<T> sutProvider)
|
||||
{
|
||||
await sutProvider.GetDependency<IPaymentService>().Received(1)
|
||||
await sutProvider.GetDependency<IStripePaymentService>().Received(1)
|
||||
.RemoveOrganizationSponsorshipAsync(sponsoredOrg, sponsorship);
|
||||
await sutProvider.GetDependency<IOrganizationRepository>().Received(1).UpsertAsync(sponsoredOrg);
|
||||
if (sponsorship != null)
|
||||
@@ -46,7 +47,7 @@ OrganizationSponsorship sponsorship, SutProvider<T> sutProvider)
|
||||
|
||||
protected static async Task AssertDidNotRemoveSponsoredPaymentAsync<T>(SutProvider<T> sutProvider)
|
||||
{
|
||||
await sutProvider.GetDependency<IPaymentService>().DidNotReceiveWithAnyArgs()
|
||||
await sutProvider.GetDependency<IStripePaymentService>().DidNotReceiveWithAnyArgs()
|
||||
.RemoveOrganizationSponsorshipAsync(default, default);
|
||||
await sutProvider.GetDependency<IOrganizationRepository>().DidNotReceiveWithAnyArgs()
|
||||
.UpsertAsync(default);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Billing.Enums;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Cloud;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Test.AutoFixture.OrganizationSponsorshipFixtures;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
@@ -82,7 +82,7 @@ public class SetUpSponsorshipCommandTests : FamiliesForEnterpriseTestsBase
|
||||
|
||||
private static async Task AssertDidNotSetUpAsync(SutProvider<SetUpSponsorshipCommand> sutProvider)
|
||||
{
|
||||
await sutProvider.GetDependency<IPaymentService>()
|
||||
await sutProvider.GetDependency<IStripePaymentService>()
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
.SponsorOrganizationAsync(default, default);
|
||||
await sutProvider.GetDependency<IOrganizationRepository>()
|
||||
|
||||
@@ -4,6 +4,7 @@ using Bit.Core.AdminConsole.Enums.Provider;
|
||||
using Bit.Core.AdminConsole.Repositories;
|
||||
using Bit.Core.Billing.Enums;
|
||||
using Bit.Core.Billing.Pricing;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.Models.StaticStore;
|
||||
@@ -54,7 +55,7 @@ public class AddSecretsManagerSubscriptionCommandTests
|
||||
c.AdditionalServiceAccounts == additionalServiceAccounts &&
|
||||
c.AdditionalSeats == organization.Seats.GetValueOrDefault()));
|
||||
|
||||
await sutProvider.GetDependency<IPaymentService>().Received()
|
||||
await sutProvider.GetDependency<IStripePaymentService>().Received()
|
||||
.AddSecretsManagerToSubscription(organization, plan, additionalSmSeats, additionalServiceAccounts);
|
||||
|
||||
// TODO: call ReferenceEventService - see AC-1481
|
||||
@@ -150,7 +151,7 @@ public class AddSecretsManagerSubscriptionCommandTests
|
||||
|
||||
private static async Task VerifyDependencyNotCalledAsync(SutProvider<AddSecretsManagerSubscriptionCommand> sutProvider)
|
||||
{
|
||||
await sutProvider.GetDependency<IPaymentService>().DidNotReceive()
|
||||
await sutProvider.GetDependency<IStripePaymentService>().DidNotReceive()
|
||||
.AddSecretsManagerToSubscription(Arg.Any<Organization>(), Arg.Any<Plan>(), Arg.Any<int>(), Arg.Any<int>());
|
||||
|
||||
// TODO: call ReferenceEventService - see AC-1481
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Billing.Enums;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Business;
|
||||
@@ -86,9 +87,9 @@ public class UpdateSecretsManagerSubscriptionCommandTests
|
||||
|
||||
await sutProvider.Sut.UpdateSubscriptionAsync(update);
|
||||
|
||||
await sutProvider.GetDependency<IPaymentService>().Received(1)
|
||||
await sutProvider.GetDependency<IStripePaymentService>().Received(1)
|
||||
.AdjustSmSeatsAsync(organization, plan, update.SmSeatsExcludingBase);
|
||||
await sutProvider.GetDependency<IPaymentService>().Received(1)
|
||||
await sutProvider.GetDependency<IStripePaymentService>().Received(1)
|
||||
.AdjustServiceAccountsAsync(organization, plan, update.SmServiceAccountsExcludingBase);
|
||||
|
||||
// TODO: call ReferenceEventService - see AC-1481
|
||||
@@ -136,9 +137,9 @@ public class UpdateSecretsManagerSubscriptionCommandTests
|
||||
|
||||
await sutProvider.Sut.UpdateSubscriptionAsync(update);
|
||||
|
||||
await sutProvider.GetDependency<IPaymentService>().Received(1)
|
||||
await sutProvider.GetDependency<IStripePaymentService>().Received(1)
|
||||
.AdjustSmSeatsAsync(organization, plan, update.SmSeatsExcludingBase);
|
||||
await sutProvider.GetDependency<IPaymentService>().Received(1)
|
||||
await sutProvider.GetDependency<IStripePaymentService>().Received(1)
|
||||
.AdjustServiceAccountsAsync(organization, plan, update.SmServiceAccountsExcludingBase);
|
||||
|
||||
// TODO: call ReferenceEventService - see AC-1481
|
||||
@@ -258,7 +259,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
|
||||
|
||||
await sutProvider.Sut.UpdateSubscriptionAsync(update);
|
||||
|
||||
await sutProvider.GetDependency<IPaymentService>().Received(1).AdjustServiceAccountsAsync(
|
||||
await sutProvider.GetDependency<IStripePaymentService>().Received(1).AdjustServiceAccountsAsync(
|
||||
Arg.Is<Organization>(o => o.Id == organizationId),
|
||||
plan,
|
||||
expectedSmServiceAccountsExcludingBase);
|
||||
@@ -779,9 +780,9 @@ public class UpdateSecretsManagerSubscriptionCommandTests
|
||||
|
||||
private static async Task VerifyDependencyNotCalledAsync(SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
|
||||
{
|
||||
await sutProvider.GetDependency<IPaymentService>().DidNotReceive()
|
||||
await sutProvider.GetDependency<IStripePaymentService>().DidNotReceive()
|
||||
.AdjustSmSeatsAsync(Arg.Any<Organization>(), Arg.Any<Plan>(), Arg.Any<int>());
|
||||
await sutProvider.GetDependency<IPaymentService>().DidNotReceive()
|
||||
await sutProvider.GetDependency<IStripePaymentService>().DidNotReceive()
|
||||
.AdjustServiceAccountsAsync(Arg.Any<Organization>(), Arg.Any<Plan>(), Arg.Any<int>());
|
||||
// TODO: call ReferenceEventService - see AC-1481
|
||||
await sutProvider.GetDependency<IMailService>().DidNotReceive()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Bit.Core.Billing.Enums;
|
||||
using Bit.Core.Billing.Pricing;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
@@ -121,7 +122,7 @@ public class UpgradeOrganizationPlanCommandTests
|
||||
Users = 1
|
||||
});
|
||||
await sutProvider.Sut.UpgradePlanAsync(organization.Id, organizationUpgrade);
|
||||
await sutProvider.GetDependency<IPaymentService>().Received(1).AdjustSubscription(
|
||||
await sutProvider.GetDependency<IStripePaymentService>().Received(1).AdjustSubscription(
|
||||
organization,
|
||||
MockPlans.Get(planType),
|
||||
organizationUpgrade.AdditionalSeats,
|
||||
|
||||
@@ -227,7 +227,7 @@ public abstract class WebApplicationFactoryBase<T> : WebApplicationFactory<T>
|
||||
services.AddSingleton<ILoggerFactory, NullLoggerFactory>();
|
||||
|
||||
// Noop StripePaymentService - this could be changed to integrate with our Stripe test account
|
||||
Replace(services, Substitute.For<IPaymentService>());
|
||||
Replace(services, Substitute.For<IStripePaymentService>());
|
||||
|
||||
Replace(services, Substitute.For<IOrganizationBillingService>());
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user