mirror of
https://github.com/bitwarden/server.git
synced 2025-12-10 00:42:07 -06:00
* 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 * Fix provider invoice generation validation * More QA fixes * Fix tests * QA defect resolutions * QA defect resolutions * Run dotnet format * Fix tests --------- Co-authored-by: cyprain-okeke <108260115+cyprain-okeke@users.noreply.github.com>
802 lines
26 KiB
C#
802 lines
26 KiB
C#
using Bit.Core.AdminConsole.Entities;
|
|
using Bit.Core.AdminConsole.Entities.Provider;
|
|
using Bit.Core.AdminConsole.Enums.Provider;
|
|
using Bit.Core.AdminConsole.Repositories;
|
|
using Bit.Core.Billing.Constants;
|
|
using Bit.Core.Billing.Enums;
|
|
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;
|
|
using NSubstitute.ReturnsExtensions;
|
|
using Stripe;
|
|
using Stripe.Tax;
|
|
using Stripe.TestHelpers;
|
|
using Xunit;
|
|
|
|
namespace Bit.Core.Test.Billing.Organizations.Queries;
|
|
|
|
using static StripeConstants;
|
|
|
|
[SutProviderCustomize]
|
|
public class GetOrganizationWarningsQueryTests
|
|
{
|
|
private static readonly string[] _requiredExpansions = ["customer.tax_ids", "latest_invoice", "test_clock"];
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_NoSubscription_NoWarnings(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Is<SubscriptionGetOptions>(options =>
|
|
options.Expand.SequenceEqual(_requiredExpansions)
|
|
))
|
|
.ReturnsNull();
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.True(response is
|
|
{
|
|
FreeTrial: null,
|
|
InactiveSubscription: null,
|
|
ResellerRenewal: null
|
|
});
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_Has_FreeTrialWarning(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
var now = DateTime.UtcNow;
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Is<SubscriptionGetOptions>(options =>
|
|
options.Expand.SequenceEqual(_requiredExpansions)
|
|
))
|
|
.Returns(new Subscription
|
|
{
|
|
Status = SubscriptionStatus.Trialing,
|
|
TrialEnd = now.AddDays(7),
|
|
Customer = new Customer
|
|
{
|
|
InvoiceSettings = new CustomerInvoiceSettings(),
|
|
Metadata = new Dictionary<string, string>()
|
|
},
|
|
TestClock = new TestClock
|
|
{
|
|
FrozenTime = now
|
|
}
|
|
});
|
|
|
|
sutProvider.GetDependency<ICurrentContext>().EditSubscription(organization.Id).Returns(true);
|
|
sutProvider.GetDependency<IHasPaymentMethodQuery>().Run(organization).Returns(false);
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.True(response is
|
|
{
|
|
FreeTrial.RemainingTrialDays: 7
|
|
});
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_Has_FreeTrialWarning_WithPaymentMethod_NoWarning(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
var now = DateTime.UtcNow;
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Is<SubscriptionGetOptions>(options =>
|
|
options.Expand.SequenceEqual(_requiredExpansions)
|
|
))
|
|
.Returns(new Subscription
|
|
{
|
|
Status = SubscriptionStatus.Trialing,
|
|
TrialEnd = now.AddDays(7),
|
|
Customer = new Customer
|
|
{
|
|
InvoiceSettings = new CustomerInvoiceSettings(),
|
|
Metadata = new Dictionary<string, string>()
|
|
},
|
|
TestClock = new TestClock
|
|
{
|
|
FrozenTime = now
|
|
}
|
|
});
|
|
|
|
sutProvider.GetDependency<ICurrentContext>().EditSubscription(organization.Id).Returns(true);
|
|
sutProvider.GetDependency<IHasPaymentMethodQuery>().Run(organization).Returns(true);
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.Null(response.FreeTrial);
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_OrganizationEnabled_NoInactiveSubscriptionWarning(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
organization.Enabled = true;
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Is<SubscriptionGetOptions>(options =>
|
|
options.Expand.SequenceEqual(_requiredExpansions)
|
|
))
|
|
.Returns(new Subscription
|
|
{
|
|
Status = SubscriptionStatus.Unpaid,
|
|
Customer = new Customer
|
|
{
|
|
InvoiceSettings = new CustomerInvoiceSettings(),
|
|
Metadata = new Dictionary<string, string>()
|
|
}
|
|
});
|
|
|
|
sutProvider.GetDependency<ICurrentContext>().OrganizationOwner(organization.Id).Returns(true);
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.Null(response.InactiveSubscription);
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_Has_InactiveSubscriptionWarning_ContactProvider(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
organization.Enabled = false;
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Is<SubscriptionGetOptions>(options =>
|
|
options.Expand.SequenceEqual(_requiredExpansions)
|
|
))
|
|
.Returns(new Subscription
|
|
{
|
|
Customer = new Customer(),
|
|
Status = SubscriptionStatus.Unpaid
|
|
});
|
|
|
|
sutProvider.GetDependency<IProviderRepository>().GetByOrganizationIdAsync(organization.Id)
|
|
.Returns(new Provider());
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.True(response is
|
|
{
|
|
InactiveSubscription.Resolution: "contact_provider"
|
|
});
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_Has_InactiveSubscriptionWarning_AddPaymentMethod(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
organization.Enabled = false;
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Is<SubscriptionGetOptions>(options =>
|
|
options.Expand.SequenceEqual(_requiredExpansions)
|
|
))
|
|
.Returns(new Subscription
|
|
{
|
|
Customer = new Customer(),
|
|
Status = SubscriptionStatus.Unpaid
|
|
});
|
|
|
|
sutProvider.GetDependency<ICurrentContext>().OrganizationOwner(organization.Id).Returns(true);
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.True(response is
|
|
{
|
|
InactiveSubscription.Resolution: "add_payment_method"
|
|
});
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_Has_InactiveSubscriptionWarning_Resubscribe(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
organization.Enabled = false;
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Is<SubscriptionGetOptions>(options =>
|
|
options.Expand.SequenceEqual(_requiredExpansions)
|
|
))
|
|
.Returns(new Subscription
|
|
{
|
|
Customer = new Customer(),
|
|
Status = SubscriptionStatus.Canceled
|
|
});
|
|
|
|
sutProvider.GetDependency<ICurrentContext>().OrganizationOwner(organization.Id).Returns(true);
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.True(response is
|
|
{
|
|
InactiveSubscription.Resolution: "resubscribe"
|
|
});
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_Has_InactiveSubscriptionWarning_ContactOwner(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
organization.Enabled = false;
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Is<SubscriptionGetOptions>(options =>
|
|
options.Expand.SequenceEqual(_requiredExpansions)
|
|
))
|
|
.Returns(new Subscription
|
|
{
|
|
Customer = new Customer(),
|
|
Status = SubscriptionStatus.Unpaid
|
|
});
|
|
|
|
sutProvider.GetDependency<ICurrentContext>().OrganizationOwner(organization.Id).Returns(false);
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.True(response is
|
|
{
|
|
InactiveSubscription.Resolution: "contact_owner"
|
|
});
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_Has_ResellerRenewalWarning_Upcoming(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
var now = DateTime.UtcNow;
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Is<SubscriptionGetOptions>(options =>
|
|
options.Expand.SequenceEqual(_requiredExpansions)
|
|
))
|
|
.Returns(new Subscription
|
|
{
|
|
CollectionMethod = CollectionMethod.SendInvoice,
|
|
Customer = new Customer(),
|
|
Status = SubscriptionStatus.Active,
|
|
Items = new StripeList<SubscriptionItem>
|
|
{
|
|
Data =
|
|
[
|
|
new SubscriptionItem
|
|
{
|
|
CurrentPeriodEnd = now.AddDays(10)
|
|
}
|
|
]
|
|
},
|
|
TestClock = new TestClock
|
|
{
|
|
FrozenTime = now
|
|
}
|
|
});
|
|
|
|
sutProvider.GetDependency<IProviderRepository>().GetByOrganizationIdAsync(organization.Id)
|
|
.Returns(new Provider
|
|
{
|
|
Type = ProviderType.Reseller
|
|
});
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.True(response is
|
|
{
|
|
ResellerRenewal.Type: "upcoming"
|
|
});
|
|
|
|
Assert.Equal(now.AddDays(10), response.ResellerRenewal.Upcoming!.RenewalDate);
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_Has_ResellerRenewalWarning_Issued(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
var now = DateTime.UtcNow;
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Is<SubscriptionGetOptions>(options =>
|
|
options.Expand.SequenceEqual(_requiredExpansions)
|
|
))
|
|
.Returns(new Subscription
|
|
{
|
|
CollectionMethod = CollectionMethod.SendInvoice,
|
|
Customer = new Customer(),
|
|
Status = SubscriptionStatus.Active,
|
|
LatestInvoice = new Invoice
|
|
{
|
|
Status = InvoiceStatus.Open,
|
|
DueDate = now.AddDays(30),
|
|
Created = now
|
|
},
|
|
TestClock = new TestClock
|
|
{
|
|
FrozenTime = now
|
|
}
|
|
});
|
|
|
|
sutProvider.GetDependency<IProviderRepository>().GetByOrganizationIdAsync(organization.Id)
|
|
.Returns(new Provider
|
|
{
|
|
Type = ProviderType.Reseller
|
|
});
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.True(response is
|
|
{
|
|
ResellerRenewal.Type: "issued"
|
|
});
|
|
|
|
Assert.Equal(now, response.ResellerRenewal.Issued!.IssuedDate);
|
|
Assert.Equal(now.AddDays(30), response.ResellerRenewal.Issued!.DueDate);
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_Has_ResellerRenewalWarning_PastDue(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
var now = DateTime.UtcNow;
|
|
|
|
const string subscriptionId = "subscription_id";
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Is<SubscriptionGetOptions>(options =>
|
|
options.Expand.SequenceEqual(_requiredExpansions)
|
|
))
|
|
.Returns(new Subscription
|
|
{
|
|
Id = subscriptionId,
|
|
CollectionMethod = CollectionMethod.SendInvoice,
|
|
Customer = new Customer(),
|
|
Status = SubscriptionStatus.PastDue,
|
|
TestClock = new TestClock
|
|
{
|
|
FrozenTime = now
|
|
}
|
|
});
|
|
|
|
sutProvider.GetDependency<IProviderRepository>().GetByOrganizationIdAsync(organization.Id)
|
|
.Returns(new Provider
|
|
{
|
|
Type = ProviderType.Reseller
|
|
});
|
|
|
|
var dueDate = now.AddDays(-10);
|
|
|
|
sutProvider.GetDependency<IStripeAdapter>().InvoiceSearchAsync(Arg.Is<InvoiceSearchOptions>(options =>
|
|
options.Query == $"subscription:'{subscriptionId}' status:'open'")).Returns([
|
|
new Invoice { DueDate = dueDate, Created = dueDate.AddDays(-30) }
|
|
]);
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.True(response is
|
|
{
|
|
ResellerRenewal.Type: "past_due"
|
|
});
|
|
|
|
Assert.Equal(dueDate.AddDays(30), response.ResellerRenewal.PastDue!.SuspensionDate);
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_USCustomer_NoTaxIdWarning(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
var subscription = new Subscription
|
|
{
|
|
Customer = new Customer
|
|
{
|
|
Address = new Address { Country = "US" },
|
|
TaxIds = new StripeList<TaxId> { Data = new List<TaxId>() },
|
|
InvoiceSettings = new CustomerInvoiceSettings(),
|
|
Metadata = new Dictionary<string, string>()
|
|
}
|
|
};
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Any<SubscriptionGetOptions>())
|
|
.Returns(subscription);
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.Null(response.TaxId);
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_FreeCustomer_NoTaxIdWarning(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
organization.PlanType = PlanType.Free;
|
|
|
|
var subscription = new Subscription
|
|
{
|
|
Customer = new Customer
|
|
{
|
|
Address = new Address { Country = "CA" },
|
|
TaxIds = new StripeList<TaxId> { Data = new List<TaxId>() },
|
|
InvoiceSettings = new CustomerInvoiceSettings(),
|
|
Metadata = new Dictionary<string, string>()
|
|
}
|
|
};
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Any<SubscriptionGetOptions>())
|
|
.Returns(subscription);
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.Null(response.TaxId);
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_NotOwner_NoTaxIdWarning(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
organization.PlanType = PlanType.TeamsAnnually;
|
|
|
|
var subscription = new Subscription
|
|
{
|
|
Customer = new Customer
|
|
{
|
|
Address = new Address { Country = "CA" },
|
|
TaxIds = new StripeList<TaxId> { Data = new List<TaxId>() },
|
|
InvoiceSettings = new CustomerInvoiceSettings(),
|
|
Metadata = new Dictionary<string, string>()
|
|
}
|
|
};
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Any<SubscriptionGetOptions>())
|
|
.Returns(subscription);
|
|
|
|
sutProvider.GetDependency<ICurrentContext>()
|
|
.OrganizationOwner(organization.Id)
|
|
.Returns(false);
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.Null(response.TaxId);
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_HasProvider_NoTaxIdWarning(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
organization.PlanType = PlanType.TeamsAnnually;
|
|
|
|
var subscription = new Subscription
|
|
{
|
|
Customer = new Customer
|
|
{
|
|
Address = new Address { Country = "CA" },
|
|
TaxIds = new StripeList<TaxId> { Data = new List<TaxId>() },
|
|
InvoiceSettings = new CustomerInvoiceSettings(),
|
|
Metadata = new Dictionary<string, string>()
|
|
}
|
|
};
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Any<SubscriptionGetOptions>())
|
|
.Returns(subscription);
|
|
|
|
sutProvider.GetDependency<ICurrentContext>()
|
|
.OrganizationOwner(organization.Id)
|
|
.Returns(true);
|
|
|
|
sutProvider.GetDependency<IProviderRepository>()
|
|
.GetByOrganizationIdAsync(organization.Id)
|
|
.Returns(new Provider());
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.Null(response.TaxId);
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_NoRegistrationInCountry_NoTaxIdWarning(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
organization.PlanType = PlanType.TeamsAnnually;
|
|
|
|
var subscription = new Subscription
|
|
{
|
|
Customer = new Customer
|
|
{
|
|
Address = new Address { Country = "CA" },
|
|
TaxIds = new StripeList<TaxId> { Data = new List<TaxId>() },
|
|
InvoiceSettings = new CustomerInvoiceSettings(),
|
|
Metadata = new Dictionary<string, string>()
|
|
}
|
|
};
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Any<SubscriptionGetOptions>())
|
|
.Returns(subscription);
|
|
|
|
sutProvider.GetDependency<ICurrentContext>()
|
|
.OrganizationOwner(organization.Id)
|
|
.Returns(true);
|
|
|
|
sutProvider.GetDependency<IStripeAdapter>()
|
|
.TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
|
|
.Returns(new StripeList<Registration>
|
|
{
|
|
Data = new List<Registration>
|
|
{
|
|
new() { Country = "GB" }
|
|
}
|
|
});
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.Null(response.TaxId);
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_Has_TaxIdWarning_Missing(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
organization.PlanType = PlanType.TeamsAnnually;
|
|
|
|
var subscription = new Subscription
|
|
{
|
|
Customer = new Customer
|
|
{
|
|
Address = new Address { Country = "CA" },
|
|
TaxIds = new StripeList<TaxId> { Data = new List<TaxId>() },
|
|
InvoiceSettings = new CustomerInvoiceSettings(),
|
|
Metadata = new Dictionary<string, string>()
|
|
}
|
|
};
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Any<SubscriptionGetOptions>())
|
|
.Returns(subscription);
|
|
|
|
sutProvider.GetDependency<ICurrentContext>()
|
|
.OrganizationOwner(organization.Id)
|
|
.Returns(true);
|
|
|
|
sutProvider.GetDependency<IStripeAdapter>()
|
|
.TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
|
|
.Returns(new StripeList<Registration>
|
|
{
|
|
Data = new List<Registration>
|
|
{
|
|
new() { Country = "CA" }
|
|
}
|
|
});
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.True(response is
|
|
{
|
|
TaxId.Type: "tax_id_missing"
|
|
});
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_Has_TaxIdWarning_PendingVerification(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
organization.PlanType = PlanType.EnterpriseAnnually;
|
|
|
|
var taxId = new TaxId
|
|
{
|
|
Verification = new TaxIdVerification
|
|
{
|
|
Status = TaxIdVerificationStatus.Pending
|
|
}
|
|
};
|
|
|
|
var subscription = new Subscription
|
|
{
|
|
Customer = new Customer
|
|
{
|
|
Address = new Address { Country = "CA" },
|
|
TaxIds = new StripeList<TaxId> { Data = new List<TaxId> { taxId } },
|
|
InvoiceSettings = new CustomerInvoiceSettings(),
|
|
Metadata = new Dictionary<string, string>()
|
|
}
|
|
};
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Any<SubscriptionGetOptions>())
|
|
.Returns(subscription);
|
|
|
|
sutProvider.GetDependency<ICurrentContext>()
|
|
.OrganizationOwner(organization.Id)
|
|
.Returns(true);
|
|
|
|
sutProvider.GetDependency<IStripeAdapter>()
|
|
.TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
|
|
.Returns(new StripeList<Registration>
|
|
{
|
|
Data = new List<Registration>
|
|
{
|
|
new() { Country = "CA" }
|
|
}
|
|
});
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.True(response is
|
|
{
|
|
TaxId.Type: "tax_id_pending_verification"
|
|
});
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_Has_TaxIdWarning_FailedVerification(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
organization.PlanType = PlanType.TeamsAnnually;
|
|
|
|
var taxId = new TaxId
|
|
{
|
|
Verification = new TaxIdVerification
|
|
{
|
|
Status = TaxIdVerificationStatus.Unverified
|
|
}
|
|
};
|
|
|
|
var subscription = new Subscription
|
|
{
|
|
Customer = new Customer
|
|
{
|
|
Address = new Address { Country = "CA" },
|
|
TaxIds = new StripeList<TaxId> { Data = new List<TaxId> { taxId } },
|
|
InvoiceSettings = new CustomerInvoiceSettings(),
|
|
Metadata = new Dictionary<string, string>()
|
|
}
|
|
};
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Any<SubscriptionGetOptions>())
|
|
.Returns(subscription);
|
|
|
|
sutProvider.GetDependency<ICurrentContext>()
|
|
.OrganizationOwner(organization.Id)
|
|
.Returns(true);
|
|
|
|
sutProvider.GetDependency<IStripeAdapter>()
|
|
.TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
|
|
.Returns(new StripeList<Registration>
|
|
{
|
|
Data = new List<Registration>
|
|
{
|
|
new() { Country = "CA" }
|
|
}
|
|
});
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.True(response is
|
|
{
|
|
TaxId.Type: "tax_id_failed_verification"
|
|
});
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_VerifiedTaxId_NoTaxIdWarning(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
organization.PlanType = PlanType.TeamsAnnually;
|
|
|
|
var taxId = new TaxId
|
|
{
|
|
Verification = new TaxIdVerification
|
|
{
|
|
Status = TaxIdVerificationStatus.Verified
|
|
}
|
|
};
|
|
|
|
var subscription = new Subscription
|
|
{
|
|
Customer = new Customer
|
|
{
|
|
Address = new Address { Country = "CA" },
|
|
TaxIds = new StripeList<TaxId> { Data = new List<TaxId> { taxId } },
|
|
InvoiceSettings = new CustomerInvoiceSettings(),
|
|
Metadata = new Dictionary<string, string>()
|
|
}
|
|
};
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Any<SubscriptionGetOptions>())
|
|
.Returns(subscription);
|
|
|
|
sutProvider.GetDependency<ICurrentContext>()
|
|
.OrganizationOwner(organization.Id)
|
|
.Returns(true);
|
|
|
|
sutProvider.GetDependency<IStripeAdapter>()
|
|
.TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
|
|
.Returns(new StripeList<Registration>
|
|
{
|
|
Data = new List<Registration>
|
|
{
|
|
new() { Country = "CA" }
|
|
}
|
|
});
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.Null(response.TaxId);
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task Run_NullVerification_NoTaxIdWarning(
|
|
Organization organization,
|
|
SutProvider<GetOrganizationWarningsQuery> sutProvider)
|
|
{
|
|
organization.PlanType = PlanType.TeamsAnnually;
|
|
|
|
var taxId = new TaxId
|
|
{
|
|
Verification = null
|
|
};
|
|
|
|
var subscription = new Subscription
|
|
{
|
|
Customer = new Customer
|
|
{
|
|
Address = new Address { Country = "CA" },
|
|
TaxIds = new StripeList<TaxId> { Data = new List<TaxId> { taxId } },
|
|
InvoiceSettings = new CustomerInvoiceSettings(),
|
|
Metadata = new Dictionary<string, string>()
|
|
}
|
|
};
|
|
|
|
sutProvider.GetDependency<ISubscriberService>()
|
|
.GetSubscription(organization, Arg.Any<SubscriptionGetOptions>())
|
|
.Returns(subscription);
|
|
|
|
sutProvider.GetDependency<ICurrentContext>()
|
|
.OrganizationOwner(organization.Id)
|
|
.Returns(true);
|
|
|
|
sutProvider.GetDependency<IStripeAdapter>()
|
|
.TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
|
|
.Returns(new StripeList<Registration>
|
|
{
|
|
Data = new List<Registration>
|
|
{
|
|
new() { Country = "CA" }
|
|
}
|
|
});
|
|
|
|
var response = await sutProvider.Sut.Run(organization);
|
|
|
|
Assert.Null(response.TaxId);
|
|
}
|
|
}
|