From 6115362c07536d108f0bb1efb311c2aea17e3825 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Sat, 11 Jul 2026 09:29:39 -0300 Subject: [PATCH] Read Pinterest pin alt text from the image, not per-platform meta --- app/Services/Social/PinterestPublisher.php | 6 +- .../Social/PinterestPublisherTest.php | 97 +++++++++++++++++++ 2 files changed, 101 insertions(+), 2 deletions(-) diff --git a/app/Services/Social/PinterestPublisher.php b/app/Services/Social/PinterestPublisher.php index b56f0b97..8e7b087f 100644 --- a/app/Services/Social/PinterestPublisher.php +++ b/app/Services/Social/PinterestPublisher.php @@ -119,8 +119,10 @@ private function publishImagePin(PostPlatform $postPlatform, ?string $content): $payload['link'] = data_get($postPlatform->meta, 'link'); } - if (! empty(data_get($postPlatform->meta, 'alt_text'))) { - $payload['alt_text'] = substr(data_get($postPlatform->meta, 'alt_text'), 0, 500); + $alt = $postPlatform->post->mediaItems->first(fn ($m) => $m->isImage())?->altText(); + + if ($alt !== null) { + $payload['alt_text'] = mb_substr($alt, 0, Platform::Pinterest->altTextMaxLength()); } $response = $this->socialHttp()->withToken($account->access_token) diff --git a/tests/Feature/Services/Social/PinterestPublisherTest.php b/tests/Feature/Services/Social/PinterestPublisherTest.php index 7f727115..c39e1ffd 100644 --- a/tests/Feature/Services/Social/PinterestPublisherTest.php +++ b/tests/Feature/Services/Social/PinterestPublisherTest.php @@ -405,6 +405,103 @@ }); }); +test('pinterest publisher sends alt text from image meta capped to platform max', function () { + $longAlt = str_repeat('x', 600); + + $this->post->update([ + 'media' => [ + [ + 'id' => 'test-media-id', + 'path' => 'media/2026-01/image.jpg', + 'url' => 'https://example.com/media/2026-01/image.jpg', + 'mime_type' => 'image/jpeg', + 'original_filename' => 'image.jpg', + 'meta' => ['alt_text' => $longAlt], + ], + ], + ]); + + Http::fake([ + '*/v5/pins' => Http::response([ + 'id' => 'pin_123456', + ], 200), + '*' => Http::response('fake-image-content', 200), + ]); + + $this->publisher->publish($this->postPlatform); + + $expectedAlt = mb_substr($longAlt, 0, Platform::Pinterest->altTextMaxLength()); + + Http::assertSent(function ($request) use ($expectedAlt) { + return str_contains($request->url(), '/v5/pins') + && data_get($request->data(), 'alt_text') === $expectedAlt + && strlen($expectedAlt) === Platform::Pinterest->altTextMaxLength(); + }); +}); + +test('pinterest publisher omits alt_text when image has no alt text set', function () { + $this->post->update([ + 'media' => [ + [ + 'id' => 'test-media-id', + 'path' => 'media/2026-01/image.jpg', + 'url' => 'https://example.com/media/2026-01/image.jpg', + 'mime_type' => 'image/jpeg', + 'original_filename' => 'image.jpg', + ], + ], + ]); + + Http::fake([ + '*/v5/pins' => Http::response([ + 'id' => 'pin_123456', + ], 200), + '*' => Http::response('fake-image-content', 200), + ]); + + $this->publisher->publish($this->postPlatform); + + Http::assertSent(function ($request) { + return str_contains($request->url(), '/v5/pins') + && ! array_key_exists('alt_text', $request->data()); + }); +}); + +test('pinterest publisher ignores postPlatform meta alt_text and only reads image alt', function () { + $this->postPlatform->update([ + 'meta' => [ + 'board_id' => 'board_123', + 'alt_text' => 'legacy per-platform alt text that should be ignored', + ], + ]); + + $this->post->update([ + 'media' => [ + [ + 'id' => 'test-media-id', + 'path' => 'media/2026-01/image.jpg', + 'url' => 'https://example.com/media/2026-01/image.jpg', + 'mime_type' => 'image/jpeg', + 'original_filename' => 'image.jpg', + ], + ], + ]); + + Http::fake([ + '*/v5/pins' => Http::response([ + 'id' => 'pin_123456', + ], 200), + '*' => Http::response('fake-image-content', 200), + ]); + + $this->publisher->publish($this->postPlatform); + + Http::assertSent(function ($request) { + return str_contains($request->url(), '/v5/pins') + && ! array_key_exists('alt_text', $request->data()); + }); +}); + test('pinterest publisher can get boards', function () { Http::fake([ '*/v5/boards*' => Http::response([