Files
chatroom/tests/Feature/ChatBotControllerTest.php
2026-04-12 22:25:18 +08:00

156 lines
4.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* 文件功能AI小班长聊天控制器测试
*
* 覆盖 AI 开关、普通回复、金币福利以及上下文清理逻辑,
* 同时验证金币福利发放时不会自动动用 AI 的银行存款。
*/
namespace Tests\Feature;
use App\Models\Sysparam;
use App\Models\User;
use App\Services\AiChatService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Redis;
use Mockery\MockInterface;
use Tests\TestCase;
/**
* 验证 AI小班长对话与金币福利接口行为。
*/
class ChatBotControllerTest extends TestCase
{
use RefreshDatabase;
/**
* 每个测试结束后清空 Redis避免每日奖励计数彼此污染。
*/
protected function tearDown(): void
{
Redis::flushall();
parent::tearDown();
}
/**
* 默认情况下AI 功能关闭时应直接拒绝聊天请求。
*/
public function test_chatbot_disabled_by_default(): void
{
$user = User::factory()->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']);
}
}