Files

416 lines
12 KiB
PHP
Raw Permalink Normal View History

2026-02-06 14:56:56 +02:00
<?php
use App\Models\Category;
use App\Models\Product;
use App\Models\Role;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
uses(RefreshDatabase::class);
beforeEach(function () {
Storage::fake('public');
// Create roles
$this->userRole = Role::create([
'name' => 'User',
'slug' => 'user',
'description' => 'Regular user',
]);
$this->moderatorRole = Role::create([
'name' => 'Moderator',
'slug' => 'moderator',
'description' => 'Moderator',
]);
$this->adminRole = Role::create([
'name' => 'Admin',
'slug' => 'admin',
'description' => 'Admin',
]);
// Create category
$this->category = Category::create([
'name' => 'Test Category',
'slug' => 'test-category',
'description' => 'Test description',
]);
});
test('guests can view approved products', function () {
$user = User::factory()->create();
$user->roles()->attach($this->userRole);
$product = Product::create([
'title' => 'Test Product',
'slug' => 'test-product',
'description' => 'Test description',
'website_url' => 'https://example.com',
'user_id' => $user->id,
'category_id' => $this->category->id,
'status' => 'approved',
]);
$response = $this->get(route('products.index'));
$response->assertStatus(200);
$response->assertSee('Test Product');
});
test('guests cannot view pending products', function () {
$user = User::factory()->create();
$user->roles()->attach($this->userRole);
$product = Product::create([
'title' => 'Pending Product',
'slug' => 'pending-product',
'description' => 'Test description',
'website_url' => 'https://example.com',
'user_id' => $user->id,
'category_id' => $this->category->id,
'status' => 'pending',
]);
$response = $this->get(route('products.show', $product));
$response->assertStatus(404);
});
test('authenticated users can submit products', function () {
$user = User::factory()->create();
$user->roles()->attach($this->userRole);
$response = $this->actingAs($user)->post(route('products.store'), [
'title' => 'New Product',
'description' => 'This is a new product',
'website_url' => 'https://newproduct.com',
'category_id' => $this->category->id,
]);
$response->assertRedirect();
$this->assertDatabaseHas('products', [
'title' => 'New Product',
'user_id' => $user->id,
'status' => 'pending',
]);
});
test('guests cannot submit products', function () {
$response = $this->get(route('products.create'));
$response->assertRedirect(route('login'));
});
test('product submission requires title', function () {
$user = User::factory()->create();
$user->roles()->attach($this->userRole);
$response = $this->actingAs($user)->post(route('products.store'), [
'description' => 'Test description',
'website_url' => 'https://example.com',
'category_id' => $this->category->id,
]);
$response->assertSessionHasErrors('title');
});
test('product submission requires description', function () {
$user = User::factory()->create();
$user->roles()->attach($this->userRole);
$response = $this->actingAs($user)->post(route('products.store'), [
'title' => 'Test Product',
'website_url' => 'https://example.com',
'category_id' => $this->category->id,
]);
$response->assertSessionHasErrors('description');
});
test('product submission requires valid url', function () {
$user = User::factory()->create();
$user->roles()->attach($this->userRole);
$response = $this->actingAs($user)->post(route('products.store'), [
'title' => 'Test Product',
'description' => 'Test description',
'website_url' => 'not-a-valid-url',
'category_id' => $this->category->id,
]);
$response->assertSessionHasErrors('website_url');
});
test('product submission requires valid category', function () {
$user = User::factory()->create();
$user->roles()->attach($this->userRole);
$response = $this->actingAs($user)->post(route('products.store'), [
'title' => 'Test Product',
'description' => 'Test description',
'website_url' => 'https://example.com',
'category_id' => 999,
]);
$response->assertSessionHasErrors('category_id');
});
test('users can upload thumbnail when submitting product', function () {
$user = User::factory()->create();
$user->roles()->attach($this->userRole);
$file = UploadedFile::fake()->image('thumbnail.jpg');
$response = $this->actingAs($user)->post(route('products.store'), [
'title' => 'Test Product',
'description' => 'Test description',
'website_url' => 'https://example.com',
'category_id' => $this->category->id,
'thumbnail' => $file,
]);
$product = Product::where('title', 'Test Product')->first();
expect($product->thumbnail)->not->toBeNull();
Storage::disk('public')->assertExists($product->thumbnail);
});
test('thumbnail must be an image', function () {
$user = User::factory()->create();
$user->roles()->attach($this->userRole);
$file = UploadedFile::fake()->create('document.pdf');
$response = $this->actingAs($user)->post(route('products.store'), [
'title' => 'Test Product',
'description' => 'Test description',
'website_url' => 'https://example.com',
'category_id' => $this->category->id,
'thumbnail' => $file,
]);
$response->assertSessionHasErrors('thumbnail');
});
test('product owner can edit their product', function () {
$user = User::factory()->create();
$user->roles()->attach($this->userRole);
$product = Product::create([
'title' => 'Test Product',
'slug' => 'test-product',
'description' => 'Test description',
'website_url' => 'https://example.com',
'user_id' => $user->id,
'category_id' => $this->category->id,
'status' => 'pending',
]);
$response = $this->actingAs($user)->put(route('products.update', $product), [
'title' => 'Updated Product',
'description' => 'Updated description',
'website_url' => 'https://updated.com',
'category_id' => $this->category->id,
]);
$response->assertRedirect();
$this->assertDatabaseHas('products', [
'id' => $product->id,
'title' => 'Updated Product',
]);
});
test('non-owner cannot edit product', function () {
$owner = User::factory()->create();
$owner->roles()->attach($this->userRole);
$other = User::factory()->create();
$other->roles()->attach($this->userRole);
$product = Product::create([
'title' => 'Test Product',
'slug' => 'test-product',
'description' => 'Test description',
'website_url' => 'https://example.com',
'user_id' => $owner->id,
'category_id' => $this->category->id,
'status' => 'pending',
]);
$response = $this->actingAs($other)->put(route('products.update', $product), [
'title' => 'Updated Product',
'description' => 'Updated description',
'website_url' => 'https://updated.com',
'category_id' => $this->category->id,
]);
$response->assertStatus(403);
});
test('product owner can delete their product', function () {
$user = User::factory()->create();
$user->roles()->attach($this->userRole);
$product = Product::create([
'title' => 'Test Product',
'slug' => 'test-product',
'description' => 'Test description',
'website_url' => 'https://example.com',
'user_id' => $user->id,
'category_id' => $this->category->id,
'status' => 'pending',
]);
$response = $this->actingAs($user)->delete(route('products.destroy', $product));
$response->assertRedirect();
$this->assertDatabaseMissing('products', ['id' => $product->id]);
});
test('moderators can approve products', function () {
$moderator = User::factory()->create();
$moderator->roles()->attach($this->moderatorRole);
$user = User::factory()->create();
$user->roles()->attach($this->userRole);
$product = Product::create([
'title' => 'Test Product',
'slug' => 'test-product',
'description' => 'Test description',
'website_url' => 'https://example.com',
'user_id' => $user->id,
'category_id' => $this->category->id,
'status' => 'pending',
]);
$response = $this->actingAs($moderator)->post(route('products.approve', $product));
$response->assertRedirect();
$this->assertDatabaseHas('products', [
'id' => $product->id,
'status' => 'approved',
]);
expect($product->fresh()->approved_at)->not->toBeNull();
});
test('moderators can reject products', function () {
$moderator = User::factory()->create();
$moderator->roles()->attach($this->moderatorRole);
$user = User::factory()->create();
$user->roles()->attach($this->userRole);
$product = Product::create([
'title' => 'Test Product',
'slug' => 'test-product',
'description' => 'Test description',
'website_url' => 'https://example.com',
'user_id' => $user->id,
'category_id' => $this->category->id,
'status' => 'pending',
]);
$response = $this->actingAs($moderator)->post(route('products.reject', $product));
$response->assertRedirect();
$this->assertDatabaseHas('products', [
'id' => $product->id,
'status' => 'rejected',
]);
expect($product->fresh()->rejected_at)->not->toBeNull();
});
test('regular users cannot approve products', function () {
$user = User::factory()->create();
$user->roles()->attach($this->userRole);
$product = Product::create([
'title' => 'Test Product',
'slug' => 'test-product',
'description' => 'Test description',
'website_url' => 'https://example.com',
'user_id' => $user->id,
'category_id' => $this->category->id,
'status' => 'pending',
]);
$response = $this->actingAs($user)->post(route('products.approve', $product));
$response->assertStatus(403);
});
test('regular users cannot access product management page', function () {
$user = User::factory()->create();
$user->roles()->attach($this->userRole);
$response = $this->actingAs($user)->get(route('products.manage'));
$response->assertStatus(403);
});
test('moderators can access product management page', function () {
$moderator = User::factory()->create();
$moderator->roles()->attach($this->moderatorRole);
$response = $this->actingAs($moderator)->get(route('products.manage'));
$response->assertStatus(200);
});
test('admins can access product management page', function () {
$admin = User::factory()->create();
$admin->roles()->attach($this->adminRole);
$response = $this->actingAs($admin)->get(route('products.manage'));
$response->assertStatus(200);
});
test('slug is auto-generated from title', function () {
$user = User::factory()->create();
$user->roles()->attach($this->userRole);
$product = Product::create([
'title' => 'My Awesome Product',
'description' => 'Test description',
'website_url' => 'https://example.com',
'user_id' => $user->id,
'category_id' => $this->category->id,
'status' => 'pending',
]);
expect($product->slug)->toBe('my-awesome-product');
});
test('duplicate slugs are handled correctly', function () {
$user = User::factory()->create();
$user->roles()->attach($this->userRole);
$product1 = Product::create([
'title' => 'Test Product',
'description' => 'Test description',
'website_url' => 'https://example.com',
'user_id' => $user->id,
'category_id' => $this->category->id,
'status' => 'pending',
]);
$product2 = Product::create([
'title' => 'Test Product',
'description' => 'Test description',
'website_url' => 'https://example2.com',
'user_id' => $user->id,
'category_id' => $this->category->id,
'status' => 'pending',
]);
expect($product1->slug)->toBe('test-product');
expect($product2->slug)->toBe('test-product-1');
});