- Tests complets pour frontend_log_handler.go (12 tests)
- Tests couvrent NewFrontendLogHandler et ReceiveLog
- Tests pour tous les niveaux de log (DEBUG, INFO, WARN, ERROR)
- Tests pour gestion des erreurs et validation JSON
- Couverture actuelle: 30.6% (objectif: 80%)
Files: veza-backend-api/internal/handlers/frontend_log_handler_test.go
VEZA_ROADMAP.json
Hours: 16 estimated, 23 actual
683 lines
20 KiB
Go
683 lines
20 KiB
Go
package user
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"database/sql"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"veza-backend-api/internal/common"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/mock"
|
|
)
|
|
|
|
// MockUserService is a mock implementation of Service for testing
|
|
type MockUserService struct {
|
|
mock.Mock
|
|
}
|
|
|
|
func (m *MockUserService) GetUserByID(userID uuid.UUID) (*UserResponse, error) {
|
|
args := m.Called(userID)
|
|
if args.Get(0) == nil {
|
|
return nil, args.Error(1)
|
|
}
|
|
return args.Get(0).(*UserResponse), args.Error(1)
|
|
}
|
|
|
|
func (m *MockUserService) GetUsers(page, limit int, search string) ([]UserResponse, int, error) {
|
|
args := m.Called(page, limit, search)
|
|
if args.Get(0) == nil {
|
|
return nil, args.Int(1), args.Error(2)
|
|
}
|
|
return args.Get(0).([]UserResponse), args.Int(1), args.Error(2)
|
|
}
|
|
|
|
func (m *MockUserService) UpdateUser(userID uuid.UUID, req UpdateUserRequest) (*UserResponse, error) {
|
|
args := m.Called(userID, req)
|
|
if args.Get(0) == nil {
|
|
return nil, args.Error(1)
|
|
}
|
|
return args.Get(0).(*UserResponse), args.Error(1)
|
|
}
|
|
|
|
func (m *MockUserService) ChangePassword(userID uuid.UUID, currentPassword, newPassword string) error {
|
|
args := m.Called(userID, currentPassword, newPassword)
|
|
return args.Error(0)
|
|
}
|
|
|
|
func (m *MockUserService) GetUserPreferences(userID uuid.UUID) (*UserPreferencesResponse, error) {
|
|
args := m.Called(userID)
|
|
if args.Get(0) == nil {
|
|
return nil, args.Error(1)
|
|
}
|
|
return args.Get(0).(*UserPreferencesResponse), args.Error(1)
|
|
}
|
|
|
|
func (m *MockUserService) UpdateUserPreferences(userID uuid.UUID, req UserPreferencesRequest) (*UserPreferencesResponse, error) {
|
|
args := m.Called(userID, req)
|
|
if args.Get(0) == nil {
|
|
return nil, args.Error(1)
|
|
}
|
|
return args.Get(0).(*UserPreferencesResponse), args.Error(1)
|
|
}
|
|
|
|
func (m *MockUserService) DeleteAccount(userID uuid.UUID, password, reason string) error {
|
|
args := m.Called(userID, password, reason)
|
|
return args.Error(0)
|
|
}
|
|
|
|
func (m *MockUserService) RecoverAccount(email, password string) error {
|
|
args := m.Called(email, password)
|
|
return args.Error(0)
|
|
}
|
|
|
|
func (m *MockUserService) RequestDataDeletion(userID uuid.UUID, password, reason string) error {
|
|
args := m.Called(userID, password, reason)
|
|
return args.Error(0)
|
|
}
|
|
|
|
func (m *MockUserService) GetAccountStatus(userID uuid.UUID) (*AccountStatus, error) {
|
|
args := m.Called(userID)
|
|
if args.Get(0) == nil {
|
|
return nil, args.Error(1)
|
|
}
|
|
return args.Get(0).(*AccountStatus), args.Error(1)
|
|
}
|
|
|
|
// MockDataExportService is a mock implementation of DataExportService for testing
|
|
type MockDataExportService struct {
|
|
mock.Mock
|
|
}
|
|
|
|
func (m *MockDataExportService) ExportUserDataAsJSON(ctx context.Context, userID uuid.UUID) ([]byte, error) {
|
|
args := m.Called(ctx, userID)
|
|
if args.Get(0) == nil {
|
|
return nil, args.Error(1)
|
|
}
|
|
return args.Get(0).([]byte), args.Error(1)
|
|
}
|
|
|
|
// setupTestUserRouter creates a test router with user handlers
|
|
func setupTestUserRouter(mockService *MockUserService, mockDataExportService *MockDataExportService) *gin.Engine {
|
|
gin.SetMode(gin.TestMode)
|
|
router := gin.New()
|
|
|
|
handler := NewHandlerWithInterfaces(mockService, mockDataExportService)
|
|
|
|
api := router.Group("/api/v1")
|
|
api.Use(func(c *gin.Context) {
|
|
// Mock auth middleware - set user_id from header if present
|
|
userIDStr := c.GetHeader("X-User-ID")
|
|
if userIDStr != "" {
|
|
uid, err := uuid.Parse(userIDStr)
|
|
if err == nil {
|
|
common.SetUserIDInContext(c, uid)
|
|
}
|
|
}
|
|
c.Next()
|
|
})
|
|
|
|
users := api.Group("/users")
|
|
{
|
|
users.GET("/me", handler.GetMe)
|
|
users.PATCH("/me", handler.UpdateMe)
|
|
users.POST("/me/password", handler.ChangePassword)
|
|
users.GET("", handler.GetUsers)
|
|
users.GET("/except-me", handler.GetUsersExceptMe)
|
|
users.GET("/search", handler.SearchUsers)
|
|
users.GET("/:id/avatar", handler.GetUserAvatar)
|
|
users.GET("/me/preferences", handler.GetPreferences)
|
|
users.PATCH("/me/preferences", handler.UpdatePreferences)
|
|
users.DELETE("/me", handler.DeleteAccount)
|
|
users.POST("/recover", handler.RecoverAccount)
|
|
users.GET("/me/export", handler.ExportData)
|
|
users.POST("/me/delete-request", handler.RequestDataDeletion)
|
|
users.GET("/me/status", handler.GetAccountStatus)
|
|
}
|
|
|
|
return router
|
|
}
|
|
|
|
func TestUserHandler_GetMe_Success(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
userID := uuid.New()
|
|
expectedUser := &UserResponse{
|
|
ID: userID,
|
|
Email: "test@example.com",
|
|
Username: "testuser",
|
|
IsActive: true,
|
|
IsVerified: true,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
mockService.On("GetUserByID", userID).Return(expectedUser, nil)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/v1/users/me", nil)
|
|
req.Header.Set("X-User-ID", userID.String())
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
mockService.AssertExpectations(t)
|
|
|
|
var response map[string]interface{}
|
|
err := json.Unmarshal(w.Body.Bytes(), &response)
|
|
assert.NoError(t, err)
|
|
assert.True(t, response["success"].(bool))
|
|
}
|
|
|
|
func TestUserHandler_GetMe_Unauthorized(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/v1/users/me", nil)
|
|
// No X-User-ID header
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, w.Code)
|
|
}
|
|
|
|
func TestUserHandler_GetMe_NotFound(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
userID := uuid.New()
|
|
mockService.On("GetUserByID", userID).Return(nil, assert.AnError)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/v1/users/me", nil)
|
|
req.Header.Set("X-User-ID", userID.String())
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusNotFound, w.Code)
|
|
mockService.AssertExpectations(t)
|
|
}
|
|
|
|
func TestUserHandler_UpdateMe_Success(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
userID := uuid.New()
|
|
username := "newusername"
|
|
reqBody := UpdateUserRequest{
|
|
Username: &username,
|
|
}
|
|
|
|
expectedUser := &UserResponse{
|
|
ID: userID,
|
|
Username: username,
|
|
Email: "test@example.com",
|
|
IsActive: true,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
mockService.On("UpdateUser", userID, reqBody).Return(expectedUser, nil)
|
|
|
|
body, _ := json.Marshal(reqBody)
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("PATCH", "/api/v1/users/me", bytes.NewBuffer(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("X-User-ID", userID.String())
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
mockService.AssertExpectations(t)
|
|
|
|
var response map[string]interface{}
|
|
err := json.Unmarshal(w.Body.Bytes(), &response)
|
|
assert.NoError(t, err)
|
|
assert.True(t, response["success"].(bool))
|
|
}
|
|
|
|
func TestUserHandler_ChangePassword_Success(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
userID := uuid.New()
|
|
reqBody := map[string]interface{}{
|
|
"current_password": "oldpass123",
|
|
"new_password": "newpass123",
|
|
}
|
|
|
|
mockService.On("ChangePassword", userID, "oldpass123", "newpass123").Return(nil)
|
|
|
|
body, _ := json.Marshal(reqBody)
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("POST", "/api/v1/users/me/password", bytes.NewBuffer(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("X-User-ID", userID.String())
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
mockService.AssertExpectations(t)
|
|
}
|
|
|
|
func TestUserHandler_ChangePassword_InvalidRequest(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
userID := uuid.New()
|
|
reqBody := map[string]interface{}{
|
|
"current_password": "oldpass123",
|
|
// Missing new_password
|
|
}
|
|
|
|
body, _ := json.Marshal(reqBody)
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("POST", "/api/v1/users/me/password", bytes.NewBuffer(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("X-User-ID", userID.String())
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, w.Code)
|
|
}
|
|
|
|
func TestUserHandler_GetUsers_Success(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
expectedUsers := []UserResponse{
|
|
{
|
|
ID: uuid.New(),
|
|
Username: "user1",
|
|
Email: "user1@example.com",
|
|
IsActive: true,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
},
|
|
{
|
|
ID: uuid.New(),
|
|
Username: "user2",
|
|
Email: "user2@example.com",
|
|
IsActive: true,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
},
|
|
}
|
|
|
|
mockService.On("GetUsers", 1, 20, "").Return(expectedUsers, 2, nil)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/v1/users?page=1&limit=20", nil)
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
mockService.AssertExpectations(t)
|
|
|
|
var response map[string]interface{}
|
|
err := json.Unmarshal(w.Body.Bytes(), &response)
|
|
assert.NoError(t, err)
|
|
assert.True(t, response["success"].(bool))
|
|
}
|
|
|
|
func TestUserHandler_SearchUsers_Success(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
query := "test"
|
|
expectedUsers := []UserResponse{
|
|
{
|
|
ID: uuid.New(),
|
|
Username: "testuser",
|
|
Email: "test@example.com",
|
|
IsActive: true,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
},
|
|
}
|
|
|
|
mockService.On("GetUsers", 1, 20, query).Return(expectedUsers, 1, nil)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/v1/users/search?q=test", nil)
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
mockService.AssertExpectations(t)
|
|
}
|
|
|
|
func TestUserHandler_SearchUsers_MissingQuery(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/v1/users/search", nil)
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, w.Code)
|
|
}
|
|
|
|
func TestUserHandler_GetUserAvatar_Success(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
userID := uuid.New()
|
|
avatarURL := "https://example.com/avatar.jpg"
|
|
expectedUser := &UserResponse{
|
|
ID: userID,
|
|
Username: "testuser",
|
|
Email: "test@example.com",
|
|
Avatar: sql.NullString{
|
|
String: avatarURL,
|
|
Valid: true,
|
|
},
|
|
IsActive: true,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
mockService.On("GetUserByID", userID).Return(expectedUser, nil)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/v1/users/"+userID.String()+"/avatar", nil)
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusFound, w.Code)
|
|
assert.Equal(t, avatarURL, w.Header().Get("Location"))
|
|
mockService.AssertExpectations(t)
|
|
}
|
|
|
|
func TestUserHandler_GetUserAvatar_NoAvatar(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
userID := uuid.New()
|
|
expectedUser := &UserResponse{
|
|
ID: userID,
|
|
Username: "testuser",
|
|
Email: "test@example.com",
|
|
Avatar: sql.NullString{
|
|
Valid: false,
|
|
},
|
|
IsActive: true,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
mockService.On("GetUserByID", userID).Return(expectedUser, nil)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/v1/users/"+userID.String()+"/avatar", nil)
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusNotFound, w.Code)
|
|
mockService.AssertExpectations(t)
|
|
}
|
|
|
|
func TestUserHandler_GetPreferences_Success(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
userID := uuid.New()
|
|
expectedPreferences := &UserPreferencesResponse{
|
|
UserID: userID,
|
|
Theme: "dark",
|
|
Language: "en",
|
|
Timezone: "UTC",
|
|
Notifications: NotificationSettings{
|
|
Email: true,
|
|
Push: false,
|
|
},
|
|
Privacy: PrivacySettings{
|
|
ShowEmail: false,
|
|
},
|
|
Audio: AudioSettings{
|
|
AutoPlay: true,
|
|
Quality: "high",
|
|
Volume: 0.8,
|
|
},
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
mockService.On("GetUserPreferences", userID).Return(expectedPreferences, nil)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/v1/users/me/preferences", nil)
|
|
req.Header.Set("X-User-ID", userID.String())
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
mockService.AssertExpectations(t)
|
|
|
|
var response map[string]interface{}
|
|
err := json.Unmarshal(w.Body.Bytes(), &response)
|
|
assert.NoError(t, err)
|
|
assert.True(t, response["success"].(bool))
|
|
}
|
|
|
|
func TestUserHandler_DeleteAccount_Success(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
userID := uuid.New()
|
|
reqBody := map[string]interface{}{
|
|
"password": "password123",
|
|
"reason": "No longer needed",
|
|
"confirm_text": "DELETE",
|
|
}
|
|
|
|
mockService.On("DeleteAccount", userID, "password123", "No longer needed").Return(nil)
|
|
|
|
body, _ := json.Marshal(reqBody)
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("DELETE", "/api/v1/users/me", bytes.NewBuffer(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("X-User-ID", userID.String())
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
mockService.AssertExpectations(t)
|
|
}
|
|
|
|
func TestUserHandler_DeleteAccount_InvalidConfirmText(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
userID := uuid.New()
|
|
reqBody := map[string]interface{}{
|
|
"password": "password123",
|
|
"reason": "No longer needed",
|
|
"confirm_text": "WRONG",
|
|
}
|
|
|
|
body, _ := json.Marshal(reqBody)
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("DELETE", "/api/v1/users/me", bytes.NewBuffer(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("X-User-ID", userID.String())
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, w.Code)
|
|
}
|
|
|
|
func TestUserHandler_ExportData_Success(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
userID := uuid.New()
|
|
exportData := []byte(`{"user_id":"` + userID.String() + `","profile":{}}`)
|
|
|
|
mockDataExportService.On("ExportUserDataAsJSON", mock.Anything, userID).Return(exportData, nil)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/v1/users/me/export", nil)
|
|
req.Header.Set("X-User-ID", userID.String())
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
assert.Contains(t, w.Header().Get("Content-Type"), "application/json")
|
|
assert.Contains(t, w.Header().Get("Content-Disposition"), "attachment")
|
|
mockDataExportService.AssertExpectations(t)
|
|
}
|
|
|
|
func TestUserHandler_GetAccountStatus_Success(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
userID := uuid.New()
|
|
expectedStatus := &AccountStatus{
|
|
UserID: userID,
|
|
Status: "active",
|
|
IsActive: true,
|
|
IsVerified: true,
|
|
CreatedAt: time.Now(),
|
|
}
|
|
|
|
mockService.On("GetAccountStatus", userID).Return(expectedStatus, nil)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/v1/users/me/status", nil)
|
|
req.Header.Set("X-User-ID", userID.String())
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
mockService.AssertExpectations(t)
|
|
|
|
var response map[string]interface{}
|
|
err := json.Unmarshal(w.Body.Bytes(), &response)
|
|
assert.NoError(t, err)
|
|
assert.True(t, response["success"].(bool))
|
|
}
|
|
|
|
func TestUserHandler_RecoverAccount_Success(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
reqBody := map[string]interface{}{
|
|
"email": "test@example.com",
|
|
"password": "password123",
|
|
}
|
|
|
|
mockService.On("RecoverAccount", "test@example.com", "password123").Return(nil)
|
|
|
|
body, _ := json.Marshal(reqBody)
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("POST", "/api/v1/users/recover", bytes.NewBuffer(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
mockService.AssertExpectations(t)
|
|
}
|
|
|
|
func TestUserHandler_RequestDataDeletion_Success(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
userID := uuid.New()
|
|
reqBody := map[string]interface{}{
|
|
"password": "password123",
|
|
"reason": "GDPR",
|
|
}
|
|
|
|
mockService.On("RequestDataDeletion", userID, "password123", "GDPR").Return(nil)
|
|
|
|
body, _ := json.Marshal(reqBody)
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("POST", "/api/v1/users/me/delete-request", bytes.NewBuffer(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("X-User-ID", userID.String())
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
mockService.AssertExpectations(t)
|
|
}
|
|
|
|
func TestUserHandler_GetUsersExceptMe_Success(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
userID := uuid.New()
|
|
otherUserID := uuid.New()
|
|
|
|
users := []UserResponse{
|
|
{ID: userID, Username: "me"},
|
|
{ID: otherUserID, Username: "other"},
|
|
}
|
|
|
|
// Mock returns both users
|
|
mockService.On("GetUsers", 1, 20, "").Return(users, 2, nil)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/v1/users/except-me", nil)
|
|
req.Header.Set("X-User-ID", userID.String())
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
mockService.AssertExpectations(t)
|
|
|
|
var response map[string]interface{}
|
|
err := json.Unmarshal(w.Body.Bytes(), &response)
|
|
assert.NoError(t, err)
|
|
|
|
// Verify data only contains "other" user
|
|
// response["data"] is the payload map (gin.H)
|
|
payload := response["data"].(map[string]interface{})
|
|
// payload["data"] is the users list
|
|
data := payload["data"].([]interface{})
|
|
assert.Len(t, data, 1)
|
|
assert.Equal(t, "other", data[0].(map[string]interface{})["username"])
|
|
}
|
|
|
|
func TestUserHandler_UpdatePreferences_Success(t *testing.T) {
|
|
mockService := new(MockUserService)
|
|
mockDataExportService := new(MockDataExportService)
|
|
router := setupTestUserRouter(mockService, mockDataExportService)
|
|
|
|
userID := uuid.New()
|
|
theme := "light"
|
|
language := "fr"
|
|
reqPreference := UserPreferencesRequest{
|
|
Theme: &theme,
|
|
Language: &language,
|
|
}
|
|
|
|
expectedResponse := &UserPreferencesResponse{
|
|
UserID: userID,
|
|
Theme: "light",
|
|
Language: "fr",
|
|
}
|
|
|
|
mockService.On("UpdateUserPreferences", userID, reqPreference).Return(expectedResponse, nil)
|
|
|
|
body, _ := json.Marshal(reqPreference)
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("PATCH", "/api/v1/users/me/preferences", bytes.NewBuffer(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("X-User-ID", userID.String())
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
mockService.AssertExpectations(t)
|
|
}
|