create([ 'email' => uniqid('oos_', true).'@test.example', 'password' => bcrypt('password'), ]); $user->forceFill([ 'admin' => $adminLevel, 'confirmed' => true, 'active' => true, 'wizard' => 100, 'blocked' => false, ])->save(); return $user->fresh(); } function oosMakeProduct(string $name): Product { return Product::query()->create([ 'name' => $name, 'title' => $name, 'active' => true, ]); } test('repository speichert out_of_stock_until aus datumsangabe', function () { $product = oosMakeProduct('OOS-Datum'); $repo = new ProductRepository($product); $repo->update([ 'id' => (string) $product->id, 'name' => $product->name, 'title' => $product->title, 'active' => '1', 'out_of_stock_active' => '1', 'out_of_stock_date' => now()->addDays(14)->format('d.m.Y'), ]); $product->refresh(); expect($product->out_of_stock_indefinite)->toBeFalse(); expect($product->out_of_stock_until)->not->toBeNull(); expect($product->out_of_stock_until->isSameDay(now()->addDays(14)))->toBeTrue(); expect($product->isOutOfStock())->toBeTrue(); }); test('unbestimmt hat vorrang und nullt das datum', function () { $product = oosMakeProduct('OOS-Unbestimmt'); $repo = new ProductRepository($product); $repo->update([ 'id' => (string) $product->id, 'name' => $product->name, 'title' => $product->title, 'active' => '1', 'out_of_stock_active' => '1', 'out_of_stock_date' => now()->addDays(14)->format('d.m.Y'), 'out_of_stock_indefinite' => '1', ]); $product->refresh(); expect($product->out_of_stock_indefinite)->toBeTrue(); expect($product->out_of_stock_until)->toBeNull(); expect($product->isOutOfStock())->toBeTrue(); expect($product->outOfStockNotice())->toBe('Zur Zeit nicht vorrätig'); }); test('ohne aktivierung werden die felder geleert', function () { $product = oosMakeProduct('OOS-Aus'); $product->update(['out_of_stock_until' => now()->addDays(5), 'out_of_stock_indefinite' => false]); $repo = new ProductRepository($product); $repo->update([ 'id' => (string) $product->id, 'name' => $product->name, 'title' => $product->title, 'active' => '1', ]); $product->refresh(); expect($product->out_of_stock_until)->toBeNull(); expect($product->out_of_stock_indefinite)->toBeFalse(); expect($product->isOutOfStock())->toBeFalse(); }); test('ungueltiges datum leert das feld statt zu crashen', function () { $product = oosMakeProduct('OOS-Invalid'); $repo = new ProductRepository($product); $repo->update([ 'id' => (string) $product->id, 'name' => $product->name, 'title' => $product->title, 'active' => '1', 'out_of_stock_active' => '1', 'out_of_stock_date' => 'kein-datum', ]); $product->refresh(); expect($product->out_of_stock_until)->toBeNull(); expect($product->isOutOfStock())->toBeFalse(); }); test('vergangenes datum gilt nicht als nicht vorrätig', function () { $product = oosMakeProduct('OOS-Vergangen'); $product->update(['out_of_stock_until' => now()->subDays(2)]); $product->refresh(); expect($product->isOutOfStock())->toBeFalse(); expect($product->outOfStockRemainingDays())->toBeNull(); expect($product->outOfStockNotice())->toBeNull(); }); test('hinweis zeigt verbleibende tage und zaehlt taeglich herunter', function () { $product = oosMakeProduct('OOS-Hinweis'); $product->update(['out_of_stock_until' => now()->addDays(5)]); $product->refresh(); expect($product->isOutOfStock())->toBeTrue(); expect($product->outOfStockRemainingDays())->toBe(5); expect($product->outOfStockNotice())->toBe('In ca. 5 Tagen wieder da!'); $this->travel(2)->days(); expect($product->outOfStockRemainingDays())->toBe(3); $this->travelBack(); }); test('http-store speichert nicht-vorrätig mit datum', function () { $this->actingAs(oosMakeUser(1), 'user'); $response = $this->post(route('admin_product_store'), [ 'id' => 'new', 'name' => 'OOS-HTTP', 'out_of_stock_active' => '1', 'out_of_stock_date' => now()->addDays(7)->format('d.m.Y'), ]); $response->assertRedirect(); $product = Product::query()->where('name', 'OOS-HTTP')->firstOrFail(); expect($product->out_of_stock_until)->not->toBeNull(); expect($product->out_of_stock_until->isSameDay(now()->addDays(7)))->toBeTrue(); expect($product->isOutOfStock())->toBeTrue(); }); test('interne bestellliste zeigt mengen-buttons trotz nicht-vorrätig', function () { // active.account prüft `payment_account` (Spalte existiert nur im Live-Schema, nicht in den Migrationen) $this->withoutMiddleware(ActiveAccount::class); $this->actingAs(oosMakeUser(1), 'user'); $product = oosMakeProduct('OOS-Bestellliste'); $product->update([ 'out_of_stock_until' => now()->addDays(12), 'show_on' => ['2'], ]); $response = $this->getJson(route('user_order_my_datatable', ['shipping_is_for' => 'me', 'draw' => 1, 'start' => 0, 'length' => 50])); $response->assertSuccessful(); $row = collect($response->json('data'))->first(fn ($r) => str_contains($r['product'] ?? '', 'OOS-Bestellliste')); expect($row)->not->toBeNull(); expect($row['product'])->toContain('product-stock-hint'); expect($row['product'])->toContain('wieder da'); expect($row['product'])->toContain('add-product-basket'); });