Errore 'FAILED' quando si tenta di rimuovere il badge 'Bug Reporter'

Questo bug è presente da molto tempo. L’ho ricercato l’anno scorso e questi sono i passaggi per riprodurlo:

  1. Come amministratore, imposta max favorite badges su 2 e crea almeno un badge che può essere guadagnato più volte.
  2. Come utente normale, imposta due badge come preferiti, uno dei quali è il badge che può essere guadagnato più volte (indicato come Badge A).
  3. Come amministratore, assegna nuovamente il Badge A all’utente.
  4. Come utente normale, aggiorna la pagina e prova a rimuovere il Badge A dai preferiti. Incontrerai un errore.

La causa dell’errore è che ogni volta che viene assegnato un badge che può essere guadagnato più volte, viene creato un nuovo record user_badge nel database. Tuttavia, quando l’utente ha aggiunto il badge ai preferiti e poi lo riceve di nuovo, il nuovo record user_badge non viene automaticamente contrassegnato come is_favorite. Quando l’utente tenta di rimuovere il Badge A dai preferiti, il frontend invia l’ID user_badge più recente per impostazione predefinita. Poiché questo record non è contrassegnato come is_favorite, il backend presume che l’utente stia tentando di impostare un nuovo badge come preferito (invece di rimuoverlo dai preferiti), superando il limite di max favorite badges, causando l’errore.

Il codice pertinente si trova qui:

Una possibile soluzione è modificare la riga 131 in:

if UserBadge.where(badge: user_badge.badge, user: user_badge.user).pluck(:is_favorite).any? &&

Tuttavia, questo non risolve completamente l’incoerenza nei record del database.

Come soluzione temporanea, un utente normale può rimuovere tutti i badge dai preferiti eseguendo il seguente codice JavaScript nella console:

const user_name = require("discourse/models/user").default.current().username;
const badges = await require("discourse/models/user-badge").default.findByUsername(user_name);
const favorites = new Map();
badges.filter((b)=>b.is_favorite).forEach((b)=>favorites.set(b.badge_id,b));
favorites.forEach((b)=>b.favorite());
9 Mi Piace