Files
SkinbaseNova/tests/Feature/Discovery/SimilarArtworksApiTest.php
2026-02-27 09:46:51 +01:00

118 lines
3.7 KiB
PHP

<?php
declare(strict_types=1);
use App\Models\Artwork;
use App\Models\User;
beforeEach(function () {
// Use null Scout driver so no Meilisearch calls are made
config(['scout.driver' => 'null']);
});
// ── 404 cases ─────────────────────────────────────────────────────────────────
it('returns 404 for a non-existent artwork id', function () {
$this->getJson('/api/art/99999/similar')
->assertStatus(404)
->assertJsonPath('error', 'Artwork not found');
});
it('returns 404 for a private artwork', function () {
$artwork = Artwork::factory()->create(['is_public' => false]);
$this->getJson("/api/art/{$artwork->id}/similar")
->assertStatus(404);
});
it('returns 404 for an unapproved artwork', function () {
$artwork = Artwork::factory()->create(['is_approved' => false]);
$this->getJson("/api/art/{$artwork->id}/similar")
->assertStatus(404);
});
it('returns 404 for an unpublished artwork', function () {
$artwork = Artwork::factory()->unpublished()->create();
$this->getJson("/api/art/{$artwork->id}/similar")
->assertStatus(404);
});
// ── Success cases ─────────────────────────────────────────────────────────────
it('returns a data array for a valid public artwork', function () {
$artwork = Artwork::factory()->create([
'is_public' => true,
'is_approved' => true,
'published_at' => now()->subDay(),
]);
$response = $this->getJson("/api/art/{$artwork->id}/similar");
$response->assertStatus(200);
$response->assertJsonStructure(['data']);
expect($response->json('data'))->toBeArray();
});
it('the source artwork id is never present in results', function () {
$artwork = Artwork::factory()->create([
'is_public' => true,
'is_approved' => true,
'published_at' => now()->subDay(),
]);
$ids = collect($this->getJson("/api/art/{$artwork->id}/similar")->json('data'))
->pluck('id')
->all();
expect($ids)->not->toContain($artwork->id);
});
it('result count does not exceed 12', function () {
$artwork = Artwork::factory()->create([
'is_public' => true,
'is_approved' => true,
'published_at' => now()->subDay(),
]);
$count = count($this->getJson("/api/art/{$artwork->id}/similar")->json('data'));
// null Scout driver returns 0 results; max is 12
expect($count <= 12)->toBeTrue();
});
it('results do not include artworks by the same creator', function () {
$creatorA = User::factory()->create();
$creatorB = User::factory()->create();
$source = Artwork::factory()->create([
'user_id' => $creatorA->id,
'is_public' => true,
'is_approved' => true,
'published_at' => now()->subDay(),
]);
// A matching artwork from a different creator
Artwork::factory()->create([
'user_id' => $creatorB->id,
'is_public' => true,
'is_approved' => true,
'published_at' => now()->subDay(),
]);
$response = $this->getJson("/api/art/{$source->id}/similar");
$response->assertStatus(200);
$items = $response->json('data');
// With null Scout driver the search returns 0 items; if items are present
// none should belong to the source artwork's creator.
foreach ($items as $item) {
expect($item)->toHaveKeys(['id', 'title', 'slug', 'thumb', 'url', 'author_id']);
expect($item['author_id'])->not->toBe($creatorA->id);
}
expect(true)->toBeTrue(); // always at least one assertion
});