package main import ( "context" "strings" "testing" "time" ) const testAuthCode = "topsecret" func setupAuthHandler(t *testing.T) (*FakeTelegram, *AuthHandler, Bot) { t.Helper() ft := NewFakeTelegram(t) m := StartMiniRedis(t) a := NewTestAuth(t, m, testAuthCode, time.Hour) h := &AuthHandler{tg: ft.Client(), auth: a} bot := Bot{Slug: "factory", Token: "tok", Secret: "sec"} return ft, h, bot } func TestAuthHandler_StartShowsHelp(t *testing.T) { ft, h, bot := setupAuthHandler(t) _ = h.Handle(bgCtx(), MakeUpdate(1, 100, 100, 1, "/start"), bot) sent := ft.Sent() if len(sent) != 1 || !strings.Contains(sent[0].Text, "/auth ") { t.Fatalf("/start should welcome + show help, got %+v", sent) } } func TestAuthHandler_AuthMissingCode(t *testing.T) { ft, h, bot := setupAuthHandler(t) _ = h.Handle(bgCtx(), MakeUpdate(1, 100, 100, 1, "/auth"), bot) sent := ft.Sent() if len(sent) != 1 || !strings.Contains(sent[0].Text, "Usage") { t.Fatalf("bare /auth should print Usage, got %+v", sent) } } func TestAuthHandler_AuthWrongCode_NoSession(t *testing.T) { ft, h, bot := setupAuthHandler(t) _ = h.Handle(bgCtx(), MakeUpdate(1, 100, 100, 1, "/auth wrong"), bot) sent := ft.Sent() if len(sent) != 1 || !strings.Contains(sent[0].Text, "Mauvais code") { t.Fatalf("wrong code should reply error, got %+v", sent) } authed, _ := h.auth.IsAuthed(context.Background(), 100) if authed { t.Fatal("session must NOT be created on wrong code") } } func TestAuthHandler_AuthRightCode_SessionAndDelete(t *testing.T) { ft, h, bot := setupAuthHandler(t) upd := MakeUpdate(1, 100, 100, 42, "/auth "+testAuthCode) _ = h.Handle(bgCtx(), upd, bot) sent := ft.Sent() if len(sent) != 1 || !strings.Contains(sent[0].Text, "Authentifié") { t.Fatalf("right code should welcome, got %+v", sent) } deleted := ft.Deleted() if len(deleted) != 1 || deleted[0].MessageID != 42 || deleted[0].ChatID != 100 { t.Fatalf("expected deleteMessage on the /auth message (id=42 chat=100), got %+v", deleted) } authed, _ := h.auth.IsAuthed(context.Background(), 100) if !authed { t.Fatal("session must exist after right code") } } func TestAuthHandler_Whoami_NotAuthed(t *testing.T) { ft, h, bot := setupAuthHandler(t) _ = h.Handle(bgCtx(), MakeUpdate(1, 200, 200, 1, "/whoami"), bot) sent := ft.Sent() if len(sent) != 1 || !strings.Contains(sent[0].Text, "non authentifié") { t.Fatalf("whoami without session should say so, got %+v", sent) } } func TestAuthHandler_Whoami_Authed_ShowsTTL(t *testing.T) { ft, h, bot := setupAuthHandler(t) _ = h.Handle(bgCtx(), MakeUpdate(1, 300, 300, 1, "/auth "+testAuthCode), bot) _ = h.Handle(bgCtx(), MakeUpdate(2, 300, 300, 2, "/whoami"), bot) sent := ft.Sent() last := sent[len(sent)-1].Text if !strings.Contains(last, "authentifié") || !strings.Contains(last, "user=300") { t.Fatalf("whoami auth answer wrong: %q", last) } } func TestAuthHandler_Logout(t *testing.T) { ft, h, bot := setupAuthHandler(t) _ = h.Handle(bgCtx(), MakeUpdate(1, 400, 400, 1, "/auth "+testAuthCode), bot) authed, _ := h.auth.IsAuthed(context.Background(), 400) if !authed { t.Fatal("setup: should be authed") } _ = h.Handle(bgCtx(), MakeUpdate(2, 400, 400, 2, "/logout"), bot) authed, _ = h.auth.IsAuthed(context.Background(), 400) if authed { t.Fatal("logout should drop the session") } last := ft.Sent()[len(ft.Sent())-1].Text if !strings.Contains(last, "Déconnecté") { t.Fatalf("logout reply wrong: %q", last) } } func TestAuthHandler_Default_PrintsHelp(t *testing.T) { ft, h, bot := setupAuthHandler(t) _ = h.Handle(bgCtx(), MakeUpdate(1, 500, 500, 1, "salut !"), bot) last := ft.Sent()[0].Text if !strings.Contains(last, "Commandes disponibles") { t.Fatalf("default reply should print help, got %q", last) } }