b2in/tests/Feature/LocalFeedTest.php
2026-02-20 17:57:50 +01:00

280 lines
8.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
use App\Enums\ProductStatus;
use App\Enums\ProductType;
use App\Models\Category;
use App\Models\Hub;
use App\Models\Partner;
use App\Models\Product;
use App\Models\User;
use Livewire\Volt\Volt;
use Spatie\Permission\Models\Role;
beforeEach(function () {
app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();
Role::create(['name' => 'Admin']);
Role::create(['name' => 'Retailer']);
Role::create(['name' => 'Customer']);
});
test('customer only sees curated active available products from own hub', function () {
$hub = Hub::factory()->create();
$otherHub = Hub::factory()->create();
$partner = Partner::factory()->setupCompleted()->create(['hub_id' => $hub->id]);
$customer = User::factory()->create(['hub_id' => $hub->id]);
$customer->assignRole('Customer');
// Sichtbares Produkt: aktiv + kuratiert + verfügbar + gleicher Hub
$visibleProduct = Product::factory()->create([
'partner_id' => $partner->id,
'hub_id' => $hub->id,
'status' => ProductStatus::Active,
'is_curated' => true,
'is_available' => true,
]);
// Nicht sichtbar: nicht kuratiert
$notCurated = Product::factory()->create([
'partner_id' => $partner->id,
'hub_id' => $hub->id,
'status' => ProductStatus::Active,
'is_curated' => false,
'is_available' => true,
]);
// Nicht sichtbar: anderen Hub
$otherHubProduct = Product::factory()->create([
'partner_id' => $partner->id,
'hub_id' => $otherHub->id,
'status' => ProductStatus::Active,
'is_curated' => true,
'is_available' => true,
]);
// Nicht sichtbar: Draft-Status
$draftProduct = Product::factory()->create([
'partner_id' => $partner->id,
'hub_id' => $hub->id,
'status' => ProductStatus::Draft,
'is_curated' => true,
'is_available' => true,
]);
$this->actingAs($customer);
Volt::test('products.index')
->assertSee($visibleProduct->name)
->assertDontSee($notCurated->name)
->assertDontSee($otherHubProduct->name)
->assertDontSee($draftProduct->name);
});
test('admin sees all products regardless of curation or status', function () {
$hub = Hub::factory()->create();
$partner = Partner::factory()->setupCompleted()->create(['hub_id' => $hub->id]);
$admin = User::factory()->create();
$admin->assignRole('Admin');
$activeProduct = Product::factory()->create([
'partner_id' => $partner->id,
'hub_id' => $hub->id,
'status' => ProductStatus::Active,
'is_curated' => true,
'is_available' => true,
]);
$draftProduct = Product::factory()->create([
'partner_id' => $partner->id,
'hub_id' => $hub->id,
'status' => ProductStatus::Draft,
'is_curated' => false,
'is_available' => false,
]);
$this->actingAs($admin);
Volt::test('products.index')
->assertSee($activeProduct->name)
->assertSee($draftProduct->name);
});
test('retailer only sees own products', function () {
$hub = Hub::factory()->create();
$partner = Partner::factory()->setupCompleted()->create(['hub_id' => $hub->id]);
$otherPartner = Partner::factory()->setupCompleted()->create(['hub_id' => $hub->id]);
$retailer = User::factory()->create(['partner_id' => $partner->id]);
$retailer->assignRole('Retailer');
$ownProduct = Product::factory()->create([
'partner_id' => $partner->id,
'hub_id' => $hub->id,
'status' => ProductStatus::Active,
]);
$otherProduct = Product::factory()->create([
'partner_id' => $otherPartner->id,
'hub_id' => $hub->id,
'status' => ProductStatus::Active,
]);
$this->actingAs($retailer);
Volt::test('products.index')
->assertSee($ownProduct->name)
->assertDontSee($otherProduct->name);
});
test('customer can search products by name', function () {
$hub = Hub::factory()->create();
$partner = Partner::factory()->setupCompleted()->create(['hub_id' => $hub->id]);
$customer = User::factory()->create(['hub_id' => $hub->id]);
$customer->assignRole('Customer');
$matchingProduct = Product::factory()->create([
'name' => 'Eiche Sideboard',
'partner_id' => $partner->id,
'hub_id' => $hub->id,
'status' => ProductStatus::Active,
'is_curated' => true,
'is_available' => true,
]);
$otherProduct = Product::factory()->create([
'name' => 'Massivholztisch',
'partner_id' => $partner->id,
'hub_id' => $hub->id,
'status' => ProductStatus::Active,
'is_curated' => true,
'is_available' => true,
]);
$this->actingAs($customer);
Volt::test('products.index')
->set('search', 'Eiche')
->assertSee($matchingProduct->name)
->assertDontSee($otherProduct->name);
});
test('customer can filter products by category', function () {
$hub = Hub::factory()->create();
$partner = Partner::factory()->setupCompleted()->create(['hub_id' => $hub->id]);
$category = Category::factory()->create();
$customer = User::factory()->create(['hub_id' => $hub->id]);
$customer->assignRole('Customer');
$categoryProduct = Product::factory()->create([
'partner_id' => $partner->id,
'hub_id' => $hub->id,
'status' => ProductStatus::Active,
'is_curated' => true,
'is_available' => true,
]);
$categoryProduct->categories()->attach($category);
$noCategory = Product::factory()->create([
'partner_id' => $partner->id,
'hub_id' => $hub->id,
'status' => ProductStatus::Active,
'is_curated' => true,
'is_available' => true,
]);
$this->actingAs($customer);
Volt::test('products.index')
->set('categoryFilter', (string) $category->id)
->assertSee($categoryProduct->name)
->assertDontSee($noCategory->name);
});
test('retailer can filter products by product type', function () {
$hub = Hub::factory()->create();
$partner = Partner::factory()->setupCompleted()->create(['hub_id' => $hub->id]);
$retailer = User::factory()->create(['partner_id' => $partner->id]);
$retailer->assignRole('Retailer');
$teaserProduct = Product::factory()->create([
'name' => 'Teaser Sideboard',
'partner_id' => $partner->id,
'hub_id' => $hub->id,
'product_type' => ProductType::LocalStock,
'status' => ProductStatus::Active,
]);
$standardProduct = Product::factory()->create([
'name' => 'Standard Sofa',
'partner_id' => $partner->id,
'hub_id' => $hub->id,
'product_type' => ProductType::SmartOrder,
'status' => ProductStatus::Active,
]);
$this->actingAs($retailer);
// Filter auf Teaser (LocalStock)
Volt::test('products.index')
->set('productTypeFilter', 'local_stock')
->assertSee($teaserProduct->name)
->assertDontSee($standardProduct->name);
// Filter auf Standard (SmartOrder)
Volt::test('products.index')
->set('productTypeFilter', 'smart_order')
->assertSee($standardProduct->name)
->assertDontSee($teaserProduct->name);
// Kein Filter beide sichtbar
Volt::test('products.index')
->set('productTypeFilter', '')
->assertSee($teaserProduct->name)
->assertSee($standardProduct->name);
});
test('product list shows both create buttons for retailer', function () {
$hub = Hub::factory()->create();
$partner = Partner::factory()->setupCompleted()->create(['hub_id' => $hub->id]);
$retailer = User::factory()->create(['partner_id' => $partner->id]);
$retailer->assignRole('Retailer');
$this->actingAs($retailer);
Volt::test('products.index')
->assertSee(__('Neues Teaser-Produkt'))
->assertSee(__('Neues Standard-Produkt'));
});
test('product list shows both create buttons for manufacturer', function () {
$hub = Hub::factory()->create();
$partner = Partner::factory()->setupCompleted()->create(['hub_id' => $hub->id]);
$manufacturer = User::factory()->create(['partner_id' => $partner->id]);
$manufacturer->assignRole('Retailer'); // Need Manufacturer role
Role::create(['name' => 'Manufacturer']);
$manufacturer->syncRoles(['Manufacturer']);
$this->actingAs($manufacturer);
Volt::test('products.index')
->assertSee(__('Neues Teaser-Produkt'))
->assertSee(__('Neues Standard-Produkt'));
});
test('product list does not show create buttons for customer', function () {
$hub = Hub::factory()->create();
$customer = User::factory()->create(['hub_id' => $hub->id]);
$customer->assignRole('Customer');
$this->actingAs($customer);
Volt::test('products.index')
->assertDontSee(__('Neues Teaser-Produkt'))
->assertDontSee(__('Neues Standard-Produkt'));
});