61 خطوط
2.3 KiB
PHP
61 خطوط
2.3 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\AI;
|
|
|
|
use App\Models\User;
|
|
use App\Modules\AI\Http\AiChatController;
|
|
use App\Modules\Identity\Domain\Enums\UserRole;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Route;
|
|
use Laravel\Sanctum\Sanctum;
|
|
use Tests\TestCase;
|
|
|
|
class AiSecurityTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
public function test_versioned_routes_do_not_contain_a_duplicated_api_prefix(): void
|
|
{
|
|
$uris = collect(Route::getRoutes())->map(fn ($route) => $route->uri());
|
|
|
|
$this->assertFalse($uris->contains(fn (string $uri) => str_starts_with($uri, 'api/v1/v1/')));
|
|
$this->assertSame(1, $uris->filter(fn (string $uri) => $uri === 'api/v1/health')->count());
|
|
$this->assertSame(1, $uris->filter(fn (string $uri) => $uri === 'api/v1/certificates/verify/{code}')->count());
|
|
$this->assertTrue($uris->contains('api/v1/ai/chat'));
|
|
}
|
|
|
|
public function test_ai_chat_route_uses_the_modular_ai_controller(): void
|
|
{
|
|
$route = collect(Route::getRoutes())->first(fn ($route) => $route->uri() === 'api/v1/ai/chat');
|
|
|
|
$this->assertNotNull($route);
|
|
$this->assertSame(AiChatController::class.'@chat', $route->getActionName());
|
|
}
|
|
|
|
public function test_ai_chat_requires_authentication_and_authorization(): void
|
|
{
|
|
$this->postJson('/api/v1/ai/chat', ['prompt' => 'test'])->assertUnauthorized();
|
|
|
|
$manager = User::factory()->create(['role' => UserRole::Manager]);
|
|
Sanctum::actingAs($manager);
|
|
$this->postJson('/api/v1/ai/chat', ['prompt' => 'test'])->assertForbidden();
|
|
|
|
$designer = User::factory()->create(['role' => UserRole::CourseDesigner]);
|
|
Sanctum::actingAs($designer);
|
|
$this->postJson('/api/v1/ai/chat', ['prompt' => 'test'])
|
|
->assertOk()
|
|
->assertJsonPath('data.answer', 'test');
|
|
}
|
|
|
|
public function test_expensive_ai_chat_is_rate_limited_per_authenticated_user(): void
|
|
{
|
|
Sanctum::actingAs(User::factory()->create(['role' => UserRole::CourseDesigner]));
|
|
|
|
foreach (range(1, 10) as $attempt) {
|
|
$this->postJson('/api/v1/ai/chat', ['prompt' => "test {$attempt}"])->assertOk();
|
|
}
|
|
|
|
$this->postJson('/api/v1/ai/chat', ['prompt' => 'limited'])->assertTooManyRequests();
|
|
}
|
|
}
|