veza/veza-backend-api/tests/integration/api_health_test.go
2025-12-16 11:23:49 -05:00

166 lines
4.7 KiB
Go

// >>> VEZA:BEGIN api_health_test.go
package integration
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"veza-backend-api/internal/api"
"veza-backend-api/internal/config"
"veza-backend-api/internal/handlers"
)
// setupTestRouter crée un router de test minimal
func setupTestRouter() *gin.Engine {
gin.SetMode(gin.TestMode)
router := gin.New()
// Créer un handler simple pour /health (utiliser Check qui retourne {status: "ok"})
healthHandler := handlers.NewHealthHandlerSimple(nil)
router.GET("/health", healthHandler.Check)
router.GET("/api/v1/health", healthHandler.Check)
return router
}
// TestAPIHealth tests the health endpoint
func TestAPIHealth(t *testing.T) {
router := setupTestRouter()
req := httptest.NewRequest("GET", "/health", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var response map[string]interface{}
err := json.Unmarshal(w.Body.Bytes(), &response)
assert.NoError(t, err)
// Le format standardisé retourne {success: true, data: {status: "ok"}}
if data, ok := response["data"].(map[string]interface{}); ok {
assert.Equal(t, "ok", data["status"])
} else {
// Fallback pour format simple (si handler retourne directement)
status, ok := response["status"]
assert.True(t, ok, "Response should have status field: %v", response)
assert.Contains(t, []interface{}{"ok", "healthy"}, status, "Status should be 'ok' or 'healthy'")
}
}
// TestAPIHealthV1 tests the v1 health endpoint
func TestAPIHealthV1(t *testing.T) {
router := setupTestRouter()
req := httptest.NewRequest("GET", "/api/v1/health", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var response map[string]interface{}
err := json.Unmarshal(w.Body.Bytes(), &response)
assert.NoError(t, err)
// Le format standardisé retourne {success: true, data: {status: "ok"}}
if data, ok := response["data"].(map[string]interface{}); ok {
assert.Equal(t, "ok", data["status"])
} else {
// Fallback pour format simple (si handler retourne directement)
status, ok := response["status"]
assert.True(t, ok, "Response should have status field: %v", response)
assert.Contains(t, []interface{}{"ok", "healthy"}, status, "Status should be 'ok' or 'healthy'")
}
}
// TestAPIStatus tests the status endpoint
func TestAPIStatus(t *testing.T) {
// Skip si pas de DB configurée
if testing.Short() {
t.Skip("Skipping integration test in short mode")
}
// Créer une config de test
cfg, err := config.NewConfig()
if err != nil {
t.Skipf("Skipping test: cannot create config: %v", err)
return
}
// Créer un router avec la config
gin.SetMode(gin.TestMode)
router := gin.New()
apiRouter := api.NewAPIRouter(cfg.Database, cfg)
apiRouter.Setup(router)
req := httptest.NewRequest("GET", "/api/v1/status", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var response handlers.StatusResponse
err = json.Unmarshal(w.Body.Bytes(), &response)
assert.NoError(t, err)
assert.NotEmpty(t, response.Status)
assert.GreaterOrEqual(t, response.UptimeSec, int64(0))
assert.NotNil(t, response.Services)
}
// TestAPIStatusDegraded tests status endpoint when a service is down
func TestAPIStatusDegraded(t *testing.T) {
// Ce test nécessite un mock ou une configuration spécifique
// Pour l'instant, on vérifie juste que le endpoint répond
if testing.Short() {
t.Skip("Skipping integration test in short mode")
}
cfg, err := config.NewConfig()
if err != nil {
t.Skipf("Skipping test: cannot create config: %v", err)
return
}
gin.SetMode(gin.TestMode)
router := gin.New()
apiRouter := api.NewAPIRouter(cfg.Database, cfg)
apiRouter.Setup(router)
req := httptest.NewRequest("GET", "/api/v1/status", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
// Le status peut être "ok" ou "degraded" selon l'état des services
assert.True(t, w.Code == http.StatusOK || w.Code == http.StatusServiceUnavailable)
var response handlers.StatusResponse
err = json.Unmarshal(w.Body.Bytes(), &response)
assert.NoError(t, err)
assert.Contains(t, []string{"ok", "degraded"}, response.Status)
}
// TestAPIHealthHTTP is a basic HTTP test
func TestAPIHealthHTTP(t *testing.T) {
// This test requires the API server to be running
// In CI, use docker-compose or a test server
baseURL := "http://localhost:8080"
if testing.Short() {
t.Skip("Skipping integration test in short mode")
}
resp, err := http.Get(baseURL + "/api/v1/health")
if err != nil {
t.Skipf("API server not available: %v", err)
return
}
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
}
// <<< VEZA:END api_health_test.go