From deb2996250611354b4356d1e45a243525f8b10c2 Mon Sep 17 00:00:00 2001 From: Lucas Vinicius Date: Mon, 21 Jul 2025 21:01:56 -0300 Subject: [PATCH 1/4] test: Cover subscription with preset expiration for plan with no periodicity --- tests/Models/Concerns/HasSubscriptionsTest.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/Models/Concerns/HasSubscriptionsTest.php b/tests/Models/Concerns/HasSubscriptionsTest.php index ad72a18..dee62d9 100644 --- a/tests/Models/Concerns/HasSubscriptionsTest.php +++ b/tests/Models/Concerns/HasSubscriptionsTest.php @@ -1077,6 +1077,21 @@ public function testItSetsAnEmptyExpirationIfThePlanHasNoPeriodicity() $this->assertNull($subscription->expired_at); } + public function testItUsesReceivedExpirationEvenIfThePlanHasNoPeriodicity() + { + $plan = Plan::factory()->createOne([ + 'periodicity' => null, + ]); + + $subscriber = User::factory()->createOne(); + $subscription = $subscriber->subscribeTo($plan, now()->addDay()); + + $this->assertDatabaseHas('subscriptions', [ + 'id' => $subscription->id, + 'expired_at' => now()->addDay(), + ]); + } + public function testItReturnsZeroForCurrentConsumptionWhenSubscriberDoesNotHaveFeature() { $feature = Feature::factory()->createOne(); From 47f860066b78fa7f6e88a6d1636f6b61c5fc954f Mon Sep 17 00:00:00 2001 From: Lucas Vinicius Date: Mon, 21 Jul 2025 21:02:10 -0300 Subject: [PATCH 2/4] feat: Handle preset expiration for plans with no periodicity --- src/Models/Concerns/HasSubscriptions.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Models/Concerns/HasSubscriptions.php b/src/Models/Concerns/HasSubscriptions.php index cd7e68a..6f106a5 100644 --- a/src/Models/Concerns/HasSubscriptions.php +++ b/src/Models/Concerns/HasSubscriptions.php @@ -121,14 +121,13 @@ public function subscribeTo(Plan $plan, $expiration = null, $startDate = null): { if ($plan->periodicity) { $expiration = $expiration ?? $plan->calculateNextRecurrenceEnd($startDate); + } else { + $expiration = $expiration ?? null; + } - $graceDaysEnd = $plan->hasGraceDays + $graceDaysEnd = $plan->hasGraceDays && $expiration ? $plan->calculateGraceDaysEnd($expiration) : null; - } else { - $expiration = null; - $graceDaysEnd = null; - } return $this->subscription() ->make([ From 228a98c57c9cf4969422aacddfd55159b526f2df Mon Sep 17 00:00:00 2001 From: Lucas Vinicius Date: Mon, 21 Jul 2025 21:02:24 -0300 Subject: [PATCH 3/4] test: Cover renewing for subscriptions with no expiration --- tests/Models/SubscriptionTest.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/Models/SubscriptionTest.php b/tests/Models/SubscriptionTest.php index 730d586..7a437a7 100644 --- a/tests/Models/SubscriptionTest.php +++ b/tests/Models/SubscriptionTest.php @@ -201,6 +201,24 @@ public function testModelRegistersOverdue() ]); } + public function testModelDoesNotRegisterOverdueIfThereIsNoExpiration() + { + $subscriber = User::factory()->create(); + $subscription = Subscription::factory() + ->for($subscriber, 'subscriber') + ->create([ + 'expired_at' => null, + ]); + + $subscription->renew(); + + $this->assertDatabaseCount('subscription_renewals', 1); + $this->assertDatabaseHas('subscription_renewals', [ + 'subscription_id' => $subscription->id, + 'overdue' => false, + ]); + } + public function testModelConsidersGraceDaysOnOverdue() { $subscriber = User::factory()->create(); From 49bf3d5314b469a40da092c99c84327761c7210e Mon Sep 17 00:00:00 2001 From: Lucas Vinicius Date: Mon, 21 Jul 2025 21:02:39 -0300 Subject: [PATCH 4/4] feat: Handle overdue for subscriptions with no expiration --- src/Models/Subscription.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Models/Subscription.php b/src/Models/Subscription.php index 3d88ba5..c4ec818 100644 --- a/src/Models/Subscription.php +++ b/src/Models/Subscription.php @@ -157,6 +157,10 @@ public function getIsOverdueAttribute(): bool and $this->grace_days_ended_at->isPast(); } + if (! $this->expired_at) { + return false; + } + return $this->expired_at->isPast(); }