1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//! gradatum-server library API for integration tests.
//!
//! T8 expose `api_v1` et `stubs` pour les tests d'intégration.
//! T9 expose `middleware` pour les tests vérifiant l'extraction JWT.
//! T10 expose `health` pour le test d'intégration `health.rs`.
//! T10 (P2.0b) expose `audit_jsonl` pour `JsonlFileSink` (caveat C4).
//! AUTH-T5 expose `auth_routes` pour le handler `/auth/exchange`.
//! W1 expose `build_rate_limit_test_app` pour les tests E2E rate limit.
/// Construit un router Axum minimal pour les tests E2E du rate limiting.
///
/// Route exposée : `GET /ping` → 200 "pong" (pas d'authentification).
/// La pile middleware utilise [`gradatum_warden::WardenLayer`] identique à la prod.
///
/// # Bypass loopback
///
/// Contrairement à l'ancienne implémentation `tower_governor` (error_handler retournait
/// `Body::empty()`), le warden appelle directement `inner.call(req)` pour les IPs loopback.
/// Le body retourné est le "pong" réel du handler.
///
/// # Usage dans les tests
///
/// Injecter `ConnectInfo<SocketAddr>` dans les extensions de la requête via
/// `req.extensions_mut().insert(ConnectInfo(addr))` avant `tower::ServiceExt::oneshot`.
///
/// # Remarques
///
/// - Si `rl.enabled == false` : aucun rate limiting, `/ping` répond toujours 200.
/// - Si `rl.exempt_localhost == false` : les connexions loopback sont rate-limitées.
/// - Pour tester le throttle depuis un test local, utiliser `exempt_localhost=false`.