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) } }