Wire admin studio SSR and search infrastructure
This commit is contained in:
@@ -19,6 +19,7 @@ beforeEach(function (): void {
|
||||
config()->set('vision.vector_gateway.base_url', 'https://vision.klevze.net');
|
||||
config()->set('vision.vector_gateway.api_key', 'test-key');
|
||||
config()->set('vision.vector_gateway.search_endpoint', '/vectors/search');
|
||||
config()->set('vision.vector_gateway.search_file_endpoint', '/vectors/search/file');
|
||||
config()->set('cdn.files_url', 'https://files.skinbase.org');
|
||||
config()->set('app.url', 'https://skinbase.test');
|
||||
Storage::fake('public');
|
||||
@@ -44,7 +45,8 @@ it('returns AI similar artworks for a public artwork', function (): void {
|
||||
]);
|
||||
|
||||
Http::fake([
|
||||
'https://vision.klevze.net/vectors/search' => Http::response([
|
||||
'https://files.skinbase.org/*' => Http::response('image-bytes', 200, ['Content-Type' => 'image/webp']),
|
||||
'https://vision.klevze.net/vectors/search/file' => Http::response([
|
||||
'results' => [
|
||||
['id' => $source->id, 'score' => 1.0],
|
||||
['id' => $match->id, 'score' => 0.91234],
|
||||
@@ -61,6 +63,43 @@ it('returns AI similar artworks for a public artwork', function (): void {
|
||||
->assertJsonCount(1, 'data');
|
||||
});
|
||||
|
||||
it('falls back to URL search when the file vector endpoint fails for similar-ai', function (): void {
|
||||
$source = Artwork::factory()->create([
|
||||
'title' => 'Fallback source artwork',
|
||||
'hash' => 'ffeeddccbbaa',
|
||||
'thumb_ext' => 'webp',
|
||||
'is_public' => true,
|
||||
'is_approved' => true,
|
||||
'published_at' => now()->subHour(),
|
||||
]);
|
||||
|
||||
$match = Artwork::factory()->create([
|
||||
'title' => 'Fallback match',
|
||||
'hash' => '998877665544',
|
||||
'thumb_ext' => 'webp',
|
||||
'is_public' => true,
|
||||
'is_approved' => true,
|
||||
'published_at' => now()->subHour(),
|
||||
]);
|
||||
|
||||
Http::fake([
|
||||
'https://files.skinbase.org/*' => Http::response('image-bytes', 200, ['Content-Type' => 'image/webp']),
|
||||
'https://vision.klevze.net/vectors/search/file' => Http::response(['error' => 'missing endpoint'], 404),
|
||||
'https://vision.klevze.net/vectors/search' => Http::response([
|
||||
'results' => [
|
||||
['id' => $source->id, 'score' => 1.0],
|
||||
['id' => $match->id, 'score' => 0.90123],
|
||||
],
|
||||
], 200),
|
||||
]);
|
||||
|
||||
getJson('/api/art/' . $source->id . '/similar-ai')
|
||||
->assertOk()
|
||||
->assertJsonPath('data.0.id', $match->id)
|
||||
->assertJsonPath('meta.artwork_id', $source->id)
|
||||
->assertJsonCount(1, 'data');
|
||||
});
|
||||
|
||||
it('returns 404 for missing similar-ai source artwork', function (): void {
|
||||
getJson('/api/art/999999/similar-ai')
|
||||
->assertStatus(404)
|
||||
@@ -79,7 +118,7 @@ it('searches by uploaded image through the vector gateway', function (): void {
|
||||
]);
|
||||
|
||||
Http::fake([
|
||||
'https://vision.klevze.net/vectors/search' => Http::response([
|
||||
'https://vision.klevze.net/vectors/search/file' => Http::response([
|
||||
'results' => [
|
||||
['id' => $match->id, 'score' => 0.88765],
|
||||
],
|
||||
@@ -99,12 +138,7 @@ it('searches by uploaded image through the vector gateway', function (): void {
|
||||
->assertJsonPath('meta.limit', 12);
|
||||
|
||||
Http::assertSent(function ($request): bool {
|
||||
$payload = json_decode($request->body(), true);
|
||||
|
||||
return $request->url() === 'https://vision.klevze.net/vectors/search'
|
||||
&& $request->hasHeader('X-API-Key', 'test-key')
|
||||
&& is_array($payload)
|
||||
&& str_contains((string) ($payload['url'] ?? ''), '/storage/ai-search/tmp/')
|
||||
&& ($payload['limit'] ?? null) === 12;
|
||||
return $request->url() === 'https://vision.klevze.net/vectors/search/file'
|
||||
&& $request->hasHeader('X-API-Key', 'test-key');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user