mirror of
https://github.com/bitwarden/server.git
synced 2024-11-25 12:45:18 +01:00
[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
This commit is contained in:
parent
92ffe5fc20
commit
3eb4d547a8
@ -55,6 +55,7 @@ public class MaxProjectsQueryTests
|
|||||||
[BitAutoData(PlanType.TeamsAnnually2019)]
|
[BitAutoData(PlanType.TeamsAnnually2019)]
|
||||||
[BitAutoData(PlanType.TeamsAnnually2020)]
|
[BitAutoData(PlanType.TeamsAnnually2020)]
|
||||||
[BitAutoData(PlanType.TeamsAnnually)]
|
[BitAutoData(PlanType.TeamsAnnually)]
|
||||||
|
[BitAutoData(PlanType.TeamsStarter)]
|
||||||
[BitAutoData(PlanType.EnterpriseMonthly2019)]
|
[BitAutoData(PlanType.EnterpriseMonthly2019)]
|
||||||
[BitAutoData(PlanType.EnterpriseMonthly2020)]
|
[BitAutoData(PlanType.EnterpriseMonthly2020)]
|
||||||
[BitAutoData(PlanType.EnterpriseMonthly)]
|
[BitAutoData(PlanType.EnterpriseMonthly)]
|
||||||
|
@ -82,7 +82,7 @@
|
|||||||
<label asp-for="PlanType"></label>
|
<label asp-for="PlanType"></label>
|
||||||
@{
|
@{
|
||||||
var planTypes = Enum.GetValues<PlanType>()
|
var planTypes = Enum.GetValues<PlanType>()
|
||||||
.Where(p => Model.Provider == null || p is >= PlanType.TeamsMonthly and <= PlanType.EnterpriseAnnually)
|
.Where(p => Model.Provider == null || p is >= PlanType.TeamsMonthly and <= PlanType.TeamsStarter)
|
||||||
.Select(e => new SelectListItem
|
.Select(e => new SelectListItem
|
||||||
{
|
{
|
||||||
Value = ((int)e).ToString(),
|
Value = ((int)e).ToString(),
|
||||||
|
@ -74,6 +74,7 @@
|
|||||||
case '@((byte)PlanType.TeamsAnnually2020)':
|
case '@((byte)PlanType.TeamsAnnually2020)':
|
||||||
case '@((byte)PlanType.TeamsMonthly)':
|
case '@((byte)PlanType.TeamsMonthly)':
|
||||||
case '@((byte)PlanType.TeamsAnnually)':
|
case '@((byte)PlanType.TeamsAnnually)':
|
||||||
|
case '@((byte)PlanType.TeamsStarter)':
|
||||||
document.getElementById('@(nameof(Model.UsePolicies))').checked = false;
|
document.getElementById('@(nameof(Model.UsePolicies))').checked = false;
|
||||||
document.getElementById('@(nameof(Model.UseSso))').checked = false;
|
document.getElementById('@(nameof(Model.UseSso))').checked = false;
|
||||||
document.getElementById('@(nameof(Model.UseGroups))').checked = true;
|
document.getElementById('@(nameof(Model.UseGroups))').checked = true;
|
||||||
|
@ -33,9 +33,12 @@ public class PlansController : Controller
|
|||||||
public ListResponseModel<PlanResponseModel> Get()
|
public ListResponseModel<PlanResponseModel> Get()
|
||||||
{
|
{
|
||||||
var plansUpgradeIsEnabled = _featureService.IsEnabled(FeatureFlagKeys.BillingPlansUpgrade, _currentContext);
|
var plansUpgradeIsEnabled = _featureService.IsEnabled(FeatureFlagKeys.BillingPlansUpgrade, _currentContext);
|
||||||
var data = StaticStore.Plans;
|
var teamsStarterPlanIsEnabled = _featureService.IsEnabled(FeatureFlagKeys.BillingStarterPlan, _currentContext);
|
||||||
var responses = data
|
var responses = StaticStore.Plans
|
||||||
.Where(plan => plansUpgradeIsEnabled || plan.Type <= PlanType.EnterpriseAnnually2020)
|
// If plans upgrade is disabled, return only the original plans. Otherwise, return everything
|
||||||
|
.Where(plan => plansUpgradeIsEnabled || plan.Type <= PlanType.EnterpriseAnnually2020 || plan.Type == PlanType.TeamsStarter)
|
||||||
|
// If teams starter is disabled, don't return that plan, otherwise return everything
|
||||||
|
.Where(plan => teamsStarterPlanIsEnabled || plan.Product != ProductType.TeamsStarter)
|
||||||
.Select(plan =>
|
.Select(plan =>
|
||||||
{
|
{
|
||||||
if (!plansUpgradeIsEnabled && plan.Type is <= PlanType.EnterpriseAnnually2020 and >= PlanType.TeamsMonthly2020)
|
if (!plansUpgradeIsEnabled && plan.Type is <= PlanType.EnterpriseAnnually2020 and >= PlanType.TeamsMonthly2020)
|
||||||
|
@ -164,6 +164,7 @@ public class FreshsalesController : Controller
|
|||||||
case PlanType.TeamsMonthly:
|
case PlanType.TeamsMonthly:
|
||||||
case PlanType.TeamsMonthly2020:
|
case PlanType.TeamsMonthly2020:
|
||||||
case PlanType.TeamsMonthly2019:
|
case PlanType.TeamsMonthly2019:
|
||||||
|
case PlanType.TeamsStarter:
|
||||||
planName = "Teams";
|
planName = "Teams";
|
||||||
return true;
|
return true;
|
||||||
case PlanType.EnterpriseAnnually:
|
case PlanType.EnterpriseAnnually:
|
||||||
|
@ -64,6 +64,7 @@ public static class FeatureFlagKeys
|
|||||||
public const string AutofillOverlay = "autofill-overlay";
|
public const string AutofillOverlay = "autofill-overlay";
|
||||||
public const string ItemShare = "item-share";
|
public const string ItemShare = "item-share";
|
||||||
public const string BillingPlansUpgrade = "billing-plans-upgrade";
|
public const string BillingPlansUpgrade = "billing-plans-upgrade";
|
||||||
|
public const string BillingStarterPlan = "billing-starter-plan";
|
||||||
|
|
||||||
public static List<string> GetAllKeys()
|
public static List<string> GetAllKeys()
|
||||||
{
|
{
|
||||||
|
@ -36,4 +36,6 @@ public enum PlanType : byte
|
|||||||
EnterpriseMonthly = 14,
|
EnterpriseMonthly = 14,
|
||||||
[Display(Name = "Enterprise (Annually)")]
|
[Display(Name = "Enterprise (Annually)")]
|
||||||
EnterpriseAnnually = 15,
|
EnterpriseAnnually = 15,
|
||||||
|
[Display(Name = "Teams Starter")]
|
||||||
|
TeamsStarter = 16,
|
||||||
}
|
}
|
||||||
|
@ -12,5 +12,7 @@ public enum ProductType : byte
|
|||||||
Teams = 2,
|
Teams = 2,
|
||||||
[Display(Name = "Enterprise")]
|
[Display(Name = "Enterprise")]
|
||||||
Enterprise = 3,
|
Enterprise = 3,
|
||||||
|
[Display(Name = "Teams Starter")]
|
||||||
|
TeamsStarter = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
70
src/Core/Models/StaticStore/Plans/TeamsStarterPlan.cs
Normal file
70
src/Core/Models/StaticStore/Plans/TeamsStarterPlan.cs
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
using Bit.Core.Enums;
|
||||||
|
|
||||||
|
namespace Bit.Core.Models.StaticStore.Plans;
|
||||||
|
|
||||||
|
public record TeamsStarterPlan : Plan
|
||||||
|
{
|
||||||
|
public TeamsStarterPlan()
|
||||||
|
{
|
||||||
|
Type = PlanType.TeamsStarter;
|
||||||
|
Product = ProductType.TeamsStarter;
|
||||||
|
Name = "Teams (Starter)";
|
||||||
|
NameLocalizationKey = "planNameTeamsStarter";
|
||||||
|
DescriptionLocalizationKey = "planDescTeams";
|
||||||
|
CanBeUsedByBusiness = true;
|
||||||
|
|
||||||
|
TrialPeriodDays = 7;
|
||||||
|
|
||||||
|
HasGroups = true;
|
||||||
|
HasDirectory = true;
|
||||||
|
HasEvents = true;
|
||||||
|
HasTotp = true;
|
||||||
|
Has2fa = true;
|
||||||
|
HasApi = true;
|
||||||
|
UsersGetPremium = true;
|
||||||
|
|
||||||
|
UpgradeSortOrder = 2;
|
||||||
|
DisplaySortOrder = 2;
|
||||||
|
|
||||||
|
PasswordManager = new TeamsStarterPasswordManagerFeatures();
|
||||||
|
SecretsManager = new TeamsStarterSecretsManagerFeatures();
|
||||||
|
}
|
||||||
|
|
||||||
|
private record TeamsStarterSecretsManagerFeatures : SecretsManagerPlanFeatures
|
||||||
|
{
|
||||||
|
public TeamsStarterSecretsManagerFeatures()
|
||||||
|
{
|
||||||
|
BaseSeats = 0;
|
||||||
|
BasePrice = 0;
|
||||||
|
BaseServiceAccount = 50;
|
||||||
|
|
||||||
|
HasAdditionalSeatsOption = true;
|
||||||
|
HasAdditionalServiceAccountOption = true;
|
||||||
|
|
||||||
|
AllowSeatAutoscale = true;
|
||||||
|
AllowServiceAccountsAutoscale = true;
|
||||||
|
|
||||||
|
StripeSeatPlanId = "secrets-manager-teams-seat-monthly";
|
||||||
|
StripeServiceAccountPlanId = "secrets-manager-service-account-monthly";
|
||||||
|
SeatPrice = 7;
|
||||||
|
AdditionalPricePerServiceAccount = 0.5M;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private record TeamsStarterPasswordManagerFeatures : PasswordManagerPlanFeatures
|
||||||
|
{
|
||||||
|
public TeamsStarterPasswordManagerFeatures()
|
||||||
|
{
|
||||||
|
BaseSeats = 10;
|
||||||
|
BaseStorageGb = 1;
|
||||||
|
BasePrice = 20;
|
||||||
|
|
||||||
|
MaxSeats = 10;
|
||||||
|
|
||||||
|
HasAdditionalStorageOption = true;
|
||||||
|
|
||||||
|
StripePlanId = "teams-org-starter";
|
||||||
|
AdditionalStoragePricePerGb = 0.5M;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -243,6 +243,12 @@ public class UpdateSecretsManagerSubscriptionCommand : IUpdateSecretsManagerSubs
|
|||||||
"You cannot decrease your subscription below your current occupied seat count.");
|
"You cannot decrease your subscription below your current occupied seat count.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that SM seats aren't greater than password manager seats
|
||||||
|
if (organization.Seats < update.SmSeats.Value)
|
||||||
|
{
|
||||||
|
throw new BadRequestException("You cannot have more Secrets Manager seats than Password Manager seats.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ValidateSmServiceAccountsUpdateAsync(SecretsManagerSubscriptionUpdate update)
|
private async Task ValidateSmServiceAccountsUpdateAsync(SecretsManagerSubscriptionUpdate update)
|
||||||
|
@ -1893,7 +1893,10 @@ public class OrganizationService : IOrganizationService
|
|||||||
throw new BadRequestException("Plan does not allow additional Service Accounts.");
|
throw new BadRequestException("Plan does not allow additional Service Accounts.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (upgrade.AdditionalSmSeats.GetValueOrDefault() > upgrade.AdditionalSeats)
|
if ((plan.Product == ProductType.TeamsStarter &&
|
||||||
|
upgrade.AdditionalSmSeats.GetValueOrDefault() > plan.PasswordManager.BaseSeats) ||
|
||||||
|
(plan.Product != ProductType.TeamsStarter &&
|
||||||
|
upgrade.AdditionalSmSeats.GetValueOrDefault() > upgrade.AdditionalSeats))
|
||||||
{
|
{
|
||||||
throw new BadRequestException("You cannot have more Secrets Manager seats than Password Manager seats.");
|
throw new BadRequestException("You cannot have more Secrets Manager seats than Password Manager seats.");
|
||||||
}
|
}
|
||||||
|
@ -106,10 +106,11 @@ public static class StaticStore
|
|||||||
GlobalDomains.Add(GlobalEquivalentDomainsType.Pinterest, new List<string> { "pinterest.com", "pinterest.com.au", "pinterest.cl", "pinterest.de", "pinterest.dk", "pinterest.es", "pinterest.fr", "pinterest.co.uk", "pinterest.jp", "pinterest.co.kr", "pinterest.nz", "pinterest.pt", "pinterest.se" });
|
GlobalDomains.Add(GlobalEquivalentDomainsType.Pinterest, new List<string> { "pinterest.com", "pinterest.com.au", "pinterest.cl", "pinterest.de", "pinterest.dk", "pinterest.es", "pinterest.fr", "pinterest.co.uk", "pinterest.jp", "pinterest.co.kr", "pinterest.nz", "pinterest.pt", "pinterest.se" });
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
Plans = new List<Models.StaticStore.Plan>
|
Plans = new List<Plan>
|
||||||
{
|
{
|
||||||
new EnterprisePlan(true),
|
new EnterprisePlan(true),
|
||||||
new EnterprisePlan(false),
|
new EnterprisePlan(false),
|
||||||
|
new TeamsStarterPlan(),
|
||||||
new TeamsPlan(true),
|
new TeamsPlan(true),
|
||||||
new TeamsPlan(false),
|
new TeamsPlan(false),
|
||||||
|
|
||||||
@ -130,7 +131,7 @@ public static class StaticStore
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static IDictionary<GlobalEquivalentDomainsType, IEnumerable<string>> GlobalDomains { get; set; }
|
public static IDictionary<GlobalEquivalentDomainsType, IEnumerable<string>> GlobalDomains { get; set; }
|
||||||
public static IEnumerable<Models.StaticStore.Plan> Plans { get; }
|
public static IEnumerable<Plan> Plans { get; }
|
||||||
public static IEnumerable<SponsoredPlan> SponsoredPlans { get; set; } = new[]
|
public static IEnumerable<SponsoredPlan> SponsoredPlans { get; set; } = new[]
|
||||||
{
|
{
|
||||||
new SponsoredPlan
|
new SponsoredPlan
|
||||||
|
@ -43,6 +43,7 @@ public class SecretsManagerSubscriptionUpdateTests
|
|||||||
[BitAutoData(PlanType.TeamsAnnually2019)]
|
[BitAutoData(PlanType.TeamsAnnually2019)]
|
||||||
[BitAutoData(PlanType.TeamsAnnually2020)]
|
[BitAutoData(PlanType.TeamsAnnually2020)]
|
||||||
[BitAutoData(PlanType.TeamsAnnually)]
|
[BitAutoData(PlanType.TeamsAnnually)]
|
||||||
|
[BitAutoData(PlanType.TeamsStarter)]
|
||||||
public void UpdateSubscription_WithNonSecretsManagerPlanType_DoesNotThrowException(
|
public void UpdateSubscription_WithNonSecretsManagerPlanType_DoesNotThrowException(
|
||||||
PlanType planType,
|
PlanType planType,
|
||||||
Organization organization)
|
Organization organization)
|
||||||
|
@ -19,9 +19,18 @@ namespace Bit.Core.Test.OrganizationFeatures.OrganizationSubscriptionUpdate;
|
|||||||
public class AddSecretsManagerSubscriptionCommandTests
|
public class AddSecretsManagerSubscriptionCommandTests
|
||||||
{
|
{
|
||||||
[Theory]
|
[Theory]
|
||||||
|
[BitAutoData(PlanType.TeamsAnnually2019)]
|
||||||
|
[BitAutoData(PlanType.TeamsAnnually2020)]
|
||||||
[BitAutoData(PlanType.TeamsAnnually)]
|
[BitAutoData(PlanType.TeamsAnnually)]
|
||||||
|
[BitAutoData(PlanType.TeamsMonthly2019)]
|
||||||
|
[BitAutoData(PlanType.TeamsMonthly2020)]
|
||||||
[BitAutoData(PlanType.TeamsMonthly)]
|
[BitAutoData(PlanType.TeamsMonthly)]
|
||||||
|
[BitAutoData(PlanType.TeamsStarter)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseAnnually2019)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseAnnually2020)]
|
||||||
[BitAutoData(PlanType.EnterpriseAnnually)]
|
[BitAutoData(PlanType.EnterpriseAnnually)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseMonthly2019)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseMonthly2020)]
|
||||||
[BitAutoData(PlanType.EnterpriseMonthly)]
|
[BitAutoData(PlanType.EnterpriseMonthly)]
|
||||||
public async Task SignUpAsync_ReturnsSuccessAndClientSecret_WhenOrganizationAndPlanExist(PlanType planType,
|
public async Task SignUpAsync_ReturnsSuccessAndClientSecret_WhenOrganizationAndPlanExist(PlanType planType,
|
||||||
SutProvider<AddSecretsManagerSubscriptionCommand> sutProvider,
|
SutProvider<AddSecretsManagerSubscriptionCommand> sutProvider,
|
||||||
|
@ -22,16 +22,26 @@ namespace Bit.Core.Test.OrganizationFeatures.OrganizationSubscriptionUpdate;
|
|||||||
public class UpdateSecretsManagerSubscriptionCommandTests
|
public class UpdateSecretsManagerSubscriptionCommandTests
|
||||||
{
|
{
|
||||||
[Theory]
|
[Theory]
|
||||||
|
[BitAutoData(PlanType.EnterpriseAnnually2019)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseAnnually2020)]
|
||||||
[BitAutoData(PlanType.EnterpriseAnnually)]
|
[BitAutoData(PlanType.EnterpriseAnnually)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseMonthly2019)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseMonthly2020)]
|
||||||
[BitAutoData(PlanType.EnterpriseMonthly)]
|
[BitAutoData(PlanType.EnterpriseMonthly)]
|
||||||
|
[BitAutoData(PlanType.TeamsMonthly2019)]
|
||||||
|
[BitAutoData(PlanType.TeamsMonthly2020)]
|
||||||
[BitAutoData(PlanType.TeamsMonthly)]
|
[BitAutoData(PlanType.TeamsMonthly)]
|
||||||
|
[BitAutoData(PlanType.TeamsAnnually2019)]
|
||||||
|
[BitAutoData(PlanType.TeamsAnnually2020)]
|
||||||
[BitAutoData(PlanType.TeamsAnnually)]
|
[BitAutoData(PlanType.TeamsAnnually)]
|
||||||
|
[BitAutoData(PlanType.TeamsStarter)]
|
||||||
public async Task UpdateSubscriptionAsync_UpdateEverything_ValidInput_Passes(
|
public async Task UpdateSubscriptionAsync_UpdateEverything_ValidInput_Passes(
|
||||||
PlanType planType,
|
PlanType planType,
|
||||||
Organization organization,
|
Organization organization,
|
||||||
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
|
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
|
||||||
{
|
{
|
||||||
organization.PlanType = planType;
|
organization.PlanType = planType;
|
||||||
|
organization.Seats = 400;
|
||||||
organization.SmSeats = 10;
|
organization.SmSeats = 10;
|
||||||
organization.MaxAutoscaleSmSeats = 20;
|
organization.MaxAutoscaleSmSeats = 20;
|
||||||
organization.SmServiceAccounts = 200;
|
organization.SmServiceAccounts = 200;
|
||||||
@ -77,6 +87,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
|
|||||||
[BitAutoData(PlanType.EnterpriseMonthly)]
|
[BitAutoData(PlanType.EnterpriseMonthly)]
|
||||||
[BitAutoData(PlanType.TeamsMonthly)]
|
[BitAutoData(PlanType.TeamsMonthly)]
|
||||||
[BitAutoData(PlanType.TeamsAnnually)]
|
[BitAutoData(PlanType.TeamsAnnually)]
|
||||||
|
[BitAutoData(PlanType.TeamsStarter)]
|
||||||
public async Task UpdateSubscriptionAsync_ValidInput_WithNullMaxAutoscale_Passes(
|
public async Task UpdateSubscriptionAsync_ValidInput_WithNullMaxAutoscale_Passes(
|
||||||
PlanType planType,
|
PlanType planType,
|
||||||
Organization organization,
|
Organization organization,
|
||||||
@ -168,10 +179,19 @@ public class UpdateSecretsManagerSubscriptionCommandTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
[BitAutoData(PlanType.EnterpriseAnnually2019)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseAnnually2020)]
|
||||||
[BitAutoData(PlanType.EnterpriseAnnually)]
|
[BitAutoData(PlanType.EnterpriseAnnually)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseMonthly2019)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseMonthly2020)]
|
||||||
[BitAutoData(PlanType.EnterpriseMonthly)]
|
[BitAutoData(PlanType.EnterpriseMonthly)]
|
||||||
|
[BitAutoData(PlanType.TeamsMonthly2019)]
|
||||||
|
[BitAutoData(PlanType.TeamsMonthly2020)]
|
||||||
[BitAutoData(PlanType.TeamsMonthly)]
|
[BitAutoData(PlanType.TeamsMonthly)]
|
||||||
|
[BitAutoData(PlanType.TeamsAnnually2019)]
|
||||||
|
[BitAutoData(PlanType.TeamsAnnually2020)]
|
||||||
[BitAutoData(PlanType.TeamsAnnually)]
|
[BitAutoData(PlanType.TeamsAnnually)]
|
||||||
|
[BitAutoData(PlanType.TeamsStarter)]
|
||||||
public async Task UpdateSubscriptionAsync_PaidPlan_NullGatewayCustomerId_ThrowsException(
|
public async Task UpdateSubscriptionAsync_PaidPlan_NullGatewayCustomerId_ThrowsException(
|
||||||
PlanType planType,
|
PlanType planType,
|
||||||
Organization organization,
|
Organization organization,
|
||||||
@ -187,10 +207,19 @@ public class UpdateSecretsManagerSubscriptionCommandTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
[BitAutoData(PlanType.EnterpriseAnnually2019)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseAnnually2020)]
|
||||||
[BitAutoData(PlanType.EnterpriseAnnually)]
|
[BitAutoData(PlanType.EnterpriseAnnually)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseMonthly2019)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseMonthly2020)]
|
||||||
[BitAutoData(PlanType.EnterpriseMonthly)]
|
[BitAutoData(PlanType.EnterpriseMonthly)]
|
||||||
|
[BitAutoData(PlanType.TeamsMonthly2019)]
|
||||||
|
[BitAutoData(PlanType.TeamsMonthly2020)]
|
||||||
[BitAutoData(PlanType.TeamsMonthly)]
|
[BitAutoData(PlanType.TeamsMonthly)]
|
||||||
|
[BitAutoData(PlanType.TeamsAnnually2019)]
|
||||||
|
[BitAutoData(PlanType.TeamsAnnually2020)]
|
||||||
[BitAutoData(PlanType.TeamsAnnually)]
|
[BitAutoData(PlanType.TeamsAnnually)]
|
||||||
|
[BitAutoData(PlanType.TeamsStarter)]
|
||||||
public async Task UpdateSubscriptionAsync_PaidPlan_NullGatewaySubscriptionId_ThrowsException(
|
public async Task UpdateSubscriptionAsync_PaidPlan_NullGatewaySubscriptionId_ThrowsException(
|
||||||
PlanType planType,
|
PlanType planType,
|
||||||
Organization organization,
|
Organization organization,
|
||||||
@ -206,10 +235,19 @@ public class UpdateSecretsManagerSubscriptionCommandTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
[BitAutoData(PlanType.EnterpriseAnnually2019)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseAnnually2020)]
|
||||||
[BitAutoData(PlanType.EnterpriseAnnually)]
|
[BitAutoData(PlanType.EnterpriseAnnually)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseMonthly2019)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseMonthly2020)]
|
||||||
[BitAutoData(PlanType.EnterpriseMonthly)]
|
[BitAutoData(PlanType.EnterpriseMonthly)]
|
||||||
|
[BitAutoData(PlanType.TeamsMonthly2019)]
|
||||||
|
[BitAutoData(PlanType.TeamsMonthly2020)]
|
||||||
[BitAutoData(PlanType.TeamsMonthly)]
|
[BitAutoData(PlanType.TeamsMonthly)]
|
||||||
|
[BitAutoData(PlanType.TeamsAnnually2019)]
|
||||||
|
[BitAutoData(PlanType.TeamsAnnually2020)]
|
||||||
[BitAutoData(PlanType.TeamsAnnually)]
|
[BitAutoData(PlanType.TeamsAnnually)]
|
||||||
|
[BitAutoData(PlanType.TeamsStarter)]
|
||||||
public async Task AdjustServiceAccountsAsync_WithEnterpriseOrTeamsPlans_Success(PlanType planType, Guid organizationId,
|
public async Task AdjustServiceAccountsAsync_WithEnterpriseOrTeamsPlans_Success(PlanType planType, Guid organizationId,
|
||||||
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
|
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
|
||||||
{
|
{
|
||||||
@ -501,10 +539,19 @@ public class UpdateSecretsManagerSubscriptionCommandTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
[BitAutoData(PlanType.EnterpriseAnnually2019)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseAnnually2020)]
|
||||||
[BitAutoData(PlanType.EnterpriseAnnually)]
|
[BitAutoData(PlanType.EnterpriseAnnually)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseMonthly2019)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseMonthly2020)]
|
||||||
[BitAutoData(PlanType.EnterpriseMonthly)]
|
[BitAutoData(PlanType.EnterpriseMonthly)]
|
||||||
|
[BitAutoData(PlanType.TeamsMonthly2019)]
|
||||||
|
[BitAutoData(PlanType.TeamsMonthly2020)]
|
||||||
[BitAutoData(PlanType.TeamsMonthly)]
|
[BitAutoData(PlanType.TeamsMonthly)]
|
||||||
|
[BitAutoData(PlanType.TeamsAnnually2019)]
|
||||||
|
[BitAutoData(PlanType.TeamsAnnually2020)]
|
||||||
[BitAutoData(PlanType.TeamsAnnually)]
|
[BitAutoData(PlanType.TeamsAnnually)]
|
||||||
|
[BitAutoData(PlanType.TeamsStarter)]
|
||||||
public async Task UpdateSmServiceAccounts_WhenCurrentServiceAccountsIsGreaterThanNew_ThrowsBadRequestException(
|
public async Task UpdateSmServiceAccounts_WhenCurrentServiceAccountsIsGreaterThanNew_ThrowsBadRequestException(
|
||||||
PlanType planType,
|
PlanType planType,
|
||||||
Organization organization,
|
Organization organization,
|
||||||
|
@ -104,6 +104,7 @@ public class UpgradeOrganizationPlanCommandTests
|
|||||||
[BitAutoData(PlanType.EnterpriseAnnually)]
|
[BitAutoData(PlanType.EnterpriseAnnually)]
|
||||||
[BitAutoData(PlanType.TeamsMonthly)]
|
[BitAutoData(PlanType.TeamsMonthly)]
|
||||||
[BitAutoData(PlanType.TeamsAnnually)]
|
[BitAutoData(PlanType.TeamsAnnually)]
|
||||||
|
[BitAutoData(PlanType.TeamsStarter)]
|
||||||
public async Task UpgradePlan_SM_Passes(PlanType planType, Organization organization, OrganizationUpgrade upgrade,
|
public async Task UpgradePlan_SM_Passes(PlanType planType, Organization organization, OrganizationUpgrade upgrade,
|
||||||
SutProvider<UpgradeOrganizationPlanCommand> sutProvider)
|
SutProvider<UpgradeOrganizationPlanCommand> sutProvider)
|
||||||
{
|
{
|
||||||
@ -135,6 +136,7 @@ public class UpgradeOrganizationPlanCommandTests
|
|||||||
[BitAutoData(PlanType.EnterpriseAnnually)]
|
[BitAutoData(PlanType.EnterpriseAnnually)]
|
||||||
[BitAutoData(PlanType.TeamsMonthly)]
|
[BitAutoData(PlanType.TeamsMonthly)]
|
||||||
[BitAutoData(PlanType.TeamsAnnually)]
|
[BitAutoData(PlanType.TeamsAnnually)]
|
||||||
|
[BitAutoData(PlanType.TeamsStarter)]
|
||||||
public async Task UpgradePlan_SM_NotEnoughSmSeats_Throws(PlanType planType, Organization organization, OrganizationUpgrade upgrade,
|
public async Task UpgradePlan_SM_NotEnoughSmSeats_Throws(PlanType planType, Organization organization, OrganizationUpgrade upgrade,
|
||||||
SutProvider<UpgradeOrganizationPlanCommand> sutProvider)
|
SutProvider<UpgradeOrganizationPlanCommand> sutProvider)
|
||||||
{
|
{
|
||||||
@ -160,6 +162,7 @@ public class UpgradeOrganizationPlanCommandTests
|
|||||||
[BitAutoData(PlanType.EnterpriseAnnually, 201)]
|
[BitAutoData(PlanType.EnterpriseAnnually, 201)]
|
||||||
[BitAutoData(PlanType.TeamsMonthly, 51)]
|
[BitAutoData(PlanType.TeamsMonthly, 51)]
|
||||||
[BitAutoData(PlanType.TeamsAnnually, 51)]
|
[BitAutoData(PlanType.TeamsAnnually, 51)]
|
||||||
|
[BitAutoData(PlanType.TeamsStarter, 51)]
|
||||||
public async Task UpgradePlan_SM_NotEnoughServiceAccounts_Throws(PlanType planType, int currentServiceAccounts,
|
public async Task UpgradePlan_SM_NotEnoughServiceAccounts_Throws(PlanType planType, int currentServiceAccounts,
|
||||||
Organization organization, OrganizationUpgrade upgrade, SutProvider<UpgradeOrganizationPlanCommand> sutProvider)
|
Organization organization, OrganizationUpgrade upgrade, SutProvider<UpgradeOrganizationPlanCommand> sutProvider)
|
||||||
{
|
{
|
||||||
|
@ -1355,10 +1355,14 @@ public class OrganizationServiceTests
|
|||||||
[BitAutoData(PlanType.Custom, OrganizationUserType.Owner)]
|
[BitAutoData(PlanType.Custom, OrganizationUserType.Owner)]
|
||||||
[BitAutoData(PlanType.EnterpriseAnnually, OrganizationUserType.Admin)]
|
[BitAutoData(PlanType.EnterpriseAnnually, OrganizationUserType.Admin)]
|
||||||
[BitAutoData(PlanType.EnterpriseAnnually, OrganizationUserType.Owner)]
|
[BitAutoData(PlanType.EnterpriseAnnually, OrganizationUserType.Owner)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseAnnually2020, OrganizationUserType.Admin)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseAnnually2020, OrganizationUserType.Owner)]
|
||||||
[BitAutoData(PlanType.EnterpriseAnnually2019, OrganizationUserType.Admin)]
|
[BitAutoData(PlanType.EnterpriseAnnually2019, OrganizationUserType.Admin)]
|
||||||
[BitAutoData(PlanType.EnterpriseAnnually2019, OrganizationUserType.Owner)]
|
[BitAutoData(PlanType.EnterpriseAnnually2019, OrganizationUserType.Owner)]
|
||||||
[BitAutoData(PlanType.EnterpriseMonthly, OrganizationUserType.Admin)]
|
[BitAutoData(PlanType.EnterpriseMonthly, OrganizationUserType.Admin)]
|
||||||
[BitAutoData(PlanType.EnterpriseMonthly, OrganizationUserType.Owner)]
|
[BitAutoData(PlanType.EnterpriseMonthly, OrganizationUserType.Owner)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseMonthly2020, OrganizationUserType.Admin)]
|
||||||
|
[BitAutoData(PlanType.EnterpriseMonthly2020, OrganizationUserType.Owner)]
|
||||||
[BitAutoData(PlanType.EnterpriseMonthly2019, OrganizationUserType.Admin)]
|
[BitAutoData(PlanType.EnterpriseMonthly2019, OrganizationUserType.Admin)]
|
||||||
[BitAutoData(PlanType.EnterpriseMonthly2019, OrganizationUserType.Owner)]
|
[BitAutoData(PlanType.EnterpriseMonthly2019, OrganizationUserType.Owner)]
|
||||||
[BitAutoData(PlanType.FamiliesAnnually, OrganizationUserType.Admin)]
|
[BitAutoData(PlanType.FamiliesAnnually, OrganizationUserType.Admin)]
|
||||||
@ -1367,10 +1371,14 @@ public class OrganizationServiceTests
|
|||||||
[BitAutoData(PlanType.FamiliesAnnually2019, OrganizationUserType.Owner)]
|
[BitAutoData(PlanType.FamiliesAnnually2019, OrganizationUserType.Owner)]
|
||||||
[BitAutoData(PlanType.TeamsAnnually, OrganizationUserType.Admin)]
|
[BitAutoData(PlanType.TeamsAnnually, OrganizationUserType.Admin)]
|
||||||
[BitAutoData(PlanType.TeamsAnnually, OrganizationUserType.Owner)]
|
[BitAutoData(PlanType.TeamsAnnually, OrganizationUserType.Owner)]
|
||||||
|
[BitAutoData(PlanType.TeamsAnnually2020, OrganizationUserType.Admin)]
|
||||||
|
[BitAutoData(PlanType.TeamsAnnually2020, OrganizationUserType.Owner)]
|
||||||
[BitAutoData(PlanType.TeamsAnnually2019, OrganizationUserType.Admin)]
|
[BitAutoData(PlanType.TeamsAnnually2019, OrganizationUserType.Admin)]
|
||||||
[BitAutoData(PlanType.TeamsAnnually2019, OrganizationUserType.Owner)]
|
[BitAutoData(PlanType.TeamsAnnually2019, OrganizationUserType.Owner)]
|
||||||
[BitAutoData(PlanType.TeamsMonthly, OrganizationUserType.Admin)]
|
[BitAutoData(PlanType.TeamsMonthly, OrganizationUserType.Admin)]
|
||||||
[BitAutoData(PlanType.TeamsMonthly, OrganizationUserType.Owner)]
|
[BitAutoData(PlanType.TeamsMonthly, OrganizationUserType.Owner)]
|
||||||
|
[BitAutoData(PlanType.TeamsMonthly2020, OrganizationUserType.Admin)]
|
||||||
|
[BitAutoData(PlanType.TeamsMonthly2020, OrganizationUserType.Owner)]
|
||||||
[BitAutoData(PlanType.TeamsMonthly2019, OrganizationUserType.Admin)]
|
[BitAutoData(PlanType.TeamsMonthly2019, OrganizationUserType.Admin)]
|
||||||
[BitAutoData(PlanType.TeamsMonthly2019, OrganizationUserType.Owner)]
|
[BitAutoData(PlanType.TeamsMonthly2019, OrganizationUserType.Owner)]
|
||||||
public async Task ConfirmUserToNonFree_AlreadyFreeAdminOrOwner_DoesNotThrow(PlanType planType, OrganizationUserType orgUserType, Organization org, OrganizationUser confirmingUser,
|
public async Task ConfirmUserToNonFree_AlreadyFreeAdminOrOwner_DoesNotThrow(PlanType planType, OrganizationUserType orgUserType, Organization org, OrganizationUser confirmingUser,
|
||||||
@ -1791,6 +1799,7 @@ public class OrganizationServiceTests
|
|||||||
[Theory]
|
[Theory]
|
||||||
[BitAutoData(PlanType.TeamsAnnually)]
|
[BitAutoData(PlanType.TeamsAnnually)]
|
||||||
[BitAutoData(PlanType.TeamsMonthly)]
|
[BitAutoData(PlanType.TeamsMonthly)]
|
||||||
|
[BitAutoData(PlanType.TeamsStarter)]
|
||||||
[BitAutoData(PlanType.EnterpriseAnnually)]
|
[BitAutoData(PlanType.EnterpriseAnnually)]
|
||||||
[BitAutoData(PlanType.EnterpriseMonthly)]
|
[BitAutoData(PlanType.EnterpriseMonthly)]
|
||||||
public void ValidateSecretsManagerPlan_ThrowsException_WhenNoSecretsManagerSeats(PlanType planType, SutProvider<OrganizationService> sutProvider)
|
public void ValidateSecretsManagerPlan_ThrowsException_WhenNoSecretsManagerSeats(PlanType planType, SutProvider<OrganizationService> sutProvider)
|
||||||
@ -1863,6 +1872,7 @@ public class OrganizationServiceTests
|
|||||||
[Theory]
|
[Theory]
|
||||||
[BitAutoData(PlanType.TeamsAnnually)]
|
[BitAutoData(PlanType.TeamsAnnually)]
|
||||||
[BitAutoData(PlanType.TeamsMonthly)]
|
[BitAutoData(PlanType.TeamsMonthly)]
|
||||||
|
[BitAutoData(PlanType.TeamsStarter)]
|
||||||
[BitAutoData(PlanType.EnterpriseAnnually)]
|
[BitAutoData(PlanType.EnterpriseAnnually)]
|
||||||
[BitAutoData(PlanType.EnterpriseMonthly)]
|
[BitAutoData(PlanType.EnterpriseMonthly)]
|
||||||
public void ValidateSecretsManagerPlan_ThrowsException_WhenSubtractingServiceAccounts(
|
public void ValidateSecretsManagerPlan_ThrowsException_WhenSubtractingServiceAccounts(
|
||||||
@ -1902,6 +1912,7 @@ public class OrganizationServiceTests
|
|||||||
[Theory]
|
[Theory]
|
||||||
[BitAutoData(PlanType.TeamsAnnually)]
|
[BitAutoData(PlanType.TeamsAnnually)]
|
||||||
[BitAutoData(PlanType.TeamsMonthly)]
|
[BitAutoData(PlanType.TeamsMonthly)]
|
||||||
|
[BitAutoData(PlanType.TeamsStarter)]
|
||||||
[BitAutoData(PlanType.EnterpriseAnnually)]
|
[BitAutoData(PlanType.EnterpriseAnnually)]
|
||||||
[BitAutoData(PlanType.EnterpriseMonthly)]
|
[BitAutoData(PlanType.EnterpriseMonthly)]
|
||||||
public void ValidateSecretsManagerPlan_ValidPlan_NoExceptionThrown(
|
public void ValidateSecretsManagerPlan_ValidPlan_NoExceptionThrown(
|
||||||
|
@ -13,7 +13,7 @@ public class StaticStoreTests
|
|||||||
var plans = StaticStore.Plans.ToList();
|
var plans = StaticStore.Plans.ToList();
|
||||||
Assert.NotNull(plans);
|
Assert.NotNull(plans);
|
||||||
Assert.NotEmpty(plans);
|
Assert.NotEmpty(plans);
|
||||||
Assert.Equal(16, plans.Count);
|
Assert.Equal(17, plans.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@ -21,6 +21,7 @@ public class StaticStoreTests
|
|||||||
[InlineData(PlanType.EnterpriseMonthly)]
|
[InlineData(PlanType.EnterpriseMonthly)]
|
||||||
[InlineData(PlanType.TeamsMonthly)]
|
[InlineData(PlanType.TeamsMonthly)]
|
||||||
[InlineData(PlanType.TeamsAnnually)]
|
[InlineData(PlanType.TeamsAnnually)]
|
||||||
|
[InlineData(PlanType.TeamsStarter)]
|
||||||
public void StaticStore_GetPlan_Success(PlanType planType)
|
public void StaticStore_GetPlan_Success(PlanType planType)
|
||||||
{
|
{
|
||||||
var plan = StaticStore.GetPlan(planType);
|
var plan = StaticStore.GetPlan(planType);
|
||||||
|
Loading…
Reference in New Issue
Block a user