package promobot
import (
"context"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/go-telegram/bot/models"
"go.uber.org/zap"
)
func TestPromoTextLocalization(t *testing.T) {
const url = "https://telegram.me/bot/app?startapp=verudit_ru-scrabble_en"
// The @username is rendered as a clickable deep link (the same target as the button),
// not a plain mention, so tapping it opens the seeded Mini App.
wantLink := `@ScrabbleBot`
en, enBtn := promoText("en", "ScrabbleBot", url)
if !strings.Contains(en, wantLink) || !strings.Contains(en, "profile settings") {
t.Errorf("en text = %q", en)
}
if enBtn != "🤩 I want to play!" {
t.Errorf("en button = %q", enBtn)
}
ru, ruBtn := promoText("ru-RU", "ScrabbleBot", url)
if !strings.Contains(ru, wantLink) || !strings.Contains(ru, "Откройте") {
t.Errorf("ru text = %q", ru)
}
if ruBtn != "🤩 Хочу играть!" {
t.Errorf("ru button = %q", ruBtn)
}
// An unknown language falls back to English, still with the linked mention.
if got, _ := promoText("de", "B", url); !strings.Contains(got, "Open ") || !strings.Contains(got, `">@B`) {
t.Errorf("fallback text = %q, want English with a linked mention", got)
}
}
func TestLaunchURLAppendsStartapp(t *testing.T) {
b := &Bot{linkURL: "https://telegram.me/bot/app"}
if got := b.launchURL(""); got != "https://telegram.me/bot/app" {
t.Errorf("empty payload = %q, want the base link unchanged", got)
}
if got := b.launchURL("g123"); got != "https://telegram.me/bot/app?startapp=g123" {
t.Errorf("launchURL = %q, want startapp=g123 appended", got)
}
}
func TestLaunchMarkupIsURLButton(t *testing.T) {
b := &Bot{linkURL: "https://telegram.me/bot/app"}
btn := b.launchMarkup("Play", "f99").InlineKeyboard[0][0]
if btn.WebApp != nil {
t.Error("the promo button must not be a web_app button (it would sign initData with the promo token, which the main bot rejects)")
}
if !strings.Contains(btn.URL, "startapp=f99") {
t.Errorf("button URL = %q, want startapp=f99", btn.URL)
}
}
// fakeAPI answers getMe (so New succeeds offline) and records the last sendMessage.
type fakeAPI struct {
chatID, text, replyMarkup string
}
func (f *fakeAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) {
switch {
case strings.HasSuffix(r.URL.Path, "/getMe"):
io.WriteString(w, `{"ok":true,"result":{"id":1,"is_bot":true,"first_name":"t","username":"promo"}}`)
case strings.HasSuffix(r.URL.Path, "/sendMessage"):
f.chatID = r.FormValue("chat_id")
f.text = r.FormValue("text")
f.replyMarkup = r.FormValue("reply_markup")
io.WriteString(w, `{"ok":true,"result":{"message_id":1}}`)
default:
io.WriteString(w, `{"ok":true,"result":true}`)
}
}
func TestHandleStartReplies(t *testing.T) {
api := &fakeAPI{}
srv := httptest.NewServer(api)
t.Cleanup(srv.Close)
b, err := New(Config{Token: "1:2", APIBaseURL: srv.URL, BotUsername: "ScrabbleBot", BotLinkURL: "https://telegram.me/bot/app"}, zap.NewNop())
if err != nil {
t.Fatalf("new: %v", err)
}
b.handleStart(context.Background(), b.api, &models.Update{Message: &models.Message{
Chat: models.Chat{ID: 42, Type: models.ChatTypePrivate},
From: &models.User{LanguageCode: "ru"},
Text: "/start f99",
}})
if api.chatID != "42" {
t.Errorf("chat_id = %q, want 42", api.chatID)
}
if !strings.Contains(api.text, `@ScrabbleBot`) {
t.Errorf("text = %q, want the @mention linked to the startapp deep link", api.text)
}
if strings.Contains(api.replyMarkup, "web_app") {
t.Errorf("reply_markup = %q has a web_app button; want a url button", api.replyMarkup)
}
if !strings.Contains(api.replyMarkup, "startapp=f99") {
t.Errorf("reply_markup = %q, want startapp=f99 (the /start payload forwarded)", api.replyMarkup)
}
}
func TestHandleStartIgnoresGroup(t *testing.T) {
api := &fakeAPI{}
srv := httptest.NewServer(api)
t.Cleanup(srv.Close)
b, err := New(Config{Token: "1:2", APIBaseURL: srv.URL, BotUsername: "B", BotLinkURL: "https://telegram.me/b/a"}, zap.NewNop())
if err != nil {
t.Fatalf("new: %v", err)
}
b.handleStart(context.Background(), b.api, &models.Update{Message: &models.Message{
Chat: models.Chat{ID: -100, Type: models.ChatTypeSupergroup}, Text: "/start",
}})
if api.chatID != "" {
t.Errorf("replied to a group message (chat=%q); want none", api.chatID)
}
}