seed(RolesAndPermissionsSeeder::class); }); test('a user without any booking and the gate off counts as unlimited and active', function () { config()->set('billing.enforce_booking', false); $user = User::factory()->create(); $status = CustomerStatusSummary::fromUser($user); expect($status->tier)->toBe(Tier::Einzel); expect($status->hasActiveBooking)->toBeTrue(); expect($status->unlimitedQuota)->toBeTrue(); expect($status->quotaRemaining)->toBeNull(); expect($status->bookingLabel())->toBe(__('Kein Abo')); expect($status->badgeLabel())->toContain('∞'); }); test('a user without booking and the gate enforced has no active booking and zero quota', function () { config()->set('billing.enforce_booking', true); $user = User::factory()->create(); $status = CustomerStatusSummary::fromUser($user); expect($status->hasActiveBooking)->toBeFalse(); expect($status->unlimitedQuota)->toBeFalse(); expect($status->quotaRemaining)->toBe(0); expect($status->quotaTotal)->toBe(0); }); test('a grandfathered bestandskunde is labelled and counts as active', function () { config()->set('billing.enforce_booking', true); $user = User::factory()->create(); UserPaymentOption::factory()->create([ 'user_id' => $user->id, 'status' => UserPaymentOptionStatus::Grandfathered->value, 'grandfathered_until' => now()->addYear(), 'stripe_subscription_id' => null, ]); $status = CustomerStatusSummary::fromUser($user->fresh()); expect($status->hasActiveBooking)->toBeTrue(); expect($status->hasGrandfathered)->toBeTrue(); expect($status->bookingLabel())->toBe(__('Bestandstarif')); }); test('credit balance is surfaced and shown in the badge', function () { config()->set('billing.enforce_booking', true); $user = User::factory()->create(); app(CreditWalletService::class)->credit($user, 27, CreditTransactionType::Topup, 'Paket 25'); $status = CustomerStatusSummary::fromUser($user->fresh()); expect($status->creditBalance)->toBe(27); expect($status->hasCredits())->toBeTrue(); expect($status->badgeLabel())->toContain('27'); }); test('a user without credits hides the credit segment in the badge', function () { config()->set('billing.enforce_booking', false); $user = User::factory()->create(); $status = CustomerStatusSummary::fromUser($user); expect($status->hasCredits())->toBeFalse(); expect($status->badgeLabel())->not->toContain('Cr'); }); test('the status menu renders inside the customer layout header', function () { /** @var TestCase $this */ config()->set('billing.enforce_booking', true); $user = User::factory()->create(['is_active' => true]); $user->assignRole('customer'); $this->actingAs($user); $this->get(route('me.dashboard')) ->assertOk() ->assertSee(__('Aktuelle Buchung')) ->assertSee(__('PMs frei')) ->assertSee(route('me.bookings.index'), false); });