mirror of
https://github.com/tiennm99/miti99bot.git
synced 2026-08-24 02:25:37 +00:00
fix(wheelofnames): pad spoiler result to longest option so length can't leak winner
This commit is contained in:
@@ -150,7 +150,7 @@ func TestWheelOfNames_UsageWhenMissingOptions(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestWheelOfNames_ResultCaptionEscapesHTML(t *testing.T) {
|
||||
got := wheelResultCaption(`<Alice & Bob>`)
|
||||
got := wheelResultCaption([]string{`<Alice & Bob>`}, 0)
|
||||
want := `Result: <span class="tg-spoiler"><Alice & Bob></span>`
|
||||
if got != want {
|
||||
t.Fatalf("wheelResultCaption() = %q, want %q", got, want)
|
||||
@@ -158,13 +158,25 @@ func TestWheelOfNames_ResultCaptionEscapesHTML(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestWheelOfNames_ResultCaptionTruncatesLongResult(t *testing.T) {
|
||||
got := wheelResultCaption(strings.Repeat("a", wheelResultCaptionMaxRunes+1))
|
||||
got := wheelResultCaption([]string{strings.Repeat("a", wheelResultCaptionMaxRunes+1)}, 0)
|
||||
want := `Result: <span class="tg-spoiler">` + strings.Repeat("a", wheelResultCaptionMaxRunes) + `...</span>`
|
||||
if got != want {
|
||||
t.Fatalf("wheelResultCaption() length = %d, want truncated caption length %d", len(got), len(want))
|
||||
}
|
||||
}
|
||||
|
||||
func TestWheelOfNames_ResultCaptionPadsShortWinnerToLongestOption(t *testing.T) {
|
||||
options := []string{"Bob", "Alexandria"}
|
||||
got := wheelResultCaption(options, 0)
|
||||
want := `Result: <span class="tg-spoiler">.......Bob</span>`
|
||||
if got != want {
|
||||
t.Fatalf("wheelResultCaption() = %q, want %q", got, want)
|
||||
}
|
||||
if longest := wheelResultCaption(options, 1); len([]rune(longest)) != len([]rune(got)) {
|
||||
t.Fatalf("caption lengths differ: winner %q vs %q", got, longest)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWheelOfNames_UsesRemoteAPIWhenConfigured(t *testing.T) {
|
||||
var got wheelAPIRequest
|
||||
var gotAuthorization string
|
||||
@@ -206,7 +218,7 @@ func TestWheelOfNames_UsesRemoteAPIWhenConfigured(t *testing.T) {
|
||||
if call.Method != "sendAnimation" {
|
||||
t.Fatalf("method = %q, want sendAnimation", call.Method)
|
||||
}
|
||||
wantCaption := wheelResultCaption(got.Options[got.WinnerIndex])
|
||||
wantCaption := wheelResultCaption(got.Options, got.WinnerIndex)
|
||||
if got := call.Form["caption"]; got != wantCaption {
|
||||
t.Fatalf("caption = %q, want %q", got, wantCaption)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"html"
|
||||
"strings"
|
||||
|
||||
"github.com/go-telegram/bot"
|
||||
"github.com/go-telegram/bot/models"
|
||||
@@ -51,7 +52,7 @@ func wheelOfNamesCommand() modules.Command {
|
||||
Duration: animation.Duration,
|
||||
Width: animation.Width,
|
||||
Height: animation.Height,
|
||||
Caption: wheelResultCaption(options[winner]),
|
||||
Caption: wheelResultCaption(options, winner),
|
||||
ParseMode: models.ParseModeHTML,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -65,9 +66,22 @@ func wheelOfNamesCommand() modules.Command {
|
||||
|
||||
const wheelUsage = "Usage: /wheelofnames <option,...>"
|
||||
|
||||
func wheelResultCaption(result string) string {
|
||||
result = truncateWheelResultCaption(result)
|
||||
return `Result: <span class="tg-spoiler">` + html.EscapeString(result) + `</span>`
|
||||
func wheelResultCaption(options []string, winner int) string {
|
||||
result := truncateWheelResultCaption(options[winner])
|
||||
padding := wheelCaptionPadding(options, len([]rune(result)))
|
||||
return `Result: <span class="tg-spoiler">` + html.EscapeString(padding+result) + `</span>`
|
||||
}
|
||||
|
||||
// wheelCaptionPadding returns leading dots so every option renders a
|
||||
// spoiler of equal length; otherwise the spoiler width reveals the winner.
|
||||
func wheelCaptionPadding(options []string, resultRunes int) string {
|
||||
longest := resultRunes
|
||||
for _, option := range options {
|
||||
if n := len([]rune(truncateWheelResultCaption(option))); n > longest {
|
||||
longest = n
|
||||
}
|
||||
}
|
||||
return strings.Repeat(".", longest-resultRunes)
|
||||
}
|
||||
|
||||
func truncateWheelResultCaption(result string) string {
|
||||
|
||||
Reference in New Issue
Block a user