From 3eb4d547a8ee61db6c357c49a3e225ab713e3f7a Mon Sep 17 00:00:00 2001
From: Conner Turnbull <133619638+cturnbull-bitwarden@users.noreply.github.com>
Date: Fri, 3 Nov 2023 18:26:47 -0400
Subject: [PATCH] [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
---
.../Queries/Projects/MaxProjectsQueryTests.cs | 1 +
.../Views/Shared/_OrganizationForm.cshtml | 2 +-
.../Shared/_OrganizationFormScripts.cshtml | 1 +
src/Api/Controllers/PlansController.cs | 9 ++-
.../Controllers/FreshsalesController.cs | 1 +
src/Core/Constants.cs | 1 +
src/Core/Enums/PlanType.cs | 2 +
src/Core/Enums/ProductType.cs | 2 +
.../StaticStore/Plans/TeamsStarterPlan.cs | 70 +++++++++++++++++++
...UpdateSecretsManagerSubscriptionCommand.cs | 6 ++
.../Implementations/OrganizationService.cs | 5 +-
src/Core/Utilities/StaticStore.cs | 5 +-
.../SecretsManagerSubscriptionUpdateTests.cs | 1 +
...dSecretsManagerSubscriptionCommandTests.cs | 9 +++
...eSecretsManagerSubscriptionCommandTests.cs | 47 +++++++++++++
.../UpgradeOrganizationPlanCommandTests.cs | 3 +
.../Services/OrganizationServiceTests.cs | 11 +++
test/Core.Test/Utilities/StaticStoreTests.cs | 3 +-
18 files changed, 171 insertions(+), 8 deletions(-)
create mode 100644 src/Core/Models/StaticStore/Plans/TeamsStarterPlan.cs
diff --git a/bitwarden_license/test/Commercial.Core.Test/SecretsManager/Queries/Projects/MaxProjectsQueryTests.cs b/bitwarden_license/test/Commercial.Core.Test/SecretsManager/Queries/Projects/MaxProjectsQueryTests.cs
index 58c944e8e..030e31d24 100644
--- a/bitwarden_license/test/Commercial.Core.Test/SecretsManager/Queries/Projects/MaxProjectsQueryTests.cs
+++ b/bitwarden_license/test/Commercial.Core.Test/SecretsManager/Queries/Projects/MaxProjectsQueryTests.cs
@@ -55,6 +55,7 @@ public class MaxProjectsQueryTests
[BitAutoData(PlanType.TeamsAnnually2019)]
[BitAutoData(PlanType.TeamsAnnually2020)]
[BitAutoData(PlanType.TeamsAnnually)]
+ [BitAutoData(PlanType.TeamsStarter)]
[BitAutoData(PlanType.EnterpriseMonthly2019)]
[BitAutoData(PlanType.EnterpriseMonthly2020)]
[BitAutoData(PlanType.EnterpriseMonthly)]
diff --git a/src/Admin/Views/Shared/_OrganizationForm.cshtml b/src/Admin/Views/Shared/_OrganizationForm.cshtml
index 9e1b488b1..76502ff75 100644
--- a/src/Admin/Views/Shared/_OrganizationForm.cshtml
+++ b/src/Admin/Views/Shared/_OrganizationForm.cshtml
@@ -82,7 +82,7 @@
@{
var planTypes = Enum.GetValues()
- .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
{
Value = ((int)e).ToString(),
diff --git a/src/Admin/Views/Shared/_OrganizationFormScripts.cshtml b/src/Admin/Views/Shared/_OrganizationFormScripts.cshtml
index 5871977fe..fc527750a 100644
--- a/src/Admin/Views/Shared/_OrganizationFormScripts.cshtml
+++ b/src/Admin/Views/Shared/_OrganizationFormScripts.cshtml
@@ -74,6 +74,7 @@
case '@((byte)PlanType.TeamsAnnually2020)':
case '@((byte)PlanType.TeamsMonthly)':
case '@((byte)PlanType.TeamsAnnually)':
+ case '@((byte)PlanType.TeamsStarter)':
document.getElementById('@(nameof(Model.UsePolicies))').checked = false;
document.getElementById('@(nameof(Model.UseSso))').checked = false;
document.getElementById('@(nameof(Model.UseGroups))').checked = true;
diff --git a/src/Api/Controllers/PlansController.cs b/src/Api/Controllers/PlansController.cs
index 14992bd97..09aa0ba1e 100644
--- a/src/Api/Controllers/PlansController.cs
+++ b/src/Api/Controllers/PlansController.cs
@@ -33,9 +33,12 @@ public class PlansController : Controller
public ListResponseModel Get()
{
var plansUpgradeIsEnabled = _featureService.IsEnabled(FeatureFlagKeys.BillingPlansUpgrade, _currentContext);
- var data = StaticStore.Plans;
- var responses = data
- .Where(plan => plansUpgradeIsEnabled || plan.Type <= PlanType.EnterpriseAnnually2020)
+ var teamsStarterPlanIsEnabled = _featureService.IsEnabled(FeatureFlagKeys.BillingStarterPlan, _currentContext);
+ var responses = StaticStore.Plans
+ // 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 =>
{
if (!plansUpgradeIsEnabled && plan.Type is <= PlanType.EnterpriseAnnually2020 and >= PlanType.TeamsMonthly2020)
diff --git a/src/Billing/Controllers/FreshsalesController.cs b/src/Billing/Controllers/FreshsalesController.cs
index a66edd6ca..545f285e0 100644
--- a/src/Billing/Controllers/FreshsalesController.cs
+++ b/src/Billing/Controllers/FreshsalesController.cs
@@ -164,6 +164,7 @@ public class FreshsalesController : Controller
case PlanType.TeamsMonthly:
case PlanType.TeamsMonthly2020:
case PlanType.TeamsMonthly2019:
+ case PlanType.TeamsStarter:
planName = "Teams";
return true;
case PlanType.EnterpriseAnnually:
diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs
index e32b0f4ce..6dbe8541d 100644
--- a/src/Core/Constants.cs
+++ b/src/Core/Constants.cs
@@ -64,6 +64,7 @@ public static class FeatureFlagKeys
public const string AutofillOverlay = "autofill-overlay";
public const string ItemShare = "item-share";
public const string BillingPlansUpgrade = "billing-plans-upgrade";
+ public const string BillingStarterPlan = "billing-starter-plan";
public static List GetAllKeys()
{
diff --git a/src/Core/Enums/PlanType.cs b/src/Core/Enums/PlanType.cs
index cb88e8360..57fcd3090 100644
--- a/src/Core/Enums/PlanType.cs
+++ b/src/Core/Enums/PlanType.cs
@@ -36,4 +36,6 @@ public enum PlanType : byte
EnterpriseMonthly = 14,
[Display(Name = "Enterprise (Annually)")]
EnterpriseAnnually = 15,
+ [Display(Name = "Teams Starter")]
+ TeamsStarter = 16,
}
diff --git a/src/Core/Enums/ProductType.cs b/src/Core/Enums/ProductType.cs
index 1e443f56f..9d6e0e2bb 100644
--- a/src/Core/Enums/ProductType.cs
+++ b/src/Core/Enums/ProductType.cs
@@ -12,5 +12,7 @@ public enum ProductType : byte
Teams = 2,
[Display(Name = "Enterprise")]
Enterprise = 3,
+ [Display(Name = "Teams Starter")]
+ TeamsStarter = 4,
}
diff --git a/src/Core/Models/StaticStore/Plans/TeamsStarterPlan.cs b/src/Core/Models/StaticStore/Plans/TeamsStarterPlan.cs
new file mode 100644
index 000000000..1b9b1b876
--- /dev/null
+++ b/src/Core/Models/StaticStore/Plans/TeamsStarterPlan.cs
@@ -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;
+ }
+ }
+}
diff --git a/src/Core/OrganizationFeatures/OrganizationSubscriptions/UpdateSecretsManagerSubscriptionCommand.cs b/src/Core/OrganizationFeatures/OrganizationSubscriptions/UpdateSecretsManagerSubscriptionCommand.cs
index 30ccbe578..ddfdee3f6 100644
--- a/src/Core/OrganizationFeatures/OrganizationSubscriptions/UpdateSecretsManagerSubscriptionCommand.cs
+++ b/src/Core/OrganizationFeatures/OrganizationSubscriptions/UpdateSecretsManagerSubscriptionCommand.cs
@@ -243,6 +243,12 @@ public class UpdateSecretsManagerSubscriptionCommand : IUpdateSecretsManagerSubs
"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)
diff --git a/src/Core/Services/Implementations/OrganizationService.cs b/src/Core/Services/Implementations/OrganizationService.cs
index cc504ae02..e7275a6d2 100644
--- a/src/Core/Services/Implementations/OrganizationService.cs
+++ b/src/Core/Services/Implementations/OrganizationService.cs
@@ -1893,7 +1893,10 @@ public class OrganizationService : IOrganizationService
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.");
}
diff --git a/src/Core/Utilities/StaticStore.cs b/src/Core/Utilities/StaticStore.cs
index 11052a446..dcf63df13 100644
--- a/src/Core/Utilities/StaticStore.cs
+++ b/src/Core/Utilities/StaticStore.cs
@@ -106,10 +106,11 @@ public static class StaticStore
GlobalDomains.Add(GlobalEquivalentDomainsType.Pinterest, new List { "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
- Plans = new List
+ Plans = new List
{
new EnterprisePlan(true),
new EnterprisePlan(false),
+ new TeamsStarterPlan(),
new TeamsPlan(true),
new TeamsPlan(false),
@@ -130,7 +131,7 @@ public static class StaticStore
}
public static IDictionary> GlobalDomains { get; set; }
- public static IEnumerable Plans { get; }
+ public static IEnumerable Plans { get; }
public static IEnumerable SponsoredPlans { get; set; } = new[]
{
new SponsoredPlan
diff --git a/test/Core.Test/Models/Business/SecretsManagerSubscriptionUpdateTests.cs b/test/Core.Test/Models/Business/SecretsManagerSubscriptionUpdateTests.cs
index 88e21862b..ce08065ab 100644
--- a/test/Core.Test/Models/Business/SecretsManagerSubscriptionUpdateTests.cs
+++ b/test/Core.Test/Models/Business/SecretsManagerSubscriptionUpdateTests.cs
@@ -43,6 +43,7 @@ public class SecretsManagerSubscriptionUpdateTests
[BitAutoData(PlanType.TeamsAnnually2019)]
[BitAutoData(PlanType.TeamsAnnually2020)]
[BitAutoData(PlanType.TeamsAnnually)]
+ [BitAutoData(PlanType.TeamsStarter)]
public void UpdateSubscription_WithNonSecretsManagerPlanType_DoesNotThrowException(
PlanType planType,
Organization organization)
diff --git a/test/Core.Test/OrganizationFeatures/OrganizationSubscriptionUpdate/AddSecretsManagerSubscriptionCommandTests.cs b/test/Core.Test/OrganizationFeatures/OrganizationSubscriptionUpdate/AddSecretsManagerSubscriptionCommandTests.cs
index e3b948719..46987d6fc 100644
--- a/test/Core.Test/OrganizationFeatures/OrganizationSubscriptionUpdate/AddSecretsManagerSubscriptionCommandTests.cs
+++ b/test/Core.Test/OrganizationFeatures/OrganizationSubscriptionUpdate/AddSecretsManagerSubscriptionCommandTests.cs
@@ -19,9 +19,18 @@ namespace Bit.Core.Test.OrganizationFeatures.OrganizationSubscriptionUpdate;
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 sutProvider,
diff --git a/test/Core.Test/OrganizationFeatures/OrganizationSubscriptionUpdate/UpdateSecretsManagerSubscriptionCommandTests.cs b/test/Core.Test/OrganizationFeatures/OrganizationSubscriptionUpdate/UpdateSecretsManagerSubscriptionCommandTests.cs
index 16508bd25..c17ab2b83 100644
--- a/test/Core.Test/OrganizationFeatures/OrganizationSubscriptionUpdate/UpdateSecretsManagerSubscriptionCommandTests.cs
+++ b/test/Core.Test/OrganizationFeatures/OrganizationSubscriptionUpdate/UpdateSecretsManagerSubscriptionCommandTests.cs
@@ -22,16 +22,26 @@ namespace Bit.Core.Test.OrganizationFeatures.OrganizationSubscriptionUpdate;
public class UpdateSecretsManagerSubscriptionCommandTests
{
[Theory]
+ [BitAutoData(PlanType.EnterpriseAnnually2019)]
+ [BitAutoData(PlanType.EnterpriseAnnually2020)]
[BitAutoData(PlanType.EnterpriseAnnually)]
+ [BitAutoData(PlanType.EnterpriseMonthly2019)]
+ [BitAutoData(PlanType.EnterpriseMonthly2020)]
[BitAutoData(PlanType.EnterpriseMonthly)]
+ [BitAutoData(PlanType.TeamsMonthly2019)]
+ [BitAutoData(PlanType.TeamsMonthly2020)]
[BitAutoData(PlanType.TeamsMonthly)]
+ [BitAutoData(PlanType.TeamsAnnually2019)]
+ [BitAutoData(PlanType.TeamsAnnually2020)]
[BitAutoData(PlanType.TeamsAnnually)]
+ [BitAutoData(PlanType.TeamsStarter)]
public async Task UpdateSubscriptionAsync_UpdateEverything_ValidInput_Passes(
PlanType planType,
Organization organization,
SutProvider sutProvider)
{
organization.PlanType = planType;
+ organization.Seats = 400;
organization.SmSeats = 10;
organization.MaxAutoscaleSmSeats = 20;
organization.SmServiceAccounts = 200;
@@ -77,6 +87,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
[BitAutoData(PlanType.EnterpriseMonthly)]
[BitAutoData(PlanType.TeamsMonthly)]
[BitAutoData(PlanType.TeamsAnnually)]
+ [BitAutoData(PlanType.TeamsStarter)]
public async Task UpdateSubscriptionAsync_ValidInput_WithNullMaxAutoscale_Passes(
PlanType planType,
Organization organization,
@@ -168,10 +179,19 @@ public class UpdateSecretsManagerSubscriptionCommandTests
}
[Theory]
+ [BitAutoData(PlanType.EnterpriseAnnually2019)]
+ [BitAutoData(PlanType.EnterpriseAnnually2020)]
[BitAutoData(PlanType.EnterpriseAnnually)]
+ [BitAutoData(PlanType.EnterpriseMonthly2019)]
+ [BitAutoData(PlanType.EnterpriseMonthly2020)]
[BitAutoData(PlanType.EnterpriseMonthly)]
+ [BitAutoData(PlanType.TeamsMonthly2019)]
+ [BitAutoData(PlanType.TeamsMonthly2020)]
[BitAutoData(PlanType.TeamsMonthly)]
+ [BitAutoData(PlanType.TeamsAnnually2019)]
+ [BitAutoData(PlanType.TeamsAnnually2020)]
[BitAutoData(PlanType.TeamsAnnually)]
+ [BitAutoData(PlanType.TeamsStarter)]
public async Task UpdateSubscriptionAsync_PaidPlan_NullGatewayCustomerId_ThrowsException(
PlanType planType,
Organization organization,
@@ -187,10 +207,19 @@ public class UpdateSecretsManagerSubscriptionCommandTests
}
[Theory]
+ [BitAutoData(PlanType.EnterpriseAnnually2019)]
+ [BitAutoData(PlanType.EnterpriseAnnually2020)]
[BitAutoData(PlanType.EnterpriseAnnually)]
+ [BitAutoData(PlanType.EnterpriseMonthly2019)]
+ [BitAutoData(PlanType.EnterpriseMonthly2020)]
[BitAutoData(PlanType.EnterpriseMonthly)]
+ [BitAutoData(PlanType.TeamsMonthly2019)]
+ [BitAutoData(PlanType.TeamsMonthly2020)]
[BitAutoData(PlanType.TeamsMonthly)]
+ [BitAutoData(PlanType.TeamsAnnually2019)]
+ [BitAutoData(PlanType.TeamsAnnually2020)]
[BitAutoData(PlanType.TeamsAnnually)]
+ [BitAutoData(PlanType.TeamsStarter)]
public async Task UpdateSubscriptionAsync_PaidPlan_NullGatewaySubscriptionId_ThrowsException(
PlanType planType,
Organization organization,
@@ -206,10 +235,19 @@ public class UpdateSecretsManagerSubscriptionCommandTests
}
[Theory]
+ [BitAutoData(PlanType.EnterpriseAnnually2019)]
+ [BitAutoData(PlanType.EnterpriseAnnually2020)]
[BitAutoData(PlanType.EnterpriseAnnually)]
+ [BitAutoData(PlanType.EnterpriseMonthly2019)]
+ [BitAutoData(PlanType.EnterpriseMonthly2020)]
[BitAutoData(PlanType.EnterpriseMonthly)]
+ [BitAutoData(PlanType.TeamsMonthly2019)]
+ [BitAutoData(PlanType.TeamsMonthly2020)]
[BitAutoData(PlanType.TeamsMonthly)]
+ [BitAutoData(PlanType.TeamsAnnually2019)]
+ [BitAutoData(PlanType.TeamsAnnually2020)]
[BitAutoData(PlanType.TeamsAnnually)]
+ [BitAutoData(PlanType.TeamsStarter)]
public async Task AdjustServiceAccountsAsync_WithEnterpriseOrTeamsPlans_Success(PlanType planType, Guid organizationId,
SutProvider sutProvider)
{
@@ -501,10 +539,19 @@ public class UpdateSecretsManagerSubscriptionCommandTests
}
[Theory]
+ [BitAutoData(PlanType.EnterpriseAnnually2019)]
+ [BitAutoData(PlanType.EnterpriseAnnually2020)]
[BitAutoData(PlanType.EnterpriseAnnually)]
+ [BitAutoData(PlanType.EnterpriseMonthly2019)]
+ [BitAutoData(PlanType.EnterpriseMonthly2020)]
[BitAutoData(PlanType.EnterpriseMonthly)]
+ [BitAutoData(PlanType.TeamsMonthly2019)]
+ [BitAutoData(PlanType.TeamsMonthly2020)]
[BitAutoData(PlanType.TeamsMonthly)]
+ [BitAutoData(PlanType.TeamsAnnually2019)]
+ [BitAutoData(PlanType.TeamsAnnually2020)]
[BitAutoData(PlanType.TeamsAnnually)]
+ [BitAutoData(PlanType.TeamsStarter)]
public async Task UpdateSmServiceAccounts_WhenCurrentServiceAccountsIsGreaterThanNew_ThrowsBadRequestException(
PlanType planType,
Organization organization,
diff --git a/test/Core.Test/OrganizationFeatures/OrganizationSubscriptionUpdate/UpgradeOrganizationPlanCommandTests.cs b/test/Core.Test/OrganizationFeatures/OrganizationSubscriptionUpdate/UpgradeOrganizationPlanCommandTests.cs
index f79001639..b7f7d32cb 100644
--- a/test/Core.Test/OrganizationFeatures/OrganizationSubscriptionUpdate/UpgradeOrganizationPlanCommandTests.cs
+++ b/test/Core.Test/OrganizationFeatures/OrganizationSubscriptionUpdate/UpgradeOrganizationPlanCommandTests.cs
@@ -104,6 +104,7 @@ public class UpgradeOrganizationPlanCommandTests
[BitAutoData(PlanType.EnterpriseAnnually)]
[BitAutoData(PlanType.TeamsMonthly)]
[BitAutoData(PlanType.TeamsAnnually)]
+ [BitAutoData(PlanType.TeamsStarter)]
public async Task UpgradePlan_SM_Passes(PlanType planType, Organization organization, OrganizationUpgrade upgrade,
SutProvider sutProvider)
{
@@ -135,6 +136,7 @@ public class UpgradeOrganizationPlanCommandTests
[BitAutoData(PlanType.EnterpriseAnnually)]
[BitAutoData(PlanType.TeamsMonthly)]
[BitAutoData(PlanType.TeamsAnnually)]
+ [BitAutoData(PlanType.TeamsStarter)]
public async Task UpgradePlan_SM_NotEnoughSmSeats_Throws(PlanType planType, Organization organization, OrganizationUpgrade upgrade,
SutProvider sutProvider)
{
@@ -160,6 +162,7 @@ public class UpgradeOrganizationPlanCommandTests
[BitAutoData(PlanType.EnterpriseAnnually, 201)]
[BitAutoData(PlanType.TeamsMonthly, 51)]
[BitAutoData(PlanType.TeamsAnnually, 51)]
+ [BitAutoData(PlanType.TeamsStarter, 51)]
public async Task UpgradePlan_SM_NotEnoughServiceAccounts_Throws(PlanType planType, int currentServiceAccounts,
Organization organization, OrganizationUpgrade upgrade, SutProvider sutProvider)
{
diff --git a/test/Core.Test/Services/OrganizationServiceTests.cs b/test/Core.Test/Services/OrganizationServiceTests.cs
index b0421309b..210e59681 100644
--- a/test/Core.Test/Services/OrganizationServiceTests.cs
+++ b/test/Core.Test/Services/OrganizationServiceTests.cs
@@ -1355,10 +1355,14 @@ public class OrganizationServiceTests
[BitAutoData(PlanType.Custom, OrganizationUserType.Owner)]
[BitAutoData(PlanType.EnterpriseAnnually, OrganizationUserType.Admin)]
[BitAutoData(PlanType.EnterpriseAnnually, OrganizationUserType.Owner)]
+ [BitAutoData(PlanType.EnterpriseAnnually2020, OrganizationUserType.Admin)]
+ [BitAutoData(PlanType.EnterpriseAnnually2020, OrganizationUserType.Owner)]
[BitAutoData(PlanType.EnterpriseAnnually2019, OrganizationUserType.Admin)]
[BitAutoData(PlanType.EnterpriseAnnually2019, OrganizationUserType.Owner)]
[BitAutoData(PlanType.EnterpriseMonthly, OrganizationUserType.Admin)]
[BitAutoData(PlanType.EnterpriseMonthly, OrganizationUserType.Owner)]
+ [BitAutoData(PlanType.EnterpriseMonthly2020, OrganizationUserType.Admin)]
+ [BitAutoData(PlanType.EnterpriseMonthly2020, OrganizationUserType.Owner)]
[BitAutoData(PlanType.EnterpriseMonthly2019, OrganizationUserType.Admin)]
[BitAutoData(PlanType.EnterpriseMonthly2019, OrganizationUserType.Owner)]
[BitAutoData(PlanType.FamiliesAnnually, OrganizationUserType.Admin)]
@@ -1367,10 +1371,14 @@ public class OrganizationServiceTests
[BitAutoData(PlanType.FamiliesAnnually2019, OrganizationUserType.Owner)]
[BitAutoData(PlanType.TeamsAnnually, OrganizationUserType.Admin)]
[BitAutoData(PlanType.TeamsAnnually, OrganizationUserType.Owner)]
+ [BitAutoData(PlanType.TeamsAnnually2020, OrganizationUserType.Admin)]
+ [BitAutoData(PlanType.TeamsAnnually2020, OrganizationUserType.Owner)]
[BitAutoData(PlanType.TeamsAnnually2019, OrganizationUserType.Admin)]
[BitAutoData(PlanType.TeamsAnnually2019, OrganizationUserType.Owner)]
[BitAutoData(PlanType.TeamsMonthly, OrganizationUserType.Admin)]
[BitAutoData(PlanType.TeamsMonthly, OrganizationUserType.Owner)]
+ [BitAutoData(PlanType.TeamsMonthly2020, OrganizationUserType.Admin)]
+ [BitAutoData(PlanType.TeamsMonthly2020, OrganizationUserType.Owner)]
[BitAutoData(PlanType.TeamsMonthly2019, OrganizationUserType.Admin)]
[BitAutoData(PlanType.TeamsMonthly2019, OrganizationUserType.Owner)]
public async Task ConfirmUserToNonFree_AlreadyFreeAdminOrOwner_DoesNotThrow(PlanType planType, OrganizationUserType orgUserType, Organization org, OrganizationUser confirmingUser,
@@ -1791,6 +1799,7 @@ public class OrganizationServiceTests
[Theory]
[BitAutoData(PlanType.TeamsAnnually)]
[BitAutoData(PlanType.TeamsMonthly)]
+ [BitAutoData(PlanType.TeamsStarter)]
[BitAutoData(PlanType.EnterpriseAnnually)]
[BitAutoData(PlanType.EnterpriseMonthly)]
public void ValidateSecretsManagerPlan_ThrowsException_WhenNoSecretsManagerSeats(PlanType planType, SutProvider sutProvider)
@@ -1863,6 +1872,7 @@ public class OrganizationServiceTests
[Theory]
[BitAutoData(PlanType.TeamsAnnually)]
[BitAutoData(PlanType.TeamsMonthly)]
+ [BitAutoData(PlanType.TeamsStarter)]
[BitAutoData(PlanType.EnterpriseAnnually)]
[BitAutoData(PlanType.EnterpriseMonthly)]
public void ValidateSecretsManagerPlan_ThrowsException_WhenSubtractingServiceAccounts(
@@ -1902,6 +1912,7 @@ public class OrganizationServiceTests
[Theory]
[BitAutoData(PlanType.TeamsAnnually)]
[BitAutoData(PlanType.TeamsMonthly)]
+ [BitAutoData(PlanType.TeamsStarter)]
[BitAutoData(PlanType.EnterpriseAnnually)]
[BitAutoData(PlanType.EnterpriseMonthly)]
public void ValidateSecretsManagerPlan_ValidPlan_NoExceptionThrown(
diff --git a/test/Core.Test/Utilities/StaticStoreTests.cs b/test/Core.Test/Utilities/StaticStoreTests.cs
index 9abd31c8f..4b16ec96f 100644
--- a/test/Core.Test/Utilities/StaticStoreTests.cs
+++ b/test/Core.Test/Utilities/StaticStoreTests.cs
@@ -13,7 +13,7 @@ public class StaticStoreTests
var plans = StaticStore.Plans.ToList();
Assert.NotNull(plans);
Assert.NotEmpty(plans);
- Assert.Equal(16, plans.Count);
+ Assert.Equal(17, plans.Count);
}
[Theory]
@@ -21,6 +21,7 @@ public class StaticStoreTests
[InlineData(PlanType.EnterpriseMonthly)]
[InlineData(PlanType.TeamsMonthly)]
[InlineData(PlanType.TeamsAnnually)]
+ [InlineData(PlanType.TeamsStarter)]
public void StaticStore_GetPlan_Success(PlanType planType)
{
var plan = StaticStore.GetPlan(planType);