veza/veza-backend-api/internal/handlers/room_handler_test.go

162 lines
4.3 KiB
Go
Raw Normal View History

2025-12-03 19:29:37 +00:00
package handlers
import (
"bytes"
"context"
"encoding/json"
"net/http"
"net/http/httptest"
2025-12-03 19:29:37 +00:00
"testing"
"veza-backend-api/internal/services"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"go.uber.org/zap"
2025-12-03 19:29:37 +00:00
)
// MockRoomService implements RoomServiceInterface for testing
type MockRoomService struct {
CreateRoomFunc func(ctx context.Context, userID uuid.UUID, req services.CreateRoomRequest) (*services.RoomResponse, error)
GetUserRoomsFunc func(ctx context.Context, userID uuid.UUID) ([]*services.RoomResponse, error)
GetRoomFunc func(ctx context.Context, roomID uuid.UUID) (*services.RoomResponse, error)
AddMemberFunc func(ctx context.Context, roomID, userID uuid.UUID) error
GetRoomHistoryFunc func(ctx context.Context, roomID uuid.UUID, limit, offset int) ([]services.ChatMessageResponse, error)
}
func (m *MockRoomService) CreateRoom(ctx context.Context, userID uuid.UUID, req services.CreateRoomRequest) (*services.RoomResponse, error) {
if m.CreateRoomFunc != nil {
return m.CreateRoomFunc(ctx, userID, req)
}
return nil, nil
}
func (m *MockRoomService) GetUserRooms(ctx context.Context, userID uuid.UUID) ([]*services.RoomResponse, error) {
if m.GetUserRoomsFunc != nil {
return m.GetUserRoomsFunc(ctx, userID)
}
return nil, nil
}
func (m *MockRoomService) GetRoom(ctx context.Context, roomID uuid.UUID) (*services.RoomResponse, error) {
if m.GetRoomFunc != nil {
return m.GetRoomFunc(ctx, roomID)
}
return nil, nil
}
func (m *MockRoomService) AddMember(ctx context.Context, roomID, userID uuid.UUID) error {
if m.AddMemberFunc != nil {
return m.AddMemberFunc(ctx, roomID, userID)
}
return nil
}
func (m *MockRoomService) GetRoomHistory(ctx context.Context, roomID uuid.UUID, limit, offset int) ([]services.ChatMessageResponse, error) {
if m.GetRoomHistoryFunc != nil {
return m.GetRoomHistoryFunc(ctx, roomID, limit, offset)
}
return nil, nil
}
func TestRoomHandler_CreateRoom(t *testing.T) {
// Setup
gin.SetMode(gin.TestMode)
logger := zap.NewNop()
userID := uuid.New()
tests := []struct {
name string
setupMock func() *MockRoomService
requestBody interface{}
setupContext func(*gin.Context)
expectedStatus int
}{
{
name: "Success",
setupMock: func() *MockRoomService {
return &MockRoomService{
CreateRoomFunc: func(ctx context.Context, uid uuid.UUID, req services.CreateRoomRequest) (*services.RoomResponse, error) {
return &services.RoomResponse{
ID: uuid.New(),
Name: req.Name,
Type: req.Type,
}, nil
},
}
},
requestBody: services.CreateRoomRequest{
Name: "General",
Type: "public",
},
setupContext: func(c *gin.Context) {
c.Set("user_id", userID)
},
expectedStatus: http.StatusCreated,
},
{
name: "Unauthorized",
setupMock: func() *MockRoomService {
return &MockRoomService{}
},
requestBody: services.CreateRoomRequest{Name: "Test"},
setupContext: func(c *gin.Context) {
// No user_id set
},
expectedStatus: http.StatusUnauthorized,
},
{
name: "Invalid Payload",
setupMock: func() *MockRoomService {
return &MockRoomService{}
},
requestBody: "invalid-json", // String instead of struct
setupContext: func(c *gin.Context) {
c.Set("user_id", userID)
},
expectedStatus: http.StatusBadRequest,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mockService := tt.setupMock()
handler := NewRoomHandler(mockService, logger)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
// Setup request
c.Request, _ = http.NewRequest(http.MethodPost, "/conversations", nil)
if body, ok := tt.requestBody.(string); ok && body == "invalid-json" {
c.Request.Body = &closingBuffer{bytes.NewBufferString("invalid-json")}
} else {
jsonBytes, _ := json.Marshal(tt.requestBody)
c.Request.Body = &closingBuffer{bytes.NewBuffer(jsonBytes)}
}
c.Request.Header.Set("Content-Type", "application/json")
// Setup context (auth)
tt.setupContext(c)
// Execute
handler.CreateRoom(c)
// Assert
if w.Code != tt.expectedStatus {
t.Errorf("Expected status %d, got %d. Body: %s", tt.expectedStatus, w.Code, w.Body.String())
}
})
}
}
// closingBuffer helps to mock ReadCloser
type closingBuffer struct {
*bytes.Buffer
}
func (cb *closingBuffer) Close() error {
return nil
}