1- using Bit . Core . Billing . Enums ;
1+ using Bit . Core . AdminConsole . Entities ;
2+ using Bit . Core . Billing . Enums ;
23using Bit . Core . Billing . Premium . Commands ;
34using Bit . Core . Billing . Pricing ;
45using Bit . Core . Billing . Services ;
56using Bit . Core . Entities ;
7+ using Bit . Core . Repositories ;
68using Bit . Core . Services ;
79using Bit . Test . Common . AutoFixture . Attributes ;
810using Microsoft . Extensions . Logging ;
@@ -88,8 +90,11 @@ private static Core.Models.StaticStore.Plan CreateTestPlan(
8890
8991 private readonly IPricingClient _pricingClient = Substitute . For < IPricingClient > ( ) ;
9092 private readonly IStripeAdapter _stripeAdapter = Substitute . For < IStripeAdapter > ( ) ;
91- private readonly ISubscriberService _subscriberService = Substitute . For < ISubscriberService > ( ) ;
9293 private readonly IUserService _userService = Substitute . For < IUserService > ( ) ;
94+ private readonly IOrganizationRepository _organizationRepository = Substitute . For < IOrganizationRepository > ( ) ;
95+ private readonly IOrganizationUserRepository _organizationUserRepository = Substitute . For < IOrganizationUserRepository > ( ) ;
96+ private readonly IOrganizationApiKeyRepository _organizationApiKeyRepository = Substitute . For < IOrganizationApiKeyRepository > ( ) ;
97+ private readonly IApplicationCacheService _applicationCacheService = Substitute . For < IApplicationCacheService > ( ) ;
9398 private readonly ILogger < UpgradePremiumToOrganizationCommand > _logger = Substitute . For < ILogger < UpgradePremiumToOrganizationCommand > > ( ) ;
9499 private readonly UpgradePremiumToOrganizationCommand _command ;
95100
@@ -99,8 +104,11 @@ public UpgradePremiumToOrganizationCommandTests()
99104 _logger ,
100105 _pricingClient ,
101106 _stripeAdapter ,
102- _subscriberService ,
103- _userService ) ;
107+ _userService ,
108+ _organizationRepository ,
109+ _organizationUserRepository ,
110+ _organizationApiKeyRepository ,
111+ _applicationCacheService ) ;
104112 }
105113
106114 [ Theory , BitAutoData ]
@@ -131,7 +139,7 @@ public async Task Run_UserNoGatewaySubscriptionId_ReturnsBadRequest(User user)
131139 // Assert
132140 Assert . True ( result . IsT1 ) ;
133141 var badRequest = result . AsT1 ;
134- Assert . Equal ( "User does not have a Stripe subscription." , badRequest . Response ) ;
142+ Assert . Equal ( "User does not have an active Premium subscription." , badRequest . Response ) ;
135143 }
136144
137145 [ Theory , BitAutoData ]
@@ -147,7 +155,7 @@ public async Task Run_UserEmptyGatewaySubscriptionId_ReturnsBadRequest(User user
147155 // Assert
148156 Assert . True ( result . IsT1 ) ;
149157 var badRequest = result . AsT1 ;
150- Assert . Equal ( "User does not have a Stripe subscription." , badRequest . Response ) ;
158+ Assert . Equal ( "User does not have an active Premium subscription." , badRequest . Response ) ;
151159 }
152160
153161 [ Theory , BitAutoData ]
@@ -212,7 +220,7 @@ public async Task Run_PlanDoesNotSupportPremiumAccess_ReturnsBadRequest(User use
212220 stripePremiumAccessPlanId : null // No premium access support
213221 ) ;
214222
215- _subscriberService . GetSubscriptionOrThrow ( user , Arg . Any < SubscriptionGetOptions > ( ) )
223+ _stripeAdapter . GetSubscriptionAsync ( "sub_123" )
216224 . Returns ( mockSubscription ) ;
217225 _pricingClient . GetPlanOrThrow ( PlanType . TeamsAnnually ) . Returns ( mockPlan ) ;
218226
@@ -254,7 +262,7 @@ public async Task Run_PlanDoesNotSupportStorage_ReturnsBadRequest(User user)
254262 stripeStoragePlanId : null // No storage support
255263 ) ;
256264
257- _subscriberService . GetSubscriptionOrThrow ( user , Arg . Any < SubscriptionGetOptions > ( ) )
265+ _stripeAdapter . GetSubscriptionAsync ( "sub_123" )
258266 . Returns ( mockSubscription ) ;
259267 _pricingClient . GetPlanOrThrow ( PlanType . TeamsAnnually ) . Returns ( mockPlan ) ;
260268
@@ -273,6 +281,7 @@ public async Task Run_SuccessfulUpgrade_SeatBasedPlan_ReturnsSuccess(User user)
273281 // Arrange
274282 user . Premium = true ;
275283 user . GatewaySubscriptionId = "sub_123" ;
284+ user . GatewayCustomerId = "cus_123" ;
276285 user . Id = Guid . NewGuid ( ) ;
277286
278287 var currentPeriodEnd = DateTime . UtcNow . AddMonths ( 1 ) ;
@@ -301,11 +310,15 @@ public async Task Run_SuccessfulUpgrade_SeatBasedPlan_ReturnsSuccess(User user)
301310 stripeStoragePlanId : "storage-plan-teams"
302311 ) ;
303312
304- _subscriberService . GetSubscriptionOrThrow ( user , Arg . Any < SubscriptionGetOptions > ( ) )
313+ _stripeAdapter . GetSubscriptionAsync ( "sub_123" )
305314 . Returns ( mockSubscription ) ;
306315 _pricingClient . GetPlanOrThrow ( PlanType . TeamsAnnually ) . Returns ( mockPlan ) ;
307316 _stripeAdapter . UpdateSubscriptionAsync ( Arg . Any < string > ( ) , Arg . Any < SubscriptionUpdateOptions > ( ) )
308317 . Returns ( Task . FromResult ( mockSubscription ) ) ;
318+ _organizationRepository . CreateAsync ( Arg . Any < Organization > ( ) ) . Returns ( callInfo => Task . FromResult ( callInfo . Arg < Organization > ( ) ) ) ;
319+ _organizationApiKeyRepository . CreateAsync ( Arg . Any < OrganizationApiKey > ( ) ) . Returns ( callInfo => Task . FromResult ( callInfo . Arg < OrganizationApiKey > ( ) ) ) ;
320+ _organizationUserRepository . CreateAsync ( Arg . Any < OrganizationUser > ( ) ) . Returns ( callInfo => Task . FromResult ( callInfo . Arg < OrganizationUser > ( ) ) ) ;
321+ _applicationCacheService . UpsertOrganizationAbilityAsync ( Arg . Any < Organization > ( ) ) . Returns ( Task . CompletedTask ) ;
309322 _userService . SaveUserAsync ( user ) . Returns ( Task . CompletedTask ) ;
310323
311324 // Act
@@ -323,8 +336,16 @@ await _stripeAdapter.Received(1).UpdateSubscriptionAsync(
323336 opts . Items . Any ( i => i . Price == "teams-premium-access-annually" && i . Quantity == 1 ) &&
324337 opts . Items . Any ( i => i . Price == "storage-plan-teams" && i . Quantity == 10 ) ) ) ;
325338
326- await _userService . Received ( 1 ) . SaveUserAsync ( user ) ;
327- Assert . Equal ( currentPeriodEnd , user . PremiumExpirationDate ) ;
339+ await _organizationRepository . Received ( 1 ) . CreateAsync ( Arg . Is < Organization > ( o =>
340+ o . GatewaySubscriptionId == "sub_123" &&
341+ o . GatewayCustomerId == "cus_123" ) ) ;
342+ await _organizationUserRepository . Received ( 1 ) . CreateAsync ( Arg . Any < OrganizationUser > ( ) ) ;
343+ await _organizationApiKeyRepository . Received ( 1 ) . CreateAsync ( Arg . Any < OrganizationApiKey > ( ) ) ;
344+
345+ await _userService . Received ( 1 ) . SaveUserAsync ( Arg . Is < User > ( u =>
346+ u . Premium == false &&
347+ u . GatewaySubscriptionId == null &&
348+ u . GatewayCustomerId == null ) ) ;
328349 }
329350
330351 [ Theory , BitAutoData ]
@@ -333,6 +354,7 @@ public async Task Run_SuccessfulUpgrade_NonSeatBasedPlan_ReturnsSuccess(User use
333354 // Arrange
334355 user . Premium = true ;
335356 user . GatewaySubscriptionId = "sub_123" ;
357+ user . GatewayCustomerId = "cus_123" ;
336358
337359 var currentPeriodEnd = DateTime . UtcNow . AddMonths ( 1 ) ;
338360 var mockSubscription = new Subscription
@@ -359,11 +381,15 @@ public async Task Run_SuccessfulUpgrade_NonSeatBasedPlan_ReturnsSuccess(User use
359381 stripeSeatPlanId : null // Non-seat-based
360382 ) ;
361383
362- _subscriberService . GetSubscriptionOrThrow ( user , Arg . Any < SubscriptionGetOptions > ( ) )
384+ _stripeAdapter . GetSubscriptionAsync ( "sub_123" )
363385 . Returns ( mockSubscription ) ;
364386 _pricingClient . GetPlanOrThrow ( PlanType . FamiliesAnnually ) . Returns ( mockPlan ) ;
365387 _stripeAdapter . UpdateSubscriptionAsync ( Arg . Any < string > ( ) , Arg . Any < SubscriptionUpdateOptions > ( ) )
366388 . Returns ( Task . FromResult ( mockSubscription ) ) ;
389+ _organizationRepository . CreateAsync ( Arg . Any < Organization > ( ) ) . Returns ( callInfo => Task . FromResult ( callInfo . Arg < Organization > ( ) ) ) ;
390+ _organizationApiKeyRepository . CreateAsync ( Arg . Any < OrganizationApiKey > ( ) ) . Returns ( callInfo => Task . FromResult ( callInfo . Arg < OrganizationApiKey > ( ) ) ) ;
391+ _organizationUserRepository . CreateAsync ( Arg . Any < OrganizationUser > ( ) ) . Returns ( callInfo => Task . FromResult ( callInfo . Arg < OrganizationUser > ( ) ) ) ;
392+ _applicationCacheService . UpsertOrganizationAbilityAsync ( Arg . Any < Organization > ( ) ) . Returns ( Task . CompletedTask ) ;
367393 _userService . SaveUserAsync ( user ) . Returns ( Task . CompletedTask ) ;
368394
369395 // Act
@@ -379,7 +405,10 @@ await _stripeAdapter.Received(1).UpdateSubscriptionAsync(
379405 opts . Items . Any ( i => i . Deleted == true ) &&
380406 opts . Items . Any ( i => i . Price == "families-plan-annually" && i . Quantity == 1 ) ) ) ;
381407
382- await _userService . Received ( 1 ) . SaveUserAsync ( user ) ;
408+ await _organizationRepository . Received ( 1 ) . CreateAsync ( Arg . Any < Organization > ( ) ) ;
409+ await _userService . Received ( 1 ) . SaveUserAsync ( Arg . Is < User > ( u =>
410+ u . Premium == false &&
411+ u . GatewaySubscriptionId == null ) ) ;
383412 }
384413
385414 [ Theory , BitAutoData ]
@@ -412,7 +441,7 @@ public async Task Run_WithTrialEndDate_SetsTrialEndOnSubscription(User user)
412441 stripeSeatPlanId : "teams-seat-annually"
413442 ) ;
414443
415- _subscriberService . GetSubscriptionOrThrow ( user , Arg . Any < SubscriptionGetOptions > ( ) )
444+ _stripeAdapter . GetSubscriptionAsync ( "sub_123" )
416445 . Returns ( mockSubscription ) ;
417446 _pricingClient . GetPlanOrThrow ( PlanType . TeamsAnnually ) . Returns ( mockPlan ) ;
418447 _stripeAdapter . UpdateSubscriptionAsync ( Arg . Any < string > ( ) , Arg . Any < SubscriptionUpdateOptions > ( ) )
@@ -429,8 +458,6 @@ await _stripeAdapter.Received(1).UpdateSubscriptionAsync(
429458 "sub_123" ,
430459 Arg . Is < SubscriptionUpdateOptions > ( opts =>
431460 opts . TrialEnd == trialEndDate ) ) ;
432-
433- Assert . Equal ( trialEndDate , user . PremiumExpirationDate ) ;
434461 }
435462
436463 [ Theory , BitAutoData ]
@@ -466,7 +493,7 @@ public async Task Run_AddsMetadataWithOriginalPremiumPriceId(User user)
466493 stripeSeatPlanId : "teams-seat-annually"
467494 ) ;
468495
469- _subscriberService . GetSubscriptionOrThrow ( user , Arg . Any < SubscriptionGetOptions > ( ) )
496+ _stripeAdapter . GetSubscriptionAsync ( "sub_123" )
470497 . Returns ( mockSubscription ) ;
471498 _pricingClient . GetPlanOrThrow ( PlanType . TeamsAnnually ) . Returns ( mockPlan ) ;
472499 _stripeAdapter . UpdateSubscriptionAsync ( Arg . Any < string > ( ) , Arg . Any < SubscriptionUpdateOptions > ( ) )
0 commit comments