1
0
mirror of https://github.com/bitwarden/server synced 2025-12-06 00:03:34 +00:00

[PM-27849] Check for sm-standalone on subscription (#6545)

* Fix coupon check

* Fixed in FF off scenario

* Run dotnet format
This commit is contained in:
Alex Morask
2025-11-11 16:01:48 -06:00
committed by GitHub
parent ea233580d2
commit 691047039b
4 changed files with 107 additions and 113 deletions

View File

@@ -22,11 +22,6 @@ public class GetOrganizationMetadataQuery(
{
public async Task<OrganizationMetadata?> Run(Organization organization)
{
if (organization == null)
{
return null;
}
if (globalSettings.SelfHosted)
{
return OrganizationMetadata.Default;
@@ -42,10 +37,12 @@ public class GetOrganizationMetadataQuery(
};
}
var customer = await subscriberService.GetCustomer(organization,
new CustomerGetOptions { Expand = ["discount.coupon.applies_to"] });
var customer = await subscriberService.GetCustomer(organization);
var subscription = await subscriberService.GetSubscription(organization);
var subscription = await subscriberService.GetSubscription(organization, new SubscriptionGetOptions
{
Expand = ["discounts.coupon.applies_to"]
});
if (customer == null || subscription == null)
{
@@ -79,16 +76,17 @@ public class GetOrganizationMetadataQuery(
return false;
}
var hasCoupon = customer.Discount?.Coupon?.Id == StripeConstants.CouponIDs.SecretsManagerStandalone;
var coupon = subscription.Discounts?.FirstOrDefault(discount =>
discount.Coupon?.Id == StripeConstants.CouponIDs.SecretsManagerStandalone)?.Coupon;
if (!hasCoupon)
if (coupon == null)
{
return false;
}
var subscriptionProductIds = subscription.Items.Data.Select(item => item.Plan.ProductId);
var couponAppliesTo = customer.Discount?.Coupon?.AppliesTo?.Products;
var couponAppliesTo = coupon.AppliesTo?.Products;
return subscriptionProductIds.Intersect(couponAppliesTo ?? []).Any();
}

View File

@@ -79,10 +79,12 @@ public class OrganizationBillingService(
};
}
var customer = await subscriberService.GetCustomer(organization,
new CustomerGetOptions { Expand = ["discount.coupon.applies_to"] });
var customer = await subscriberService.GetCustomer(organization);
var subscription = await subscriberService.GetSubscription(organization);
var subscription = await subscriberService.GetSubscription(organization, new SubscriptionGetOptions
{
Expand = ["discounts.coupon.applies_to"]
});
if (customer == null || subscription == null)
{
@@ -542,16 +544,17 @@ public class OrganizationBillingService(
return false;
}
var hasCoupon = customer.Discount?.Coupon?.Id == StripeConstants.CouponIDs.SecretsManagerStandalone;
var coupon = subscription.Discounts?.FirstOrDefault(discount =>
discount.Coupon?.Id == StripeConstants.CouponIDs.SecretsManagerStandalone)?.Coupon;
if (!hasCoupon)
if (coupon == null)
{
return false;
}
var subscriptionProductIds = subscription.Items.Data.Select(item => item.Plan.ProductId);
var couponAppliesTo = customer.Discount?.Coupon?.AppliesTo?.Products;
var couponAppliesTo = coupon.AppliesTo?.Products;
return subscriptionProductIds.Intersect(couponAppliesTo ?? []).Any();
}

View File

@@ -21,15 +21,6 @@ namespace Bit.Core.Test.Billing.Organizations.Queries;
[SutProviderCustomize]
public class GetOrganizationMetadataQueryTests
{
[Theory, BitAutoData]
public async Task Run_NullOrganization_ReturnsNull(
SutProvider<GetOrganizationMetadataQuery> sutProvider)
{
var result = await sutProvider.Sut.Run(null);
Assert.Null(result);
}
[Theory, BitAutoData]
public async Task Run_SelfHosted_ReturnsDefault(
Organization organization,
@@ -74,8 +65,7 @@ public class GetOrganizationMetadataQueryTests
.Returns(new OrganizationSeatCounts { Users = 5, Sponsored = 0 });
sutProvider.GetDependency<ISubscriberService>()
.GetCustomer(organization, Arg.Is<CustomerGetOptions>(options =>
options.Expand.Contains("discount.coupon.applies_to")))
.GetCustomer(organization)
.ReturnsNull();
var result = await sutProvider.Sut.Run(organization);
@@ -100,12 +90,12 @@ public class GetOrganizationMetadataQueryTests
.Returns(new OrganizationSeatCounts { Users = 7, Sponsored = 0 });
sutProvider.GetDependency<ISubscriberService>()
.GetCustomer(organization, Arg.Is<CustomerGetOptions>(options =>
options.Expand.Contains("discount.coupon.applies_to")))
.GetCustomer(organization)
.Returns(customer);
sutProvider.GetDependency<ISubscriberService>()
.GetSubscription(organization)
.GetSubscription(organization, Arg.Is<SubscriptionGetOptions>(options =>
options.Expand.Contains("discounts.coupon.applies_to")))
.ReturnsNull();
var result = await sutProvider.Sut.Run(organization);
@@ -124,23 +114,24 @@ public class GetOrganizationMetadataQueryTests
organization.PlanType = PlanType.EnterpriseAnnually;
var productId = "product_123";
var customer = new Customer
{
Discount = new Discount
{
Coupon = new Coupon
{
Id = StripeConstants.CouponIDs.SecretsManagerStandalone,
AppliesTo = new CouponAppliesTo
{
Products = [productId]
}
}
}
};
var customer = new Customer();
var subscription = new Subscription
{
Discounts =
[
new Discount
{
Coupon = new Coupon
{
Id = StripeConstants.CouponIDs.SecretsManagerStandalone,
AppliesTo = new CouponAppliesTo
{
Products = [productId]
}
}
}
],
Items = new StripeList<SubscriptionItem>
{
Data =
@@ -162,12 +153,12 @@ public class GetOrganizationMetadataQueryTests
.Returns(new OrganizationSeatCounts { Users = 15, Sponsored = 0 });
sutProvider.GetDependency<ISubscriberService>()
.GetCustomer(organization, Arg.Is<CustomerGetOptions>(options =>
options.Expand.Contains("discount.coupon.applies_to")))
.GetCustomer(organization)
.Returns(customer);
sutProvider.GetDependency<ISubscriberService>()
.GetSubscription(organization)
.GetSubscription(organization, Arg.Is<SubscriptionGetOptions>(options =>
options.Expand.Contains("discounts.coupon.applies_to")))
.Returns(subscription);
sutProvider.GetDependency<IPricingClient>()
@@ -189,13 +180,11 @@ public class GetOrganizationMetadataQueryTests
organization.GatewaySubscriptionId = "sub_123";
organization.PlanType = PlanType.TeamsAnnually;
var customer = new Customer
{
Discount = null
};
var customer = new Customer();
var subscription = new Subscription
{
Discounts = null,
Items = new StripeList<SubscriptionItem>
{
Data =
@@ -217,12 +206,12 @@ public class GetOrganizationMetadataQueryTests
.Returns(new OrganizationSeatCounts { Users = 20, Sponsored = 0 });
sutProvider.GetDependency<ISubscriberService>()
.GetCustomer(organization, Arg.Is<CustomerGetOptions>(options =>
options.Expand.Contains("discount.coupon.applies_to")))
.GetCustomer(organization)
.Returns(customer);
sutProvider.GetDependency<ISubscriberService>()
.GetSubscription(organization)
.GetSubscription(organization, Arg.Is<SubscriptionGetOptions>(options =>
options.Expand.Contains("discounts.coupon.applies_to")))
.Returns(subscription);
sutProvider.GetDependency<IPricingClient>()
@@ -244,23 +233,24 @@ public class GetOrganizationMetadataQueryTests
organization.GatewaySubscriptionId = "sub_123";
organization.PlanType = PlanType.EnterpriseAnnually;
var customer = new Customer
{
Discount = new Discount
{
Coupon = new Coupon
{
Id = StripeConstants.CouponIDs.SecretsManagerStandalone,
AppliesTo = new CouponAppliesTo
{
Products = ["different_product_id"]
}
}
}
};
var customer = new Customer();
var subscription = new Subscription
{
Discounts =
[
new Discount
{
Coupon = new Coupon
{
Id = StripeConstants.CouponIDs.SecretsManagerStandalone,
AppliesTo = new CouponAppliesTo
{
Products = ["different_product_id"]
}
}
}
],
Items = new StripeList<SubscriptionItem>
{
Data =
@@ -282,12 +272,12 @@ public class GetOrganizationMetadataQueryTests
.Returns(new OrganizationSeatCounts { Users = 12, Sponsored = 0 });
sutProvider.GetDependency<ISubscriberService>()
.GetCustomer(organization, Arg.Is<CustomerGetOptions>(options =>
options.Expand.Contains("discount.coupon.applies_to")))
.GetCustomer(organization)
.Returns(customer);
sutProvider.GetDependency<ISubscriberService>()
.GetSubscription(organization)
.GetSubscription(organization, Arg.Is<SubscriptionGetOptions>(options =>
options.Expand.Contains("discounts.coupon.applies_to")))
.Returns(subscription);
sutProvider.GetDependency<IPricingClient>()
@@ -310,23 +300,24 @@ public class GetOrganizationMetadataQueryTests
organization.PlanType = PlanType.FamiliesAnnually;
var productId = "product_123";
var customer = new Customer
{
Discount = new Discount
{
Coupon = new Coupon
{
Id = StripeConstants.CouponIDs.SecretsManagerStandalone,
AppliesTo = new CouponAppliesTo
{
Products = [productId]
}
}
}
};
var customer = new Customer();
var subscription = new Subscription
{
Discounts =
[
new Discount
{
Coupon = new Coupon
{
Id = StripeConstants.CouponIDs.SecretsManagerStandalone,
AppliesTo = new CouponAppliesTo
{
Products = [productId]
}
}
}
],
Items = new StripeList<SubscriptionItem>
{
Data =
@@ -348,12 +339,12 @@ public class GetOrganizationMetadataQueryTests
.Returns(new OrganizationSeatCounts { Users = 8, Sponsored = 0 });
sutProvider.GetDependency<ISubscriberService>()
.GetCustomer(organization, Arg.Is<CustomerGetOptions>(options =>
options.Expand.Contains("discount.coupon.applies_to")))
.GetCustomer(organization)
.Returns(customer);
sutProvider.GetDependency<ISubscriberService>()
.GetSubscription(organization)
.GetSubscription(organization, Arg.Is<SubscriptionGetOptions>(options =>
options.Expand.Contains("discounts.coupon.applies_to")))
.Returns(subscription);
sutProvider.GetDependency<IPricingClient>()

View File

@@ -38,31 +38,32 @@ public class OrganizationBillingServiceTests
var subscriberService = sutProvider.GetDependency<ISubscriberService>();
var organizationSeatCount = new OrganizationSeatCounts { Users = 1, Sponsored = 0 };
var customer = new Customer
{
Discount = new Discount
{
Coupon = new Coupon
{
Id = StripeConstants.CouponIDs.SecretsManagerStandalone,
AppliesTo = new CouponAppliesTo
{
Products = ["product_id"]
}
}
}
};
var customer = new Customer();
subscriberService
.GetCustomer(organization, Arg.Is<CustomerGetOptions>(options =>
options.Expand.Contains("discount.coupon.applies_to")))
.GetCustomer(organization)
.Returns(customer);
subscriberService.GetSubscription(organization).Returns(new Subscription
{
Items = new StripeList<SubscriptionItem>
subscriberService.GetSubscription(organization, Arg.Is<SubscriptionGetOptions>(options =>
options.Expand.Contains("discounts.coupon.applies_to"))).Returns(new Subscription
{
Data =
Discounts =
[
new Discount
{
Coupon = new Coupon
{
Id = StripeConstants.CouponIDs.SecretsManagerStandalone,
AppliesTo = new CouponAppliesTo
{
Products = ["product_id"]
}
}
}
],
Items = new StripeList<SubscriptionItem>
{
Data =
[
new SubscriptionItem
{
@@ -72,8 +73,8 @@ public class OrganizationBillingServiceTests
}
}
]
}
});
}
});
sutProvider.GetDependency<IOrganizationRepository>()
.GetOccupiedSeatCountByOrganizationIdAsync(organization.Id)
@@ -109,11 +110,12 @@ public class OrganizationBillingServiceTests
// Set up subscriber service to return null for customer
subscriberService
.GetCustomer(organization, Arg.Is<CustomerGetOptions>(options => options.Expand.FirstOrDefault() == "discount.coupon.applies_to"))
.GetCustomer(organization)
.Returns((Customer)null);
// Set up subscriber service to return null for subscription
subscriberService.GetSubscription(organization).Returns((Subscription)null);
subscriberService.GetSubscription(organization, Arg.Is<SubscriptionGetOptions>(options =>
options.Expand.Contains("discounts.coupon.applies_to"))).Returns((Subscription)null);
var metadata = await sutProvider.Sut.GetMetadata(organizationId);