From 3f326f291aac287eccaaa66b9e57d63acd868a4f Mon Sep 17 00:00:00 2001 From: jrmccannon Date: Wed, 26 Nov 2025 09:37:27 -0600 Subject: [PATCH] Added tests for provider service additions --- .../Services/ProviderServiceTests.cs | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/bitwarden_license/test/Commercial.Core.Test/AdminConsole/Services/ProviderServiceTests.cs b/bitwarden_license/test/Commercial.Core.Test/AdminConsole/Services/ProviderServiceTests.cs index 78376f6d98..e771a3e55d 100644 --- a/bitwarden_license/test/Commercial.Core.Test/AdminConsole/Services/ProviderServiceTests.cs +++ b/bitwarden_license/test/Commercial.Core.Test/AdminConsole/Services/ProviderServiceTests.cs @@ -1,5 +1,6 @@ using Bit.Commercial.Core.AdminConsole.Services; using Bit.Commercial.Core.Test.AdminConsole.AutoFixture; +using Bit.Core; using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.Entities.Provider; using Bit.Core.AdminConsole.Enums.Provider; @@ -7,6 +8,9 @@ using Bit.Core.AdminConsole.Models.Business.Provider; using Bit.Core.AdminConsole.Models.Business.Tokenables; using Bit.Core.AdminConsole.Models.Data.Provider; using Bit.Core.AdminConsole.OrganizationFeatures.Organizations; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.AutoConfirmUser; +using Bit.Core.AdminConsole.OrganizationFeatures.Policies; +using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements; using Bit.Core.AdminConsole.Repositories; using Bit.Core.Billing.Enums; using Bit.Core.Billing.Payment.Models; @@ -851,6 +855,126 @@ public class ProviderServiceTests Assert.Equal(organization.PlanType, expectedPlanType); } + [Theory, BitAutoData] + public async Task AddOrganization_WithAutoConfirmEnabledAndPolicyExists_Throws( + Provider provider, + Organization organization, + string key, + SutProvider sutProvider) + { + // Arrange + organization.PlanType = PlanType.EnterpriseMonthly; + organization.UseSecretsManager = false; + + var providerRepository = sutProvider.GetDependency(); + providerRepository.GetByIdAsync(provider.Id).Returns(provider); + + var providerOrganizationRepository = sutProvider.GetDependency(); + providerOrganizationRepository.GetByOrganizationId(organization.Id).ReturnsNull(); + + var organizationRepository = sutProvider.GetDependency(); + organizationRepository.GetByIdAsync(organization.Id).Returns(organization); + + // Feature flag enabled + sutProvider.GetDependency() + .IsEnabled(FeatureFlagKeys.AutomaticConfirmUsers) + .Returns(true); + + // Organization has automatic user confirmation policy (returns user IDs affected by the policy) + var userIds = new List { Guid.NewGuid() }; + sutProvider.GetDependency() + .GetManyByOrganizationIdAsync(organization.Id) + .Returns(userIds); + + // Act & Assert + var exception = await Assert.ThrowsAsync( + () => sutProvider.Sut.AddOrganization(provider.Id, organization.Id, key)); + + Assert.Equal(new ProviderUsersCannotJoin().Message, exception.Message); + } + + [Theory, BitAutoData] + public async Task AddOrganization_WithAutoConfirmEnabledButNoPolicyExists_Success( + Provider provider, + Organization organization, + string key, + SutProvider sutProvider) + { + // Arrange + organization.PlanType = PlanType.EnterpriseMonthly; + organization.UseSecretsManager = false; + + var providerRepository = sutProvider.GetDependency(); + providerRepository.GetByIdAsync(provider.Id).Returns(provider); + + var providerOrganizationRepository = sutProvider.GetDependency(); + providerOrganizationRepository.GetByOrganizationId(organization.Id).ReturnsNull(); + + var organizationRepository = sutProvider.GetDependency(); + organizationRepository.GetByIdAsync(organization.Id).Returns(organization); + + // Feature flag enabled + sutProvider.GetDependency() + .IsEnabled(FeatureFlagKeys.AutomaticConfirmUsers) + .Returns(true); + + // Organization has NO automatic user confirmation policy (returns empty list) + sutProvider.GetDependency() + .GetManyByOrganizationIdAsync(organization.Id) + .Returns(new List()); + + // Act + await sutProvider.Sut.AddOrganization(provider.Id, organization.Id, key); + + // Assert + await providerOrganizationRepository.Received(1) + .CreateAsync(Arg.Is(providerOrganization => + providerOrganization.ProviderId == provider.Id && + providerOrganization.OrganizationId == organization.Id && + providerOrganization.Key == key)); + } + + [Theory, BitAutoData] + public async Task AddOrganization_WithAutoConfirmDisabledAndPolicyExists_Success( + Provider provider, + Organization organization, + string key, + SutProvider sutProvider) + { + // Arrange + organization.PlanType = PlanType.EnterpriseMonthly; + organization.UseSecretsManager = false; + + var providerRepository = sutProvider.GetDependency(); + providerRepository.GetByIdAsync(provider.Id).Returns(provider); + + var providerOrganizationRepository = sutProvider.GetDependency(); + providerOrganizationRepository.GetByOrganizationId(organization.Id).ReturnsNull(); + + var organizationRepository = sutProvider.GetDependency(); + organizationRepository.GetByIdAsync(organization.Id).Returns(organization); + + // Feature flag DISABLED + sutProvider.GetDependency() + .IsEnabled(FeatureFlagKeys.AutomaticConfirmUsers) + .Returns(false); + + // Act + await sutProvider.Sut.AddOrganization(provider.Id, organization.Id, key); + + // Assert - Should succeed because feature flag is disabled + await providerOrganizationRepository.Received(1) + .CreateAsync(Arg.Is(providerOrganization => + providerOrganization.ProviderId == provider.Id && + providerOrganization.OrganizationId == organization.Id && + providerOrganization.Key == key)); + + // Verify that policy check was never called when feature flag is disabled + await sutProvider.GetDependency() + .DidNotReceive() + .GetManyByOrganizationIdAsync(organization.Id); + } + [Theory, BitAutoData] public async Task AddOrganizationsToReseller_WithResellerProvider_Success(Provider provider, ICollection organizations, SutProvider sutProvider) {