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() }