seed(RolesAndPermissionsSeeder::class); }); function draftForGate(): array { $customer = User::factory()->create(['is_active' => true]); $customer->assignRole('customer'); $company = Company::factory()->presseecho()->create(); $customer->companies()->attach($company->id, ['role' => 'owner']); $pr = PressRelease::factory()->create([ 'user_id' => $customer->id, 'company_id' => $company->id, 'category_id' => Category::factory()->create()->id, 'portal' => $company->portal->value, 'status' => 'draft', ]); return compact('customer', 'pr'); } test('with the gate on a draft without a booking shows the notice and links to bookings', function () { /** @var TestCase $this */ config()->set('billing.enforce_booking', true); ['customer' => $customer, 'pr' => $pr] = draftForGate(); $this->actingAs($customer); Livewire::test('customer.press-releases.show', ['id' => $pr->id]) ->assertSee('Noch keine Buchung') ->assertSee('Buchung wählen') ->assertSee(route('me.bookings.index'), false) ->assertDontSee('Zur Prüfung freigeben'); }); test('with the gate on a paid single purchase unlocks the submission action', function () { /** @var TestCase $this */ config()->set('billing.enforce_booking', true); ['customer' => $customer, 'pr' => $pr] = draftForGate(); SinglePurchase::factory()->paid()->create(['user_id' => $customer->id]); $this->actingAs($customer); Livewire::test('customer.press-releases.show', ['id' => $pr->id]) ->assertDontSee('Noch keine Buchung') ->assertSee('Zur Prüfung freigeben'); }); test('submitting without a booking is rejected at the service level', function () { /** @var TestCase $this */ config()->set('billing.enforce_booking', true); Queue::fake(); ['pr' => $pr] = draftForGate(); expect(fn () => app(PressReleaseService::class)->submitForReview($pr)) ->toThrow(BookingRequiredException::class); expect($pr->fresh()->status)->toBe(PressReleaseStatus::Draft); }); test('a legacy grandfathered booking allows submitting for review', function () { /** @var TestCase $this */ config()->set('billing.enforce_booking', true); Queue::fake(); ['customer' => $customer, 'pr' => $pr] = draftForGate(); UserPaymentOption::factory()->create([ 'user_id' => $customer->id, 'status' => UserPaymentOptionStatus::Grandfathered->value, 'grandfathered_until' => now()->addYear(), 'stripe_subscription_id' => null, ]); app(PressReleaseService::class)->submitForReview($pr); expect($pr->fresh()->status)->toBe(PressReleaseStatus::Review); }); test('with the gate off the notice never shows', function () { /** @var TestCase $this */ config()->set('billing.enforce_booking', false); ['customer' => $customer, 'pr' => $pr] = draftForGate(); $this->actingAs($customer); Livewire::test('customer.press-releases.show', ['id' => $pr->id]) ->assertDontSee('Noch keine Buchung') ->assertSee('Zur Prüfung freigeben'); });