feat: product screenshots gallery
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
bf365d029f
commit
a3894d2f37
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Product;
|
||||
use App\Models\ProductScreenshot;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
function shotPayload(array $overrides = []): array
|
||||
{
|
||||
return array_merge([
|
||||
'title' => '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);
|
||||
});
|
||||
Reference in New Issue
Block a user