Abo: Fix Checkout-Rücksprung bei Einmalprodukten in der Bestellstrecke

Die Submit-Validierung checkSendYardForPayment() prüfte jede Cart-Zeile
gegen das Abo-Sortiment (12/13) – Einmal-Zeilen (show_on 3) fielen durch
und der Checkout-Klick sprang per back() kommentarlos auf die
Bestellseite zurück. Einmal-Zeilen werden jetzt gegen das
Einmal-Sortiment validiert (manipulierte Zeilen weiterhin abgewiesen).

Zusätzlich zeigt list.blade.php jetzt alle Validierungsfehler an
(vorher nur Comp-Produkt-Fehler → Fehler blieb unsichtbar).

Tests: 2 neue Regressionstests in AboCreateOneTimeCartTest (19 grün).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin 2026-07-22 13:02:43 +00:00
parent cdb121fde0
commit 657d4bd5b7
4 changed files with 93 additions and 1 deletions

View file

@ -11,7 +11,9 @@ use App\Models\Country;
use App\Models\Shipping;
use App\Models\ShippingCountry;
use App\Models\ShippingPrice;
use App\Models\UserAccount;
use App\Services\ProductOrderContext;
use App\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Collection;
use Tests\TestCase;
@ -122,6 +124,71 @@ it('lehnt ein reines Abo-Produkt als Einmal-Artikel ab', function () {
->and(Yard::instance('shopping')->content())->toHaveCount(0);
});
/**
* Eingeloggter Berater mit Versandland-Account (Voraussetzung für checkSendYardForPayment).
*/
function makeCheckoutValidationUser(ShippingCountry $shippingCountry): User
{
$account = UserAccount::create([
'salutation' => 'Herr',
'first_name' => 'Max',
'last_name' => 'Muster',
'address' => 'Musterstr. 1',
'zipcode' => '12345',
'city' => 'Musterstadt',
'country_id' => $shippingCountry->country_id,
'phone' => '123456',
'same_as_billing' => 1,
'language' => 'de',
]);
$user = User::forceCreate([
'email' => 'checkout-'.uniqid('', true).'@example.com',
'password' => bcrypt('secret'),
'lang' => 'de',
'account_id' => $account->id,
]);
test()->be($user);
return $user;
}
function invokeCheckSendYardForPayment(): void
{
$controller = app(OrderController::class);
$reflection = new ReflectionMethod($controller, 'checkSendYardForPayment');
$reflection->invoke($controller, ['shipping_is_for' => 'abo-me'], null);
}
it('lässt die Checkout-Validierung Einmal-Zeilen im Abo-Cart passieren', function () {
makeCheckoutValidationUser($this->shippingCountry);
$aboProduct = makeProduct(['12'], 90, 19);
$addonProduct = makeProduct(['3'], 25.50, 19);
postCartUpdate(['product_id' => $aboProduct->id, 'qty' => 1, 'shipping_is_for' => 'abo-me']);
postCartUpdate(['product_id' => $addonProduct->id, 'qty' => 2, 'abo_addon' => 1, 'shipping_is_for' => 'abo-me']);
// Vor dem Fix warf die Sortiment-Prüfung hier "cart_product_not_allowed_for_order_type"
// und der Checkout-Klick sprang kommentarlos auf die Bestellseite zurück.
invokeCheckSendYardForPayment();
expect(findYardRows($addonProduct->id, true))->toHaveCount(1);
});
it('weist manipulierte Einmal-Zeilen mit Abo-Produkt bei der Checkout-Validierung ab', function () {
makeCheckoutValidationUser($this->shippingCountry);
$aboProduct = makeProduct(['12'], 90, 19);
postCartUpdate(['product_id' => $aboProduct->id, 'qty' => 1, 'shipping_is_for' => 'abo-me']);
Yard::instance('shopping')->add($aboProduct->id, 'Manipuliert', 1, 90.0, false, false, [
'slug' => $aboProduct->slug, 'weight' => 500, 'points' => 10, 'show_on' => ['12'],
'abo_addon' => true,
]);
invokeCheckSendYardForPayment();
})->throws(Exception::class);
it('entfernt mit qty=0 nur die Einmal-Zeile, die Abo-Zeile bleibt', function () {
$product = makeProduct(['3', '12'], 90, 19);