Move neighbor lookup into a dedicated service and let the viewer load adjacent artworks after first paint instead of blocking the detail request.
93 lines
3.0 KiB
PHP
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);
|
|
});
|