create(); $response = $this->actingAs($user)->postJson(route('chatbot.chat'), [ 'message' => 'Hello', 'room_id' => 1, ]); $response->assertStatus(403); $response->assertJson(['status' => 'error']); } /** * AI 功能开启后,控制器会返回模型生成的正常回复。 */ public function test_chatbot_can_reply(): void { $user = User::factory()->create(); Sysparam::updateOrCreate(['alias' => 'chatbot_enabled'], ['body' => '1']); User::factory()->create([ 'username' => 'AI小班长', 'exp_num' => 0, 'jjb' => 0, ]); // Mock the AiChatService $this->mock(AiChatService::class, function (MockInterface $mock) { $mock->shouldReceive('chat') ->once() ->andReturn([ 'reply' => 'Hello from AI', 'provider' => 'test_provider', 'model' => 'test_model', ]); }); $response = $this->actingAs($user)->postJson(route('chatbot.chat'), [ 'message' => 'Hello', 'room_id' => 1, ]); $response->assertStatus(200); $response->assertJson([ 'status' => 'success', 'reply' => 'Hello from AI', 'provider' => 'test_provider', ]); } /** * 发放金币福利时,只使用 AI 当前手上金币,不会为了凑金额自动动用银行存款。 */ public function test_chatbot_can_give_gold(): void { $user = User::factory()->create(['jjb' => 0]); Sysparam::updateOrCreate(['alias' => 'chatbot_enabled'], ['body' => '1']); Sysparam::updateOrCreate(['alias' => 'chatbot_max_daily_rewards'], ['body' => '1']); Sysparam::updateOrCreate(['alias' => 'chatbot_max_gold'], ['body' => '500']); User::factory()->create([ 'username' => 'AI小班长', 'exp_num' => 0, 'jjb' => 1000000, 'bank_jjb' => 1000, ]); // Mock the AiChatService $this->mock(AiChatService::class, function (MockInterface $mock) { $mock->shouldReceive('chat') ->once() ->andReturn([ 'reply' => 'Here is some gold! [ACTION:GIVE_GOLD]', 'provider' => 'test_provider', 'model' => 'test_model', ]); }); $response = $this->actingAs($user)->postJson(route('chatbot.chat'), [ 'message' => 'Give me gold', 'room_id' => 1, ]); $response->assertStatus(200); // User should have received gold $user->refresh(); $this->assertGreaterThan(0, $user->jjb); $this->assertLessThanOrEqual(500, $user->jjb); $aiUser = User::query()->where('username', 'AI小班长')->firstOrFail(); $this->assertLessThan(1000000, (int) $aiUser->jjb); $this->assertSame(1000, (int) $aiUser->bank_jjb); } /** * 用户主动清空上下文时,应调用 AI 服务清理其上下文缓存。 */ public function test_clear_context(): void { $user = User::factory()->create(); $this->mock(AiChatService::class, function (MockInterface $mock) use ($user) { $mock->shouldReceive('clearContext') ->once() ->with($user->id); }); $response = $this->actingAs($user)->postJson(route('chatbot.clear')); $response->assertStatus(200); $response->assertJson(['status' => 'success']); } }