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>
79 lines
2.4 KiB
PHP
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();
|
|
});
|