'Shot Product', 'description' => 'A product description', 'website_url' => 'https://example.com', 'category_id' => makeCategory()->id, ], $overrides); } function makeShot(Product $product, string $name = 'a.jpg'): ProductScreenshot { Storage::disk('public')->put("screenshots/{$product->id}-{$name}", 'x'); return $product->screenshots()->create(['path' => "screenshots/{$product->id}-{$name}"]); } test('submitter uploads several screenshots', function () { Storage::fake('public'); $user = userWithRole('user'); $this->actingAs($user)->post(route('products.store'), shotPayload([ 'screenshots' => [ UploadedFile::fake()->image('a.jpg'), UploadedFile::fake()->image('b.png'), UploadedFile::fake()->image('c.jpg'), ], ]))->assertRedirect(); $product = Product::firstOrFail(); expect($product->screenshots)->toHaveCount(3); expect($product->screenshots->pluck('position')->all())->toBe([0, 1, 2]); foreach ($product->screenshots as $shot) { Storage::disk('public')->assertExists($shot->path); } }); test('screenshots must be images up to 2 MB', function () { Storage::fake('public'); $user = userWithRole('user'); $this->actingAs($user)->post(route('products.store'), shotPayload([ 'screenshots' => [UploadedFile::fake()->create('doc.pdf', 100, 'application/pdf')], ]))->assertSessionHasErrors('screenshots.0'); $this->actingAs($user)->post(route('products.store'), shotPayload([ 'screenshots' => [UploadedFile::fake()->image('big.jpg')->size(3000)], ]))->assertSessionHasErrors('screenshots.0'); expect(Product::count())->toBe(0); }); test('owner removes a screenshot on edit', function () { Storage::fake('public'); $user = userWithRole('user'); $product = Product::factory()->pending()->create(['user_id' => $user->id]); $shot = makeShot($product); $this->actingAs($user)->put(route('products.update', $product), shotPayload([ 'category_id' => $product->category_id, 'remove_screenshots' => [$shot->id], ]))->assertRedirect(); expect(ProductScreenshot::count())->toBe(0); Storage::disk('public')->assertMissing($shot->path); }); test('remove_screenshots ignores ids from another product', function () { Storage::fake('public'); $user = userWithRole('user'); $product = Product::factory()->pending()->create(['user_id' => $user->id]); $other = Product::factory()->pending()->create(); $foreign = makeShot($other, 'f.jpg'); $this->actingAs($user)->put(route('products.update', $product), shotPayload([ 'category_id' => $product->category_id, 'remove_screenshots' => [$foreign->id], ]))->assertRedirect()->assertSessionHasNoErrors(); expect($foreign->fresh())->not->toBeNull(); Storage::disk('public')->assertExists($foreign->path); }); test('deleting a product removes its screenshot files', function () { Storage::fake('public'); $user = userWithRole('user'); $product = Product::factory()->pending()->create(['user_id' => $user->id]); $shot = makeShot($product); $this->actingAs($user)->delete(route('products.destroy', $product))->assertRedirect(); Storage::disk('public')->assertMissing($shot->path); expect(ProductScreenshot::count())->toBe(0); }); test('show page renders gallery only when screenshots exist', function () { Storage::fake('public'); $product = Product::factory()->approved()->create(); $this->get(route('products.show', $product))->assertOk()->assertDontSee('data-gallery', false); makeShot($product); $this->get(route('products.show', $product))->assertOk()->assertSee('data-gallery', false); });