veza/veza-backend-api/internal/testutils/integration/integration.go

163 lines
4.4 KiB
Go

package integration
import (
"bytes"
"context"
"net/http"
"net/http/httptest"
"testing"
"time"
"veza-backend-api/internal/config"
"veza-backend-api/internal/database"
"veza-backend-api/internal/testutils"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/require"
)
// IntegrationTestSetup contient les ressources pour un test d'intégration (T0041)
type IntegrationTestSetup struct {
DB *database.Database
Router *gin.Engine
Config *config.Config
}
// SetupIntegrationDB configure une base de données PostgreSQL pour les tests d'intégration (T0041)
func SetupIntegrationDB(t *testing.T) *database.Database {
// Utiliser une base de données de test dédiée
dbURL := testutils.GetTestDatabaseURL()
dbConfig := &database.Config{
URL: dbURL,
MaxOpenConns: 5,
MaxIdleConns: 2,
MaxLifetime: 5 * time.Minute,
MaxIdleTime: 1 * time.Minute,
}
db, err := database.NewDatabase(dbConfig)
require.NoError(t, err, "Failed to setup integration database")
// Nettoyer les tables
testutils.CleanupDatabase(t, db)
t.Cleanup(func() {
testutils.CleanupDatabase(t, db)
if err := db.Close(); err != nil {
t.Logf("Error closing database: %v", err)
}
})
return db
}
// SetupIntegrationTest configure un environnement de test complet (T0041)
func SetupIntegrationTest(t *testing.T) *IntegrationTestSetup {
// Skip si mode short
if testing.Short() {
t.Skip("Skipping integration test in short mode")
}
// Setup database
db := SetupIntegrationDB(t)
// Setup config avec valeurs de test
testConfig := config.NewTestConfig(t)
testConfig.Database = db
// Setup router
gin.SetMode(gin.TestMode)
router := gin.New()
// Note: routes.SetupRoutes nécessite des services complets
// Pour les tests d'intégration, on peut créer un router minimal
// ou utiliser routes.SetupRoutes si tous les services sont configurés
// routes.SetupRoutes(router, ...)
return &IntegrationTestSetup{
DB: db,
Router: router,
Config: testConfig,
}
}
// TestClient simplifie les appels HTTP dans les tests (T0041)
type TestClient struct {
server *httptest.Server
client *http.Client
}
// NewTestClient crée un nouveau client de test (T0041)
func NewTestClient(router *gin.Engine) *TestClient {
server := httptest.NewServer(router)
return &TestClient{
server: server,
client: &http.Client{
Timeout: 30 * time.Second,
},
}
}
// Get fait une requête GET (T0041)
func (c *TestClient) Get(path string) (*http.Response, error) {
return c.client.Get(c.server.URL + path)
}
// GetWithContext fait une requête GET avec contexte (T0041)
func (c *TestClient) GetWithContext(ctx context.Context, path string) (*http.Response, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.server.URL+path, nil)
if err != nil {
return nil, err
}
return c.client.Do(req)
}
// Post fait une requête POST (T0041)
func (c *TestClient) Post(path, contentType string, body []byte) (*http.Response, error) {
return c.client.Post(c.server.URL+path, contentType, http.NoBody)
}
// PostWithBody fait une requête POST avec body (T0041)
func (c *TestClient) PostWithBody(path, contentType string, body []byte) (*http.Response, error) {
req, err := http.NewRequest(http.MethodPost, c.server.URL+path, bytes.NewReader(body))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", contentType)
return c.client.Do(req)
}
// PostWithContext fait une requête POST avec contexte et body (T0041)
func (c *TestClient) PostWithContext(ctx context.Context, path, contentType string, body []byte) (*http.Response, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.server.URL+path, bytes.NewReader(body))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", contentType)
return c.client.Do(req)
}
// Put fait une requête PUT (T0041)
func (c *TestClient) Put(path, contentType string, body []byte) (*http.Response, error) {
req, err := http.NewRequest(http.MethodPut, c.server.URL+path, bytes.NewReader(body))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", contentType)
return c.client.Do(req)
}
// Delete fait une requête DELETE (T0041)
func (c *TestClient) Delete(path string) (*http.Response, error) {
req, err := http.NewRequest(http.MethodDelete, c.server.URL+path, nil)
if err != nil {
return nil, err
}
return c.client.Do(req)
}
// Close ferme le serveur de test (T0041)
func (c *TestClient) Close() {
c.server.Close()
}