diff --git a/app/Jobs/StripeProcessJob.php b/app/Jobs/StripeProcessJob.php index c3827d9fb..6ddbfe145 100644 --- a/app/Jobs/StripeProcessJob.php +++ b/app/Jobs/StripeProcessJob.php @@ -260,7 +260,10 @@ public function handle(): void $comment = data_get($data, 'cancellation_details.comment'); $lookup_key = data_get($data, 'items.data.0.price.lookup_key'); if (str($lookup_key)->contains('dynamic')) { - $quantity = min((int) data_get($data, 'items.data.0.quantity', 2), UpdateSubscriptionQuantity::MAX_SERVER_LIMIT); + $quantity = max( + UpdateSubscriptionQuantity::MIN_SERVER_LIMIT, + min((int) data_get($data, 'items.data.0.quantity', 2), UpdateSubscriptionQuantity::MAX_SERVER_LIMIT) + ); $team = data_get($subscription, 'team'); if ($team) { $team->update([ diff --git a/tests/Feature/Subscription/StripeProcessJobTest.php b/tests/Feature/Subscription/StripeProcessJobTest.php index a95e08338..302edf9e2 100644 --- a/tests/Feature/Subscription/StripeProcessJobTest.php +++ b/tests/Feature/Subscription/StripeProcessJobTest.php @@ -143,7 +143,51 @@ }); }); -describe('customer.subscription.updated clamps quantity to MAX_SERVER_LIMIT', function () { +describe('customer.subscription.updated clamps quantity to subscription bounds', function () { + test('quantity below MIN is clamped to 2', function () { + Queue::fake(); + + Subscription::create([ + 'team_id' => $this->team->id, + 'stripe_subscription_id' => 'sub_existing', + 'stripe_customer_id' => 'cus_min_clamp_test', + 'stripe_invoice_paid' => true, + ]); + + $event = [ + 'type' => 'customer.subscription.updated', + 'data' => [ + 'object' => [ + 'customer' => 'cus_min_clamp_test', + 'id' => 'sub_existing', + 'status' => 'active', + 'metadata' => [ + 'team_id' => $this->team->id, + 'user_id' => $this->user->id, + ], + 'items' => [ + 'data' => [[ + 'subscription' => 'sub_existing', + 'plan' => ['id' => 'price_dynamic_monthly'], + 'price' => ['lookup_key' => 'dynamic_monthly'], + 'quantity' => 1, + ]], + ], + 'cancel_at_period_end' => false, + 'cancellation_details' => ['feedback' => null, 'comment' => null], + ], + ], + ]; + + $job = new StripeProcessJob($event); + $job->handle(); + + $this->team->refresh(); + expect($this->team->custom_server_limit)->toBe(2); + + Queue::assertPushed(ServerLimitCheckJob::class); + }); + test('quantity exceeding MAX is clamped to 100', function () { Queue::fake();