From 5be0abfae330a38924ddd3f041914ddcd0476296 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Fri, 5 Jun 2026 18:45:48 -0300 Subject: [PATCH] Cover carousel/multi crop per-ratio and FB multi abort-on-crop-failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Instagram carousel and Facebook multi-image crop tests now run as datasets over 1:1 and 4:5, asserting each image's real cropped ratio (previously 1:1 only) — proving the chosen ratio flows through the multi-image paths. - Add a Facebook test that a multi-image post aborts entirely (throws FacebookPublishException) when one image can't be downloaded for cropping. --- .../Services/Social/FacebookPublisherTest.php | 31 +++++++++++++++++-- .../Social/InstagramPublisherTest.php | 11 ++++--- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/tests/Feature/Services/Social/FacebookPublisherTest.php b/tests/Feature/Services/Social/FacebookPublisherTest.php index 79b9c6ac..a5e8e37e 100644 --- a/tests/Feature/Services/Social/FacebookPublisherTest.php +++ b/tests/Feature/Services/Social/FacebookPublisherTest.php @@ -684,10 +684,10 @@ function facebookJpegBytes(int $width = 1200, int $height = 800): string '16:9' => ['16:9', 16 / 9], ]); -test('facebook multi image post applies the aspect ratio crop to every image', function () { +test('facebook multi image post applies the chosen aspect ratio crop to every image', function (string $aspectRatio, float $expected) { Storage::fake(); - $this->postPlatform->update(['meta' => ['aspect_ratio' => '1:1']]); + $this->postPlatform->update(['meta' => ['aspect_ratio' => $aspectRatio]]); $this->post->update([ 'media' => [ ['id' => 'm1', 'path' => 'media/a.jpg', 'url' => 'https://example.com/media/a.jpg', 'mime_type' => 'image/jpeg', 'original_filename' => 'a.jpg'], @@ -714,12 +714,37 @@ function facebookJpegBytes(int $width = 1200, int $height = 800): string $tempFile = tempnam(sys_get_temp_dir(), 'verify_'); file_put_contents($tempFile, Storage::get($cropPath)); $image = $manager->decodePath($tempFile); - expect($image->width())->toBe($image->height()); + expect(abs($image->width() / $image->height() - $expected))->toBeLessThan(0.01); @unlink($tempFile); } Http::assertSent(fn ($request) => str_contains($request->url(), '/page_123/photos') && str_contains($request['url'] ?? '', 'social-crops/')); +})->with([ + '1:1' => ['1:1', 1.0], + '4:5' => ['4:5', 4 / 5], +]); + +test('facebook multi image post aborts entirely when one image cannot be downloaded for cropping', function () { + Storage::fake(); + + $this->postPlatform->update(['meta' => ['aspect_ratio' => '4:5']]); + $this->post->update([ + 'media' => [ + ['id' => 'm1', 'path' => 'media/a.jpg', 'url' => 'https://example.com/media/a.jpg', 'mime_type' => 'image/jpeg', 'original_filename' => 'a.jpg'], + ['id' => 'm2', 'path' => 'media/b.jpg', 'url' => 'https://example.com/media/b.jpg', 'mime_type' => 'image/jpeg', 'original_filename' => 'b.jpg'], + ], + ]); + + Http::fake([ + 'https://example.com/media/a.jpg' => Http::response('', 404), + 'https://example.com/media/b.jpg' => Http::response(facebookJpegBytes(900, 1600), 200), + '*/page_123/photos' => Http::response(['id' => 'up'], 200), + '*/page_123/feed' => Http::response(['id' => 'post_1'], 200), + ]); + + expect(fn () => $this->publisher->publish($this->postPlatform)) + ->toThrow(FacebookPublishException::class, 'Failed to download image for cropping'); }); test('facebook image post throws when the source image cannot be downloaded for cropping', function () { diff --git a/tests/Feature/Services/Social/InstagramPublisherTest.php b/tests/Feature/Services/Social/InstagramPublisherTest.php index c32db466..30ff943b 100644 --- a/tests/Feature/Services/Social/InstagramPublisherTest.php +++ b/tests/Feature/Services/Social/InstagramPublisherTest.php @@ -869,10 +869,10 @@ function fakeJpegBytes(int $width = 1200, int $height = 800): string }); }); -test('carousel applies aspect ratio crop to every image', function () { +test('carousel applies the chosen aspect ratio crop to every image', function (string $aspectRatio, float $expected) { Storage::fake(); - $this->postPlatform->update(['meta' => ['aspect_ratio' => '1:1']]); + $this->postPlatform->update(['meta' => ['aspect_ratio' => $aspectRatio]]); $this->post->update([ 'media' => [ @@ -905,7 +905,10 @@ function fakeJpegBytes(int $width = 1200, int $height = 800): string $tempFile = tempnam(sys_get_temp_dir(), 'verify_'); file_put_contents($tempFile, Storage::get($cropPath)); $image = $manager->decodePath($tempFile); - expect($image->width())->toBe($image->height()); + expect(abs($image->width() / $image->height() - $expected))->toBeLessThan(0.01); @unlink($tempFile); } -}); +})->with([ + '1:1' => ['1:1', 1.0], + '4:5' => ['4:5', 4 / 5], +]);