151 lines
4.7 KiB
PHP
151 lines
4.7 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace Tests\Feature;
|
||
|
|
|
||
|
|
use App\Models\Room;
|
||
|
|
use App\Models\User;
|
||
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||
|
|
use Illuminate\Support\Facades\Redis;
|
||
|
|
use Tests\TestCase;
|
||
|
|
|
||
|
|
class ChatControllerTest extends TestCase
|
||
|
|
{
|
||
|
|
use RefreshDatabase;
|
||
|
|
|
||
|
|
protected function setUp(): void
|
||
|
|
{
|
||
|
|
parent::setUp();
|
||
|
|
Redis::flushall();
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_can_view_room()
|
||
|
|
{
|
||
|
|
$room = Room::create(['room_name' => 'testroom']);
|
||
|
|
$user = User::factory()->create();
|
||
|
|
|
||
|
|
$response = $this->actingAs($user)->get(route('chat.room', $room->id));
|
||
|
|
|
||
|
|
$response->assertStatus(200);
|
||
|
|
$response->assertViewIs('chat.frame');
|
||
|
|
|
||
|
|
// Assert user was added to room in redis
|
||
|
|
$this->assertEquals(1, Redis::hexists("room:{$room->id}:users", $user->username));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_can_send_message()
|
||
|
|
{
|
||
|
|
$room = Room::create(['room_name' => 'test_send']);
|
||
|
|
$user = User::factory()->create();
|
||
|
|
|
||
|
|
// 进房
|
||
|
|
$this->actingAs($user)->get(route('chat.room', $room->id));
|
||
|
|
|
||
|
|
$response = $this->actingAs($user)->postJson(route('chat.send', $room->id), [
|
||
|
|
'to_user' => '大家',
|
||
|
|
'content' => '测试消息',
|
||
|
|
'is_secret' => false,
|
||
|
|
'font_color' => '#000000',
|
||
|
|
'action' => 'say',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$response->assertStatus(200);
|
||
|
|
$response->assertJson(['status' => 'success']);
|
||
|
|
|
||
|
|
// 查看 Redis 里的消息记录
|
||
|
|
$messages = Redis::lrange("room:{$room->id}:messages", 0, -1);
|
||
|
|
$this->assertNotEmpty($messages);
|
||
|
|
|
||
|
|
$found = false;
|
||
|
|
foreach ($messages as $msgJson) {
|
||
|
|
$msg = json_decode($msgJson, true);
|
||
|
|
if ($msg['from_user'] === $user->username && $msg['content'] === '测试消息') {
|
||
|
|
$found = true;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
$this->assertTrue($found, 'Message not found in Redis');
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_can_trigger_heartbeat()
|
||
|
|
{
|
||
|
|
$room = Room::create(['room_name' => 'test_hb']);
|
||
|
|
$user = User::factory()->create(['exp_num' => 0]);
|
||
|
|
|
||
|
|
$response = $this->actingAs($user)->postJson(route('chat.heartbeat', $room->id));
|
||
|
|
|
||
|
|
$response->assertStatus(200);
|
||
|
|
$response->assertJsonFragment(['status' => 'success']);
|
||
|
|
|
||
|
|
$user->refresh();
|
||
|
|
$this->assertGreaterThanOrEqual(0, $user->exp_num); // Might be 1 depending on sysparam
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_can_leave_room()
|
||
|
|
{
|
||
|
|
$room = Room::create(['room_name' => 'test_leave']);
|
||
|
|
$user = User::factory()->create();
|
||
|
|
|
||
|
|
// 进房
|
||
|
|
$this->actingAs($user)->get(route('chat.room', $room->id));
|
||
|
|
$this->assertEquals(1, Redis::hexists("room:{$room->id}:users", $user->username));
|
||
|
|
|
||
|
|
// 显式退房
|
||
|
|
$response = $this->actingAs($user)->postJson(route('chat.leave', $room->id).'?explicit=1');
|
||
|
|
|
||
|
|
$response->assertStatus(200);
|
||
|
|
|
||
|
|
// 缓存中被移除
|
||
|
|
$this->assertEquals(0, Redis::hexists("room:{$room->id}:users", $user->username));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_can_get_rooms_online_status()
|
||
|
|
{
|
||
|
|
$user = User::factory()->create();
|
||
|
|
$room1 = Room::create(['room_name' => 'room1']);
|
||
|
|
$room2 = Room::create(['room_name' => 'room2']);
|
||
|
|
|
||
|
|
$this->actingAs($user)->get(route('chat.room', $room1->id));
|
||
|
|
|
||
|
|
$response = $this->actingAs($user)->getJson(route('chat.rooms-online-status'));
|
||
|
|
|
||
|
|
$response->assertStatus(200);
|
||
|
|
|
||
|
|
// Assert room1 has 1 online, room2 has 0
|
||
|
|
$response->assertJsonFragment([
|
||
|
|
'id' => $room1->id,
|
||
|
|
'online' => 1,
|
||
|
|
]);
|
||
|
|
$response->assertJsonFragment([
|
||
|
|
'id' => $room2->id,
|
||
|
|
'online' => 0,
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_can_set_announcement()
|
||
|
|
{
|
||
|
|
$user = User::factory()->create(['user_level' => 100]); // superadmin
|
||
|
|
$room = Room::create(['room_name' => 'test_ann', 'room_owner' => 'someone']);
|
||
|
|
|
||
|
|
$response = $this->actingAs($user)->postJson(route('chat.announcement', $room->id), [
|
||
|
|
'announcement' => 'This is a new test announcement',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$response->assertStatus(200);
|
||
|
|
|
||
|
|
$room->refresh();
|
||
|
|
$this->assertStringContainsString('This is a new test announcement', $room->announcement);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_cannot_set_announcement_without_permission()
|
||
|
|
{
|
||
|
|
$user = User::factory()->create(['user_level' => 0]);
|
||
|
|
$room = Room::create(['room_name' => 'test_ann2', 'room_owner' => 'someone']);
|
||
|
|
|
||
|
|
$response = $this->actingAs($user)->postJson(route('chat.announcement', $room->id), [
|
||
|
|
'announcement' => 'This is a new test announcement',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$response->assertStatus(403);
|
||
|
|
}
|
||
|
|
}
|