mirror of
https://github.com/bitwarden/server
synced 2026-01-07 11:03:37 +00:00
Merge branch 'main' into SM-1571-DisableSMAdsForUsers
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
using Bit.Core.Billing.Caches;
|
||||
using Bit.Core.Billing.Constants;
|
||||
using Bit.Core.Billing.Extensions;
|
||||
using Bit.Core.Billing.Payment.Models;
|
||||
using Bit.Core.Billing.Premium.Commands;
|
||||
using Bit.Core.Billing.Pricing;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Platform.Push;
|
||||
@@ -14,6 +16,8 @@ using NSubstitute;
|
||||
using Stripe;
|
||||
using Xunit;
|
||||
using Address = Stripe.Address;
|
||||
using PremiumPlan = Bit.Core.Billing.Pricing.Premium.Plan;
|
||||
using PremiumPurchasable = Bit.Core.Billing.Pricing.Premium.Purchasable;
|
||||
using StripeCustomer = Stripe.Customer;
|
||||
using StripeSubscription = Stripe.Subscription;
|
||||
|
||||
@@ -28,6 +32,7 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
private readonly ISubscriberService _subscriberService = Substitute.For<ISubscriberService>();
|
||||
private readonly IUserService _userService = Substitute.For<IUserService>();
|
||||
private readonly IPushNotificationService _pushNotificationService = Substitute.For<IPushNotificationService>();
|
||||
private readonly IPricingClient _pricingClient = Substitute.For<IPricingClient>();
|
||||
private readonly CreatePremiumCloudHostedSubscriptionCommand _command;
|
||||
|
||||
public CreatePremiumCloudHostedSubscriptionCommandTests()
|
||||
@@ -36,6 +41,17 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
baseServiceUri.CloudRegion.Returns("US");
|
||||
_globalSettings.BaseServiceUri.Returns(baseServiceUri);
|
||||
|
||||
// Setup default premium plan with standard pricing
|
||||
var premiumPlan = new PremiumPlan
|
||||
{
|
||||
Name = "Premium",
|
||||
Available = true,
|
||||
LegacyYear = null,
|
||||
Seat = new PremiumPurchasable { Price = 10M, StripePriceId = StripeConstants.Prices.PremiumAnnually },
|
||||
Storage = new PremiumPurchasable { Price = 4M, StripePriceId = StripeConstants.Prices.StoragePlanPersonal }
|
||||
};
|
||||
_pricingClient.GetAvailablePremiumPlan().Returns(premiumPlan);
|
||||
|
||||
_command = new CreatePremiumCloudHostedSubscriptionCommand(
|
||||
_braintreeGateway,
|
||||
_globalSettings,
|
||||
@@ -44,7 +60,8 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
|
||||
_subscriberService,
|
||||
_userService,
|
||||
_pushNotificationService,
|
||||
Substitute.For<ILogger<CreatePremiumCloudHostedSubscriptionCommand>>());
|
||||
Substitute.For<ILogger<CreatePremiumCloudHostedSubscriptionCommand>>(),
|
||||
_pricingClient);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
|
||||
@@ -1,23 +1,38 @@
|
||||
using Bit.Core.Billing.Payment.Models;
|
||||
using Bit.Core.Billing.Premium.Commands;
|
||||
using Bit.Core.Billing.Pricing;
|
||||
using Bit.Core.Services;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NSubstitute;
|
||||
using Stripe;
|
||||
using Xunit;
|
||||
using static Bit.Core.Billing.Constants.StripeConstants;
|
||||
using PremiumPlan = Bit.Core.Billing.Pricing.Premium.Plan;
|
||||
using PremiumPurchasable = Bit.Core.Billing.Pricing.Premium.Purchasable;
|
||||
|
||||
namespace Bit.Core.Test.Billing.Premium.Commands;
|
||||
|
||||
public class PreviewPremiumTaxCommandTests
|
||||
{
|
||||
private readonly ILogger<PreviewPremiumTaxCommand> _logger = Substitute.For<ILogger<PreviewPremiumTaxCommand>>();
|
||||
private readonly IPricingClient _pricingClient = Substitute.For<IPricingClient>();
|
||||
private readonly IStripeAdapter _stripeAdapter = Substitute.For<IStripeAdapter>();
|
||||
private readonly PreviewPremiumTaxCommand _command;
|
||||
|
||||
public PreviewPremiumTaxCommandTests()
|
||||
{
|
||||
_command = new PreviewPremiumTaxCommand(_logger, _stripeAdapter);
|
||||
// Setup default premium plan with standard pricing
|
||||
var premiumPlan = new PremiumPlan
|
||||
{
|
||||
Name = "Premium",
|
||||
Available = true,
|
||||
LegacyYear = null,
|
||||
Seat = new PremiumPurchasable { Price = 10M, StripePriceId = Prices.PremiumAnnually },
|
||||
Storage = new PremiumPurchasable { Price = 4M, StripePriceId = Prices.StoragePlanPersonal }
|
||||
};
|
||||
_pricingClient.GetAvailablePremiumPlan().Returns(premiumPlan);
|
||||
|
||||
_command = new PreviewPremiumTaxCommand(_logger, _pricingClient, _stripeAdapter);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -278,21 +278,27 @@ public class UpdateSecretsManagerSubscriptionCommandTests
|
||||
SutProvider<UpdateSecretsManagerSubscriptionCommand> 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<IOrganizationUserRepository>()
|
||||
.GetOccupiedSmSeatCountByOrganizationIdAsync(organization.Id)
|
||||
.Returns(existingSeatCount);
|
||||
.Returns(5);
|
||||
|
||||
// Act
|
||||
await sutProvider.Sut.UpdateSubscriptionAsync(update);
|
||||
@@ -316,21 +322,29 @@ public class UpdateSecretsManagerSubscriptionCommandTests
|
||||
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
|
||||
{
|
||||
// Arrange
|
||||
const int seatCount = 10;
|
||||
const int existingSeatCount = 10;
|
||||
var ownerDetailsList = new List<OrganizationUserUserDetails> { 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<OrganizationUserUserDetails> { 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<IOrganizationUserRepository>()
|
||||
.GetOccupiedSmSeatCountByOrganizationIdAsync(organization.Id)
|
||||
.Returns(existingSeatCount);
|
||||
.Returns(maxSeatCount);
|
||||
sutProvider.GetDependency<IOrganizationUserRepository>()
|
||||
.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<IOrganizationUserRepository>()
|
||||
.Received(2)
|
||||
.Received(1)
|
||||
.GetOccupiedSmSeatCountByOrganizationIdAsync(organization.Id);
|
||||
|
||||
await sutProvider.GetDependency<IMailService>()
|
||||
.Received(1)
|
||||
.SendSecretsManagerMaxSeatLimitReachedEmailAsync(Arg.Is(organization),
|
||||
Arg.Is(seatCount),
|
||||
Arg.Is(maxSeatCount),
|
||||
Arg.Is<IEnumerable<string>>(emails => emails.Contains(ownerDetailsList[0].Email)));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user