admin_handler_pagination.rs
87 lignes · 2933 octets
//! RFC 0022 — anti-régression pagination admin. //! //! Le template `templates/admin/users_list.html` utilisait //! `{% elif p >= page - 2 %}` et `{% elif p == page - 3 %}`, qui //! paniquent en `attempt to subtract with overflow` sur `u64` dès que //! `page < 3`. Toute première visite `/admin/users?page=1` (la valeur //! par défaut) crashait le worker tokio sans log d'erreur. //! //! Le fix utilise les formes additives équivalentes //! `p + 2 >= page && p <= page + 2` et `p + 3 == page || p == page + 3` //! qui n'underflow jamais sur `u64`. Ce fichier vérifie ces formes //! pour tout `(page, p) ∈ [0..10]²` et empêche un retour silencieux //! aux soustractions naïves. /// Mirroir de la condition « afficher la page p si elle est dans la /// fenêtre [page-2 ; page+2] » utilisée dans `users_list.html` ligne 211. #[inline] fn in_window_central(p: u64, page: u64) -> bool { p + 2 >= page && p <= page + 2 } /// Mirroir de la condition « afficher l'ellipse … si p est exactement /// page-3 ou page+3 » utilisée dans `users_list.html` ligne 214. #[inline] fn is_ellipsis_marker(p: u64, page: u64) -> bool { p + 3 == page || p == page + 3 } #[test] fn central_window_does_not_underflow_for_low_pages() { for page in 0u64..=4 { for p in 0u64..=10 { // Ne doit pas paniquer. let _ = in_window_central(p, page); let _ = is_ellipsis_marker(p, page); } } } #[test] fn central_window_matches_naive_subtraction_when_safe() { for page in 3u64..=10 { for p in 0u64..=15 { let additive = in_window_central(p, page); // Comparaison à la version naïve (sûre uniquement quand page >= 2). let naive = p >= page - 2 && p <= page + 2; assert_eq!( additive, naive, "additive form must equal naive form for page={page}, p={p}", ); } } } #[test] fn ellipsis_marker_matches_naive_when_safe() { for page in 3u64..=10 { for p in 0u64..=15 { let additive = is_ellipsis_marker(p, page); // page >= 3 garantit pas d'underflow. let naive = p == page - 3 || p == page + 3; assert_eq!( additive, naive, "additive ellipsis form must equal naive for page={page}, p={p}", ); } } } #[test] fn central_window_rejects_far_outside_pages() { // page=1 : fenêtre centrale = [0, 0..3]. p=4 doit être hors fenêtre. assert!(!in_window_central(4, 1)); // page=10 : fenêtre = [8, 12]. p=7 hors fenêtre. assert!(!in_window_central(7, 10)); } #[test] fn central_window_includes_self() { // Pour toute page, page elle-même est toujours dans la fenêtre. for page in 0u64..=20 { assert!( in_window_central(page, page), "page {page} must always include itself", ); } }
GitRust