1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-21 12:05:42 +01:00

[AC-2284] Set organization billing email to MSP billing email when linked (#3897)

* Set org billing email to provider billing email when added to provider

* Remove anonymous args for test assertions
This commit is contained in:
Alex Morask 2024-03-19 09:36:25 -04:00 committed by GitHub
parent 84cbd9ee7d
commit 15eea77d66
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 110 additions and 65 deletions

View File

@ -17,6 +17,7 @@ using Bit.Core.Services;
using Bit.Core.Settings;
using Bit.Core.Utilities;
using Microsoft.AspNetCore.DataProtection;
using Stripe;
namespace Bit.Commercial.Core.AdminConsole.Services;
@ -374,8 +375,18 @@ public class ProviderService : IProviderService
Key = key,
};
await ApplyProviderPriceRateAsync(organizationId, providerId);
var provider = await _providerRepository.GetByIdAsync(providerId);
await ApplyProviderPriceRateAsync(organization, provider);
await _providerOrganizationRepository.CreateAsync(providerOrganization);
organization.BillingEmail = provider.BillingEmail;
await _organizationRepository.ReplaceAsync(organization);
await _stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, new CustomerUpdateOptions
{
Email = provider.BillingEmail
});
await _eventService.LogProviderOrganizationEventAsync(providerOrganization, EventType.ProviderOrganization_Added);
}
@ -400,16 +411,14 @@ public class ProviderService : IProviderService
await _eventService.LogProviderOrganizationEventsAsync(insertedProviderOrganizations.Select(ipo => (ipo, EventType.ProviderOrganization_Added, (DateTime?)null)));
}
private async Task ApplyProviderPriceRateAsync(Guid organizationId, Guid providerId)
private async Task ApplyProviderPriceRateAsync(Organization organization, Provider provider)
{
var provider = await _providerRepository.GetByIdAsync(providerId);
// if a provider was created before Nov 6, 2023.If true, the organization plan assigned to that provider is updated to a 2020 plan.
if (provider.CreationDate >= Constants.ProviderCreatedPriorNov62023)
{
return;
}
var organization = await _organizationRepository.GetByIdAsync(organizationId);
var subscriptionItem = await GetSubscriptionItemAsync(organization.GatewaySubscriptionId, GetStripeSeatPlanId(organization.PlanType));
var extractedPlanType = PlanTypeMappings(organization);
if (subscriptionItem != null)

View File

@ -458,17 +458,112 @@ public class ProviderServiceTests
{
organization.PlanType = PlanType.EnterpriseAnnually;
var providerRepository = sutProvider.GetDependency<IProviderRepository>();
providerRepository.GetByIdAsync(provider.Id).Returns(provider);
var providerOrganizationRepository = sutProvider.GetDependency<IProviderOrganizationRepository>();
providerOrganizationRepository.GetByOrganizationId(organization.Id).ReturnsNull();
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
organizationRepository.GetByIdAsync(organization.Id).Returns(organization);
await sutProvider.Sut.AddOrganization(provider.Id, organization.Id, key);
await providerOrganizationRepository.Received(1)
.CreateAsync(Arg.Is<ProviderOrganization>(providerOrganization =>
providerOrganization.ProviderId == provider.Id &&
providerOrganization.OrganizationId == organization.Id &&
providerOrganization.Key == key));
await organizationRepository.Received(1)
.ReplaceAsync(Arg.Is<Organization>(org => org.BillingEmail == provider.BillingEmail));
await sutProvider.GetDependency<IStripeAdapter>().Received(1).CustomerUpdateAsync(
organization.GatewayCustomerId,
Arg.Is<CustomerUpdateOptions>(options => options.Email == provider.BillingEmail));
await sutProvider.GetDependency<IEventService>()
.Received().LogProviderOrganizationEventAsync(Arg.Is<ProviderOrganization>(providerOrganization =>
providerOrganization.ProviderId == provider.Id &&
providerOrganization.OrganizationId == organization.Id &&
providerOrganization.Key == key),
EventType.ProviderOrganization_Added);
}
[Theory, BitAutoData]
public async Task AddOrganization_CreateAfterNov62023_PlanTypeDoesNotUpdated(Provider provider, Organization organization, string key,
SutProvider<ProviderService> sutProvider)
{
provider.Type = ProviderType.Msp;
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(provider.Id).Returns(provider);
var providerOrganizationRepository = sutProvider.GetDependency<IProviderOrganizationRepository>();
var expectedPlanType = PlanType.EnterpriseAnnually;
organization.PlanType = PlanType.EnterpriseAnnually;
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organization.Id).Returns(organization);
await sutProvider.Sut.AddOrganization(provider.Id, organization.Id, key);
await providerOrganizationRepository.Received(1)
.CreateAsync(Arg.Is<ProviderOrganization>(providerOrganization =>
providerOrganization.ProviderId == provider.Id &&
providerOrganization.OrganizationId == organization.Id &&
providerOrganization.Key == key));
await sutProvider.GetDependency<IEventService>()
.Received().LogProviderOrganizationEventAsync(Arg.Is<ProviderOrganization>(providerOrganization =>
providerOrganization.ProviderId == provider.Id &&
providerOrganization.OrganizationId == organization.Id &&
providerOrganization.Key == key),
EventType.ProviderOrganization_Added);
Assert.Equal(organization.PlanType, expectedPlanType);
}
[Theory, BitAutoData]
public async Task AddOrganization_CreateBeforeNov62023_PlanTypeUpdated(Provider provider, Organization organization, string key,
SutProvider<ProviderService> sutProvider)
{
var newCreationDate = new DateTime(2023, 11, 5);
BackdateProviderCreationDate(provider, newCreationDate);
provider.Type = ProviderType.Msp;
organization.PlanType = PlanType.EnterpriseAnnually;
organization.Plan = "Enterprise (Annually)";
var expectedPlanType = PlanType.EnterpriseAnnually2020;
var expectedPlanId = "2020-enterprise-org-seat-annually";
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(provider.Id).Returns(provider);
var providerOrganizationRepository = sutProvider.GetDependency<IProviderOrganizationRepository>();
providerOrganizationRepository.GetByOrganizationId(organization.Id).ReturnsNull();
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organization.Id).Returns(organization);
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organization.Id).Returns(organization);
var subscriptionItem = GetSubscription(organization.GatewaySubscriptionId);
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(organization.GatewaySubscriptionId)
.Returns(GetSubscription(organization.GatewaySubscriptionId));
await sutProvider.GetDependency<IStripeAdapter>().SubscriptionUpdateAsync(
organization.GatewaySubscriptionId, SubscriptionUpdateRequest(expectedPlanId, subscriptionItem));
await sutProvider.Sut.AddOrganization(provider.Id, organization.Id, key);
await providerOrganizationRepository.ReceivedWithAnyArgs().CreateAsync(default);
await providerOrganizationRepository.Received(1)
.CreateAsync(Arg.Is<ProviderOrganization>(providerOrganization =>
providerOrganization.ProviderId == provider.Id &&
providerOrganization.OrganizationId == organization.Id &&
providerOrganization.Key == key));
await sutProvider.GetDependency<IEventService>()
.Received().LogProviderOrganizationEventAsync(Arg.Any<ProviderOrganization>(),
.Received().LogProviderOrganizationEventAsync(Arg.Is<ProviderOrganization>(providerOrganization =>
providerOrganization.ProviderId == provider.Id &&
providerOrganization.OrganizationId == organization.Id &&
providerOrganization.Key == key),
EventType.ProviderOrganization_Added);
Assert.Equal(organization.PlanType, expectedPlanType);
}
[Theory, BitAutoData]
@ -576,65 +671,6 @@ public class ProviderServiceTests
t.First().Item2 == null));
}
[Theory, BitAutoData]
public async Task AddOrganization_CreateAfterNov62023_PlanTypeDoesNotUpdated(Provider provider, Organization organization, string key,
SutProvider<ProviderService> sutProvider)
{
provider.Type = ProviderType.Msp;
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(provider.Id).Returns(provider);
var providerOrganizationRepository = sutProvider.GetDependency<IProviderOrganizationRepository>();
var expectedPlanType = PlanType.EnterpriseAnnually;
organization.PlanType = PlanType.EnterpriseAnnually;
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organization.Id).Returns(organization);
await sutProvider.Sut.AddOrganization(provider.Id, organization.Id, key);
await providerOrganizationRepository.ReceivedWithAnyArgs().CreateAsync(default);
await sutProvider.GetDependency<IEventService>()
.Received().LogProviderOrganizationEventAsync(Arg.Any<ProviderOrganization>(),
EventType.ProviderOrganization_Added);
Assert.Equal(organization.PlanType, expectedPlanType);
}
[Theory, BitAutoData]
public async Task AddOrganization_CreateBeforeNov62023_PlanTypeUpdated(Provider provider, Organization organization, string key,
SutProvider<ProviderService> sutProvider)
{
var newCreationDate = new DateTime(2023, 11, 5);
BackdateProviderCreationDate(provider, newCreationDate);
provider.Type = ProviderType.Msp;
organization.PlanType = PlanType.EnterpriseAnnually;
organization.Plan = "Enterprise (Annually)";
var expectedPlanType = PlanType.EnterpriseAnnually2020;
var expectedPlanId = "2020-enterprise-org-seat-annually";
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(provider.Id).Returns(provider);
var providerOrganizationRepository = sutProvider.GetDependency<IProviderOrganizationRepository>();
providerOrganizationRepository.GetByOrganizationId(organization.Id).ReturnsNull();
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organization.Id).Returns(organization);
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organization.Id).Returns(organization);
var subscriptionItem = GetSubscription(organization.GatewaySubscriptionId);
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(organization.GatewaySubscriptionId)
.Returns(GetSubscription(organization.GatewaySubscriptionId));
await sutProvider.GetDependency<IStripeAdapter>().SubscriptionUpdateAsync(
organization.GatewaySubscriptionId, SubscriptionUpdateRequest(expectedPlanId, subscriptionItem));
await sutProvider.Sut.AddOrganization(provider.Id, organization.Id, key);
await providerOrganizationRepository.ReceivedWithAnyArgs().CreateAsync(default);
await sutProvider.GetDependency<IEventService>()
.Received().LogProviderOrganizationEventAsync(Arg.Any<ProviderOrganization>(),
EventType.ProviderOrganization_Added);
Assert.Equal(organization.PlanType, expectedPlanType);
}
private static SubscriptionUpdateOptions SubscriptionUpdateRequest(string expectedPlanId, Subscription subscriptionItem) =>
new()
{