280 lines
8.8 KiB
PHP
280 lines
8.8 KiB
PHP
<?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'));
|
||
});
|