set('academy_billing.subscription_name', 'academy'); config()->set('academy_billing.plans', [ 'creator_monthly' => [ 'label' => 'Creator Monthly', 'tier' => 'creator', 'interval' => 'monthly', 'stripe_price_id' => 'price_creator_month', 'featured' => false, ], 'pro_monthly' => [ 'label' => 'Pro Monthly', 'tier' => 'pro', 'interval' => 'monthly', 'stripe_price_id' => 'price_pro_month', 'featured' => true, ], ]); } public function test_current_tier_uses_cashier_subscription_items(): void { $user = User::factory()->create(); $this->attachSubscription($user, 'sub_creator_unit', 'price_creator_month'); $service = app(AcademyAccessService::class); $this->assertSame('creator', $service->currentTier($user)); $this->assertTrue($service->canAccessContent($user, 'creator')); $this->assertFalse($service->canAccessContent($user, 'pro')); } public function test_pro_subscription_unlocks_creator_and_pro_content(): void { $user = User::factory()->create(); $this->attachSubscription($user, 'sub_pro_unit', 'price_pro_month'); $service = app(AcademyAccessService::class); $this->assertSame('pro', $service->currentTier($user)); $this->assertTrue($service->canAccessContent($user, 'creator')); $this->assertTrue($service->canAccessContent($user, 'pro')); } public function test_grace_period_keeps_access_and_ended_subscription_loses_it(): void { $graceUser = User::factory()->create(); $endedUser = User::factory()->create(); $this->attachSubscription($graceUser, 'sub_grace_unit', 'price_creator_month', now()->addHour()); $this->attachSubscription($endedUser, 'sub_ended_unit', 'price_creator_month', now()->subHour()); $service = app(AcademyAccessService::class); $this->assertTrue($service->canAccessContent($graceUser, 'creator')); $this->assertFalse($service->canAccessContent($endedUser, 'creator')); } public function test_staff_and_moderators_bypass_billing_checks(): void { $admin = User::factory()->create(['role' => 'admin']); $moderator = User::factory()->create(['role' => 'moderator']); $service = app(AcademyAccessService::class); $this->assertSame('admin', $service->currentTier($admin)); $this->assertSame('admin', $service->currentTier($moderator)); $this->assertTrue($service->canAccessContent($admin, 'pro')); $this->assertTrue($service->canAccessContent($moderator, 'pro')); } private function attachSubscription(User $user, string $subscriptionId, string $priceId, ?\Illuminate\Support\Carbon $endsAt = null): Subscription { $subscription = $user->subscriptions()->create([ 'type' => 'academy', 'stripe_id' => $subscriptionId, 'stripe_status' => 'active', 'stripe_price' => $priceId, 'quantity' => 1, 'ends_at' => $endsAt, ]); $subscription->items()->create([ 'stripe_id' => 'si_'.$subscriptionId, 'stripe_product' => 'prod_'.($priceId === 'price_pro_month' ? 'pro' : 'creator'), 'stripe_price' => $priceId, 'quantity' => 1, ]); return $subscription; } }