package transcode_test import ( "context" "encoding/json" "net/http" "testing" flatbuffers "github.com/google/flatbuffers/go" "scrabble/gateway/internal/connector" "scrabble/gateway/internal/transcode" fb "scrabble/pkg/fbs/scrabblefb" ) func linkEmailConfirmPayload(email, code string) []byte { b := flatbuffers.NewBuilder(64) e := b.CreateString(email) c := b.CreateString(code) fb.LinkEmailConfirmStart(b) fb.LinkEmailConfirmAddEmail(b, e) fb.LinkEmailConfirmAddCode(b, c) b.Finish(fb.LinkEmailConfirmEnd(b)) return b.FinishedBytes() } func linkTelegramPayload(data string) []byte { b := flatbuffers.NewBuilder(64) d := b.CreateString(data) fb.LinkTelegramRequestStart(b) fb.LinkTelegramRequestAddData(b, d) b.Finish(fb.LinkTelegramRequestEnd(b)) return b.FinishedBytes() } func TestLinkEmailConfirmMergeRequired(t *testing.T) { backend, cleanup := fakeBackend(t, func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/api/v1/user/link/email/confirm" { t.Errorf("path = %q", r.URL.Path) } _, _ = w.Write([]byte(`{"status":"merge_required","secondary_user_id":"b-1","secondary_display_name":"Ann","secondary_games":7,"secondary_friends":3}`)) }) defer cleanup() reg := transcode.NewRegistry(backend, nil) op, ok := reg.Lookup(transcode.MsgLinkEmailConfirm) if !ok { t.Fatal("link.email.confirm not registered") } payload, err := op.Handler(context.Background(), transcode.Request{UserID: "u-1", Payload: linkEmailConfirmPayload("e@x.com", "123456")}) if err != nil { t.Fatalf("handler: %v", err) } lr := fb.GetRootAsLinkResult(payload, 0) if string(lr.Status()) != "merge_required" || string(lr.SecondaryUserId()) != "b-1" || string(lr.SecondaryDisplayName()) != "Ann" || lr.SecondaryGames() != 7 || lr.SecondaryFriends() != 3 { t.Fatalf("link result = %q/%q/%q/%d/%d", lr.Status(), lr.SecondaryUserId(), lr.SecondaryDisplayName(), lr.SecondaryGames(), lr.SecondaryFriends()) } if lr.Session(nil) != nil { t.Error("a merge_required result must not carry a session") } } func TestLinkEmailMergeSwitchesSession(t *testing.T) { backend, cleanup := fakeBackend(t, func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/api/v1/user/link/email/merge" { t.Errorf("path = %q", r.URL.Path) } _, _ = w.Write([]byte(`{"status":"merged","token":"tok-9","profile":{"user_id":"a-1","display_name":"Kaya","is_guest":false}}`)) }) defer cleanup() reg := transcode.NewRegistry(backend, nil) op, _ := reg.Lookup(transcode.MsgLinkEmailMerge) payload, err := op.Handler(context.Background(), transcode.Request{UserID: "u-1", Payload: linkEmailConfirmPayload("e@x.com", "123456")}) if err != nil { t.Fatalf("handler: %v", err) } lr := fb.GetRootAsLinkResult(payload, 0) if string(lr.Status()) != "merged" { t.Fatalf("status = %q, want merged", lr.Status()) } sess := lr.Session(nil) if sess == nil { t.Fatal("a switched merge must carry a session") } if string(sess.Token()) != "tok-9" || string(sess.UserId()) != "a-1" { t.Fatalf("session = %q/%q, want tok-9/a-1", sess.Token(), sess.UserId()) } } func TestLinkTelegramValidatesAndForwards(t *testing.T) { var gotExternalID string backend, cleanup := fakeBackend(t, func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/api/v1/user/link/telegram" { t.Errorf("path = %q", r.URL.Path) } var body struct { ExternalID string `json:"external_id"` } _ = json.NewDecoder(r.Body).Decode(&body) gotExternalID = body.ExternalID _, _ = w.Write([]byte(`{"status":"linked"}`)) }) defer cleanup() reg := transcode.NewRegistry(backend, fakeValidator{user: connector.User{ExternalID: "42"}}) op, ok := reg.Lookup(transcode.MsgLinkTelegram) if !ok { t.Fatal("link.telegram.confirm not registered") } payload, err := op.Handler(context.Background(), transcode.Request{UserID: "u-1", Payload: linkTelegramPayload("id=42&hash=x")}) if err != nil { t.Fatalf("handler: %v", err) } if gotExternalID != "42" { t.Errorf("backend external_id = %q, want 42 (the gateway-validated id)", gotExternalID) } if string(fb.GetRootAsLinkResult(payload, 0).Status()) != "linked" { t.Error("expected a linked result") } }