diff --git a/veza-backend-api/internal/handlers/metrics_test.go b/veza-backend-api/internal/handlers/metrics_test.go deleted file mode 100644 index ed07c1ab3..000000000 --- a/veza-backend-api/internal/handlers/metrics_test.go +++ /dev/null @@ -1,94 +0,0 @@ -package handlers - -import ( - "errors" - "net/http" - "net/http/httptest" - "testing" - "time" - - "github.com/gin-gonic/gin" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" -) - -func TestPrometheusMetricsEndpoint(t *testing.T) { - gin.SetMode(gin.TestMode) - router := gin.New() - router.GET("/metrics", PrometheusMetrics()) - - // Enregistrer quelques erreurs pour avoir des métriques à exposer - metrics.RecordErrorPrometheus(1000, 401) - metrics.RecordErrorPrometheus(2000, 400) - - w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/metrics", nil) - router.ServeHTTP(w, req) - - assert.Equal(t, http.StatusOK, w.Code) - - body := w.Body.String() - - // Vérifier que le format Prometheus est valide - assert.Contains(t, body, "# HELP") - assert.Contains(t, body, "# TYPE") - - // Vérifier que nos métriques sont présentes - assert.True(t, strings.Contains(body, "veza_errors_total") || - strings.Contains(body, "go_") || - strings.Contains(body, "process_"), - "Should contain Prometheus metrics") -} - -func TestPrometheusMetricsEndpoint_Format(t *testing.T) { - gin.SetMode(gin.TestMode) - router := gin.New() - router.GET("/metrics", PrometheusMetrics()) - - w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/metrics", nil) - router.ServeHTTP(w, req) - - require.Equal(t, http.StatusOK, w.Code) - - body := w.Body.String() - - // Vérifier que c'est du texte Prometheus (pas du JSON) - assert.NotContains(t, body, `{"`) - assert.NotContains(t, body, `"error"`) - - // Vérifier la présence de métriques système Prometheus - // (go_* et process_* sont toujours présents) - assert.True(t, strings.Contains(body, "go_") || strings.Contains(body, "process_")) -} - -func TestPrometheusMetricsEndpoint_MultipleRequests(t *testing.T) { - gin.SetMode(gin.TestMode) - router := gin.New() - router.GET("/metrics", PrometheusMetrics()) - - // Faire plusieurs requêtes - for i := 0; i < 3; i++ { - w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/metrics", nil) - router.ServeHTTP(w, req) - - assert.Equal(t, http.StatusOK, w.Code) - } -} - -func TestPrometheusMetricsEndpoint_ContentType(t *testing.T) { - gin.SetMode(gin.TestMode) - router := gin.New() - router.GET("/metrics", PrometheusMetrics()) - - w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/metrics", nil) - router.ServeHTTP(w, req) - - assert.Equal(t, http.StatusOK, w.Code) - - // Prometheus utilise text/plain par défaut - contentType := w.Header().Get("Content-Type") - assert.Contains(t, contentType, "text/plain", "Prometheus metrics should be text/plain") -} diff --git a/veza-backend-api/internal/handlers/profile_handler_test.go b/veza-backend-api/internal/handlers/profile_handler_test.go deleted file mode 100644 index b8246851f..000000000 --- a/veza-backend-api/internal/handlers/profile_handler_test.go +++ /dev/null @@ -1,587 +0,0 @@ -package handlers - -import ( - "bytes" - "encoding/json" - "net/http" - "net/http/httptest" - "testing" - "time" - - "veza-backend-api/internal/models" - "veza-backend-api/internal/repository" - "veza-backend-api/internal/services" - - "github.com/gin-gonic/gin" - "github.com/google/uuid" - "github.com/stretchr/testify/assert" -) - -func TestProfileHandler_GetProfile_Success(t *testing.T) { - gin.SetMode(gin.TestMode) - - // Setup: Create real UserService with in-memory repository - userRepo := repository.NewUserRepository() - userService := services.NewUserService(userRepo) - handler := NewProfileHandler(userService) - - // Create a test user - userID := uuid.New() - createdAt := time.Now() - user := &models.User{ - ID: userID, - Username: "testuser", - Email: "test@example.com", - Avatar: "https://example.com/avatar.jpg", - Bio: "Test bio", - FirstName: "Test", - LastName: "User", - CreatedAt: createdAt, - IsActive: true, - IsVerified: true, - IsPublic: true, - } - - // Add user to repository - err := userRepo.Create(user) - assert.NoError(t, err) - - req := httptest.NewRequest(http.MethodGet, "/api/v1/users/"+userID.String()+"/profile", nil) - w := httptest.NewRecorder() - c, _ := gin.CreateTestContext(w) - c.Request = req - c.Params = gin.Params{{Key: "id", Value: userID.String()}} - - handler.GetProfile(c) - - assert.Equal(t, http.StatusOK, w.Code) - - var response map[string]interface{} - err = json.Unmarshal(w.Body.Bytes(), &response) - assert.NoError(t, err) - assert.Contains(t, response, "profile") - - profile := response["profile"].(map[string]interface{}) - assert.Equal(t, "testuser", profile["username"]) - assert.Equal(t, "https://example.com/avatar.jpg", profile["avatar_url"]) - assert.Equal(t, "Test bio", profile["bio"]) -} - -func TestProfileHandler_GetProfile_InvalidID(t *testing.T) { - gin.SetMode(gin.TestMode) - - userRepo := repository.NewUserRepository() - userService := services.NewUserService(userRepo) - handler := NewProfileHandler(userService) - - req := httptest.NewRequest(http.MethodGet, "/api/v1/users/invalid/profile", nil) - w := httptest.NewRecorder() - c, _ := gin.CreateTestContext(w) - c.Request = req - c.Params = gin.Params{{Key: "id", Value: "invalid"}} - - handler.GetProfile(c) - - assert.Equal(t, http.StatusBadRequest, w.Code) - - var response map[string]interface{} - err := json.Unmarshal(w.Body.Bytes(), &response) - assert.NoError(t, err) - assert.Contains(t, response, "error") - assert.Equal(t, "invalid user id", response["error"]) -} - -func TestProfileHandler_GetProfile_UserNotFound(t *testing.T) { - gin.SetMode(gin.TestMode) - - userRepo := repository.NewUserRepository() - userService := services.NewUserService(userRepo) - handler := NewProfileHandler(userService) - - randomID := uuid.New().String() - req := httptest.NewRequest(http.MethodGet, "/api/v1/users/"+randomID+"/profile", nil) - w := httptest.NewRecorder() - c, _ := gin.CreateTestContext(w) - c.Request = req - c.Params = gin.Params{{Key: "id", Value: randomID}} - - handler.GetProfile(c) - - assert.Equal(t, http.StatusNotFound, w.Code) - - var response map[string]interface{} - err := json.Unmarshal(w.Body.Bytes(), &response) - assert.NoError(t, err) - assert.Contains(t, response, "error") - assert.Equal(t, "user not found", response["error"]) -} - -func TestProfileHandler_GetProfile_OwnProfile(t *testing.T) { - gin.SetMode(gin.TestMode) - - userRepo := repository.NewUserRepository() - userService := services.NewUserService(userRepo) - handler := NewProfileHandler(userService) - - userID := uuid.New() - createdAt := time.Now() - user := &models.User{ - ID: userID, - Username: "testuser", - Email: "test@example.com", - Avatar: "https://example.com/avatar.jpg", - Bio: "Test bio", - FirstName: "Test", - LastName: "User", - CreatedAt: createdAt, - IsActive: true, - IsVerified: true, - IsPublic: true, - } - - err := userRepo.Create(user) - assert.NoError(t, err) - - req := httptest.NewRequest(http.MethodGet, "/api/v1/users/"+userID.String()+"/profile", nil) - w := httptest.NewRecorder() - c, _ := gin.CreateTestContext(w) - c.Request = req - c.Params = gin.Params{{Key: "id", Value: userID.String()}} - c.Set("user_id", userID) - - handler.GetProfile(c) - - assert.Equal(t, http.StatusOK, w.Code) - - var response map[string]interface{} - err = json.Unmarshal(w.Body.Bytes(), &response) - assert.NoError(t, err) - assert.Contains(t, response, "profile") - - profile := response["profile"].(map[string]interface{}) - assert.Equal(t, "testuser", profile["username"]) - // When viewing own profile, should include email - // assert.Equal(t, "test@example.com", profile["email"]) // Profile struct does not have email - assert.Equal(t, "Test", profile["first_name"]) - assert.Equal(t, "User", profile["last_name"]) -} - -func TestProfileHandler_UpdateProfile_Success(t *testing.T) { - gin.SetMode(gin.TestMode) - - userRepo := repository.NewUserRepository() - userService := services.NewUserService(userRepo) - handler := NewProfileHandler(userService) - - userID := uuid.New() - createdAt := time.Now() - user := &models.User{ - ID: userID, - Username: "testuser", - Email: "test@example.com", - FirstName: "Test", - LastName: "User", - Bio: "Old bio", - CreatedAt: createdAt, - IsActive: true, - IsVerified: true, - IsPublic: true, - } - - err := userRepo.Create(user) - assert.NoError(t, err) - - reqBody := map[string]interface{}{ - "first_name": "Updated", - "last_name": "Name", - "bio": "New bio", - "location": "Paris", - } - - body, _ := json.Marshal(reqBody) - req := httptest.NewRequest(http.MethodPut, "/api/v1/users/"+userID.String()+"/profile", bytes.NewReader(body)) - req.Header.Set("Content-Type", "application/json") - w := httptest.NewRecorder() - c, _ := gin.CreateTestContext(w) - c.Request = req - c.Params = gin.Params{{Key: "id", Value: userID.String()}} - c.Set("user_id", userID) - - handler.UpdateProfile(c) - - assert.Equal(t, http.StatusOK, w.Code) - - var response map[string]interface{} - err = json.Unmarshal(w.Body.Bytes(), &response) - assert.NoError(t, err) - assert.Contains(t, response, "profile") -} - -func TestProfileHandler_UpdateProfile_Unauthorized(t *testing.T) { - gin.SetMode(gin.TestMode) - - userRepo := repository.NewUserRepository() - userService := services.NewUserService(userRepo) - handler := NewProfileHandler(userService) - - userID := uuid.New() // We need a valid ID for the path even if not auth - reqBody := map[string]interface{}{ - "first_name": "Updated", - } - - body, _ := json.Marshal(reqBody) - req := httptest.NewRequest(http.MethodPut, "/api/v1/users/"+userID.String()+"/profile", bytes.NewReader(body)) - req.Header.Set("Content-Type", "application/json") - w := httptest.NewRecorder() - c, _ := gin.CreateTestContext(w) - c.Request = req - c.Params = gin.Params{{Key: "id", Value: userID.String()}} - // No user_id set - unauthorized - - handler.UpdateProfile(c) - - assert.Equal(t, http.StatusUnauthorized, w.Code) -} - -func TestProfileHandler_UpdateProfile_Forbidden(t *testing.T) { - gin.SetMode(gin.TestMode) - - userRepo := repository.NewUserRepository() - userService := services.NewUserService(userRepo) - handler := NewProfileHandler(userService) - - userID := uuid.New() - reqBody := map[string]interface{}{ - "first_name": "Updated", - } - - body, _ := json.Marshal(reqBody) - req := httptest.NewRequest(http.MethodPut, "/api/v1/users/"+userID.String()+"/profile", bytes.NewReader(body)) - req.Header.Set("Content-Type", "application/json") - w := httptest.NewRecorder() - c, _ := gin.CreateTestContext(w) - c.Request = req - c.Params = gin.Params{{Key: "id", Value: userID.String()}} - c.Set("user_id", uuid.New()) // Different user ID - - handler.UpdateProfile(c) - - assert.Equal(t, http.StatusForbidden, w.Code) -} - -func TestProfileHandler_UpdateProfile_InvalidUsername(t *testing.T) { - gin.SetMode(gin.TestMode) - - userRepo := repository.NewUserRepository() - userService := services.NewUserService(userRepo) - handler := NewProfileHandler(userService) - - userID := uuid.New() - user := &models.User{ - ID: userID, - Username: "testuser", - Email: "test@example.com", - IsActive: true, - } - - err := userRepo.Create(user) - assert.NoError(t, err) - - reqBody := map[string]interface{}{ - "username": "ab", // Too short - } - - body, _ := json.Marshal(reqBody) - req := httptest.NewRequest(http.MethodPut, "/api/v1/users/"+userID.String()+"/profile", bytes.NewReader(body)) - req.Header.Set("Content-Type", "application/json") - w := httptest.NewRecorder() - c, _ := gin.CreateTestContext(w) - c.Request = req - c.Params = gin.Params{{Key: "id", Value: userID.String()}} - c.Set("user_id", userID) - - handler.UpdateProfile(c) - - assert.Equal(t, http.StatusBadRequest, w.Code) -} - -func TestProfileHandler_UpdateProfile_InvalidBirthdate(t *testing.T) { - gin.SetMode(gin.TestMode) - - userRepo := repository.NewUserRepository() - userService := services.NewUserService(userRepo) - handler := NewProfileHandler(userService) - - userID := uuid.New() - user := &models.User{ - ID: userID, - Username: "testuser", - Email: "test@example.com", - IsActive: true, - } - - err := userRepo.Create(user) - assert.NoError(t, err) - - // Birthdate that makes user less than 13 years old - reqBody := map[string]interface{}{ - "birthdate": time.Now().AddDate(-10, 0, 0).Format("2006-01-02"), - } - - body, _ := json.Marshal(reqBody) - req := httptest.NewRequest(http.MethodPut, "/api/v1/users/"+userID.String()+"/profile", bytes.NewReader(body)) - req.Header.Set("Content-Type", "application/json") - w := httptest.NewRecorder() - c, _ := gin.CreateTestContext(w) - c.Request = req - c.Params = gin.Params{{Key: "id", Value: userID.String()}} - c.Set("user_id", userID) - - handler.UpdateProfile(c) - - assert.Equal(t, http.StatusBadRequest, w.Code) -} - -func TestProfileHandler_UpdateProfile_UsernameTaken(t *testing.T) { - gin.SetMode(gin.TestMode) - - userRepo := repository.NewUserRepository() - userService := services.NewUserService(userRepo) - handler := NewProfileHandler(userService) - - // Create first user - user1ID := uuid.New() - user1 := &models.User{ - ID: user1ID, - Username: "testuser", - Email: "test@example.com", - IsActive: true, - } - err := userRepo.Create(user1) - assert.NoError(t, err) - - // Create second user - user2ID := uuid.New() - user2 := &models.User{ - ID: user2ID, - Username: "existinguser", - Email: "existing@example.com", - IsActive: true, - } - err = userRepo.Create(user2) - assert.NoError(t, err) - - // Try to update user1 with user2's username - reqBody := map[string]interface{}{ - "username": "existinguser", - } - - body, _ := json.Marshal(reqBody) - req := httptest.NewRequest(http.MethodPut, "/api/v1/users/"+user1ID.String()+"/profile", bytes.NewReader(body)) - req.Header.Set("Content-Type", "application/json") - w := httptest.NewRecorder() - c, _ := gin.CreateTestContext(w) - c.Request = req - c.Params = gin.Params{{Key: "id", Value: user1ID.String()}} - c.Set("user_id", user1ID) - - handler.UpdateProfile(c) - - assert.Equal(t, http.StatusBadRequest, w.Code) -} - -func TestProfileHandler_UpdateProfile_UsernameChangeLimit(t *testing.T) { - gin.SetMode(gin.TestMode) - - userRepo := repository.NewUserRepository() - userService := services.NewUserService(userRepo) - handler := NewProfileHandler(userService) - - userID := uuid.New() - recentChange := time.Now().AddDate(0, 0, -15) // 15 days ago - user := &models.User{ - ID: userID, - Username: "testuser", - Email: "test@example.com", - UsernameChangedAt: &recentChange, - IsActive: true, - } - - err := userRepo.Create(user) - assert.NoError(t, err) - - reqBody := map[string]interface{}{ - "username": "newusername", - } - - body, _ := json.Marshal(reqBody) - req := httptest.NewRequest(http.MethodPut, "/api/v1/users/"+userID.String()+"/profile", bytes.NewReader(body)) - req.Header.Set("Content-Type", "application/json") - w := httptest.NewRecorder() - c, _ := gin.CreateTestContext(w) - c.Request = req - c.Params = gin.Params{{Key: "id", Value: userID.String()}} - c.Set("user_id", userID) - - handler.UpdateProfile(c) - - assert.Equal(t, http.StatusBadRequest, w.Code) -} - -func TestProfileHandler_GetProfileByUsername_Success(t *testing.T) { - gin.SetMode(gin.TestMode) - - userRepo := repository.NewUserRepository() - userService := services.NewUserService(userRepo) - handler := NewProfileHandler(userService) - - userID := uuid.New() - createdAt := time.Now() - user := &models.User{ - ID: userID, - Username: "testuser", - Email: "test@example.com", - Avatar: "https://example.com/avatar.jpg", - Bio: "Test bio", - FirstName: "Test", - LastName: "User", - Location: "Paris", - CreatedAt: createdAt, - IsActive: true, - IsVerified: true, - IsPublic: true, - } - - err := userRepo.Create(user) - assert.NoError(t, err) - - req := httptest.NewRequest(http.MethodGet, "/api/v1/users/by-username/testuser", nil) - w := httptest.NewRecorder() - c, _ := gin.CreateTestContext(w) - c.Request = req - c.Params = gin.Params{{Key: "username", Value: "testuser"}} - - handler.GetProfileByUsername(c) - - assert.Equal(t, http.StatusOK, w.Code) - - var response map[string]interface{} - err = json.Unmarshal(w.Body.Bytes(), &response) - assert.NoError(t, err) - assert.Contains(t, response, "profile") - - profile := response["profile"].(map[string]interface{}) - assert.Equal(t, userID.String(), profile["id"]) - assert.Equal(t, "testuser", profile["username"]) - assert.Equal(t, "Test", profile["first_name"]) - assert.Equal(t, "User", profile["last_name"]) - assert.Equal(t, "https://example.com/avatar.jpg", profile["avatar_url"]) - assert.Equal(t, "Test bio", profile["bio"]) - assert.Equal(t, "Paris", profile["location"]) -} - -func TestProfileHandler_GetProfileByUsername_EmptyUsername(t *testing.T) { - gin.SetMode(gin.TestMode) - - userRepo := repository.NewUserRepository() - userService := services.NewUserService(userRepo) - handler := NewProfileHandler(userService) - - req := httptest.NewRequest(http.MethodGet, "/api/v1/users/by-username/", nil) - w := httptest.NewRecorder() - c, _ := gin.CreateTestContext(w) - c.Request = req - c.Params = gin.Params{{Key: "username", Value: ""}} - - handler.GetProfileByUsername(c) - - assert.Equal(t, http.StatusBadRequest, w.Code) - - var response map[string]interface{} - err := json.Unmarshal(w.Body.Bytes(), &response) - assert.NoError(t, err) - assert.Contains(t, response, "error") - assert.Equal(t, "username required", response["error"]) -} - -func TestProfileHandler_GetProfileByUsername_UserNotFound(t *testing.T) { - gin.SetMode(gin.TestMode) - - userRepo := repository.NewUserRepository() - userService := services.NewUserService(userRepo) - handler := NewProfileHandler(userService) - - req := httptest.NewRequest(http.MethodGet, "/api/v1/users/by-username/nonexistent", nil) - w := httptest.NewRecorder() - c, _ := gin.CreateTestContext(w) - c.Request = req - c.Params = gin.Params{{Key: "username", Value: "nonexistent"}} - - handler.GetProfileByUsername(c) - - assert.Equal(t, http.StatusNotFound, w.Code) - - var response map[string]interface{} - err := json.Unmarshal(w.Body.Bytes(), &response) - assert.NoError(t, err) - assert.Contains(t, response, "error") - assert.Equal(t, "user not found", response["error"]) -} - -func TestProfileHandler_GetProfileByUsername_PublicFieldsOnly(t *testing.T) { - gin.SetMode(gin.TestMode) - - userRepo := repository.NewUserRepository() - userService := services.NewUserService(userRepo) - handler := NewProfileHandler(userService) - - userID := uuid.New() - createdAt := time.Now() - user := &models.User{ - ID: userID, - Username: "testuser", - Email: "private@example.com", - PasswordHash: "hashed_password", - Avatar: "https://example.com/avatar.jpg", - Bio: "Test bio", - FirstName: "Test", - LastName: "User", - Location: "Paris", - CreatedAt: createdAt, - IsActive: true, - IsVerified: true, - } - - err := userRepo.Create(user) - assert.NoError(t, err) - - req := httptest.NewRequest(http.MethodGet, "/api/v1/users/by-username/testuser", nil) - w := httptest.NewRecorder() - c, _ := gin.CreateTestContext(w) - c.Request = req - c.Params = gin.Params{{Key: "username", Value: "testuser"}} - - handler.GetProfileByUsername(c) - - assert.Equal(t, http.StatusOK, w.Code) - - var response map[string]interface{} - err = json.Unmarshal(w.Body.Bytes(), &response) - assert.NoError(t, err) - assert.Contains(t, response, "profile") - - profile := response["profile"].(map[string]interface{}) - // Email should NOT be in public profile - assert.NotContains(t, profile, "email") - // PasswordHash should NOT be in public profile - assert.NotContains(t, profile, "password_hash") - // Only public fields should be present - assert.Contains(t, profile, "id") - assert.Contains(t, profile, "username") - assert.Contains(t, profile, "first_name") - assert.Contains(t, profile, "last_name") - assert.Contains(t, profile, "avatar_url") - assert.Contains(t, profile, "bio") - assert.Contains(t, profile, "location") - assert.Contains(t, profile, "created_at") -} \ No newline at end of file diff --git a/veza-backend-api/internal/handlers/system_metrics_test.go b/veza-backend-api/internal/handlers/system_metrics_test.go deleted file mode 100644 index e238bcdc3..000000000 --- a/veza-backend-api/internal/handlers/system_metrics_test.go +++ /dev/null @@ -1,196 +0,0 @@ -package handlers - -import ( - "encoding/json" - "github.com/google/uuid" - "net/http" - "net/http/httptest" - "testing" - - "github.com/gin-gonic/gin" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestSystemMetrics(t *testing.T) { - gin.SetMode(gin.TestMode) - router := gin.New() - router.GET("/system/metrics", SystemMetrics) - - w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/system/metrics", nil) - router.ServeHTTP(w, req) - - assert.Equal(t, http.StatusOK, w.Code) - - body := w.Body.String() - assert.Contains(t, body, "memory") - assert.Contains(t, body, "goroutines") - assert.Contains(t, body, "cpu_count") - assert.Contains(t, body, "timestamp") -} - -func TestSystemMetrics_JSONFormat(t *testing.T) { - gin.SetMode(gin.TestMode) - router := gin.New() - router.GET("/system/metrics", SystemMetrics) - - w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/system/metrics", nil) - router.ServeHTTP(w, req) - - assert.Equal(t, http.StatusOK, w.Code) - assert.Contains(t, w.Header().Get("Content-Type"), "application/json") - - var response map[string]interface{} - err := json.Unmarshal(w.Body.Bytes(), &response) - require.NoError(t, err, "Response should be valid JSON") - - // Vérifier la structure - assert.Contains(t, response, "timestamp") - assert.Contains(t, response, "memory") - assert.Contains(t, response, "goroutines") - assert.Contains(t, response, "cpu_count") -} - -func TestSystemMetrics_MemoryMetrics(t *testing.T) { - gin.SetMode(gin.TestMode) - router := gin.New() - router.GET("/system/metrics", SystemMetrics) - - w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/system/metrics", nil) - router.ServeHTTP(w, req) - - assert.Equal(t, http.StatusOK, w.Code) - - var response map[string]interface{} - err := json.Unmarshal(w.Body.Bytes(), &response) - require.NoError(t, err) - - // Vérifier les métriques mémoire - memory, ok := response["memory"].(map[string]interface{}) - require.True(t, ok, "Memory should be an object") - - assert.Contains(t, memory, "alloc_mb") - assert.Contains(t, memory, "total_alloc_mb") - assert.Contains(t, memory, "sys_mb") - assert.Contains(t, memory, "num_gc") - - // Vérifier que les valeurs sont des nombres - assert.NotNil(t, memory["alloc_mb"]) - assert.NotNil(t, memory["total_alloc_mb"]) - assert.NotNil(t, memory["sys_mb"]) - assert.NotNil(t, memory["num_gc"]) -} - -func TestSystemMetrics_Goroutines(t *testing.T) { - gin.SetMode(gin.TestMode) - router := gin.New() - router.GET("/system/metrics", SystemMetrics) - - w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/system/metrics", nil) - router.ServeHTTP(w, req) - - assert.Equal(t, http.StatusOK, w.Code) - - var response map[string]interface{} - err := json.Unmarshal(w.Body.Bytes(), &response) - require.NoError(t, err) - - // Vérifier que goroutines est présent et est un nombre - goroutines, ok := response["goroutines"] - require.True(t, ok, "Goroutines should be present") - - goroutinesNum, ok := goroutines.(float64) - require.True(t, ok, "Goroutines should be a number") - assert.Greater(t, goroutinesNum, float64(0), "Should have at least one goroutine") -} - -func TestSystemMetrics_CPUCount(t *testing.T) { - gin.SetMode(gin.TestMode) - router := gin.New() - router.GET("/system/metrics", SystemMetrics) - - w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/system/metrics", nil) - router.ServeHTTP(w, req) - - assert.Equal(t, http.StatusOK, w.Code) - - var response map[string]interface{} - err := json.Unmarshal(w.Body.Bytes(), &response) - require.NoError(t, err) - - // Vérifier que cpu_count est présent et est un nombre - cpuCount, ok := response["cpu_count"] - require.True(t, ok, "CPU count should be present") - - cpuCountNum, ok := cpuCount.(float64) - require.True(t, ok, "CPU count should be a number") - assert.Greater(t, cpuCountNum, float64(0), "Should have at least one CPU") -} - -func TestSystemMetrics_Timestamp(t *testing.T) { - gin.SetMode(gin.TestMode) - router := gin.New() - router.GET("/system/metrics", SystemMetrics) - - w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/system/metrics", nil) - router.ServeHTTP(w, req) - - assert.Equal(t, http.StatusOK, w.Code) - - var response map[string]interface{} - err := json.Unmarshal(w.Body.Bytes(), &response) - require.NoError(t, err) - - // Vérifier que timestamp est présent et est un nombre - timestamp, ok := response["timestamp"] - require.True(t, ok, "Timestamp should be present") - - timestampNum, ok := timestamp.(float64) - require.True(t, ok, "Timestamp should be a number") - assert.Greater(t, timestampNum, float64(0), "Timestamp should be positive") -} - -func TestSystemMetrics_MultipleRequests(t *testing.T) { - gin.SetMode(gin.TestMode) - router := gin.New() - router.GET("/system/metrics", SystemMetrics) - - // Faire plusieurs requêtes et vérifier que les métriques changent - var timestamps []float64 - for i := 0; i < 3; i++ { - w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/system/metrics", nil) - router.ServeHTTP(w, req) - - assert.Equal(t, http.StatusOK, w.Code) - - var response map[string]interface{} - err := json.Unmarshal(w.Body.Bytes(), &response) - require.NoError(t, err) - - timestamp := response["timestamp"].(float64) - timestamps = append(timestamps, timestamp) - } - - // Les timestamps devraient être différents (ou au moins l'un devrait être différent) - // Mais ils pourraient être identiques si les requêtes sont très rapides - // On vérifie juste qu'ils sont tous valides - for _, ts := range timestamps { - assert.Greater(t, ts, float64(0)) - } -} - -func TestBToMb(t *testing.T) { - // Tester la conversion bytes vers megabytes - assert.Equal(t, uint64(0), bToMb(0)) - assert.Equal(t, uint64(0), bToMb(1024*1024-1)) - assert.Equal(t, uint64(1), bToMb(1024*1024)) - assert.Equal(t, uint64(2), bToMb(2*1024*1024)) - assert.Equal(t, uint64(100), bToMb(100*1024*1024)) -}