修复普通定向发言公屏可见
This commit is contained in:
@@ -26,9 +26,9 @@ class MessageSent implements ShouldBroadcastNow
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
* 创建消息广播事件实例。
|
||||
*
|
||||
* @param int $roomId 房间ID
|
||||
* @param int $roomId 房间 ID
|
||||
* @param array $message 发送的消息数据
|
||||
*/
|
||||
public function __construct(
|
||||
@@ -39,8 +39,8 @@ class MessageSent implements ShouldBroadcastNow
|
||||
/**
|
||||
* 获取消息应广播到的频道。
|
||||
*
|
||||
* 公共消息走房间 Presence 频道;
|
||||
* 定向消息 / 悄悄话只发给发送方与接收方的私有用户频道。
|
||||
* 公共消息和普通定向发言走房间 Presence 频道;
|
||||
* 悄悄话只发给发送方与接收方的私有用户频道。
|
||||
*
|
||||
* @return array<int, \Illuminate\Broadcasting\Channel>
|
||||
*/
|
||||
@@ -78,9 +78,7 @@ class MessageSent implements ShouldBroadcastNow
|
||||
*/
|
||||
private function shouldBroadcastPrivately(): bool
|
||||
{
|
||||
$toUser = trim((string) ($this->message['to_user'] ?? ''));
|
||||
|
||||
return $toUser !== '' && $toUser !== '大家';
|
||||
return (bool) ($this->message['is_secret'] ?? false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -248,8 +248,8 @@ class ChatController extends Controller
|
||||
return $fromUser === $username || $toUser === $username;
|
||||
}
|
||||
|
||||
// 对特定人说话:只显示发给自己或自己发出的(含系统通知)
|
||||
return $fromUser === $username || $toUser === $username;
|
||||
// 非悄悄话的定向发言仍属于公屏消息,历史回放也要让房间内其他人可见。
|
||||
return true;
|
||||
}));
|
||||
|
||||
// 7. 如果用户有在职職务,开始记录这次入场的心跳登录 (仅初次)
|
||||
|
||||
@@ -568,9 +568,54 @@ class ChatControllerTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试定向消息仅广播到发送方与接收方私有频道。
|
||||
* 测试历史消息会让旁观用户看到普通定向发言,但不会泄露悄悄话。
|
||||
*/
|
||||
public function test_targeted_message_event_uses_private_user_channels(): void
|
||||
public function test_room_history_keeps_non_secret_targeted_messages_visible_to_others(): void
|
||||
{
|
||||
$room = Room::create(['room_name' => 'histtg']);
|
||||
$sender = User::factory()->create(['username' => 'history-sender']);
|
||||
$receiver = User::factory()->create(['username' => 'history-receiver']);
|
||||
$observer = User::factory()->create(['username' => 'history-observer']);
|
||||
$chatState = app(\App\Services\ChatStateService::class);
|
||||
|
||||
$chatState->pushMessage($room->id, [
|
||||
'id' => 1,
|
||||
'room_id' => $room->id,
|
||||
'from_user' => $sender->username,
|
||||
'to_user' => $receiver->username,
|
||||
'content' => '公开对你说',
|
||||
'is_secret' => false,
|
||||
'font_color' => '#000000',
|
||||
'action' => '',
|
||||
'sent_at' => now()->toDateTimeString(),
|
||||
]);
|
||||
$chatState->pushMessage($room->id, [
|
||||
'id' => 2,
|
||||
'room_id' => $room->id,
|
||||
'from_user' => $sender->username,
|
||||
'to_user' => $receiver->username,
|
||||
'content' => '旁人不可见悄悄话',
|
||||
'is_secret' => true,
|
||||
'font_color' => '#000000',
|
||||
'action' => '',
|
||||
'sent_at' => now()->toDateTimeString(),
|
||||
]);
|
||||
|
||||
$response = $this->actingAs($observer)->get(route('chat.room', $room->id));
|
||||
|
||||
$response->assertOk();
|
||||
$response->assertViewHas('historyMessages', function (array $messages): bool {
|
||||
$contents = collect($messages)->pluck('content');
|
||||
|
||||
return $contents->contains('公开对你说')
|
||||
&& ! $contents->contains('旁人不可见悄悄话');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试悄悄话消息仅广播到发送方与接收方私有频道。
|
||||
*/
|
||||
public function test_secret_message_event_uses_private_user_channels(): void
|
||||
{
|
||||
$sender = User::factory()->create(['username' => 'sender-user']);
|
||||
$receiver = User::factory()->create(['username' => 'receiver-user']);
|
||||
@@ -597,7 +642,30 @@ class ChatControllerTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试公共消息仍广播到房间 Presence 频道。
|
||||
* 测试普通定向消息仍广播到房间 Presence 频道。
|
||||
*/
|
||||
public function test_non_secret_targeted_message_event_uses_room_presence_channel(): void
|
||||
{
|
||||
$event = new MessageSent(3, [
|
||||
'room_id' => 3,
|
||||
'from_user' => 'tester',
|
||||
'to_user' => 'receiver-user',
|
||||
'content' => '公开对你说',
|
||||
'is_secret' => false,
|
||||
'font_color' => '#000000',
|
||||
'action' => '',
|
||||
'sent_at' => now()->toDateTimeString(),
|
||||
]);
|
||||
|
||||
$channels = $event->broadcastOn();
|
||||
|
||||
$this->assertCount(1, $channels);
|
||||
$this->assertInstanceOf(PresenceChannel::class, $channels[0]);
|
||||
$this->assertSame('presence-room.3', $channels[0]->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试对大家消息仍广播到房间 Presence 频道。
|
||||
*/
|
||||
public function test_public_message_event_still_uses_room_presence_channel(): void
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user