messages implemented

This commit is contained in:
2026-02-26 21:12:32 +01:00
parent d0aefc5ddc
commit 15b7b77d20
168 changed files with 14728 additions and 6786 deletions

View File

@@ -0,0 +1,156 @@
<?php
use App\Enums\ReactionType;
use App\Models\Artwork;
use App\Models\ArtworkComment;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
// ── Comment CRUD ──────────────────────────────────────────────────────────────
test('authenticated user can post a comment', function () {
$user = User::factory()->create();
$artwork = Artwork::factory()->create();
$this->actingAs($user)
->postJson("/api/artworks/{$artwork->id}/comments", [
'content' => 'Great work! Really love the **colours**.',
])
->assertStatus(201)
->assertJsonPath('data.user.id', $user->id)
->assertJsonStructure(['data' => ['id', 'raw_content', 'rendered_content', 'user']]);
});
test('guest cannot post a comment', function () {
$artwork = Artwork::factory()->create();
$this->postJson("/api/artworks/{$artwork->id}/comments", ['content' => 'Nice!'])
->assertStatus(401);
});
test('comment with raw HTML is rejected via validation', function () {
$user = User::factory()->create();
$artwork = Artwork::factory()->create();
$this->actingAs($user)
->postJson("/api/artworks/{$artwork->id}/comments", [
'content' => '<script>alert("xss")</script>',
])
->assertStatus(422);
});
test('user can view comments on public artwork', function () {
$artwork = Artwork::factory()->create();
$comment = ArtworkComment::factory()->create(['artwork_id' => $artwork->id]);
$this->getJson("/api/artworks/{$artwork->id}/comments")
->assertStatus(200)
->assertJsonStructure(['data', 'meta'])
->assertJsonCount(1, 'data');
});
// ── Reactions ─────────────────────────────────────────────────────────────────
test('authenticated user can add an artwork reaction', function () {
$user = User::factory()->create();
$artwork = Artwork::factory()->create();
$this->actingAs($user)
->postJson("/api/artworks/{$artwork->id}/reactions", [
'reaction' => ReactionType::Heart->value,
])
->assertStatus(200)
->assertJsonPath('reaction', ReactionType::Heart->value)
->assertJsonPath('active', true);
});
test('reaction is toggled off when posted twice', function () {
$user = User::factory()->create();
$artwork = Artwork::factory()->create();
// First toggle — on
$this->actingAs($user)
->postJson("/api/artworks/{$artwork->id}/reactions", [
'reaction' => ReactionType::ThumbsUp->value,
])
->assertJsonPath('active', true);
// Second toggle — off
$this->actingAs($user)
->postJson("/api/artworks/{$artwork->id}/reactions", [
'reaction' => ReactionType::ThumbsUp->value,
])
->assertJsonPath('active', false);
});
test('guest cannot add a reaction', function () {
$artwork = Artwork::factory()->create();
$this->postJson("/api/artworks/{$artwork->id}/reactions", [
'reaction' => ReactionType::Fire->value,
])->assertStatus(401);
});
test('invalid reaction slug is rejected', function () {
$user = User::factory()->create();
$artwork = Artwork::factory()->create();
$this->actingAs($user)
->postJson("/api/artworks/{$artwork->id}/reactions", [
'reaction' => 'not_valid_slug',
])
->assertStatus(422);
});
test('reaction totals are returned for public artworks', function () {
$artwork = Artwork::factory()->create();
$user = User::factory()->create();
// Insert a reaction directly
\Illuminate\Support\Facades\DB::table('artwork_reactions')->insert([
'artwork_id' => $artwork->id,
'user_id' => $user->id,
'reaction' => ReactionType::Clap->value,
'created_at' => now(),
]);
$this->getJson("/api/artworks/{$artwork->id}/reactions")
->assertStatus(200)
->assertJsonPath('totals.' . ReactionType::Clap->value . '.count', 1)
->assertJsonPath('totals.' . ReactionType::Clap->value . '.emoji', '👏');
});
test('user can react to a comment', function () {
$user = User::factory()->create();
$artwork = Artwork::factory()->create();
$comment = ArtworkComment::factory()->create(['artwork_id' => $artwork->id]);
$this->actingAs($user)
->postJson("/api/comments/{$comment->id}/reactions", [
'reaction' => ReactionType::Laugh->value,
])
->assertStatus(200)
->assertJsonPath('active', true)
->assertJsonPath('entity_type', 'comment');
});
test('reaction uniqueness per user per slug', function () {
$user = User::factory()->create();
$artwork = Artwork::factory()->create();
$slug = ReactionType::Wow->value;
// Toggle on
$this->actingAs($user)->postJson("/api/artworks/{$artwork->id}/reactions", ['reaction' => $slug]);
// DB should have exactly 1 row
$this->assertDatabaseCount('artwork_reactions', 1);
// Toggle off
$this->actingAs($user)->postJson("/api/artworks/{$artwork->id}/reactions", ['reaction' => $slug]);
// DB should have 0 rows
$this->assertDatabaseCount('artwork_reactions', 0);
});