From 79661dd5f5848df2ce6991a36bd3be06c20c1447 Mon Sep 17 00:00:00 2001 From: cyprain-okeke <108260115+cyprain-okeke@users.noreply.github.com> Date: Mon, 21 Jul 2025 14:17:12 +0100 Subject: [PATCH] [PM 22967] Add change to enable organization after unlink (#6086) * Add change to enable organization after unlink * PM-22967 remove comments --- .../RemoveOrganizationFromProviderCommand.cs | 1 + ...oveOrganizationFromProviderCommandTests.cs | 64 ++++++++++++++++++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/bitwarden_license/src/Commercial.Core/AdminConsole/Providers/RemoveOrganizationFromProviderCommand.cs b/bitwarden_license/src/Commercial.Core/AdminConsole/Providers/RemoveOrganizationFromProviderCommand.cs index 824691d8d2..ed71b5f438 100644 --- a/bitwarden_license/src/Commercial.Core/AdminConsole/Providers/RemoveOrganizationFromProviderCommand.cs +++ b/bitwarden_license/src/Commercial.Core/AdminConsole/Providers/RemoveOrganizationFromProviderCommand.cs @@ -156,6 +156,7 @@ public class RemoveOrganizationFromProviderCommand : IRemoveOrganizationFromProv organization.GatewaySubscriptionId = subscription.Id; organization.Status = OrganizationStatusType.Created; + organization.Enabled = true; await _providerBillingService.ScaleSeats(provider, organization.PlanType, -organization.Seats ?? 0); } diff --git a/bitwarden_license/test/Commercial.Core.Test/AdminConsole/ProviderFeatures/RemoveOrganizationFromProviderCommandTests.cs b/bitwarden_license/test/Commercial.Core.Test/AdminConsole/ProviderFeatures/RemoveOrganizationFromProviderCommandTests.cs index 5be18116c0..c9b5b93d5e 100644 --- a/bitwarden_license/test/Commercial.Core.Test/AdminConsole/ProviderFeatures/RemoveOrganizationFromProviderCommandTests.cs +++ b/bitwarden_license/test/Commercial.Core.Test/AdminConsole/ProviderFeatures/RemoveOrganizationFromProviderCommandTests.cs @@ -263,7 +263,8 @@ public class RemoveOrganizationFromProviderCommandTests org => org.BillingEmail == "a@example.com" && org.GatewaySubscriptionId == "subscription_id" && - org.Status == OrganizationStatusType.Created)); + org.Status == OrganizationStatusType.Created && + org.Enabled == true)); // Verify organization is enabled when new subscription is created await sutProvider.GetDependency().Received(1) .DeleteAsync(providerOrganization); @@ -354,7 +355,8 @@ public class RemoveOrganizationFromProviderCommandTests org => org.BillingEmail == "a@example.com" && org.GatewaySubscriptionId == "subscription_id" && - org.Status == OrganizationStatusType.Created)); + org.Status == OrganizationStatusType.Created && + org.Enabled == true)); // Verify organization is enabled when new subscription is created await sutProvider.GetDependency().Received(1) .DeleteAsync(providerOrganization); @@ -390,4 +392,62 @@ public class RemoveOrganizationFromProviderCommandTests } } }; + + [Theory, BitAutoData] + public async Task RemoveOrganizationFromProvider_DisabledOrganization_ConsolidatedBilling_EnablesOrganization( + Provider provider, + ProviderOrganization providerOrganization, + Organization organization, + SutProvider sutProvider) + { + // Arrange: Set up a disabled organization that meets the criteria for consolidated billing + provider.Status = ProviderStatusType.Billable; + providerOrganization.ProviderId = provider.Id; + organization.Status = OrganizationStatusType.Managed; + organization.PlanType = PlanType.TeamsMonthly; + organization.Enabled = false; // Start with a disabled organization + + var teamsMonthlyPlan = StaticStore.GetPlan(PlanType.TeamsMonthly); + + sutProvider.GetDependency().GetPlanOrThrow(PlanType.TeamsMonthly).Returns(teamsMonthlyPlan); + + sutProvider.GetDependency().HasConfirmedOwnersExceptAsync( + providerOrganization.OrganizationId, + [], + includeProvider: false) + .Returns(true); + + var organizationRepository = sutProvider.GetDependency(); + + organizationRepository.GetOwnerEmailAddressesById(organization.Id).Returns([ + "owner@example.com" + ]); + + var stripeAdapter = sutProvider.GetDependency(); + + stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, Arg.Any()) + .Returns(new Customer + { + Id = "customer_id", + Address = new Address + { + Country = "US" + } + }); + + stripeAdapter.SubscriptionCreateAsync(Arg.Any()).Returns(new Subscription + { + Id = "new_subscription_id" + }); + + // Act + await sutProvider.Sut.RemoveOrganizationFromProvider(provider, providerOrganization, organization); + + // Assert: Verify the disabled organization is now enabled + await organizationRepository.Received(1).ReplaceAsync(Arg.Is( + org => + org.Enabled == true && // The previously disabled organization should now be enabled + org.Status == OrganizationStatusType.Created && + org.GatewaySubscriptionId == "new_subscription_id")); + } }