mivita/tests/Feature/CheckoutOrderSourceValidationTest.php
Kevin 3d0864713b Kunden loeschen: DSGVO-geloeschte Kunden ausblenden und sperren; Checkout-Herkunft freiwillig
Kunden loeschen (Rueckmeldung "es wird nichts geloescht"):
- DSGVO-geloeschte Eintraege blieben mit Name in den Listen stehen; Kunde
  61009 wurde deshalb achtmal geloescht, bei Eintrag 45013 wurde die E-Mail
  danach ueber ein offenes Bearbeiten-Formular zurueckgeschrieben
- neue Spalte shopping_users.gdpr_deleted_at (Bestand per Migration markiert)
- Admin-Kundenliste blendet geloeschte Kunden aus (Filter: ausblenden /
  mit anzeigen / nur geloeschte), Berater-Kundenliste immer
- Bearbeiten/Speichern im Admin und beim Berater gesperrt; ShoppingUser
  verweigert das Zurueckschreiben von E-Mail und Telefon
- Modal und Erfolgsmeldung (de/en/es/fr) sagen klar, dass Name und
  Rechnungsadresse wegen der Aufbewahrungspflicht bleiben
- gdpr:repair-customers [--execute] zieht protokollierte Loeschungen nach
- DSGVO-Loeschung prueft Superadmin serverseitig; Berater duerfen eine
  Kunden-E-Mail nur beim eigenen Kunden nachtragen
- setFakerMail setzt faker_mail bei geloeschten Eintraegen nicht zurueck

Checkout: "Wie bist du auf uns aufmerksam geworden?" ist kein Pflichtfeld
mehr und wird farbig hervorgehoben.

Deploy: php artisan migrate && php artisan gdpr:repair-customers --execute

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 12:36:02 +00:00

79 lines
2.4 KiB
PHP

<?php
use App\Http\Controllers\Web\CheckoutController;
use Illuminate\Validation\Validator;
use Tests\TestCase;
uses(TestCase::class);
/**
* Ruft die private Checkout-Validierung mit dem gegebenen Request-Input auf.
* (route() ist wegen Domain-Routing im Test nicht verfügbar, daher direkt.)
*/
function cosvValidateCheckout(array $input): Validator
{
request()->replace($input);
$method = new ReflectionMethod(CheckoutController::class, 'validateCheckoutData');
return $method->invoke(app(CheckoutController::class));
}
/**
* @return array<string, string>
*/
function cosvBaseCheckoutInput(array $overrides = []): array
{
return array_merge([
'is_from' => 'shopping',
'billing_salutation' => 'Frau',
'billing_firstname' => 'Erika',
'billing_lastname' => 'Muster',
'billing_email' => 'erika@example.com',
'billing_address' => 'Musterweg 1',
'billing_zipcode' => '12345',
'billing_city' => 'Berlin',
'accepted_data_checkbox' => '1',
], $overrides);
}
it('akzeptiert Shop-Kundenbestellungen ohne Herkunfts-Freitext', function () {
$validator = cosvValidateCheckout(cosvBaseCheckoutInput());
expect($validator->fails())->toBeFalse();
expect($validator->errors()->has('customer_order_source_comment'))->toBeFalse();
});
it('akzeptiert einen leeren Herkunfts-Freitext', function () {
$validator = cosvValidateCheckout(cosvBaseCheckoutInput([
'customer_order_source_comment' => null,
]));
expect($validator->fails())->toBeFalse();
});
it('akzeptiert den Checkout ohne das frühere Herkunfts-Dropdown', function () {
$validator = cosvValidateCheckout(cosvBaseCheckoutInput([
'customer_order_source_comment' => 'Empfehlung von Maria Mustermann',
]));
expect($validator->fails())->toBeFalse();
expect($validator->errors()->has('customer_order_source'))->toBeFalse();
});
it('begrenzt den Herkunfts-Freitext auf 500 Zeichen', function () {
$validator = cosvValidateCheckout(cosvBaseCheckoutInput([
'customer_order_source_comment' => str_repeat('a', 501),
]));
expect($validator->fails())->toBeTrue();
expect($validator->errors()->has('customer_order_source_comment'))->toBeTrue();
});
it('verlangt keinen Herkunfts-Freitext außerhalb des Shop-Checkouts', function () {
$validator = cosvValidateCheckout(cosvBaseCheckoutInput([
'is_from' => 'user',
]));
expect($validator->fails())->toBeFalse();
});