veza/veza-backend-api/internal/handlers/health_test.go
2025-12-12 21:34:34 -05:00

136 lines
4.2 KiB
Go

//go:build !integration
// +build !integration
package handlers
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
// setupTestHealthHandler crée un handler de test avec une DB en mémoire
func setupTestHealthHandler(t *testing.T) (*HealthHandler, *gorm.DB, func()) {
// DB en mémoire SQLite
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
require.NoError(t, err)
logger := zap.NewNop()
handler := NewHealthHandler(db, logger, nil, nil, "test")
cleanup := func() {
sqlDB, _ := db.DB()
if sqlDB != nil {
sqlDB.Close()
}
}
return handler, db, cleanup
}
// TestReadiness_DBOK_OptionalServicesDown_Returns200Degraded vérifie que /readyz retourne 200 avec status "degraded" si DB OK mais optionnels KO
func TestReadiness_DBOK_OptionalServicesDown_Returns200Degraded(t *testing.T) {
gin.SetMode(gin.TestMode)
handler, _, cleanup := setupTestHealthHandler(t)
defer cleanup()
// Créer un handler avec Redis/RabbitMQ non configurés (simule services down)
// Le handler est déjà configuré avec redis=nil et rabbitMQ=nil dans setupTestHealthHandler
req := httptest.NewRequest("GET", "/readyz", nil)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = req
// Exécuter
handler.Readiness(c)
// Vérifier : doit retourner 200 OK avec status "degraded"
assert.Equal(t, http.StatusOK, w.Code)
// Parser la réponse JSON
var response struct {
Success bool `json:"success"`
Data map[string]interface{} `json:"data"`
}
err := json.Unmarshal(w.Body.Bytes(), &response)
require.NoError(t, err)
assert.True(t, response.Success)
// Vérifier que le status est "degraded" ou "ready" selon la configuration
// Si Redis/RabbitMQ ne sont pas configurés, ils retournent "error"
// mais le status global doit être "degraded" si DB est OK
status := response.Data["status"].(string)
assert.Contains(t, []string{"ready", "degraded"}, status)
// Vérifier que la DB est OK
checks := response.Data["checks"].(map[string]interface{})
dbCheck := checks["database"].(map[string]interface{})
assert.Equal(t, "ok", dbCheck["status"].(string))
}
// TestReadiness_DBDown_Returns503 vérifie que /readyz retourne 503 si DB est down
func TestReadiness_DBDown_Returns503(t *testing.T) {
gin.SetMode(gin.TestMode)
// Créer un handler avec une DB nil (simule DB down)
logger := zap.NewNop()
handler := NewHealthHandler(nil, logger, nil, nil, "test")
req := httptest.NewRequest("GET", "/readyz", nil)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = req
// Exécuter
handler.Readiness(c)
// Vérifier : doit retourner 503 Service Unavailable
assert.Equal(t, http.StatusServiceUnavailable, w.Code)
}
// TestReadiness_AllServicesOK_Returns200Ready vérifie que /readyz retourne 200 avec status "ready" si tous les services sont OK
// Note: Dans ce test, Redis/RabbitMQ ne sont pas configurés, donc le status sera "degraded" (comportement attendu)
func TestReadiness_AllServicesOK_Returns200Ready(t *testing.T) {
gin.SetMode(gin.TestMode)
handler, _, cleanup := setupTestHealthHandler(t)
defer cleanup()
req := httptest.NewRequest("GET", "/readyz", nil)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = req
// Exécuter
handler.Readiness(c)
// Vérifier : doit retourner 200 OK (même si degraded)
assert.Equal(t, http.StatusOK, w.Code)
// Parser la réponse JSON
var response struct {
Success bool `json:"success"`
Data map[string]interface{} `json:"data"`
}
err := json.Unmarshal(w.Body.Bytes(), &response)
require.NoError(t, err)
assert.True(t, response.Success)
// Si Redis/RabbitMQ ne sont pas configurés, le status sera "degraded" (comportement attendu)
// Si tous les services sont configurés et OK, le status sera "ready"
status := response.Data["status"].(string)
assert.Contains(t, []string{"ready", "degraded"}, status)
// Dans tous les cas, la DB doit être OK
checks := response.Data["checks"].(map[string]interface{})
dbCheck := checks["database"].(map[string]interface{})
assert.Equal(t, "ok", dbCheck["status"].(string))
}