95 lines
4.1 KiB
PHP
95 lines
4.1 KiB
PHP
<?php
|
|
|
|
use App\Livewire\Billing;
|
|
use App\Models\Customer;
|
|
use App\Models\Instance;
|
|
use App\Models\Order;
|
|
use App\Models\User;
|
|
use App\Services\Billing\AddonCatalogue;
|
|
use Livewire\Livewire;
|
|
|
|
/**
|
|
* Office liefert nicht — siehe App\Support\OpenWork::all() — und die
|
|
* Preistafel verspricht `collabora_pro` deshalb seit der Umstellung nicht
|
|
* mehr (LandingPriceSheetTest). Offen blieb der zweite Weg, den der Umsetzer
|
|
* selbst gemeldet hat: ein eingeloggter Team- oder Business-Kunde konnte das
|
|
* Modul weiterhin über die Abrechnungsseite buchen, weil AddonCatalogue den
|
|
* Preis unverändert kannte (BookAddon braucht ihn für Bestandsfälle und ein
|
|
* Geschenk des Betreibers) und App\Livewire\Billing::purchase() nie danach
|
|
* gefragt hat.
|
|
*
|
|
* Der Riegel sitzt jetzt in AddonCatalogue::saleRefusal() — derselben Stelle,
|
|
* die auch LandingController::modulePrices() liest — und wird hier an BEIDEN
|
|
* Enden geprüft: der Kauf selbst (am Formular vorbei, nicht nur "der Knopf
|
|
* fehlt") und die Karte, die ihn anbieten würde.
|
|
*/
|
|
function officeShopper(string $plan = 'team'): array
|
|
{
|
|
$customer = Customer::factory()->create();
|
|
$user = User::factory()->create(['email' => $customer->email]);
|
|
$order = Order::factory()->withSubscription()->for($customer)->create(['plan' => $plan]);
|
|
$instance = Instance::factory()->for($customer)->create([
|
|
'order_id' => $order->id,
|
|
'plan' => $plan,
|
|
'status' => 'active',
|
|
]);
|
|
|
|
$order->subscription->update(['instance_id' => $instance->id]);
|
|
|
|
// purchase() refuses outright without a Stripe key for the active mode
|
|
// (Task 5) — the refusal this test is about must not be masked by that
|
|
// earlier one.
|
|
withStripeSecret();
|
|
|
|
return [$customer, $user];
|
|
}
|
|
|
|
it('weist eine Buchung von collabora_pro am Formular vorbei ab, solange Office nicht verkauft wird', function () {
|
|
// Absichtlich NICHT über einen fehlenden Knopf geprüft: das würde nur
|
|
// zeigen, dass die Anzeige geschlossen ist. Dieser Aufruf geht am
|
|
// Formular vorbei — genau der Weg, den ein zweites Browser-Fenster, eine
|
|
// alte Sitzung oder ein direkter Aufruf des Komponentennamens auch nähme.
|
|
[$customer, $user] = officeShopper('team');
|
|
|
|
Livewire::actingAs($user)->test(Billing::class)
|
|
->call('purchase', 'addon', 'collabora_pro')
|
|
->assertDispatched('notify', message: __('billing.addon_not_on_sale', [
|
|
'module' => __('billing.addon.collabora_pro.name'),
|
|
]));
|
|
|
|
// Kein Auftrag, also nichts, das später fälschlich zur Buchung würde.
|
|
expect(Order::query()->where('customer_id', $customer->id)->where('type', 'addon')->exists())->toBeFalse();
|
|
});
|
|
|
|
it('zeigt die Office-Karte im Portal nicht mehr an, solange sie ohnehin abgewiesen würde', function () {
|
|
[, $user] = officeShopper('team');
|
|
|
|
// Team trägt `collabora_pro` nicht in `unavailable_on` — ohne den neuen
|
|
// Riegel stünde die Karte hier also, mit einem Kauf-Knopf, der beim
|
|
// Anklicken nur die Meldung aus dem Test oben gezeigt hätte.
|
|
Livewire::actingAs($user)->test(Billing::class)
|
|
->assertDontSee(__('billing.addon.collabora_pro.name'));
|
|
});
|
|
|
|
it('lässt die anderen Module unberührt, sowohl in der Anzeige als auch bei der Buchung', function () {
|
|
// Der Riegel gilt nur `collabora_pro` (und, seit
|
|
// tests/Feature/Billing/ExtraBackupsNotSoldTest.php, `extra_backups`) —
|
|
// für alles andere muss saleRefusal() weiterhin null bleiben, sonst hätte
|
|
// diese Änderung den ganzen Shop zugesperrt statt zweier einzelner
|
|
// Module. `extra_backups` steht deshalb absichtlich NICHT mehr in dieser
|
|
// Liste.
|
|
$catalogue = app(AddonCatalogue::class);
|
|
|
|
foreach (['priority_support', 'custom_domain', AddonCatalogue::STORAGE] as $key) {
|
|
expect($catalogue->saleRefusal($key))->toBeNull();
|
|
}
|
|
|
|
[, $user] = officeShopper('team');
|
|
|
|
Livewire::actingAs($user)->test(Billing::class)
|
|
->call('purchase', 'addon', 'priority_support')
|
|
->assertDispatched('notify', message: __('billing.purchased'));
|
|
|
|
expect(Order::query()->where('type', 'addon')->where('addon_key', 'priority_support')->exists())->toBeTrue();
|
|
});
|