Search the public site through the API
Full-text on Postgres, stemmed in the language searched; word matching elsewhere. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -117,6 +117,7 @@ class PublicApiContractTest extends TestCase
|
||||
'testimonials' => ['path' => '/public/v1/testimonials', 'detail' => false],
|
||||
'talks' => ['path' => '/public/v1/talks', 'detail' => false],
|
||||
'technologies' => ['path' => '/public/v1/technologies', 'detail' => false],
|
||||
'search' => ['path' => '/public/v1/search', 'detail' => true],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -133,6 +134,7 @@ class PublicApiContractTest extends TestCase
|
||||
'/public/v1/members/{slug}' => '/public/v1/members/ada-lovelace',
|
||||
'/public/v1/calls/{slug}' => '/public/v1/calls/backend',
|
||||
'/public/v1/services/{slug}' => '/public/v1/services/desarrollo',
|
||||
'/public/v1/search' => '/public/v1/search?lang=es&q=proyecto',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
80
tests/Feature/Api/SearchApiTest.php
Normal file
80
tests/Feature/Api/SearchApiTest.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Feature\Api;
|
||||
|
||||
use App\Models\Member;
|
||||
use App\Models\Page;
|
||||
use App\Models\Project;
|
||||
use App\Models\Technology;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* GET /public/v1/search — run here on SQLite, so through the word-matching
|
||||
* fallback; the shape and the rules about what is visible are the same.
|
||||
*/
|
||||
class SearchApiTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
#[Test]
|
||||
public function it_finds_published_content_in_the_language_asked(): void
|
||||
{
|
||||
Project::factory()->published()->create([
|
||||
'title' => ['es' => 'Catálogo abierto', 'en' => 'Open catalogue'],
|
||||
'slug' => ['es' => 'catalogo', 'en' => 'catalogue'],
|
||||
'tagline' => ['es' => 'Una herramienta para bibliotecas.', 'en' => 'A tool for libraries.'],
|
||||
]);
|
||||
Page::factory()->published()->create([
|
||||
'title' => ['es' => 'Bibliotecas libres'],
|
||||
'slug' => ['es' => 'bibliotecas'],
|
||||
'body' => ['es' => '<p>Sobre <strong>bibliotecas</strong>.</p>'],
|
||||
]);
|
||||
|
||||
$response = $this->getJson('/api/public/v1/search?lang=es&q=bibliotecas')
|
||||
->assertOk()
|
||||
->assertJsonCount(2, 'data')
|
||||
->assertJsonPath('meta.count', 2);
|
||||
|
||||
// The title match first.
|
||||
$response->assertJsonPath('data.0.type', 'page')
|
||||
->assertJsonPath('data.0.path', '/bibliotecas');
|
||||
|
||||
$this->getJson('/api/public/v1/search?q=libraries&lang=en')
|
||||
->assertJsonCount(1, 'data')
|
||||
->assertJsonPath('data.0.title', 'Open catalogue')
|
||||
->assertJsonPath('data.0.path', '/en/projects/catalogue');
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function drafts_and_private_people_are_not_found(): void
|
||||
{
|
||||
Page::factory()->draft()->create(['title' => ['es' => 'Borrador secreto'], 'slug' => ['es' => 'borrador']]);
|
||||
Member::factory()->create(['name' => 'Secreto Oculto', 'slug' => 'oculto', 'is_public' => false]);
|
||||
Technology::factory()->create(['name' => 'Secretlang']);
|
||||
|
||||
$this->getJson('/api/public/v1/search?lang=es&q=secret')->assertOk()->assertJsonCount(0, 'data');
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function every_word_has_to_match_and_types_can_be_narrowed(): void
|
||||
{
|
||||
Project::factory()->published()->create(['title' => ['es' => 'Radar técnico'], 'slug' => ['es' => 'radar']]);
|
||||
Page::factory()->published()->create(['title' => ['es' => 'Radar de tecnologías'], 'slug' => ['es' => 'radar-pagina']]);
|
||||
|
||||
$this->getJson('/api/public/v1/search?lang=es&q=radar+técnico')->assertJsonCount(1, 'data');
|
||||
$this->getJson('/api/public/v1/search?lang=es&q=radar&type[]=page')
|
||||
->assertJsonCount(1, 'data')
|
||||
->assertJsonPath('data.0.type', 'page');
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function a_query_is_required(): void
|
||||
{
|
||||
$this->getJson('/api/public/v1/search')->assertUnprocessable()->assertJsonValidationErrors('q');
|
||||
$this->getJson('/api/public/v1/search?q=a')->assertUnprocessable();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user