feat(attachment): add cropping functionality for images and update metadata storage

This commit is contained in:
2026-08-18 12:04:39 -03:00
parent 1c2f6c4127
commit 460ed528cf
5 changed files with 269 additions and 2 deletions

View File

@@ -70,6 +70,76 @@ class AttachmentTest extends TestCase
}
}
public function test_it_stores_an_original_image_and_its_crop(): void
{
Storage::fake('s3');
$original = app(AttachmentService::class)->storeCroppedImage(
UploadedFile::fake()->image('product.jpg', 200, 100),
'attachments/acme',
50,
25,
);
$cropped = $original->croppedAttachment;
$this->assertNotNull($cropped);
$this->assertSame(50.0, $original->crop_horizontal_start_percent);
$this->assertSame(25.0, $original->crop_vertical_start_percent);
$this->assertTrue($cropped->originalAttachment->is($original));
$this->assertDatabaseCount('attachments', 2);
$this->assertDatabaseHas('attachments', [
'id' => $original->id,
'cropped_attachment_id' => $cropped->id,
]);
Storage::disk('s3')->assertExists($original->path);
Storage::disk('s3')->assertExists($cropped->path);
$croppedSize = getimagesizefromstring(Storage::disk('s3')->get($cropped->path));
$this->assertIsArray($croppedSize);
$this->assertSame(100, $croppedSize[0]);
$this->assertSame(75, $croppedSize[1]);
}
public function test_it_rejects_invalid_crop_percentages_without_storing_files(): void
{
Storage::fake('s3');
try {
app(AttachmentService::class)->storeCroppedImage(
UploadedFile::fake()->image('product.png'),
'attachments/acme',
100,
0,
);
$this->fail('Expected an AttachmentStorageException to be thrown.');
} catch (AttachmentStorageException) {
$this->assertDatabaseCount('attachments', 0);
$this->assertSame([], Storage::disk('s3')->allFiles());
}
}
public function test_it_rolls_back_the_original_when_the_file_is_not_a_valid_image(): void
{
Storage::fake('s3');
try {
app(AttachmentService::class)->storeCroppedImage(
UploadedFile::fake()->createWithContent('invalid.png', 'not-an-image'),
'attachments/acme',
10,
10,
);
$this->fail('Expected an AttachmentStorageException to be thrown.');
} catch (AttachmentStorageException) {
$this->assertDatabaseCount('attachments', 0);
$this->assertSame([], Storage::disk('s3')->allFiles());
}
}
public function test_it_deletes_from_s3_before_removing_the_database_record(): void
{
Storage::fake('s3');