RUN  v2.1.9 D:/Jeu/RollerLogic/rollerlogic-api Ô£ô src/routes/__tests__/security.test.ts > security > JWT validation > rejette les tokens JWT malform├®s Ô£ô src/routes/__tests__/security.test.ts > security > JWT validation > rejette les tokens JWT expir├®s Ô£ô src/routes/__tests__/security.test.ts > security > JWT validation > valide les tokens JWT avec la bonne signature Ô£ô src/routes/__tests__/security.test.ts > security > XSS prevention > ├®chappe les caract├¿res HTML dangereux Ô£ô src/routes/__tests__/security.test.ts > security > XSS prevention > valide que les usernames ne contiennent pas de scripts Ô£ô src/routes/__tests__/security.test.ts > security > XSS prevention > valide les URLs pour ├®viter les redirections dangereuses Ô£ô src/routes/__tests__/security.test.ts > security > injection prevention > ├®chappe les valeurs SQL Ô£ô src/routes/__tests__/security.test.ts > security > injection prevention > valide que les param├¿tres ne contiennent pas de commandes shell Ô£ô src/routes/__tests__/security.test.ts > security > injection prevention > valide les email pour ├®viter les injections SMTP Ô£ô src/routes/__tests__/security.test.ts > security > CSRF prevention > valide les CSRF tokens Ô£ô src/routes/__tests__/security.test.ts > security > CSRF prevention > rejette les requ├¬tes POST sans CSRF token Ô£ô src/routes/__tests__/security.test.ts > security > rate limiting > respecte les limites de d├®bit pour l'authentification Ô£ô src/routes/__tests__/security.test.ts > security > password security > valide la force du mot de passe Ô£ô src/routes/__tests__/security.test.ts > security > password security > ne stocke pas les mots de passe en clair Ô£ô src/routes/__tests__/security.test.ts > security > authorization checks > v├®rifie que les users ne peuvent acc├®der qu'├á leurs donn├®es Ô£ô src/routes/__tests__/security.test.ts > security > authorization checks > emp├¬che l'escalade de privil├¿ges Ô£ô src/routes/__tests__/security.test.ts > security > data validation > valide les types de donn├®es entrantes Ô£ô src/routes/__tests__/security.test.ts > security > data validation > limite la taille des payloads Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > database error handling > g├¿re les erreurs de connexion DB Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > database error handling > g├¿re les timeouts de requ├¬te DB Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > database error handling > g├¿re les contraintes d'int├®grit├® DB Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > validation errors > rejette les valeurs null/undefined Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > validation errors > valide les longueurs min/max Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > validation errors > valide les nombres min/max Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > validation errors > valide les formats d'enum Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > validation errors > g├¿re les valeurs d├®cimales invalides Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > input sanitization > supprime les espaces blancs Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > input sanitization > normalise la casse Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > input sanitization > filtre les caract├¿res non autoris├®s Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > input sanitization > g├¿re les valeurs vides apr├¿s normalisation Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > rate limiting & throttling > compte les tentatives ├®chou├®es Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > rate limiting & throttling > r├®initialise le compteur apr├¿s la fen├¬tre d'expiration Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > rate limiting & throttling > rejette les requ├¬tes apr├¿s le d├®passement de limite Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > concurrent request handling > g├¿re les condition races sur les updates Ô£ô src/server/__tests__/email-service.test.ts > email-service > escapeHtml > ├®chappe le caract├¿re & Ô£ô src/server/__tests__/email-service.test.ts > email-service > escapeHtml > ├®chappe le caract├¿re < Ô£ô src/server/__tests__/email-service.test.ts > email-service > escapeHtml > ├®chappe le caract├¿re > Ô£ô src/server/__tests__/email-service.test.ts > email-service > escapeHtml > ├®chappe le caract├¿re " Ô£ô src/server/__tests__/email-service.test.ts > email-service > escapeHtml > ├®chappe le caract├¿re ' Ô£ô src/server/__tests__/email-service.test.ts > email-service > escapeHtml > ├®chappe tous les caract├¿res sp├®ciaux ensemble Ô£ô src/server/__tests__/email-service.test.ts > email-service > escapeHtml > ne modifie pas une cha├«ne sans caract├¿res sp├®ciaux Ô£ô src/server/__tests__/email-service.test.ts > email-service > escapeHtml > g├¿re une cha├«ne vide Ô£ô src/server/__tests__/email-service.test.ts > email-service > escapeHtml > ├®chappe les multiples occurrences Ô£ô src/server/__tests__/email-service.test.ts > email-service > buildResetEmail > retourne subject, text et html Ô£ô src/server/__tests__/email-service.test.ts > email-service > buildResetEmail > inclut le lien de reset si appUrl est fourni Ô£ô src/server/__tests__/email-service.test.ts > email-service > buildResetEmail > supprime le trailing slash de appUrl Ô£ô src/server/__tests__/email-service.test.ts > email-service > buildResetEmail > utilise le nom personnalis├® si fromName est fourni Ô£ô src/server/__tests__/email-service.test.ts > email-service > buildResetEmail > utilise le nom par d├®faut si fromName est absent Ô£ô src/server/__tests__/email-service.test.ts > email-service > buildResetEmail > contient le token dans le texte brut Ô£ô src/server/__tests__/email-service.test.ts > email-service > buildContactEmail > retourne subject, text et html Ô£ô src/server/__tests__/email-service.test.ts > email-service > buildContactEmail > utilise le sujet par d├®faut si non fourni Ô£ô src/server/__tests__/email-service.test.ts > email-service > buildContactEmail > utilise le sujet personnalis├® si fourni Ô£ô src/server/__tests__/email-service.test.ts > email-service > buildContactEmail > inclut l'email et le userId dans le texte Ô£ô src/server/__tests__/email-service.test.ts > email-service > buildContactEmail > inclut le message dans le texte Ô£ô src/server/__tests__/email-service.test.ts > email-service > buildContactEmail > inclut l'IP si fournie Ô£ô src/server/__tests__/email-service.test.ts > email-service > buildContactEmail > inclut le User-Agent si fourni Ô£ô src/server/__tests__/email-service.test.ts > email-service > buildContactEmail > tronque le User-Agent ├á 100 caract├¿res dans le HTML Ô£ô src/server/__tests__/email-service.test.ts > email-service > buildContactEmail > ├®chappe le HTML dans le displayName Ô£ô src/server/__tests__/email-service.test.ts > email-service > buildContactEmail > ├®chappe le HTML dans le message Ô£ô src/server/__tests__/email-service.test.ts > email-service > buildContactEmail > ne contient pas d'IP si non fournie Ô£ô src/routes/__tests__/webhook-routes.test.ts > webhook-routes > retourne 503 si Stripe non configur├® Ô£ô src/routes/__tests__/webhook-routes.test.ts > webhook-routes > retourne 400 si signature manquante Ô£ô src/routes/__tests__/webhook-routes.test.ts > webhook-routes > idempotence > traite un paiement cash dans une transaction Ô£ô src/routes/__tests__/webhook-routes.test.ts > webhook-routes > idempotence > ignore un webhook doublon (session d├®j├á trait├®e) Ô£ô src/routes/__tests__/webhook-routes.test.ts > webhook-routes > idempotence > rollback + cleanup si erreur pendant le traitement Ô£ô src/routes/__tests__/misc-routes.test.ts > contact-routes > POST /contact > envoie un message de contact valide Ô£ô src/routes/__tests__/admin-panel-routes.test.ts > admin-panel-routes > GET /admin/stats > retourne les stats dashboard Ô£ô src/routes/__tests__/admin-panel-routes.test.ts > admin-panel-routes > GET /admin/players > retourne une liste pagin├®e de joueurs Ô£ô src/routes/__tests__/admin-panel-routes.test.ts > admin-panel-routes > GET /admin/players > supporte la recherche Ô£ô src/routes/__tests__/admin-panel-routes.test.ts > admin-panel-routes > GET /admin/players > filtre par statut Ô£ô src/routes/__tests__/admin-panel-routes.test.ts > admin-panel-routes > GET /admin/players/:id > retourne les d├®tails d'un joueur Ô£ô src/routes/__tests__/admin-panel-routes.test.ts > admin-panel-routes > GET /admin/players/:id > retourne 404 pour un joueur inexistant Ô£ô src/routes/__tests__/admin-panel-routes.test.ts > admin-panel-routes > GET /admin/players/:id > retourne 400 pour un id invalide Ô£ô src/routes/__tests__/admin-panel-routes.test.ts > admin-panel-routes > POST /admin/players/:id/ban > bannit un joueur normal Ô£ô src/routes/__tests__/gamemode-routes.test.ts > gamemode-routes > GET /arcade/:userId > retourne les records arcade Ô£ô src/routes/__tests__/gamemode-routes.test.ts > gamemode-routes > GET /arcade/:userId > retourne 403 si userId ne correspond pas Ô£ô src/routes/__tests__/gamemode-routes.test.ts > gamemode-routes > GET /arcade/:userId > retourne 400 pour userId non num├®rique Ô£ô src/routes/__tests__/gamemode-routes.test.ts > gamemode-routes > POST /arcade/:userId/record > enregistre un score arcade valide Ô£ô src/routes/__tests__/wallet-routes.test.ts > wallet-routes > GET /wallet/:userId > retourne le wallet pour l'utilisateur authentifi├® Ô£ô src/routes/__tests__/wallet-routes.test.ts > wallet-routes > GET /wallet/:userId > retourne 403 si userId ne correspond pas au token Ô£ô src/routes/__tests__/wallet-routes.test.ts > wallet-routes > GET /wallet/:userId > retourne 400 si userId n'est pas un nombre Ô£ô src/routes/__tests__/wallet-routes.test.ts > wallet-routes > POST /wallet/reward > ajoute les points de r├®compense Ô£ô src/routes/__tests__/avatar-pack-routes.test.ts > avatar-pack-routes > GET /avatar-packs > retourne la liste des packs Ô£ô src/routes/__tests__/avatar-pack-routes.test.ts > avatar-pack-routes > GET /avatar-packs/:packId > retourne un pack existant Ô£ô src/routes/__tests__/avatar-pack-routes.test.ts > avatar-pack-routes > GET /avatar-packs/:packId > retourne 404 pour un pack inexistant Ô£ô src/routes/__tests__/avatar-pack-routes.test.ts > avatar-pack-routes > GET /avatar-packs/user/:userId > retourne les packs poss├®d├®s par l'utilisateur Ô£ô src/routes/__tests__/avatar-pack-routes.test.ts > avatar-pack-routes > GET /avatar-packs/user/:userId > retourne 403 si userId ne correspond pas Ô£ô src/routes/__tests__/avatar-pack-routes.test.ts > avatar-pack-routes > POST /avatar-packs/purchase/:userId > refuse sans transactionId Ô£ô src/routes/__tests__/stats-routes.test.ts > stats-routes > GET /stats/:userId > retourne les stats pour l'utilisateur authentifi├® Ô£ô src/routes/__tests__/stats-routes.test.ts > stats-routes > GET /stats/:userId > retourne 403 si userId ne correspond pas Ô£ô src/routes/__tests__/stats-routes.test.ts > stats-routes > GET /stats/:userId > retourne 400 pour userId non num├®rique Ô£ô src/routes/__tests__/stats-routes.test.ts > stats-routes > POST /stats/:userId/level-complete > enregistre une compl├®tion de niveau valide Ô£ô src/routes/__tests__/weekly-routes.test.ts > weekly-routes > GET /weekly/:userId > retourne le challenge hebdomadaire Ô£ô src/routes/__tests__/weekly-routes.test.ts > weekly-routes > GET /weekly/:userId > retourne 403 si userId ne correspond pas Ô£ô src/routes/__tests__/weekly-routes.test.ts > weekly-routes > GET /weekly/:userId > retourne 400 pour un userId non num├®rique Ô£ô src/routes/__tests__/weekly-routes.test.ts > weekly-routes > POST /weekly/:userId/complete > refuse un dayOfWeek < 1 Ô£ô src/routes/__tests__/bonus-routes.test.ts > bonus-routes > GET /bonus/daily > retourne le status du bonus quotidien pour un user authentifi├® Ô£ô src/routes/__tests__/bonus-routes.test.ts > bonus-routes > GET /bonus/daily > retourne 401 sans authentification Ô£ô src/routes/__tests__/bonus-routes.test.ts > bonus-routes > POST /bonus/daily/claim > tente de r├®clamer le bonus quotidien Ô£ô src/routes/__tests__/bonus-routes.test.ts > bonus-routes > POST /bonus/daily/claim > retourne 401 sans authentification Ô£ô src/routes/__tests__/bonus-routes.test.ts > bonus-routes > GET /bonus/arcade > retourne le status du bonus arcade Ô£ô src/routes/__tests__/bonus-routes.test.ts > bonus-routes > GET /bonus/arcade > retourne 401 sans authentification Ô£ô src/routes/__tests__/bonus-routes.test.ts > bonus-routes > POST /bonus/arcade/record > enregistre une partie arcade termin├®e Ô£ô src/routes/__tests__/bonus-routes.test.ts > bonus-routes > POST /bonus/arcade/record > retourne 401 sans authentification Ô£ô src/routes/__tests__/misc-routes.test.ts > contact-routes > POST /contact > refuse un message trop court (< 10 caract├¿res) Ô£ô src/routes/__tests__/misc-routes.test.ts > contact-routes > POST /contact > refuse sans message dans le payload Ô£ô src/routes/__tests__/misc-routes.test.ts > contact-routes > POST /contact > accepte un sujet optionnel Ô£ô src/routes/__tests__/misc-routes.test.ts > ads-routes > GET /ads/daily/:userId (ads d├®sactiv├®es) > retourne 503 quand les pubs sont d├®sactiv├®es Ô£ô src/routes/__tests__/misc-routes.test.ts > ads-routes > GET /ads/daily/:userId (ads activ├®es) > retourne le status quand authentifi├® Ô£ô src/routes/__tests__/misc-routes.test.ts > ads-routes > GET /ads/daily/:userId (ads activ├®es) > retourne 403 si userId ne correspond pas Ô£ô src/routes/__tests__/misc-routes.test.ts > ads-routes > POST /ads/daily/reward (ads d├®sactiv├®es) > retourne 503 quand les pubs sont d├®sactiv├®es Ô£ô src/routes/__tests__/misc-routes.test.ts > ads-routes > POST /ads/double-points > refuse si payload invalide Ô£ô src/routes/__tests__/admin-panel-routes.test.ts > admin-panel-routes > POST /admin/players/:id/ban > refuse de bannir un admin Ô£ô src/routes/__tests__/admin-panel-routes.test.ts > admin-panel-routes > POST /admin/players/:id/ban > retourne 404 pour joueur inexistant Ô£ô src/routes/__tests__/admin-panel-routes.test.ts > admin-panel-routes > POST /admin/players/:id/unban > d├®bannit un joueur Ô£ô src/routes/__tests__/admin-panel-routes.test.ts > admin-panel-routes > POST /admin/db/reset > refuse sans confirmation RESET Ô£ô src/routes/__tests__/admin-panel-routes.test.ts > admin-panel-routes > GET /admin/analytics > retourne les analytics Ô£ô src/routes/__tests__/admin-panel-routes.test.ts > admin-panel-routes > GET /admin/logs > retourne les logs pagin├®s Ô£ô src/routes/__tests__/admin-panel-routes.test.ts > admin-panel-routes > DELETE /admin/players/:id > refuse de supprimer un admin Ô£ô src/routes/__tests__/admin-panel-routes.test.ts > admin-panel-routes > DELETE /admin/players/:id > retourne 404 pour joueur inexistant Ô£ô src/routes/__tests__/admin-panel-routes.test.ts > admin-panel-routes > POST /admin/ban-email > bannit par email valide Ô£ô src/routes/__tests__/admin-panel-routes.test.ts > admin-panel-routes > POST /admin/ban-email > refuse un email invalide Ô£ô src/routes/__tests__/avatar-pack-routes.test.ts > avatar-pack-routes > POST /avatar-packs/purchase/:userId > refuse si userId ne correspond pas Ô£ô src/routes/__tests__/avatar-pack-routes.test.ts > avatar-pack-routes > POST /avatar-packs/purchase/:userId > refuse un pack inexistant Ô£ô src/routes/__tests__/gamemode-routes.test.ts > gamemode-routes > POST /arcade/:userId/record > refuse un score n├®gatif Ô£ô src/routes/__tests__/gamemode-routes.test.ts > gamemode-routes > POST /arcade/:userId/record > refuse sans score Ô£ô src/routes/__tests__/gamemode-routes.test.ts > gamemode-routes > POST /arcade/:userId/record > refuse si userId ne correspond pas Ô£ô src/routes/__tests__/gamemode-routes.test.ts > gamemode-routes > GET /infinite/:userId > retourne les records infini Ô£ô src/routes/__tests__/gamemode-routes.test.ts > gamemode-routes > GET /infinite/:userId > retourne 403 si userId ne correspond pas Ô£ô src/routes/__tests__/wallet-routes.test.ts > wallet-routes > POST /wallet/reward > applique la p├®nalit├® auto-solve Ô£ô src/routes/__tests__/wallet-routes.test.ts > wallet-routes > POST /wallet/reward > refuse sans difficult├® Ô£ô src/routes/__tests__/wallet-routes.test.ts > wallet-routes > POST /wallet/reward > refuse une difficult├® invalide Ô£ô src/routes/__tests__/wallet-routes.test.ts > wallet-routes > POST /wallet/reward > refuse si userId ne correspond pas au token Ô£ô src/routes/__tests__/wallet-routes.test.ts > wallet-routes > POST /wallet/purchase > ach├¿te un pack valide Ô£ô src/routes/__tests__/wallet-routes.test.ts > wallet-routes > POST /wallet/purchase > refuse un pack inexistant Ô£ô src/routes/__tests__/misc-routes.test.ts > ads-routes > POST /ads/double-points > refuse basePoints hors limites Ô£ô src/server/__tests__/user-service.test.ts > user-service > mapUserRow > mappe les champs obligatoires Ô£ô src/server/__tests__/user-service.test.ts > user-service > mapUserRow > extrait le displayName depuis l'email si absent Ô£ô src/server/__tests__/user-service.test.ts > user-service > mapUserRow > utilise le displayName fourni Ô£ô src/server/__tests__/user-service.test.ts > user-service > mapUserRow > fallback ├á 'Joueur' si email est vide Ô£ô src/server/__tests__/user-service.test.ts > user-service > mapUserRow > convertit guest 0/1 en boolean Ô£ô src/server/__tests__/user-service.test.ts > user-service > mapUserRow > convertit isAdmin en boolean Ô£ô src/server/__tests__/user-service.test.ts > user-service > mapUserRow > convertit vipNoAds en boolean Ô£ô src/server/__tests__/user-service.test.ts > user-service > mapUserRow > g├¿re les valeurs null pour avatar/accent/title/motto Ô£ô src/server/__tests__/user-service.test.ts > user-service > mapUserRow > mappe les valeurs optionnelles quand pr├®sentes Ô£ô src/server/__tests__/user-service.test.ts > user-service > mapUserRow > failedAttempts default ├á 0 si null/undefined Ô£ô src/server/__tests__/user-service.test.ts > user-service > mapUserRow > failedAttempts default ├á 0 si NaN Ô£ô src/server/__tests__/user-service.test.ts > user-service > toPublicUser > retourne les champs publics Ô£ô src/server/__tests__/user-service.test.ts > user-service > toPublicUser > ne contient PAS les donn├®es sensibles Ô£ô src/server/__tests__/user-service.test.ts > user-service > toPublicUser > inclut vipNoAds et vipExpiresAt Ô£ô src/routes/__tests__/gamemode-routes.test.ts > gamemode-routes > POST /infinite/:userId/record > enregistre un record infini valide Ô£ô src/routes/__tests__/stats-routes.test.ts > stats-routes > POST /stats/:userId/level-complete > refuse un temps trop court (< 500ms) Ô£ô src/routes/__tests__/stats-routes.test.ts > stats-routes > POST /stats/:userId/level-complete > refuse une difficult├® invalide Ô£ô src/routes/__tests__/stats-routes.test.ts > stats-routes > POST /stats/:userId/level-complete > refuse sans payload complet Ô£ô src/routes/__tests__/stats-routes.test.ts > stats-routes > POST /stats/:userId/level-complete > refuse si userId ne correspond pas Ô£ô src/routes/__tests__/stats-routes.test.ts > stats-routes > POST /stats/:userId/tutorial > marque le tutoriel comme compl├®t├® Ô£ô src/routes/__tests__/stats-routes.test.ts > stats-routes > POST /stats/:userId/tutorial > refuse si userId ne correspond pas Ô£ô src/routes/__tests__/misc-routes.test.ts > ads-routes > POST /ads/double-points > refuse si userId ne correspond pas Ô£ô src/routes/__tests__/gamemode-routes.test.ts > gamemode-routes > POST /infinite/:userId/record > refuse sans levels Ô£ô src/routes/__tests__/wallet-routes.test.ts > wallet-routes > POST /wallet/purchase > refuse sans payload Ô£ô src/routes/__tests__/weekly-routes.test.ts > weekly-routes > POST /weekly/:userId/complete > refuse un dayOfWeek > 7 Ô£ô src/routes/__tests__/weekly-routes.test.ts > weekly-routes > POST /weekly/:userId/complete > refuse sans dayOfWeek Ô£ô src/routes/__tests__/weekly-routes.test.ts > weekly-routes > POST /weekly/:userId/complete > refuse si userId ne correspond pas Ô£ô src/routes/__tests__/weekly-routes.test.ts > weekly-routes > POST /weekly/:userId/complete > compl├¿te un d├®fi journalier valide Ô£ô src/routes/__tests__/weekly-routes.test.ts > weekly-routes > POST /weekly/:userId/claim > refuse si userId ne correspond pas Ô£ô src/routes/__tests__/weekly-routes.test.ts > weekly-routes > POST /weekly/:userId/claim > tente le claim pour l'utilisateur authentifi├® Ô£ô src/routes/__tests__/weekly-routes.test.ts > weekly-routes > GET /weekly/:userId/avatars > retourne les avatars gagn├®s Ô£ô src/routes/__tests__/weekly-routes.test.ts > weekly-routes > GET /weekly/:userId/avatars > retourne 403 si userId ne correspond pas Ô£ô src/routes/__tests__/misc-routes.test.ts > ads-routes > POST /ads/free-solution (ads d├®sactiv├®es) > retourne 503 quand les pubs sont d├®sactiv├®es Ô£ô src/routes/__tests__/gamemode-routes.test.ts > gamemode-routes > POST /infinite/:userId/record > refuse un levels n├®gatif Ô£ô src/routes/__tests__/gamemode-routes.test.ts > gamemode-routes > POST /infinite/:userId/record > refuse si userId ne correspond pas Ô£ô src/routes/__tests__/wallet-routes.test.ts > wallet-routes > POST /wallet/consume > consomme un hint Ô£ô src/routes/__tests__/wallet-routes.test.ts > wallet-routes > POST /wallet/consume > refuse un kind invalide Ô£ô src/routes/__tests__/wallet-routes.test.ts > wallet-routes > POST /wallet/consume > refuse sans payload Ô£ô src/routes/__tests__/wallet-routes.test.ts > settings-routes > GET /settings/:userId > retourne les param├¿tres pour l'utilisateur Ô£ô src/routes/__tests__/wallet-routes.test.ts > settings-routes > GET /settings/:userId > retourne 403 si userId ne correspond pas stderr | src/routes/__tests__/error-handling.test.ts > error handling & edge cases > concurrent request handling > g├¿re les deadlocks avec timeout Promise returned by `expect(actual).rejects.toThrow(expected)` was not awaited. Vitest currently auto-awaits hanging assertions at the end of the test, but this will cause the test to fail in Vitest 3. Please remember to await the assertion. at D:/Jeu/RollerLogic/rollerlogic-api/src/routes/__tests__/error-handling.test.ts:318:49 Ô£ô src/routes/__tests__/wallet-routes.test.ts > settings-routes > PUT /settings/:userId > met ├á jour les param├¿tres valides Ô£ô src/routes/__tests__/wallet-routes.test.ts > settings-routes > PUT /settings/:userId > refuse un theme invalide Ô£ô src/routes/__tests__/wallet-routes.test.ts > settings-routes > PUT /settings/:userId > refuse un animationSpeed invalide Ô£ô src/routes/__tests__/wallet-routes.test.ts > settings-routes > PUT /settings/:userId > refuse sfxVolume hors limites Ô£ô src/routes/__tests__/wallet-routes.test.ts > progress-routes > GET /progress/:userId > retourne la progression Ô£ô src/routes/__tests__/wallet-routes.test.ts > progress-routes > GET /progress/:userId > retourne 403 si userId ne correspond pas Ô£ô src/routes/__tests__/wallet-routes.test.ts > progress-routes > POST /progress/:userId/increment > incr├®mente la progression Ô£ô src/routes/__tests__/wallet-routes.test.ts > progress-routes > POST /progress/:userId/increment > refuse une difficult├® invalide Ô£ô src/routes/__tests__/wallet-routes.test.ts > progress-routes > POST /progress/:userId/increment > refuse sans difficult├® Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > concurrent request handling > g├¿re les deadlocks avec timeout 1023ms Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > resource limits > limite la taille des uploads Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > resource limits > limite le nombre de r├®sultats pagin├®s Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > state consistency > g├¿re les transitions d'├®tat invalides Ô£ô src/routes/__tests__/error-handling.test.ts > error handling & edge cases > state consistency > g├¿re les commandes idempotentes Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseLevelPayload > retourne null si payload est null Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseLevelPayload > retourne null si payload est undefined Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseLevelPayload > retourne null si payload est une cha├«ne vide Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseLevelPayload > retourne null si payload est 0 Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseLevelPayload > parse une cha├«ne JSON valide Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseLevelPayload > retourne null pour une cha├«ne JSON invalide Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseLevelPayload > retourne l'objet tel quel s'il n'est pas une cha├«ne Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseLevelPayload > retourne un tableau tel quel Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseLevelPayload > parse un tableau JSON string Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonArray > retourne un tableau de strings filtr├® depuis un tableau Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonArray > retourne un tableau vide pour un tableau vide Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonArray > parse une cha├«ne JSON contenant un tableau de strings Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonArray > filtre les non-strings depuis un JSON Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonArray > retourne un tableau vide pour un JSON non-tableau Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonArray > retourne un tableau vide pour une cha├«ne JSON invalide Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonArray > retourne un tableau vide pour null Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonArray > retourne un tableau vide pour undefined Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonArray > retourne un tableau vide pour un nombre Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonArray > retourne un tableau vide pour une cha├«ne vide Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonNumberArray > retourne un tableau de nombres filtr├® depuis un tableau Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonNumberArray > retourne un tableau vide pour un tableau vide Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonNumberArray > parse une cha├«ne JSON contenant des nombres Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonNumberArray > convertit les strings num├®riques depuis un JSON Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonNumberArray > exclut les NaN Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonNumberArray > retourne un tableau vide pour null Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonNumberArray > retourne un tableau vide pour undefined Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonNumberArray > retourne un tableau vide pour un JSON non-tableau Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonNumberArray > retourne un tableau vide pour une cha├«ne vide Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonNumberArray > retourne un tableau vide pour une cha├«ne JSON invalide Ô£ô src/server/__tests__/parsers.test.ts > parsers > parseJsonNumberArray > g├¿re un m├®lange de nombres et strings num├®riques Ô£ô src/server/__tests__/badges.test.ts > badges > aucun badge si rien n'est compl├®t├® Ô£ô src/server/__tests__/badges.test.ts > badges > badge starter ├á 1 compl├®tion Ô£ô src/server/__tests__/badges.test.ts > badges > badge explorer ├á 10 compl├®tions Ô£ô src/server/__tests__/badges.test.ts > badges > badge solver ├á 25 compl├®tions Ô£ô src/server/__tests__/badges.test.ts > badges > badge veteran ├á 100 compl├®tions Ô£ô src/server/__tests__/badges.test.ts > badges > badge marathon ├á 250 compl├®tions Ô£ô src/server/__tests__/badges.test.ts > badges > badge replay ├á 50 totalCompletions Ô£ô src/server/__tests__/badges.test.ts > badges > badge steady ├á 1000 totalMoves Ô£ô src/server/__tests__/badges.test.ts > badges > badge endurance ├á 3600 totalTime Ô£ô src/server/__tests__/badges.test.ts > badges > badge tutorial si tutorialCompleted Ô£ô src/server/__tests__/badges.test.ts > badges > badge all-rounder si tous les modes ont au moins 1 Ô£ô src/server/__tests__/badges.test.ts > badges > pas de badge all-rounder si un mode manque Ô£ô src/server/__tests__/badges.test.ts > badges > badge specialist ├á 50% d'une difficult├® (120/240) Ô£ô src/server/__tests__/badges.test.ts > badges > pas de badge specialist ├á 49% Ô£ô src/server/__tests__/badges.test.ts > badges > badge master si toutes les 960 niveaux compl├®t├®s Ô£ô src/server/__tests__/badges.test.ts > badges > pas de badge master ├á 959 niveaux Ô£ô src/server/__tests__/badges.test.ts > badges > joueur complet a tous les 12 badges Ô£ô src/routes/__tests__/daily-routes.test.ts > daily-routes > GET /daily/:userId > retourne le status daily pour l'utilisateur Ô£ô src/routes/__tests__/daily-routes.test.ts > daily-routes > GET /daily/:userId > retourne 403 si userId ne correspond pas Ô£ô src/routes/__tests__/daily-routes.test.ts > daily-routes > GET /daily/:userId > retourne 400 pour userId non num├®rique Ô£ô src/routes/__tests__/daily-routes.test.ts > daily-routes > POST /daily/:userId/complete > compl├¿te un d├®fi daily valide Ô£ô src/routes/__tests__/daily-routes.test.ts > daily-routes > POST /daily/:userId/complete > refuse sans dateKey Ô£ô src/routes/__tests__/daily-routes.test.ts > daily-routes > POST /daily/:userId/complete > refuse un dateKey trop court (< 8 chars) Ô£ô src/routes/__tests__/daily-routes.test.ts > daily-routes > POST /daily/:userId/complete > refuse si userId ne correspond pas Ô£ô src/routes/__tests__/daily-routes.test.ts > daily-routes > POST /daily/:userId/claim > tente le claim mensuel Ô£ô src/server/__tests__/constants.test.ts > constants > DIFFICULTIES > contient les 4 difficult├®s dans l'ordre Ô£ô src/server/__tests__/constants.test.ts > constants > DIFFICULTIES > est un tuple readonly (as const) Ô£ô src/server/__tests__/constants.test.ts > constants > LEVELS_PER_DIFFICULTY > vaut 240 Ô£ô src/server/__tests__/constants.test.ts > constants > REWARD_POINTS > a une entr├®e pour chaque difficult├® Ô£ô src/server/__tests__/constants.test.ts > constants > REWARD_POINTS > les points augmentent avec la difficult├® Ô£ô src/server/__tests__/constants.test.ts > constants > REWARD_POINTS > valeurs exactes : 8, 12, 16, 22 Ô£ô src/server/__tests__/constants.test.ts > constants > AID_PACKS > contient 4 packs Ô£ô src/server/__tests__/constants.test.ts > constants > AID_PACKS > chaque pack a id, cost et inventory Ô£ô src/server/__tests__/constants.test.ts > constants > AID_PACKS > les IDs sont uniques Ô£ô src/server/__tests__/constants.test.ts > constants > AID_PACKS > les co├╗ts sont croissants Ô£ô src/server/__tests__/constants.test.ts > constants > valeurs de s├®curit├® > TOKEN_TTL est d├®fini Ô£ô src/server/__tests__/constants.test.ts > constants > valeurs de s├®curit├® > REFRESH_TTL est d├®fini Ô£ô src/server/__tests__/constants.test.ts > constants > valeurs de s├®curit├® > REFRESH_COOKIE_NAME est d├®fini Ô£ô src/server/__tests__/constants.test.ts > constants > valeurs de s├®curit├® > MAX_FAILED_LOGINS = 5 Ô£ô src/server/__tests__/constants.test.ts > constants > valeurs de s├®curit├® > LOCK_TIME_MS = 15 minutes Ô£ô src/server/__tests__/constants.test.ts > constants > valeurs de s├®curit├® > RESET_TOKEN_TTL_MS = 1 heure Ô£ô src/routes/__tests__/challenge-pack-routes.test.ts > challenge-pack-routes > GET /challenge-pack/status > retourne le status du challenge pack Ô£ô src/routes/__tests__/challenge-pack-routes.test.ts > challenge-pack-routes > POST /challenge-pack/purchase/:userId > refuse si userId ne correspond pas Ô£ô src/routes/__tests__/daily-routes.test.ts > daily-routes > POST /daily/:userId/claim > refuse sans monthKey Ô£ô src/routes/__tests__/daily-routes.test.ts > daily-routes > POST /daily/:userId/claim > refuse si userId ne correspond pas Ô£ô src/routes/__tests__/challenge-pack-routes.test.ts > challenge-pack-routes > POST /challenge-pack/purchase/:userId > refuse un userId non num├®rique Ô£ô src/routes/__tests__/challenge-pack-routes.test.ts > challenge-pack-routes > GET /challenge-pack/challenges/:userId > refuse si userId ne correspond pas Ô£ô src/routes/__tests__/challenge-pack-routes.test.ts > challenge-pack-routes > GET /challenge-pack/challenges/:userId > refuse un userId non num├®rique Ô£ô src/routes/__tests__/challenge-pack-routes.test.ts > challenge-pack-routes > GET /challenge-pack/level/:dateKey > refuse une date invalide Ô£ô src/routes/__tests__/challenge-pack-routes.test.ts > challenge-pack-routes > GET /challenge-pack/level/:dateKey > refuse une date future Ô£ô src/server/__tests__/crypto-utils.test.ts > crypto-utils > clampInt garde la valeur dans la plage Ô£ô src/server/__tests__/crypto-utils.test.ts > crypto-utils > parseDurationMs convertit les unit├®s Ô£ô src/server/__tests__/crypto-utils.test.ts > crypto-utils > expiresAtFrom calcule une date future Ô£ô src/server/__tests__/crypto-utils.test.ts > crypto-utils > getDayOfYear retourne un index coh├®rent Ô£ô src/server/__tests__/crypto-utils.test.ts > crypto-utils > hashToken et hashResetToken donnent un sha256 Ô£ô src/routes/__tests__/health-routes.test.ts > health-routes > GET /health > retourne 200 et status ok quand la BDD r├®pond Ô£ô src/routes/__tests__/health-routes.test.ts > health-routes > GET /health > retourne 503 quand la BDD est inaccessible Ô£ô src/routes/__tests__/health-routes.test.ts > health-routes > GET /version > retourne la version et l'environnement Ô£ô src/routes/__tests__/health-routes.test.ts > health-routes > GET /maintenance > retourne maintenance: false quand d├®sactiv├® Ô£ô src/routes/__tests__/health-routes.test.ts > health-routes > GET /maintenance > retourne maintenance: true avec message quand activ├® Ô£ô src/routes/__tests__/health-routes.test.ts > health-routes > GET /maintenance > retourne maintenance: false en cas d'erreur DB Ô£ô src/routes/__tests__/profile-routes.test.ts > profile-routes > POST /profile/check-display-name > v├®rifie un displayName valide Ô£ô src/routes/__tests__/ball-skin-pack-routes.test.ts > ball-skin-pack-routes > GET /ball-skins/user/:userId > retourne les skins poss├®d├®s par l'utilisateur Ô£ô src/routes/__tests__/ball-skin-pack-routes.test.ts > ball-skin-pack-routes > GET /ball-skins/user/:userId > retourne 403 si userId ne correspond pas Ô£ô src/routes/__tests__/ball-skin-pack-routes.test.ts > ball-skin-pack-routes > GET /ball-skins/user/:userId > retourne 400 pour userId non num├®rique Ô£ô src/routes/__tests__/ball-skin-pack-routes.test.ts > ball-skin-pack-routes > GET /ball-skin-packs > retourne la liste des packs de skins Ô£ô src/routes/__tests__/ball-skin-pack-routes.test.ts > ball-skin-pack-routes > GET /ball-skin-packs/:packId > retourne 404 pour un pack inexistant Ô£ô src/routes/__tests__/ball-skin-pack-routes.test.ts > ball-skin-pack-routes > GET /ball-skin-packs/user/:userId > retourne les packs poss├®d├®s Ô£ô src/routes/__tests__/profile-routes.test.ts > profile-routes > POST /profile/check-display-name > refuse un displayName vide Ô£ô src/routes/__tests__/profile-routes.test.ts > profile-routes > POST /profile/check-display-name > refuse sans displayName dans le payload Ô£ô src/routes/__tests__/profile-routes.test.ts > profile-routes > PUT /profile/:userId > met ├á jour un profil valide Ô£ô src/routes/__tests__/admin-routes.test.ts > admin-routes > GET /admin/overview > retourne l'overview admin Ô£ô src/routes/__tests__/admin-routes.test.ts > admin-routes > GET /config/public > retourne la configuration publique (pas besoin d'admin) Ô£ô src/routes/__tests__/admin-routes.test.ts > admin-routes > GET /admin/config > retourne la config admin Ô£ô src/routes/__tests__/admin-routes.test.ts > admin-routes > PUT /admin/config > met ├á jour la configuration admin Ô£ô src/routes/__tests__/admin-routes.test.ts > admin-routes > PUT /admin/config > supprime silencieusement les propri├®t├®s additionnelles (Fastify removeAdditional) Ô£ô src/routes/__tests__/admin-routes.test.ts > admin-routes > POST /admin/init-maintenance-config > retourne already_exists si la config existe Ô£ô src/routes/__tests__/admin-routes.test.ts > admin-routes > GET /admin/dashboard > retourne un dashboard HTML Ô£ô src/routes/__tests__/profile-routes.test.ts > profile-routes > PUT /profile/:userId > retourne 403 si userId ne correspond pas au token Ô£ô src/routes/__tests__/profile-routes.test.ts > profile-routes > PUT /profile/:userId > refuse un displayName avec caract├¿res HTML Ô£ô src/routes/__tests__/profile-routes.test.ts > profile-routes > PUT /profile/:userId > refuse un displayName trop long (>100 chars) Ô£ô src/routes/__tests__/profile-routes.test.ts > profile-routes > PUT /profile/:userId > refuse sans tous les champs requis Ô£ô src/server/__tests__/crypto-utils.test.ts > crypto-utils > hashPassword / verifyPassword (argon2) fonctionne 458ms Ô£ô src/routes/__tests__/payments-routes.test.ts > payments-routes > retourne 503 si Stripe non configur├® (checkout-session) Ô£ô src/routes/__tests__/payments-routes.test.ts > payments-routes > retourne 503 si Stripe non configur├® (checkout-cash) Ô£ô src/routes/__tests__/levels-routes.test.ts > levels-routes > GET /levels/:difficulty/:index > retourne un niveau quand trouv├® en BDD Ô£ô src/routes/__tests__/levels-routes.test.ts > levels-routes > GET /levels/:difficulty/:index > retourne 404 si le niveau n'existe pas en BDD Ô£ô src/routes/__tests__/levels-routes.test.ts > levels-routes > GET /levels/:difficulty/:index > refuse une difficult├® invalide Ô£ô src/routes/__tests__/levels-routes.test.ts > levels-routes > GET /levels/:difficulty/:index > refuse un index n├®gatif Ô£ô src/routes/__tests__/levels-routes.test.ts > levels-routes > GET /levels/:difficulty/:index > refuse un index sup├®rieur ├á 239 Ô£ô src/routes/__tests__/levels-routes.test.ts > levels-routes > GET /levels/daily/:dateKey > retourne le niveau quotidien pour une date valide Ô£ô src/routes/__tests__/levels-routes.test.ts > levels-routes > GET /levels/daily/:dateKey > retourne 404 si le niveau quotidien n'existe pas en BDD Ô£ô src/routes/__tests__/levels-routes.test.ts > levels-routes > GET /levels/daily/:dateKey > retourne 400 pour une date invalide Ô£ô src/server/__tests__/crypto-utils.test.ts > crypto-utils > verifyPassword fonctionne avec bcrypt legacy Ô£ô src/server/__tests__/crypto-utils.test.ts > crypto-utils > randomId et randomTokenBase64Url g├®n├¿rent des valeurs Ô£ô src/server/__tests__/crypto-utils.test.ts > crypto-utils > isLocked d├®tecte un verrouillage futur Ô£ô src/routes/__tests__/auth-routes.test.ts > auth-routes > refuse un login sans payload Ô£ô src/routes/__tests__/auth-routes.test.ts > auth-routes > refuse un register sans email/password