presseportale/tests/Feature/PressReleaseShowAddonsTest.php
Kevin Adametz 77a4476fd0 UI: Credit-Wallet-Hub + Per-PM Add-ons im Backend-Pressekonto
Wallet-Oekonomie im Customer-Bereich sichtbar gemacht:

- Buchungen & Add-ons: Guthaben-Anzeige, Credit-Paket-Topup (Bonus-Staffel),
  Extra-PM-Kauf aus der Wallet mit kontextuellem Mini-Checkout-Hinweis,
  Pruefkontingent-Status (frei/Monat, heute/Tageslimit), Wallet-Verlauf
- PM-Detailseite: Add-ons-Panel fuer veroeffentlichte PMs -- Boost buchen
  (7/14/30 Tage, Gate nur gruen, Verlaengerung), Veroeffentlichungsnachweis
  kaufen + Download. Aktionen ueber BoostService/ProofPdfService

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 15:02:31 +00:00

100 lines
3.4 KiB
PHP

<?php
use App\Enums\PressReleaseClassification;
use App\Models\Category;
use App\Models\Company;
use App\Models\PressRelease;
use App\Models\User;
use App\Services\Billing\CreditWalletService;
use App\Services\Billing\ProofPdfService;
use Database\Seeders\RolesAndPermissionsSeeder;
use Livewire\Volt\Volt as LivewireVolt;
use Tests\TestCase;
beforeEach(function (): void {
/** @var TestCase $this */
$this->seed(RolesAndPermissionsSeeder::class);
$this->wallet = app(CreditWalletService::class);
});
/**
* @return array{customer: User, pr: PressRelease}
*/
function publishedGreenPrForOwner(): 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()->published()->create([
'user_id' => $customer->id,
'company_id' => $company->id,
'category_id' => Category::factory()->create()->id,
'portal' => $company->portal->value,
'classification' => PressReleaseClassification::Green->value,
]);
return compact('customer', 'pr');
}
test('a published green release shows the boost and proof add-ons', function () {
/** @var TestCase $this */
['customer' => $customer, 'pr' => $pr] = publishedGreenPrForOwner();
$this->wallet->credit($customer, 40);
$this->actingAs($customer);
LivewireVolt::test('customer.press-releases.show', ['id' => $pr->id])
->assertSee('Add-ons')
->assertSee('Boost — Platzierung')
->assertSee('7 Tage · 12 Credits')
->assertSee('Veröffentlichungsnachweis')
->assertSee('Für 3 Credits kaufen');
});
test('booking a boost from the detail page debits the wallet and activates it', function () {
/** @var TestCase $this */
['customer' => $customer, 'pr' => $pr] = publishedGreenPrForOwner();
$this->wallet->credit($customer, 40);
$this->actingAs($customer);
LivewireVolt::test('customer.press-releases.show', ['id' => $pr->id])
->call('buyBoost', 14);
expect($customer->fresh()->creditBalance())->toBe(20); // 40 - 20 (14 Tage)
expect($pr->fresh()->isBoosted())->toBeTrue();
});
test('buying a proof from the detail page unlocks the download', function () {
/** @var TestCase $this */
['customer' => $customer, 'pr' => $pr] = publishedGreenPrForOwner();
$this->wallet->credit($customer, 10);
$this->actingAs($customer);
LivewireVolt::test('customer.press-releases.show', ['id' => $pr->id])
->call('buyProof')
->assertSee('Nachweis herunterladen');
expect(app(ProofPdfService::class)->hasPurchased($customer->fresh(), $pr))->toBeTrue();
expect($customer->fresh()->creditBalance())->toBe(7);
});
test('a non-green release cannot be boosted from the detail page', function () {
/** @var TestCase $this */
['customer' => $customer, 'pr' => $pr] = publishedGreenPrForOwner();
$pr->update(['classification' => PressReleaseClassification::Yellow->value]);
$this->wallet->credit($customer, 40);
$this->actingAs($customer);
LivewireVolt::test('customer.press-releases.show', ['id' => $pr->id])
->assertSee('Nur grün geprüfte Pressemitteilungen sind boostbar')
->call('buyBoost', 7);
expect($customer->fresh()->creditBalance())->toBe(40); // nichts abgebucht
expect($pr->fresh()->isBoosted())->toBeFalse();
});