Refactor attachment cropping functionality to support multiple variants

- Introduced AttachmentCrop model to manage crop variants for attachments.
- Updated Attachment model to remove direct crop fields and establish relationships with AttachmentCrop.
- Modified AttachmentService to handle storing and updating multiple crop variants (desktop and mobile).
- Adjusted validation rules to accommodate new crop structure.
- Updated database migration to create attachment_crops table and migrate existing crop data.
- Refactored tests to ensure compatibility with the new cropping structure and validate multiple crop variants.
- Enhanced documentation to reflect changes in attachment handling and cropping capabilities.
This commit is contained in:
2026-08-18 14:40:22 -03:00
parent c00b3d609c
commit e619c51ac9
14 changed files with 526 additions and 150 deletions

View File

@@ -4,6 +4,7 @@ namespace Tests\Feature\Tenant;
use App\Domains\Attachable\Enums\AttachmentType;
use App\Domains\Attachable\Models\Attachment;
use App\Domains\Attachable\Models\AttachmentCrop;
use App\Domains\Authorization\Enums\RoleCode;
use App\Domains\Authorization\Models\Role;
use App\Domains\Catalog\Models\Category;
@@ -338,10 +339,18 @@ class BootstrapTenantControllerTest extends TestCase
],
],
]);
$cropped = Attachment::query()->create([
$desktop = Attachment::query()->create([
'key' => (string) Str::uuid(),
'path' => 'tenants/acme/cropped.jpg',
'filename' => 'cropped.jpg',
'path' => 'tenants/acme/desktop.jpg',
'filename' => 'desktop.jpg',
'type' => AttachmentType::Image,
'mime_type' => 'image/jpeg',
'extension' => 'jpg',
]);
$mobile = Attachment::query()->create([
'key' => (string) Str::uuid(),
'path' => 'tenants/acme/mobile.jpg',
'filename' => 'mobile.jpg',
'type' => AttachmentType::Image,
'mime_type' => 'image/jpeg',
'extension' => 'jpg',
@@ -353,10 +362,15 @@ class BootstrapTenantControllerTest extends TestCase
'type' => AttachmentType::Image,
'mime_type' => 'image/jpeg',
'extension' => 'jpg',
'crop_horizontal' => ['start_percentage' => 10, 'end_percentage' => 90],
'crop_vertical' => ['start_percentage' => 20, 'end_percentage' => 80],
'cropped_attachment_id' => $cropped->id,
]);
foreach ([AttachmentCrop::DESKTOP => $desktop, AttachmentCrop::MOBILE => $mobile] as $variant => $crop) {
$original->cropVariants()->create([
'variant' => $variant,
'crop_horizontal' => ['start_percentage' => 10, 'end_percentage' => 90],
'crop_vertical' => ['start_percentage' => 20, 'end_percentage' => 80],
'cropped_attachment_id' => $crop->id,
]);
}
$tenant->websiteExtras()->create([
'website_type_extra_id' => $heroDefinition->id,
'config' => ['background_image_id' => $original->id],
@@ -368,11 +382,9 @@ class BootstrapTenantControllerTest extends TestCase
->assertJsonMissingPath('data.extras.heroConfig.crop_horizontal')
->assertJsonMissingPath('data.extras.heroConfig.crop_vertical');
$backgroundImage = $response->json('data.extras.heroConfig.background_image_id');
$this->assertIsString($backgroundImage);
$this->assertStringContainsString('cropped.jpg', $backgroundImage);
$this->assertStringNotContainsString('original.jpg', $backgroundImage);
$response
->assertJsonPath('data.extras.heroConfig.background_image_id.desktop', fn (string $url): bool => str_contains($url, 'desktop.jpg'))
->assertJsonPath('data.extras.heroConfig.background_image_id.mobile', fn (string $url): bool => str_contains($url, 'mobile.jpg'));
}
public function test_it_returns_not_found_when_the_domain_does_not_exist(): void