package chat import ( "context" "encoding/json" "testing" "time" "veza-backend-api/internal/models" "github.com/google/uuid" "github.com/stretchr/testify/assert" ) func TestHandleTyping_BroadcastsToOthers(t *testing.T) { handler, hub, db := setupTestHandler(t) ctx := context.Background() user1 := uuid.New() user2 := uuid.New() roomID := uuid.New() db.Exec("CREATE TABLE IF NOT EXISTS room_members (user_id TEXT, room_id TEXT, role TEXT DEFAULT 'member', is_muted INTEGER DEFAULT 0)") client1 := newTestClient(hub, user1) client2 := newTestClient(hub, user2) hub.Register(client1) hub.Register(client2) hub.JoinRoom(client1, roomID) hub.JoinRoom(client2, roomID) time.Sleep(20 * time.Millisecond) isTyping := true msg := &IncomingMessage{ Type: TypeTyping, ConversationID: &roomID, IsTyping: &isTyping, } handler.HandleTyping(ctx, client1, msg) time.Sleep(20 * time.Millisecond) // client1 gets ActionConfirmed, client2 gets UserTyping broadcast assert.GreaterOrEqual(t, len(client1.send), 1) assert.GreaterOrEqual(t, len(client2.send), 1) typingResp := <-client2.send var parsed map[string]interface{} json.Unmarshal(typingResp, &parsed) assert.Equal(t, TypeUserTyping, parsed["type"]) assert.Equal(t, true, parsed["is_typing"]) } func TestHandleMarkAsRead_PersistsReceipt(t *testing.T) { handler, hub, db := setupTestHandler(t) ctx := context.Background() userID := uuid.New() roomID := uuid.New() msgID := uuid.New() client := newTestClient(hub, userID) hub.Register(client) hub.JoinRoom(client, roomID) time.Sleep(20 * time.Millisecond) msg := &IncomingMessage{ Type: TypeMarkAsRead, ConversationID: &roomID, MessageID: &msgID, } handler.HandleMarkAsRead(ctx, client, msg) time.Sleep(20 * time.Millisecond) var count int64 db.Model(&models.ReadReceipt{}).Where("user_id = ? AND message_id = ?", userID, msgID).Count(&count) assert.Equal(t, int64(1), count) } func TestHandleAddReaction_PersistsAndBroadcasts(t *testing.T) { handler, hub, db := setupTestHandler(t) ctx := context.Background() userID := uuid.New() roomID := uuid.New() msgID := uuid.New() client := newTestClient(hub, userID) hub.Register(client) hub.JoinRoom(client, roomID) time.Sleep(20 * time.Millisecond) msg := &IncomingMessage{ Type: TypeAddReaction, ConversationID: &roomID, MessageID: &msgID, Emoji: "👍", } handler.HandleAddReaction(ctx, client, msg) time.Sleep(20 * time.Millisecond) var count int64 db.Model(&models.MessageReaction{}).Where("user_id = ? AND message_id = ?", userID, msgID).Count(&count) assert.Equal(t, int64(1), count) // Check broadcast assert.GreaterOrEqual(t, len(client.send), 1) } func TestHandleRemoveReaction_DeletesFromDB(t *testing.T) { handler, hub, db := setupTestHandler(t) ctx := context.Background() userID := uuid.New() roomID := uuid.New() msgID := uuid.New() reaction := &models.MessageReaction{ ID: uuid.New(), UserID: userID, MessageID: msgID, Emoji: "👍", CreatedAt: time.Now(), } db.Create(reaction) client := newTestClient(hub, userID) hub.Register(client) hub.JoinRoom(client, roomID) time.Sleep(20 * time.Millisecond) msg := &IncomingMessage{ Type: TypeRemoveReaction, ConversationID: &roomID, MessageID: &msgID, } handler.HandleRemoveReaction(ctx, client, msg) time.Sleep(20 * time.Millisecond) var count int64 db.Model(&models.MessageReaction{}).Where("user_id = ? AND message_id = ?", userID, msgID).Count(&count) assert.Equal(t, int64(0), count) } func TestHandleDelivered_PersistsStatus(t *testing.T) { handler, hub, db := setupTestHandler(t) ctx := context.Background() userID := uuid.New() roomID := uuid.New() msgID := uuid.New() client := newTestClient(hub, userID) hub.Register(client) hub.JoinRoom(client, roomID) time.Sleep(20 * time.Millisecond) msg := &IncomingMessage{ Type: TypeDelivered, ConversationID: &roomID, MessageID: &msgID, } handler.HandleDelivered(ctx, client, msg) time.Sleep(20 * time.Millisecond) var count int64 db.Model(&models.DeliveredStatus{}).Where("user_id = ? AND message_id = ?", userID, msgID).Count(&count) assert.Equal(t, int64(1), count) }