` prüft und meine
* Zeilen `
` waren. Der Buchstabe der Prüfung, nicht ihr Sinn. Dieser Test
* schliesst die Lücke für diese Seite; die allgemeine Fassung wäre ein eigener
* Punkt (siehe unten).
*/
function bouncedPayment(): FailedCheckout
{
return FailedCheckout::query()->create([
'stripe_session_id' => 'cs_geplatzt', 'email' => 'neu@example.test',
'name' => 'Neu GmbH', 'plan' => 'start', 'amount_cents' => 4900,
'currency' => 'EUR', 'failed_at' => Carbon::now(),
]);
}
it('carries no input field on the page itself', function () {
// Die Zeile bleibt eine Zeile. Ein Feld darin lässt sie wachsen, die
// Nachbarzeilen springen, und eine halb im Bearbeitungsmodus stehende
// Liste liest sich wie ein Darstellungsfehler.
bouncedPayment();
$html = Livewire::actingAs(operator('Owner'), 'operator')
->test(PaymentProblems::class)
->html();
expect($html)->not->toContain('wire:model="note.');
});
it('opens a modal instead', function () {
$problem = bouncedPayment();
$html = Livewire::actingAs(operator('Owner'), 'operator')
->test(PaymentProblems::class)
->html();
expect($html)->toContain('admin.resolve-failed-checkout')
->and($html)->toContain((string) $problem->id);
});
it('lets the modal hand the reason back to the page', function () {
// R23: das Modal mutiert nichts selbst. Es löst ein Ereignis aus, und die
// Seiten-Komponente behält ihre eigene Berechtigungsprüfung.
$problem = bouncedPayment();
Livewire::actingAs(operator('Owner'), 'operator')
->test(ResolveFailedCheckout::class, ['id' => $problem->id])
->set('note', 'Kunde hat überwiesen')
->call('confirm')
->assertDispatched('failed-checkout-resolved');
});
it('records reason and person when the page catches that event', function () {
$problem = bouncedPayment();
Livewire::actingAs(operator('Owner'), 'operator')
->test(PaymentProblems::class)
->call('onResolved', $problem->id, 'Kunde hat überwiesen')
->assertHasNoErrors();
$problem->refresh();
expect($problem->resolved_at)->not->toBeNull()
->and($problem->note)->toContain('überwiesen');
});
it('keeps the capability check on the page, not only on the modal', function () {
// Ein Modal ist OHNE die Route-Middleware der Seite erreichbar — und das
// Ereignis, das es auslöst, könnte jemand auch direkt schicken.
$problem = bouncedPayment();
Livewire::actingAs(operator('Support'), 'operator')
->test(ResolveFailedCheckout::class, ['id' => $problem->id])
->assertForbidden();
expect($problem->fresh()->resolved_at)->toBeNull();
});