1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-28 13:15:12 +01:00
bitwarden-server/test/Core.Test/OrganizationFeatures/OrganizationSubscriptionUpdate/AddSecretsManagerSubscriptionCommandTests.cs
Conner Turnbull 3eb4d547a8
[AC-1708] Teams Starter Plan (#3386)
* Upgraded old 2019 plans to have the same features as 2020 and beyond

* Removed redundant test and moved additional test cases to GetByOrgIdAsync_SmNoneFreePlans_ReturnsNull

* Fixed issue where feature flag wasn't returning correct plans

* Added teams 2010 plan

* Reverted accidental change to StripePaymentService

* Split feature flag logic and added some explanatory comments

* Removed families changes

* Resolved issue where Teams Starter could not sign up for a new org with SM enabled

* Fixed issue with signing up for SM with Teams Starter

* Resolved issue where an active plan could increase their SM seat count to be greater than the base seats in the password manager plan

* Updated unit test to ensure Seats are higher than SmSeats

* Resolved issue where getting plans would return a value that LINQ previously cached when feature flag was in a different state
2023-11-03 22:26:47 +00:00

171 lines
7.3 KiB
C#

using Bit.Core.AdminConsole.Entities.Provider;
using Bit.Core.AdminConsole.Enums.Provider;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Business;
using Bit.Core.Models.StaticStore;
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions;
using Bit.Core.Services;
using Bit.Core.Utilities;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
using NSubstitute;
using Xunit;
namespace Bit.Core.Test.OrganizationFeatures.OrganizationSubscriptionUpdate;
[SutProviderCustomize]
public class AddSecretsManagerSubscriptionCommandTests
{
[Theory]
[BitAutoData(PlanType.TeamsAnnually2019)]
[BitAutoData(PlanType.TeamsAnnually2020)]
[BitAutoData(PlanType.TeamsAnnually)]
[BitAutoData(PlanType.TeamsMonthly2019)]
[BitAutoData(PlanType.TeamsMonthly2020)]
[BitAutoData(PlanType.TeamsMonthly)]
[BitAutoData(PlanType.TeamsStarter)]
[BitAutoData(PlanType.EnterpriseAnnually2019)]
[BitAutoData(PlanType.EnterpriseAnnually2020)]
[BitAutoData(PlanType.EnterpriseAnnually)]
[BitAutoData(PlanType.EnterpriseMonthly2019)]
[BitAutoData(PlanType.EnterpriseMonthly2020)]
[BitAutoData(PlanType.EnterpriseMonthly)]
public async Task SignUpAsync_ReturnsSuccessAndClientSecret_WhenOrganizationAndPlanExist(PlanType planType,
SutProvider<AddSecretsManagerSubscriptionCommand> sutProvider,
int additionalServiceAccounts,
int additionalSmSeats,
Organization organization,
bool useSecretsManager)
{
organization.PlanType = planType;
var plan = StaticStore.Plans.FirstOrDefault(p => p.Type == organization.PlanType);
await sutProvider.Sut.SignUpAsync(organization, additionalSmSeats, additionalServiceAccounts);
sutProvider.GetDependency<IOrganizationService>().Received(1)
.ValidateSecretsManagerPlan(plan, Arg.Is<OrganizationUpgrade>(c =>
c.UseSecretsManager == useSecretsManager &&
c.AdditionalSmSeats == additionalSmSeats &&
c.AdditionalServiceAccounts == additionalServiceAccounts &&
c.AdditionalSeats == organization.Seats.GetValueOrDefault()));
await sutProvider.GetDependency<IPaymentService>().Received()
.AddSecretsManagerToSubscription(organization, plan, additionalSmSeats, additionalServiceAccounts);
// TODO: call ReferenceEventService - see AC-1481
sutProvider.GetDependency<IOrganizationService>().Received(1).ReplaceAndUpdateCacheAsync(Arg.Is<Organization>(c =>
c.SmSeats == plan.SecretsManager.BaseSeats + additionalSmSeats &&
c.SmServiceAccounts == plan.SecretsManager.BaseServiceAccount + additionalServiceAccounts &&
c.UseSecretsManager == true));
}
[Theory]
[BitAutoData]
public async Task SignUpAsync_ThrowsNotFoundException_WhenOrganizationIsNull(
SutProvider<AddSecretsManagerSubscriptionCommand> sutProvider,
int additionalServiceAccounts,
int additionalSmSeats)
{
await Assert.ThrowsAsync<NotFoundException>(() =>
sutProvider.Sut.SignUpAsync(null, additionalSmSeats, additionalServiceAccounts));
await VerifyDependencyNotCalledAsync(sutProvider);
}
[Theory]
[BitAutoData]
public async Task SignUpAsync_ThrowsGatewayException_WhenGatewayCustomerIdIsNullOrWhitespace(
SutProvider<AddSecretsManagerSubscriptionCommand> sutProvider,
Organization organization,
int additionalServiceAccounts,
int additionalSmSeats)
{
organization.GatewayCustomerId = null;
organization.PlanType = PlanType.EnterpriseAnnually;
var exception = await Assert.ThrowsAsync<BadRequestException>(() =>
sutProvider.Sut.SignUpAsync(organization, additionalSmSeats, additionalServiceAccounts));
Assert.Contains("No payment method found.", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
[Theory]
[BitAutoData]
public async Task SignUpAsync_ThrowsGatewayException_WhenGatewaySubscriptionIdIsNullOrWhitespace(
SutProvider<AddSecretsManagerSubscriptionCommand> sutProvider,
Organization organization,
int additionalServiceAccounts,
int additionalSmSeats)
{
organization.GatewaySubscriptionId = null;
organization.PlanType = PlanType.EnterpriseAnnually;
var exception = await Assert.ThrowsAsync<BadRequestException>(() =>
sutProvider.Sut.SignUpAsync(organization, additionalSmSeats, additionalServiceAccounts));
Assert.Contains("No subscription found.", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
[Theory]
[BitAutoData]
public async Task SignUpAsync_ThrowsException_WhenOrganizationEnrolledInSmBeta(
SutProvider<AddSecretsManagerSubscriptionCommand> sutProvider,
Organization organization)
{
organization.UseSecretsManager = true;
organization.SecretsManagerBeta = true;
var exception = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.SignUpAsync(organization, 10, 10));
Assert.Contains("Organization is enrolled in Secrets Manager Beta", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
[Theory]
[BitAutoData]
public async Task SignUpAsync_ThrowsException_WhenOrganizationAlreadyHasSecretsManager(
SutProvider<AddSecretsManagerSubscriptionCommand> sutProvider,
Organization organization)
{
organization.UseSecretsManager = true;
organization.SecretsManagerBeta = false;
var exception = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.SignUpAsync(organization, 10, 10));
Assert.Contains("Organization already uses Secrets Manager", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
[Theory]
[BitAutoData]
public async Task SignUpAsync_ThrowsException_WhenOrganizationIsManagedByMSP(
SutProvider<AddSecretsManagerSubscriptionCommand> sutProvider,
Organization organization,
Provider provider)
{
organization.UseSecretsManager = false;
organization.SecretsManagerBeta = false;
provider.Type = ProviderType.Msp;
sutProvider.GetDependency<IProviderRepository>().GetByOrganizationIdAsync(organization.Id).Returns(provider);
var exception = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.SignUpAsync(organization, 10, 10));
Assert.Contains("Organizations with a Managed Service Provider do not support Secrets Manager.", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
private static async Task VerifyDependencyNotCalledAsync(SutProvider<AddSecretsManagerSubscriptionCommand> sutProvider)
{
await sutProvider.GetDependency<IPaymentService>().DidNotReceive()
.AddSecretsManagerToSubscription(Arg.Any<Organization>(), Arg.Any<Plan>(), Arg.Any<int>(), Arg.Any<int>());
// TODO: call ReferenceEventService - see AC-1481
await sutProvider.GetDependency<IOrganizationService>().DidNotReceive().ReplaceAndUpdateCacheAsync(Arg.Any<Organization>());
}
}