hyapp-server/services/room-service/internal/room/service/presence_replay_internal_test.go
2026-07-13 12:22:30 +08:00

75 lines
2.7 KiB
Go
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.

package service
import (
"testing"
"hyapp/services/room-service/internal/room/command"
"hyapp/services/room-service/internal/room/state"
)
func replayHeartbeat(t *testing.T, current *state.RoomState, userID int64, sentAtMS int64) {
t.Helper()
cmd := &command.RoomHeartbeat{Base: command.Base{
AppCode: "lalu",
RequestID: "req-replay-heartbeat",
CommandID: "cmd-replay-heartbeat",
ActorID: userID,
Room: current.RoomID,
SentAtMS: sentAtMS,
}}
if err := replay(current, cmd, sentAtMS); err != nil {
t.Fatalf("replay heartbeat for user %d failed: %v", userID, err)
}
}
// 线上心跳会静默恢复丢失的 presence 后才提交命令日志;回放必须重现恢复(含 Version++
// 否则恢复出的 OnlineUsers/版本与快照谱系分叉。
func TestReplayRoomHeartbeatRecreatesMissingPresence(t *testing.T) {
ownerID := int64(11)
adminID := int64(22)
viewerID := int64(33)
current := state.NewRoomState("room-replay-heartbeat", ownerID, 4, "voice")
current.AdminUsers[adminID] = true
baseVersion := current.Version
replayHeartbeat(t, current, viewerID, 1_000)
viewer, exists := current.OnlineUsers[viewerID]
if !exists || viewer.Role != "audience" || viewer.JoinedAtMS != 1_000 || viewer.LastSeenAtMS != 1_000 {
t.Fatalf("replayed heal must recreate audience presence from SentAtMS: %+v", viewer)
}
if current.Version != baseVersion+1 {
t.Fatalf("replayed heal must advance version exactly once: base=%d now=%d", baseVersion, current.Version)
}
// 角色从权威字段推导owner/admin 恢复后徽标不丢失。
replayHeartbeat(t, current, ownerID, 2_000)
if owner := current.OnlineUsers[ownerID]; owner == nil || owner.Role != "owner" {
t.Fatalf("replayed heal must restore owner role: %+v", owner)
}
replayHeartbeat(t, current, adminID, 3_000)
if admin := current.OnlineUsers[adminID]; admin == nil || admin.Role != "admin" {
t.Fatalf("replayed heal must restore admin role: %+v", admin)
}
}
func TestReplayRoomHeartbeatRefreshesExistingPresence(t *testing.T) {
viewerID := int64(44)
current := state.NewRoomState("room-replay-heartbeat-refresh", 11, 4, "voice")
current.OnlineUsers[viewerID] = &state.RoomUserState{
UserID: viewerID,
Role: "audience",
JoinedAtMS: 500,
LastSeenAtMS: 500,
}
baseVersion := current.Version
replayHeartbeat(t, current, viewerID, 9_000)
viewer := current.OnlineUsers[viewerID]
if viewer.LastSeenAtMS != 9_000 || viewer.JoinedAtMS != 500 {
t.Fatalf("replayed refresh must only update last_seen: %+v", viewer)
}
if current.Version != baseVersion+1 {
t.Fatalf("replayed refresh must advance version exactly once: base=%d now=%d", baseVersion, current.Version)
}
}