veza/veza-backend-api/internal/websocket/chat/handler_realtime_test.go
senke 02605b0405 test(chat): Sprint 5 -- unit tests, E2E tests, feature parity validation
- Add hub_test.go: register/unregister, join/leave room, broadcast, exclude sender,
  send to user, multiple clients same user (6 tests)
- Add handler_messages_test.go: send message, missing fields, edit ownership check,
  soft delete (4 tests)
- Add handler_realtime_test.go: typing broadcast, read receipts, reactions add/remove,
  delivered status (5 tests)
- Add e2e_chat_ws_test.go: auth valid, missing token, invalid token, ping/pong
- Add e2e_chat_messages_test.go: 2-client message flow, typing indicator
- Create CHAT_FEATURE_PARITY.md: 25-feature checklist (all OK or IMPROVED)
2026-02-22 20:49:32 +01:00

173 lines
4.2 KiB
Go

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)
}