main: 用户管理和会话功能初始实现

- 添加用户管理功能的测试,包括创建、更新、停用、激活用户及用户登录 JWT 测试
- 提供用户管理相关的请求验证类与控制器
- 引入 CORS 配置信息,支持跨域请求
- 添加数据库播种器以便创建根用户
- 配置 API 默认使用 JWT 认证
- 添加聊天会话和消息的模型、迁移文件及关联功能
This commit is contained in:
2025-12-14 17:49:08 +08:00
parent e28318b4ec
commit c6d6534b63
36 changed files with 2119 additions and 16 deletions

View File

@@ -0,0 +1,108 @@
<?php
namespace Tests\Feature;
use App\Enums\ChatSessionStatus;
use App\Models\User;
use App\Services\ChatService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use PHPOpenSourceSaver\JWTAuth\Facades\JWTAuth;
use Tests\TestCase;
class ChatSessionTest extends TestCase
{
use RefreshDatabase;
private function authHeader(User $user): array
{
return ['Authorization' => 'Bearer '.JWTAuth::fromUser($user)];
}
public function test_append_messages_sequential_seq_and_last_seq(): void
{
$service = app(ChatService::class);
$session = $service->createSession('Test Session');
$messages = collect(range(1, 20))->map(function ($i) use ($service, $session) {
return $service->appendMessage([
'session_id' => $session->session_id,
'role' => 'USER',
'type' => 'user.prompt',
'content' => 'msg '.$i,
]);
});
$seqs = $messages->pluck('seq')->all();
$this->assertEquals(range(1, 20), $seqs);
$session->refresh();
$this->assertEquals(20, $session->last_seq);
}
public function test_dedupe_returns_existing_message(): void
{
$service = app(ChatService::class);
$session = $service->createSession('Test Session');
$first = $service->appendMessage([
'session_id' => $session->session_id,
'role' => 'USER',
'type' => 'user.prompt',
'content' => 'hello',
'dedupe_key' => 'k1',
]);
$second = $service->appendMessage([
'session_id' => $session->session_id,
'role' => 'USER',
'type' => 'user.prompt',
'content' => 'hello again',
'dedupe_key' => 'k1',
]);
$this->assertEquals($first->message_id, $second->message_id);
$this->assertEquals($first->seq, $second->seq);
$this->assertCount(1, $session->messages()->get());
}
public function test_closed_session_blocks_append_except_whitelisted(): void
{
$service = app(ChatService::class);
$session = $service->createSession('Test Session');
$session->update(['status' => ChatSessionStatus::CLOSED]);
$this->expectExceptionMessage('Session is closed');
$service->appendMessage([
'session_id' => $session->session_id,
'role' => 'USER',
'type' => 'user.prompt',
'content' => 'blocked',
]);
}
public function test_http_append_and_list_messages(): void
{
$user = User::factory()->create();
$headers = $this->authHeader($user);
$createSession = $this->withHeaders($headers)->postJson('/api/sessions', [
'session_name' => 'API Session',
])->assertCreated();
$sessionId = $createSession->json('session_id');
$append = $this->withHeaders($headers)->postJson("/api/sessions/{$sessionId}/messages", [
'role' => 'USER',
'type' => 'user.prompt',
'content' => 'hello api',
])->assertCreated();
$this->assertEquals(1, $append->json('data.seq'));
$list = $this->withHeaders($headers)->getJson("/api/sessions/{$sessionId}/messages?after_seq=0&limit=10")
->assertOk();
$this->assertEquals(1, $list->json('data.0.seq'));
$this->assertEquals('hello api', $list->json('data.0.content'));
}
}