From 521cfca72438c0c4c4ef3e05fc9530a768e06d18 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Sat, 11 Jul 2026 08:46:09 -0300 Subject: [PATCH] Validate per-image media alt_text (max 2000) in PostMediaRules --- app/Support/PostMediaRules.php | 1 + .../PostMediaAltTextValidationTest.php | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 tests/Feature/PostMediaAltTextValidationTest.php diff --git a/app/Support/PostMediaRules.php b/app/Support/PostMediaRules.php index e57c72dd..fd177f7f 100644 --- a/app/Support/PostMediaRules.php +++ b/app/Support/PostMediaRules.php @@ -35,6 +35,7 @@ public static function rules(bool $hosted): array 'media.*.original_filename' => ['sometimes', 'nullable', 'string', 'max:500'], 'media.*.size' => ['sometimes', 'nullable', 'integer'], 'media.*.meta' => ['sometimes', 'nullable', 'array'], + 'media.*.meta.alt_text' => ['sometimes', 'nullable', 'string', 'max:2000'], 'media.*.source' => ['sometimes', 'nullable', 'string', Rule::in(array_column(Source::cases(), 'value'))], 'media.*.source_meta' => ['sometimes', 'nullable', 'array'], ]; diff --git a/tests/Feature/PostMediaAltTextValidationTest.php b/tests/Feature/PostMediaAltTextValidationTest.php new file mode 100644 index 00000000..3529a62e --- /dev/null +++ b/tests/Feature/PostMediaAltTextValidationTest.php @@ -0,0 +1,55 @@ +create(); + $workspace = Workspace::factory()->create(['user_id' => $user->id]); + $workspace->members()->attach($user->id, ['role' => Role::Member->value]); + $user->update(['current_workspace_id' => $workspace->id]); + + $post = Post::factory()->create([ + 'workspace_id' => $workspace->id, + 'user_id' => $user->id, + ]); + + $response = $this->actingAs($user)->put(route('app.posts.update', $post), [ + 'status' => 'draft', + 'content' => 'hi', + 'media' => [[ + 'id' => 'm1', 'path' => 'uploads/x.jpg', 'url' => 'https://cdn.test/x.jpg', + 'meta' => ['alt_text' => 'a golden retriever on a beach'], + ]], + ]); + + $response->assertSessionDoesntHaveErrors(); + expect($post->fresh()->media[0]['meta']['alt_text'])->toBe('a golden retriever on a beach'); +}); + +test('media alt_text over 2000 chars is rejected', function () { + $user = User::factory()->create(); + $workspace = Workspace::factory()->create(['user_id' => $user->id]); + $workspace->members()->attach($user->id, ['role' => Role::Member->value]); + $user->update(['current_workspace_id' => $workspace->id]); + + $post = Post::factory()->create([ + 'workspace_id' => $workspace->id, + 'user_id' => $user->id, + ]); + + $response = $this->actingAs($user)->put(route('app.posts.update', $post), [ + 'status' => 'draft', + 'content' => 'hi', + 'media' => [[ + 'id' => 'm1', 'path' => 'uploads/x.jpg', 'url' => 'https://cdn.test/x.jpg', + 'meta' => ['alt_text' => str_repeat('a', 2001)], + ]], + ]); + + $response->assertSessionHasErrors('media.0.meta.alt_text'); +});