0022-smoke-tests-regression.md 5295 octets

RFC 0022 — Smoke tests anti-régression (middleware + pagination)

  • Auteur : EBO (rustwarden)
  • Date : 2026-05-10
  • Statut : Accepted (auto-revue mainteneur unique 2026-05-10, score 26/35)
  • Apps consommatrices concernées : toutes — ces tests vivent dans rustwarden-core et rustwarden-ui et tournent dans le suite par défaut.
  • Plan associé : aucun (livrable autonome qui répond à une régression observée le 2026-05-10).

Summary

Ajouter deux fichiers de tests qui auraient permis de détecter en CI les régressions découvertes manuellement aujourd'hui :

  1. crates/rustwarden-core/tests/middleware_authconfig_fallback.rs — vérifie que AuthService et AdminService ne renvoient pas 500 quand Extension(Arc<AuthConfig>) n'est pas appliqué avant dans le ServiceBuilder (c'est-à-dire qu'ils retombent bien sur AuthConfig::from_env()).
  2. crates/rustwarden-ui/tests/admin_handler_pagination.rs — vérifie que admin_handler::list_users ne panique pas sur ?page=0, ?page=1, ?page=2 (le template users_list.html faisait page - 2 qui underflow sur u64).

Les deux tests sont isolés (Mock DB / direct service call), pas de PostgreSQL ni de runtime complet requis. Total : ~120 LoC.

Motivation

Les régressions vues aujourd'hui :

  • Régression 1 (commit d4d6828, 2026-05-08) — AuthService est passé de AuthConfig::from_env() à parts.extensions.get::<Arc<AuthConfig>>() strict. Tout consommateur dont le ServiceBuilder met le layer Extension(auth_config) après le layer AuthService voit toutes les routes protégées renvoyer 500 silencieusement (pas de log ERROR). Idem AdminService et admin_helper.
  • Régression 2 (pré-existante) — templates/admin/users_list.html lignes 211 / 214 contiennent p >= page - 2 et p == page - 3. Sur u64, ces soustractions paniquent quand page < 3. Toute première visite /admin/users (par défaut page=1) crash le worker tokio.

Ce que les tests existants ne couvraient pas :

  • Aucun test n'instancie un ServiceBuilder proche de la prod et fire une requête.
  • Aucun test n'exerce list_users avec page=1 (les 6 tests rustwarden-ui couvrent uniquement les DTOs).
  • clippy / cargo doc / les unit tests de RFC 0011/0021 ne touchent pas le câblage middleware ni les chemins de rendu Askama.

Non-goals

  • Pas de smoke test full-stack qui boote RustwardenApp::build() et lance un serveur réel. Trop coûteux en CI ; suivi dans une RFC future.
  • Pas de property-based tests sur la pagination — un échantillon de pages représentatives suffit pour cette classe de bug.
  • Pas d'intégration wiremock ici — ces tests ciblent le câblage interne, pas l'interop externe (déjà couvert RFC 0020).

API proposée

Aucune API publique modifiée.

Test 1 — middleware AuthConfig fallback

crates/rustwarden-core/tests/middleware_authconfig_fallback.rs

Stratégie :

  1. Setter JWT_SECRET et autres variables AuthConfig minimales.
  2. Construire un ServiceBuilder qui n'a pas de .layer(Extension(Arc<AuthConfig>)).
  3. Le wrapper avec AuthService::new(inner, db).
  4. Fire une requête sur /anything avec un JWT cookie minimal.
  5. Asserter que la réponse n'est pas 500.

Test 2 — pagination handler

crates/rustwarden-ui/tests/admin_handler_pagination.rs

Stratégie : pour chaque page ∈ {0, 1, 2, 3, 100}, instancier Query<UserListQuery>, appeler list_users avec MockDatabase (vide ou 1 user), asserter Ok(200) et l'absence de panic.

Compatibilité

Aucun impact runtime. Les tests sont sous [dev-dependencies] existants. Pas de nouvelle dépendance.

Alternatives

  1. Ne rien faire — rejeté : régressions silencieuses quasi-certaines (déjà 2 en 48 h).
  2. Smoke test full-stack avec PostgreSQL — différé : exige docker-compose en CI, latence × 30s.
  3. Property-based via proptest — différé : utile pour la pagination mais on couvre les cas avec 5 valeurs représentatives.

Testing plan

Les tests sont eux-mêmes le testing plan. Validation :

  • cargo test --workspace -p rustwarden-core --test middleware_authconfig_fallback → 1 pass
  • cargo test --workspace -p rustwarden-ui --test admin_handler_pagination → 5 pass (un par valeur de page)
  • Reverter manuellement les fixes des bugs d'aujourd'hui → les tests doivent échouer, prouvant qu'ils ferment la boucle.

Migration guide

Aucune. Les tests sont additifs.

Open questions

  • Q1 : faut-il étendre à un vrai smoke test avec axum::serve ? Réponse : oui, suivi RFC 0023 quand on aura besoin (par ex. valider un lifecycle complet de session).

Score (26/35)

CritèreNoteDétail
Généralité4/5Sert toute app rustwarden-*.
Stabilité API5/5Tests purs, zéro impact API.
Performance5/5MockDatabase + service unitaire = ms par test.
Sécurité3/5Indirectement : empêche un 500 silencieux exploitable comme oracle.
Complexité3/5~120 LoC totaux, bien dans la norme.
Maintenance3/5Les tests doivent évoluer avec la signature des middlewares.
Documentation3/5Cette RFC + commentaires inline.