Files
SkinbaseNova/tests/Feature/Artworks/M18B6ArtworkNavigationTest.php
T
klevze 437d943827 Prefetch artwork prev/next navigation off the critical path.
Move neighbor lookup into a dedicated service and let the viewer load adjacent artworks after first paint instead of blocking the detail request.
2026-08-29 12:25:49 +02:00

93 lines
3.0 KiB
PHP

<?php
use App\Models\Artwork;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
function m18b6PublishedArtwork(User $user, string $slug): Artwork
{
return Artwork::factory()->for($user)->create([
'slug' => $slug,
'published_at' => now()->subDay(),
'is_public' => true,
'is_approved' => true,
]);
}
it('returns the correct previous and next artwork for a middle item', function (): void {
$user = User::factory()->create();
$first = m18b6PublishedArtwork($user, 'first');
$middle = m18b6PublishedArtwork($user, 'middle');
$last = m18b6PublishedArtwork($user, 'last');
$this->getJson('/api/artworks/navigation/'.$middle->id)
->assertOk()
->assertJson([
'prev_id' => $first->id,
'next_id' => $last->id,
'prev_url' => url('/art/'.$first->id.'/first'),
'next_url' => url('/art/'.$last->id.'/last'),
'prev_slug' => 'first',
'next_slug' => 'last',
])
->assertJsonStructure([
'prev_preview' => ['id', 'title', 'slug', 'thumbs' => ['md', 'lg']],
'next_preview' => ['id', 'title', 'slug', 'thumbs' => ['md', 'lg']],
]);
});
it('wraps the first item to the last item', function (): void {
$user = User::factory()->create();
$first = m18b6PublishedArtwork($user, 'first');
$last = m18b6PublishedArtwork($user, 'last');
$this->getJson('/api/artworks/navigation/'.$first->id)
->assertOk()
->assertJsonPath('prev_id', $last->id)
->assertJsonPath('next_id', $last->id)
->assertJsonPath('prev_preview.id', $last->id)
->assertJsonPath('next_preview.id', $last->id);
});
it('wraps the last item to the first item', function (): void {
$user = User::factory()->create();
$first = m18b6PublishedArtwork($user, 'first');
$last = m18b6PublishedArtwork($user, 'last');
$this->getJson('/api/artworks/navigation/'.$last->id)
->assertOk()
->assertJsonPath('prev_id', $first->id)
->assertJsonPath('next_id', $first->id)
->assertJsonPath('prev_preview.id', $first->id)
->assertJsonPath('next_preview.id', $first->id);
});
it('returns the empty contract for a missing or hidden artwork', function (): void {
$empty = [
'prev_id' => null,
'next_id' => null,
'prev_url' => null,
'next_url' => null,
'prev_slug' => null,
'next_slug' => null,
'prev_preview' => null,
'next_preview' => null,
];
$this->getJson('/api/artworks/navigation/999999')
->assertOk()
->assertExactJson($empty);
$private = Artwork::factory()->private()->create();
$this->getJson('/api/artworks/navigation/'.$private->id)
->assertOk()
->assertExactJson($empty);
$this->actingAs(User::factory()->create())
->getJson('/api/artworks/navigation/'.$private->id)
->assertOk()
->assertExactJson($empty);
});