Files
alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiSearchIndexAndAutocompleteContractTest.php
T
2026-06-09 00:03:03 -04:00

52 lines
2.4 KiB
PHP

<?php
namespace Tests\Feature\Api\V1\FullSurface;
use Tests\Feature\Api\V1\FullSurface\Support\FullSurfaceE2EContractCase;
class ApiSearchIndexAndAutocompleteContractTest extends FullSurfaceE2EContractCase
{
public function test_search_autocomplete_and_lookup_routes_handle_empty_short_and_hostile_terms(): void
{
$routes = $this->apiRoutesContainingAny(['search', 'lookup', 'autocomplete', 'suggest', 'filter']);
$terms = ['', 'a', ' ', '%', "' OR '1'='1", '<script>alert(1)</script>', str_repeat('x', 2048)];
foreach ($routes as $route) {
$method = $this->primaryMethod($route);
if ($method !== 'GET') {
continue;
}
$uri = $route->uri();
foreach ($terms as $term) {
$response = $this->requestAs($this->actorFor($uri), 'GET', $uri.'?q='.urlencode($term).'&term='.urlencode($term).'&search='.urlencode($term));
$this->assertNoServerError($response, "GET $uri search term $term");
$this->assertControlled($response, 'GET', $uri);
$this->assertStringNotContainsStringIgnoringCase('SQLSTATE', $response->getContent(), $uri.' should not leak SQLSTATE from search.');
$this->assertStringNotContainsString('<script>alert(1)</script>', $response->getContent(), $uri.' should not reflect raw script search terms.');
}
}
}
public function test_cross_domain_search_does_not_bypass_role_scope(): void
{
$routes = $this->apiRoutesContainingAny(['search', 'lookup', 'autocomplete']);
foreach ($routes as $route) {
if ($this->primaryMethod($route) !== 'GET') {
continue;
}
$uri = $route->uri();
$query = '?q=*&scope=all&include=users,parents,students,finance,medical';
foreach (['parent' => $this->parent, 'teacher' => $this->teacher, 'student' => $this->studentUser] as $label => $actor) {
$response = $this->requestAs($actor, 'GET', $uri.$query);
$this->assertNoServerError($response, "$label GET $uri broad search");
$this->assertStatusIn($response, [200, 204, 302, 400, 401, 403, 404, 409, 419, 422], "$label GET $uri broad search");
$this->assertStringNotContainsStringIgnoringCase('remember_token', $response->getContent(), "$uri broad search must not leak auth internals.");
}
}
}
}