diff --git a/app/Enums/SocialAccount/Platform.php b/app/Enums/SocialAccount/Platform.php index afcd02f3..25f2b743 100644 --- a/app/Enums/SocialAccount/Platform.php +++ b/app/Enums/SocialAccount/Platform.php @@ -127,6 +127,33 @@ public function maxImages(): int }; } + /** + * Character cap the platform's API accepts for image alt text (accessibility + * description), or null when the platform has no alt-text field. Facebook and + * Threads document no limit, so a defensive 1000 is used. Single source of + * truth — publishers truncate to this value, never a literal. + */ + public function altTextMaxLength(): ?int + { + return match ($this) { + self::Bluesky => 2000, + self::X => 1000, + self::Mastodon => 1500, + self::LinkedIn, self::LinkedInPage => 4086, + self::Facebook => 1000, + self::Instagram, self::InstagramFacebook => 1000, + self::Threads => 1000, + self::Pinterest => 500, + self::Discord => 1024, + self::TikTok, self::YouTube, self::Telegram => null, + }; + } + + public function supportsAltText(): bool + { + return $this->altTextMaxLength() !== null; + } + /** * Hard cap (in characters) the platform's API will accept. Going over this * means the post can't be published. Values are the documented API maxes: diff --git a/tests/Unit/PlatformAltTextTest.php b/tests/Unit/PlatformAltTextTest.php new file mode 100644 index 00000000..c5777903 --- /dev/null +++ b/tests/Unit/PlatformAltTextTest.php @@ -0,0 +1,28 @@ +altTextMaxLength())->toBe(2000) + ->and(Platform::X->altTextMaxLength())->toBe(1000) + ->and(Platform::Mastodon->altTextMaxLength())->toBe(1500) + ->and(Platform::LinkedIn->altTextMaxLength())->toBe(4086) + ->and(Platform::Instagram->altTextMaxLength())->toBe(1000) + ->and(Platform::Pinterest->altTextMaxLength())->toBe(500) + ->and(Platform::Discord->altTextMaxLength())->toBe(1024) + ->and(Platform::Facebook->altTextMaxLength())->toBe(1000) + ->and(Platform::Threads->altTextMaxLength())->toBe(1000); +}); + +test('altTextMaxLength is null for platforms without alt-text support', function () { + expect(Platform::TikTok->altTextMaxLength())->toBeNull() + ->and(Platform::Telegram->altTextMaxLength())->toBeNull() + ->and(Platform::YouTube->altTextMaxLength())->toBeNull(); +}); + +test('supportsAltText mirrors altTextMaxLength', function () { + expect(Platform::Bluesky->supportsAltText())->toBeTrue() + ->and(Platform::TikTok->supportsAltText())->toBeFalse(); +});