Lancer les tests unitaires

Référence des commandes et de la stratégie de tests pour gitrust.

Infrastructure existante

Tests unitaires Rust

cargo test --workspace          # Tous les tests
cargo test -p gitrust-core      # Un crate spécifique
cargo test -p gitrust-git       # Tests Git (tempdir)

Les tests unitaires sont intégrés dans chaque crate via #[cfg(test)].

Tests e2e Playwright

17 specs couvrant : auth, admin, repos, issues, labels, teams, tokens, settings, navigation.

# Pré-requis (première fois)
npm install
./scripts/e2e-setup-db.sh       # Crée la DB gitrust_test

# Lancer les tests
npm run test:e2e                 # Mode headless
npm run test:e2e:ui              # Mode interactif (navigateur visible)
npm run test:e2e:debug           # Mode debug
npm run test:e2e:report          # Voir le rapport HTML

Configuration : playwright.config.ts (port 4001, DB gitrust_test, locale fr-FR).

Structure des répertoires

tests/
  e2e/                    # Specs Playwright (TypeScript)
    global-setup.ts       # Setup : lancer l'app, créer admin
    global-teardown.ts    # Teardown : arrêter l'app
    fixtures.ts           # Fixtures Playwright partagées
    auth.spec.ts          # Tests authentification
    admin.spec.ts         # Tests administration
    issues.spec.ts        # Tests issues
    ...
  integration/            # Tests d'intégration Rust (DB réelle) [à créer]
  fixtures/               # Fichiers de test (repos, configs) [à créer]
  seeds/                  # Seeds Rust pour initialiser la DB de test
    mod.rs
    seed.rs

Tests à ajouter

1. Tests fonctionnels API REST (intégration Rust)

Tests avec une DB PostgreSQL réelle pour vérifier les endpoints API.

Emplacement : tests/integration/ ou crates/gitrust-web/tests/

Approche recommandée : utiliser reqwest + un serveur de test :

// tests/integration/api_test.rs
use reqwest::Client;

#[tokio::test]
#[ignore] // Nécessite une DB + serveur running
async fn test_api_login() {
    let client = Client::new();
    let res = client.post("http://localhost:4001/api/v1/auth/login")
        .json(&serde_json::json!({
            "login": "admin",
            "password": "test_password"
        }))
        .send()
        .await
        .unwrap();
    assert_eq!(res.status(), 200);
}

Alternative : axum::test pour tester les handlers sans serveur HTTP :

use axum::body::Body;
use axum::http::Request;
use tower::ServiceExt;

#[tokio::test]
async fn test_health_check() {
    let app = create_test_app().await; // Build router with test DB
    let response = app
        .oneshot(Request::builder().uri("/api/hello").body(Body::empty()).unwrap())
        .await
        .unwrap();
    assert_eq!(response.status(), 200);
}

2. Tests fonctionnels CI

Test Description Priorité
CI detection Repo avec .gitrust-ci.yml -> Easy, .dagger/ -> Power, rien -> None Haute
Pipeline CRUD Créer, lister, mettre à jour, annuler un pipeline Haute
Config CI Activer/désactiver CI, modifier triggers, vérifier effet Haute
Variables héritage Team var + repo var -> merge correct Moyenne
Auto-cancel Nouveau push annule les pipelines en cours Moyenne
Logs streaming Append logs + lecture paginée Moyenne
Notifications CI Pipeline échoue -> notification créée Moyenne

Pour les tests CI : mocker dagger avec un script shell qui simule success/failure :

#!/bin/bash
# tests/fixtures/mock-dagger.sh
echo "Step 1: Building..."
echo "Step 2: Testing..."
if [ "$MOCK_FAIL" = "true" ]; then
    echo "FAILED" >&2
    exit 1
fi
echo "All checks passed"
exit 0

Configurer CI_DAGGER_BIN=tests/fixtures/mock-dagger.sh dans les tests.

3. Tests e2e Playwright à ajouter

Nouvelles specs pour les fonctionnalités CI et notifications :

Spec Couverture
ci-pipelines.spec.ts Liste pipelines, détail, status badges
ci-config.spec.ts Config CI (enable/disable, triggers, timeout)
ci-variables.spec.ts CRUD variables CI, masquage secrets
notifications.spec.ts Liste notifications, marquer lu, préférences
api-docs.spec.ts Swagger UI accessible, spec chargée
i18n.spec.ts Changement de langue, textes traduits
docker-smoke.spec.ts docker compose up + smoke test

Exemple de spec CI :

// tests/e2e/ci-pipelines.spec.ts
import { test, expect } from './fixtures';

test.describe('CI Pipelines', () => {
  test('affiche la page CI vide', async ({ authenticatedPage }) => {
    await authenticatedPage.goto('/admin/mon-repo/ci');
    await expect(authenticatedPage.locator('text=Aucun pipeline')).toBeVisible();
  });

  test('bouton trigger CI visible pour le maintainer', async ({ authenticatedPage }) => {
    await authenticatedPage.goto('/admin/mon-repo/ci');
    await expect(authenticatedPage.locator('text=Lancer CI')).toBeVisible();
  });
});

4. Tests settings ↔ comportement

Les tests les plus critiques vérifient que changer un setting modifie le comportement observable :

Setting Action Vérification
PAT révoqué Appel API 401 immédiatement
ci_enabled = false Push Pas de pipeline créé
trigger_on_push = false Push Pas de pipeline
auto_cancel = true 2 pushes rapides 1er pipeline annulé
email_on_pipeline_failure = false Pipeline échoue Pas d'email, notif in-app ok
DEFAULT_LOCALE = en Charger page Texte en anglais

Commandes de test

# Tests unitaires Rust
cargo test --workspace

# Tests avec filtrage
cargo test -p gitrust-core -- ci_service
cargo test -p gitrust-core -- notification

# Tests e2e Playwright
npm run test:e2e

# Tests e2e spécifiques
npx playwright test tests/e2e/ci-pipelines.spec.ts
npx playwright test --grep "notifications"

# Lint
cargo clippy --workspace -- -D warnings

# Format check
cargo fmt --all -- --check

CI locale (exécuter avant un push)

# Script rapide de vérification pré-push
cargo fmt --all -- --check && \
cargo clippy --workspace -- -D warnings && \
cargo test --workspace && \
echo "All checks passed"