gruene-seele/tests/Feature/SalesShippedStatusTest.php
Kevin Adametz 6b8fcadcbf Warenwirtschaft: SalesController::store() gehärtet (Validierung, Transaktion, Lock)
Vorbereitung AP-13: Versand-Statuswechsel validiert Eingaben (Status aus
shippedTypes, Action-Whitelist), läuft in DB::transaction mit lockForUpdate
gegen Doppelklick/parallele Tabs. Verhalten sonst unverändert.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 07:44:21 +00:00

137 lines
3.9 KiB
PHP

<?php
use App\Models\Country;
use App\Models\Shipping;
use App\Models\ShippingCountry;
use App\Models\ShoppingOrder;
use App\Models\ShoppingUser;
use App\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
uses(TestCase::class, RefreshDatabase::class);
function salesMakeAdmin(int $adminLevel = 7): User
{
$user = User::query()->create([
'email' => uniqid('sales_', true).'@test.example',
'password' => bcrypt('password'),
]);
$user->forceFill([
'admin' => $adminLevel,
'confirmed' => true,
'active' => true,
'wizard' => 100,
'blocked' => false,
])->save();
return $user->fresh();
}
function salesMakeOrder(array $overrides = []): ShoppingOrder
{
$country = Country::query()->forceCreate([
'code' => 'DE',
'en' => 'Germany',
'de' => 'Deutschland',
'es' => 'Alemania',
'fr' => 'Allemagne',
'it' => 'Germania',
'ru' => 'Germanija',
]);
$shipping = Shipping::query()->forceCreate(['name' => 'Standard']);
$shippingCountry = ShippingCountry::query()->forceCreate([
'shipping_id' => $shipping->id,
'country_id' => $country->id,
]);
$shoppingUser = ShoppingUser::query()->forceCreate([
'billing_country_id' => $country->id,
'shipping_country_id' => $country->id,
'billing_firstname' => 'Test',
'billing_lastname' => 'Kunde',
]);
return ShoppingOrder::query()->forceCreate(array_merge([
'shopping_user_id' => $shoppingUser->id,
'auth_user_id' => salesMakeAdmin(0)->id,
'country_id' => $shippingCountry->id,
'shipped' => 0,
], $overrides));
}
test('versand-status versendet setzt shipped_at', function () {
$admin = salesMakeAdmin();
$order = salesMakeOrder();
$response = $this->actingAs($admin)->post(route('admin_sales_store'), [
'id' => $order->id,
'action' => 'store_shipped',
'shipped' => 2,
]);
$response->assertRedirect();
$order->refresh();
expect($order->shipped)->toBe(2)
->and($order->shipped_at)->not->toBeNull();
});
test('zuruecksetzen auf offen entfernt shipped_at', function () {
$admin = salesMakeAdmin();
$order = salesMakeOrder(['shipped' => 2, 'shipped_at' => now()]);
$this->actingAs($admin)->post(route('admin_sales_store'), [
'id' => $order->id,
'action' => 'store_shipped',
'shipped' => 0,
])->assertRedirect();
$order->refresh();
expect($order->shipped)->toBe(0)
->and($order->shipped_at)->toBeNull();
});
test('ungueltiger versand-status wird abgelehnt', function () {
$admin = salesMakeAdmin();
$order = salesMakeOrder();
$response = $this->actingAs($admin)->from(route('admin_sales'))->post(route('admin_sales_store'), [
'id' => $order->id,
'action' => 'store_shipped',
'shipped' => 99,
]);
$response->assertSessionHasErrors('shipped');
expect($order->fresh()->shipped)->toBe(0);
});
test('unbekannte action wird abgelehnt', function () {
$admin = salesMakeAdmin();
$order = salesMakeOrder();
$this->actingAs($admin)->post(route('admin_sales_store'), [
'id' => $order->id,
'action' => 'delete_everything',
])->assertSessionHasErrors('action');
});
test('nicht-admin wird umgeleitet und aendert nichts', function () {
$user = salesMakeAdmin(1);
$order = salesMakeOrder();
$this->actingAs($user)->post(route('admin_sales_store'), [
'id' => $order->id,
'action' => 'store_shipped',
'shipped' => 2,
])->assertRedirect('/home');
expect($order->fresh()->shipped)->toBe(0);
});
test('fehlende id ergibt 404', function () {
$admin = salesMakeAdmin();
$this->actingAs($admin)->post(route('admin_sales_store'), [
'action' => 'store_shipped',
'shipped' => 2,
])->assertNotFound();
});