263 lines
8.2 KiB
Go
263 lines
8.2 KiB
Go
package services
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/assert"
|
|
"go.uber.org/zap"
|
|
"gorm.io/gorm"
|
|
"veza-backend-api/internal/models"
|
|
"veza-backend-api/internal/repositories"
|
|
)
|
|
|
|
type MockRoomRepository struct {
|
|
rooms map[uuid.UUID]*models.Room
|
|
members map[uuid.UUID][]*models.RoomMember
|
|
}
|
|
|
|
func NewMockRoomRepository() *MockRoomRepository {
|
|
return &MockRoomRepository{
|
|
rooms: make(map[uuid.UUID]*models.Room),
|
|
members: make(map[uuid.UUID][]*models.RoomMember),
|
|
}
|
|
}
|
|
|
|
func (m *MockRoomRepository) Create(ctx context.Context, room *models.Room) error {
|
|
room.ID = uuid.New() // Generate new UUID
|
|
room.CreatedAt = time.Now()
|
|
room.UpdatedAt = time.Now()
|
|
m.rooms[room.ID] = room
|
|
return nil
|
|
}
|
|
|
|
func (m *MockRoomRepository) GetByID(ctx context.Context, id uuid.UUID) (*models.Room, error) {
|
|
room, ok := m.rooms[id]
|
|
if !ok {
|
|
return nil, gorm.ErrRecordNotFound
|
|
}
|
|
return room, nil
|
|
}
|
|
|
|
func (m *MockRoomRepository) GetByUserID(ctx context.Context, userID uuid.UUID) ([]*models.Room, error) {
|
|
var userRooms []*models.Room
|
|
for _, room := range m.rooms {
|
|
// In a real scenario, this would query room_members.
|
|
// For mock, we'll assume a direct match for now.
|
|
// This mock is simplified and doesn't fully simulate the join logic of a real repo.
|
|
// We'll rely on the AddMember mock below to add members correctly.
|
|
if _, ok := m.members[room.ID]; ok {
|
|
for _, member := range m.members[room.ID] {
|
|
if member.UserID == userID {
|
|
userRooms = append(userRooms, room)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return userRooms, nil
|
|
}
|
|
|
|
func (m *MockRoomRepository) AddMember(ctx context.Context, member *models.RoomMember) error {
|
|
// If the member ID is not set, generate it
|
|
if member.ID == uuid.Nil {
|
|
// This is a mock internal ID, actual GORM might auto-increment
|
|
member.ID = int64(len(m.members[member.RoomID]) + 1)
|
|
}
|
|
m.members[member.RoomID] = append(m.members[member.RoomID], member)
|
|
return nil
|
|
}
|
|
|
|
func (m *MockRoomRepository) GetMembersByRoomID(ctx context.Context, roomID uuid.UUID) ([]*models.RoomMember, error) {
|
|
return m.members[roomID], nil
|
|
}
|
|
|
|
func (m *MockRoomRepository) Update(ctx context.Context, room *models.Room) error {
|
|
panic("not implemented")
|
|
}
|
|
func (m *MockRoomRepository) Delete(ctx context.Context, id uuid.UUID) error {
|
|
panic("not implemented")
|
|
}
|
|
func (m *MockRoomRepository) RemoveMember(ctx context.Context, roomID uuid.UUID, userID uuid.UUID) error {
|
|
panic("not implemented")
|
|
}
|
|
|
|
type MockChatMessageRepository struct {
|
|
messages []models.ChatMessage
|
|
}
|
|
|
|
func NewMockChatMessageRepository() *MockChatMessageRepository {
|
|
return &MockChatMessageRepository{
|
|
messages: make([]models.ChatMessage, 0),
|
|
}
|
|
}
|
|
|
|
func (m *MockChatMessageRepository) GetConversationMessages(ctx context.Context, conversationID uuid.UUID, limit, offset int) ([]models.ChatMessage, error) {
|
|
var filtered []models.ChatMessage
|
|
for _, msg := range m.messages {
|
|
if msg.ConversationID == conversationID {
|
|
filtered = append(filtered, msg)
|
|
}
|
|
}
|
|
// Simple reverse order and limit/offset for mock
|
|
// Order by CreatedAt DESC
|
|
if len(filtered) > 1 {
|
|
for i := 0; i < len(filtered)/2; i++ {
|
|
filtered[i], filtered[len(filtered)-1-i] = filtered[len(filtered)-1-i], filtered[i]
|
|
}
|
|
}
|
|
|
|
start := offset
|
|
end := offset + limit
|
|
if start > len(filtered) {
|
|
start = len(filtered)
|
|
}
|
|
if end > len(filtered) {
|
|
end = len(filtered)
|
|
}
|
|
|
|
return filtered[start:end], nil
|
|
}
|
|
|
|
func TestRoomService_CreateRoom(t *testing.T) {
|
|
logger := zap.NewNop()
|
|
roomRepo := NewMockRoomRepository()
|
|
messageRepo := NewMockChatMessageRepository() // Not used in this test
|
|
service := NewRoomService(roomRepo, messageRepo, logger)
|
|
|
|
userID := int64(1)
|
|
req := CreateRoomRequest{
|
|
Name: "Test Room",
|
|
Type: "public",
|
|
IsPrivate: false,
|
|
}
|
|
|
|
room, err := service.CreateRoom(context.Background(), userID, req)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, room)
|
|
assert.Equal(t, req.Name, room.Name)
|
|
assert.Contains(t, room.Participants, userID)
|
|
|
|
// Verify room created in repo
|
|
createdRoom, _ := roomRepo.GetByID(context.Background(), room.ID)
|
|
assert.NotNil(t, createdRoom)
|
|
assert.Equal(t, room.ID, createdRoom.ID) // Check UUID match
|
|
}
|
|
|
|
func TestRoomService_GetUserRooms(t *testing.T) {
|
|
logger := zap.NewNop()
|
|
roomRepo := NewMockRoomRepository()
|
|
messageRepo := NewMockChatMessageRepository()
|
|
service := NewRoomService(roomRepo, messageRepo, logger)
|
|
|
|
userID := int64(1)
|
|
userID2 := int64(2)
|
|
|
|
roomReq1 := CreateRoomRequest{Name: "Room 1", Type: "public", IsPrivate: false}
|
|
roomReq2 := CreateRoomRequest{Name: "Room 2", Type: "private", IsPrivate: true}
|
|
|
|
room1, _ := service.CreateRoom(context.Background(), userID, roomReq1)
|
|
room2, _ := service.CreateRoom(context.Background(), userID2, roomReq2)
|
|
|
|
// User 1 joins room 2
|
|
err := service.AddMember(context.Background(), room2.ID, userID)
|
|
assert.NoError(t, err)
|
|
|
|
rooms, err := service.GetUserRooms(context.Background(), userID)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, rooms, 2) // Should contain Room 1 and Room 2
|
|
|
|
// Check content
|
|
var foundRoom1, foundRoom2 bool
|
|
for _, r := range rooms {
|
|
if r.ID == room1.ID {
|
|
foundRoom1 = true
|
|
}
|
|
if r.ID == room2.ID {
|
|
foundRoom2 = true
|
|
}
|
|
}
|
|
assert.True(t, foundRoom1)
|
|
assert.True(t, foundRoom2)
|
|
}
|
|
|
|
func TestRoomService_GetRoomHistory(t *testing.T) {
|
|
logger := zap.NewNop()
|
|
roomRepo := NewMockRoomRepository()
|
|
mockMessageRepo := NewMockChatMessageRepository()
|
|
service := NewRoomService(roomRepo, mockMessageRepo, logger)
|
|
|
|
// Create a dummy conversation ID
|
|
convID := uuid.New()
|
|
|
|
// Create a room first to simulate existence
|
|
roomReq := CreateRoomRequest{Name: "History Room", Type: "public", IsPrivate: false}
|
|
_, _ = service.CreateRoom(context.Background(), int64(1), roomReq)
|
|
|
|
// Add mock messages
|
|
mockMessageRepo.messages = []models.ChatMessage{
|
|
{ID: uuid.New(), ConversationID: convID, SenderID: uuid.New(), Content: "Hello 1", CreatedAt: time.Now().Add(-2 * time.Minute)},
|
|
{ID: uuid.New(), ConversationID: convID, SenderID: uuid.New(), Content: "Hello 2", CreatedAt: time.Now().Add(-1 * time.Minute)},
|
|
{ID: uuid.New(), ConversationID: convID, SenderID: uuid.New(), Content: "Hello 3", CreatedAt: time.Now()},
|
|
}
|
|
|
|
history, err := service.GetRoomHistory(context.Background(), convID, 10, 0)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, history, 3)
|
|
assert.Equal(t, "Hello 3", history[0].Content) // Should be ordered by created_at DESC
|
|
|
|
history, err = service.GetRoomHistory(context.Background(), convID, 1, 1) // limit 1, offset 1
|
|
assert.NoError(t, err)
|
|
assert.Len(t, history, 1)
|
|
assert.Equal(t, "Hello 2", history[0].Content)
|
|
}
|
|
|
|
func TestRoomService_GetRoom_Success(t *testing.T) {
|
|
logger := zap.NewNop()
|
|
roomRepo := NewMockRoomRepository()
|
|
messageRepo := NewMockChatMessageRepository()
|
|
service := NewRoomService(roomRepo, messageRepo, logger)
|
|
|
|
userID := int64(1)
|
|
req := CreateRoomRequest{Name: "Single Room", Type: "public", IsPrivate: false}
|
|
createdRoom, _ := service.CreateRoom(context.Background(), userID, req)
|
|
|
|
retrievedRoom, err := service.GetRoom(context.Background(), createdRoom.ID)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, retrievedRoom)
|
|
assert.Equal(t, createdRoom.ID, retrievedRoom.ID)
|
|
assert.Equal(t, "Single Room", retrievedRoom.Name)
|
|
}
|
|
|
|
func TestRoomService_GetRoom_NotFound(t *testing.T) {
|
|
logger := zap.NewNop()
|
|
roomRepo := NewMockRoomRepository()
|
|
messageRepo := NewMockChatMessageRepository()
|
|
service := NewRoomService(roomRepo, messageRepo, logger)
|
|
|
|
_, err := service.GetRoom(context.Background(), uuid.New())
|
|
assert.Error(t, err)
|
|
assert.Equal(t, "playlist not found", err.Error()) // Gorm returns playlist not found here
|
|
}
|
|
|
|
func TestRoomService_AddMember_Success(t *testing.T) {
|
|
logger := zap.NewNop()
|
|
roomRepo := NewMockRoomRepository()
|
|
messageRepo := NewMockChatMessageRepository()
|
|
service := NewRoomService(roomRepo, messageRepo, logger)
|
|
|
|
userID := int64(1)
|
|
roomReq := CreateRoomRequest{Name: "Member Room", Type: "public", IsPrivate: false}
|
|
room, _ := service.CreateRoom(context.Background(), userID, roomReq)
|
|
|
|
newMemberID := int64(2)
|
|
err := service.AddMember(context.Background(), room.ID, newMemberID)
|
|
assert.NoError(t, err)
|
|
|
|
members, _ := roomRepo.GetMembersByRoomID(context.Background(), room.ID)
|
|
assert.Len(t, members, 2) // Original creator + new member
|
|
assert.Equal(t, newMemberID, members[1].UserID)
|
|
}
|