package chat import ( "testing" "time" "github.com/google/uuid" "github.com/stretchr/testify/assert" "go.uber.org/zap/zaptest" ) func newTestHub(t *testing.T) *Hub { logger := zaptest.NewLogger(t) hub := NewHub(logger) go hub.Run() time.Sleep(10 * time.Millisecond) return hub } func newTestClient(hub *Hub, userID uuid.UUID) *Client { return &Client{ Hub: hub, UserID: userID, send: make(chan []byte, 256), } } func TestHub_RegisterAndUnregister(t *testing.T) { hub := newTestHub(t) userID := uuid.New() client := newTestClient(hub, userID) hub.Register(client) time.Sleep(20 * time.Millisecond) assert.True(t, hub.IsUserOnline(userID)) assert.Equal(t, 1, hub.GetConnectedUsersCount()) hub.Unregister(client) time.Sleep(20 * time.Millisecond) assert.False(t, hub.IsUserOnline(userID)) assert.Equal(t, 0, hub.GetConnectedUsersCount()) } func TestHub_JoinAndLeaveRoom(t *testing.T) { hub := newTestHub(t) userID := uuid.New() roomID := uuid.New() client := newTestClient(hub, userID) hub.Register(client) time.Sleep(20 * time.Millisecond) hub.JoinRoom(client, roomID) members := hub.GetRoomMembers(roomID) assert.Len(t, members, 1) assert.Equal(t, userID, members[0].UserID) hub.LeaveRoom(client, roomID) members = hub.GetRoomMembers(roomID) assert.Nil(t, members) } func TestHub_BroadcastToRoom(t *testing.T) { hub := newTestHub(t) user1 := uuid.New() user2 := uuid.New() roomID := uuid.New() client1 := newTestClient(hub, user1) client2 := newTestClient(hub, user2) hub.Register(client1) hub.Register(client2) time.Sleep(20 * time.Millisecond) hub.JoinRoom(client1, roomID) hub.JoinRoom(client2, roomID) msg := []byte(`{"type":"NewMessage","content":"hello"}`) hub.BroadcastToRoom(roomID, msg, nil) time.Sleep(20 * time.Millisecond) assert.Len(t, client1.send, 1) assert.Len(t, client2.send, 1) received1 := <-client1.send received2 := <-client2.send assert.Equal(t, msg, received1) assert.Equal(t, msg, received2) } func TestHub_BroadcastToRoom_ExcludesSender(t *testing.T) { hub := newTestHub(t) user1 := uuid.New() user2 := uuid.New() roomID := uuid.New() client1 := newTestClient(hub, user1) client2 := newTestClient(hub, user2) hub.Register(client1) hub.Register(client2) time.Sleep(20 * time.Millisecond) hub.JoinRoom(client1, roomID) hub.JoinRoom(client2, roomID) msg := []byte(`{"type":"UserTyping"}`) hub.BroadcastToRoom(roomID, msg, client1) time.Sleep(20 * time.Millisecond) assert.Len(t, client1.send, 0) assert.Len(t, client2.send, 1) } func TestHub_SendToUser(t *testing.T) { hub := newTestHub(t) userID := uuid.New() otherID := uuid.New() client := newTestClient(hub, userID) other := newTestClient(hub, otherID) hub.Register(client) hub.Register(other) time.Sleep(20 * time.Millisecond) msg := []byte(`{"type":"CallOffer"}`) hub.SendToUser(userID, msg) time.Sleep(20 * time.Millisecond) assert.Len(t, client.send, 1) assert.Len(t, other.send, 0) } func TestHub_MultipleClientsSameUser(t *testing.T) { hub := newTestHub(t) userID := uuid.New() client1 := newTestClient(hub, userID) client2 := newTestClient(hub, userID) hub.Register(client1) hub.Register(client2) time.Sleep(20 * time.Millisecond) assert.Equal(t, 1, hub.GetConnectedUsersCount()) assert.True(t, hub.IsUserOnline(userID)) msg := []byte(`{"type":"notification"}`) hub.SendToUser(userID, msg) time.Sleep(20 * time.Millisecond) assert.Len(t, client1.send, 1) assert.Len(t, client2.send, 1) hub.Unregister(client1) time.Sleep(20 * time.Millisecond) assert.True(t, hub.IsUserOnline(userID)) hub.Unregister(client2) time.Sleep(20 * time.Millisecond) assert.False(t, hub.IsUserOnline(userID)) }