feat(telegram): promo deep-link seeds English Scrabble for new users
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 18s
CI / ui (pull_request) Successful in 56s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 50s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 18s
CI / ui (pull_request) Successful in 56s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 50s
The promo bot button carries a configurable variant-seed start-param (default verudit_ru-scrabble_en). The gateway parses start_param from the validated initData and forwards it; the backend, on first contact only, seeds the new account variant_preferences from it (English Scrabble alongside the default Erudit). No schema change (the scrabble_en CHECK is already in the baseline) and the gateway<->backend REST field is additive, so the rolling deploy is safe in either order. TELEGRAM_PROMO_START_PARAM configures the payload (empty forwards the user own /start payload). Covered by account unit tests, a gateway transcode test, and an integration test asserting new-only seeding.
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
//go:build integration
|
||||
|
||||
package inttest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"go.uber.org/zap/zaptest"
|
||||
|
||||
"scrabble/backend/internal/account"
|
||||
"scrabble/backend/internal/server"
|
||||
"scrabble/backend/internal/session"
|
||||
)
|
||||
|
||||
// TestTelegramAuthSeedsPromoVariantForNewUserOnly drives the sessions/telegram endpoint
|
||||
// to confirm a promo deep-link start-param seeds a brand-new account's variant
|
||||
// preferences (English Scrabble alongside the default Erudit), that a new account with no
|
||||
// such payload keeps the Erudit-only default, and that an existing account is never
|
||||
// re-seeded on a later login (the new-user-only contract).
|
||||
func TestTelegramAuthSeedsPromoVariantForNewUserOnly(t *testing.T) {
|
||||
srv := server.New(":0", server.Deps{
|
||||
Logger: zaptest.NewLogger(t),
|
||||
DB: testDB,
|
||||
Accounts: account.NewStore(testDB),
|
||||
Sessions: session.NewService(session.NewStore(testDB), session.NewCache()),
|
||||
Notifier: &captureNotifier{},
|
||||
})
|
||||
h := srv.Handler()
|
||||
|
||||
post := func(ext, startParam string) {
|
||||
body := `{"external_id":"` + ext + `","language_code":"en","first_name":"Promo"`
|
||||
if startParam != "" {
|
||||
body += `,"start_param":"` + startParam + `"`
|
||||
}
|
||||
body += `}`
|
||||
rec := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/internal/sessions/telegram", strings.NewReader(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
h.ServeHTTP(rec, req)
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("telegram auth = %d: %s", rec.Code, rec.Body.String())
|
||||
}
|
||||
}
|
||||
store := account.NewStore(testDB)
|
||||
reload := func(ext string) []string {
|
||||
acc, err := store.AccountByIdentity(context.Background(), account.KindTelegram, ext)
|
||||
if err != nil {
|
||||
t.Fatalf("lookup %s: %v", ext, err)
|
||||
}
|
||||
return acc.VariantPreferences
|
||||
}
|
||||
|
||||
// A brand-new account reached through a promo deep-link is seeded with English
|
||||
// Scrabble alongside the default Erudit.
|
||||
promoExt := "tg-" + uuid.NewString()
|
||||
post(promoExt, "verudit_ru-scrabble_en")
|
||||
if got, want := reload(promoExt), []string{"erudit_ru", "scrabble_en"}; !slices.Equal(got, want) {
|
||||
t.Errorf("promo new account variants = %v, want %v", got, want)
|
||||
}
|
||||
|
||||
// A brand-new account with no promo payload keeps the Erudit-only default.
|
||||
plainExt := "tg-" + uuid.NewString()
|
||||
post(plainExt, "")
|
||||
if got, want := reload(plainExt), []string{"erudit_ru"}; !slices.Equal(got, want) {
|
||||
t.Errorf("plain new account variants = %v, want %v", got, want)
|
||||
}
|
||||
|
||||
// A later login of the promo account, even via a different payload, must not re-seed:
|
||||
// the seed is first-contact only.
|
||||
post(promoExt, "vscrabble_ru")
|
||||
if got, want := reload(promoExt), []string{"erudit_ru", "scrabble_en"}; !slices.Equal(got, want) {
|
||||
t.Errorf("existing account re-seeded = %v, want unchanged %v", got, want)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user