diff --git a/src/Core/OrganizationFeatures/OrganizationSubscriptions/UpdateSecretsManagerSubscriptionCommand.cs b/src/Core/OrganizationFeatures/OrganizationSubscriptions/UpdateSecretsManagerSubscriptionCommand.cs index 739dca5228..d4e1b3cd8d 100644 --- a/src/Core/OrganizationFeatures/OrganizationSubscriptions/UpdateSecretsManagerSubscriptionCommand.cs +++ b/src/Core/OrganizationFeatures/OrganizationSubscriptions/UpdateSecretsManagerSubscriptionCommand.cs @@ -226,7 +226,11 @@ public class UpdateSecretsManagerSubscriptionCommand : IUpdateSecretsManagerSubs // Check minimum seats currently in use by the organization if (organization.SmSeats.Value > update.SmSeats.Value) { + // Retrieve the number of currently occupied Secrets Manager seats for the organization. var occupiedSeats = await _organizationUserRepository.GetOccupiedSmSeatCountByOrganizationIdAsync(organization.Id); + + // Check if the occupied number of seats exceeds the updated seat count. + // If so, throw an exception indicating that the subscription cannot be decreased below the current usage. if (occupiedSeats > update.SmSeats.Value) { throw new BadRequestException($"{occupiedSeats} users are currently occupying Secrets Manager seats. " + @@ -412,7 +416,7 @@ public class UpdateSecretsManagerSubscriptionCommand : IUpdateSecretsManagerSubs } /// - /// Requests the number of Secret Manager seats and service accounts are currently used by the organization + /// Requests the number of Secret Manager seats and service accounts currently used by the organization /// /// The id of the organization /// A tuple containing the occupied seats and the occupied service account counts diff --git a/test/Core.Test/OrganizationFeatures/OrganizationSubscriptionUpdate/UpdateSecretsManagerSubscriptionCommandTests.cs b/test/Core.Test/OrganizationFeatures/OrganizationSubscriptionUpdate/UpdateSecretsManagerSubscriptionCommandTests.cs index 8b00741215..1e764de6d7 100644 --- a/test/Core.Test/OrganizationFeatures/OrganizationSubscriptionUpdate/UpdateSecretsManagerSubscriptionCommandTests.cs +++ b/test/Core.Test/OrganizationFeatures/OrganizationSubscriptionUpdate/UpdateSecretsManagerSubscriptionCommandTests.cs @@ -278,21 +278,27 @@ public class UpdateSecretsManagerSubscriptionCommandTests SutProvider sutProvider) { // Arrange - const int seatCount = 10; - var existingSeatCount = 9; - // Make sure Password Manager seats is greater or equal to Secrets Manager seats - organization.Seats = seatCount; + const int initialSeatCount = 9; + const int maxSeatCount = 20; + // This represents the total number of users allowed in the organization. + organization.Seats = maxSeatCount; + // This represents the number of Secrets Manager users allowed in the organization. + organization.SmSeats = initialSeatCount; + // This represents the upper limit of Secrets Manager seats that can be automatically scaled. + organization.MaxAutoscaleSmSeats = maxSeatCount; + + organization.PlanType = PlanType.EnterpriseAnnually; var plan = StaticStore.GetPlan(organization.PlanType); var update = new SecretsManagerSubscriptionUpdate(organization, plan, false) { - SmSeats = seatCount, - MaxAutoscaleSmSeats = seatCount + SmSeats = 8, + MaxAutoscaleSmSeats = maxSeatCount }; sutProvider.GetDependency() .GetOccupiedSmSeatCountByOrganizationIdAsync(organization.Id) - .Returns(existingSeatCount); + .Returns(5); // Act await sutProvider.Sut.UpdateSubscriptionAsync(update); @@ -316,21 +322,29 @@ public class UpdateSecretsManagerSubscriptionCommandTests SutProvider sutProvider) { // Arrange - const int seatCount = 10; - const int existingSeatCount = 10; - var ownerDetailsList = new List { new() { Email = "owner@example.com" } }; + const int initialSeatCount = 5; + const int maxSeatCount = 10; - // The amount of seats for users in an organization + // This represents the total number of users allowed in the organization. + organization.Seats = maxSeatCount; + // This represents the number of Secrets Manager users allowed in the organization. + organization.SmSeats = initialSeatCount; + // This represents the upper limit of Secrets Manager seats that can be automatically scaled. + organization.MaxAutoscaleSmSeats = maxSeatCount; + + var ownerDetailsList = new List { new() { Email = "owner@example.com" } }; + organization.PlanType = PlanType.EnterpriseAnnually; var plan = StaticStore.GetPlan(organization.PlanType); + var update = new SecretsManagerSubscriptionUpdate(organization, plan, false) { - SmSeats = seatCount, - MaxAutoscaleSmSeats = seatCount + SmSeats = maxSeatCount, + MaxAutoscaleSmSeats = maxSeatCount }; sutProvider.GetDependency() .GetOccupiedSmSeatCountByOrganizationIdAsync(organization.Id) - .Returns(existingSeatCount); + .Returns(maxSeatCount); sutProvider.GetDependency() .GetManyByMinimumRoleAsync(organization.Id, OrganizationUserType.Owner) .Returns(ownerDetailsList); @@ -340,15 +354,14 @@ public class UpdateSecretsManagerSubscriptionCommandTests // Assert - // Currently being called once each for different validation methods await sutProvider.GetDependency() - .Received(2) + .Received(1) .GetOccupiedSmSeatCountByOrganizationIdAsync(organization.Id); await sutProvider.GetDependency() .Received(1) .SendSecretsManagerMaxSeatLimitReachedEmailAsync(Arg.Is(organization), - Arg.Is(seatCount), + Arg.Is(maxSeatCount), Arg.Is>(emails => emails.Contains(ownerDetailsList[0].Email))); }