tgbot_level_test.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package tgbot
  2. import (
  3. "testing"
  4. "github.com/mymmrac/telego"
  5. )
  6. func withAdmins(t *testing.T, ids ...int64) {
  7. t.Helper()
  8. tgBotMutex.Lock()
  9. orig := adminIds
  10. adminIds = ids
  11. tgBotMutex.Unlock()
  12. t.Cleanup(func() {
  13. tgBotMutex.Lock()
  14. adminIds = orig
  15. tgBotMutex.Unlock()
  16. })
  17. }
  18. // newLevelTgbot binds ownerMail to ownerTgID in both the inbound settings and
  19. // the clients table, and makes account 1 the only admin.
  20. func newLevelTgbot(t *testing.T) (*Tgbot, func(string) int) {
  21. t.Helper()
  22. tb, calls := newLinksCallbackTgbot(t, ownerMail)
  23. seedClientRecord(t, ownerMail, "sub-owned", ownerTgID)
  24. withAdmins(t, 1)
  25. return tb, calls
  26. }
  27. func commandFrom(tgUserID int64, text string) *telego.Message {
  28. return &telego.Message{
  29. From: &telego.User{ID: tgUserID},
  30. Chat: telego.Chat{ID: tgUserID, Type: telego.ChatTypePrivate},
  31. Text: text,
  32. }
  33. }
  34. func TestLevelOfFollowsTheClientBinding(t *testing.T) {
  35. tb, _ := newLevelTgbot(t)
  36. for id, want := range map[int64]userLevel{1: levelAdmin, ownerTgID: levelClient, 777: levelStranger, 0: levelStranger} {
  37. if got := tb.levelOf(id); got != want {
  38. t.Errorf("levelOf(%d) = %d, want %d", id, got, want)
  39. }
  40. }
  41. }
  42. // A stranger's refused command must get no reply at all, while a bound client
  43. // is still told the command is unknown, as before the gate existed.
  44. func TestGateCommand(t *testing.T) {
  45. cases := []struct {
  46. name string
  47. from int64
  48. text string
  49. wantOK bool
  50. wantAdmin bool
  51. wantSends int
  52. }{
  53. {"stranger start", 777, "/start", true, false, 0},
  54. {"stranger help", 777, "/help", false, false, 0},
  55. {"stranger admin command", 777, "/restart", false, false, 0},
  56. {"client usage", ownerTgID, "/usage", true, false, 0},
  57. {"client admin command", ownerTgID, "/clearall", false, false, 1},
  58. {"admin", 1, "/clearall", true, true, 0},
  59. }
  60. for _, c := range cases {
  61. t.Run(c.name, func(t *testing.T) {
  62. tb, calls := newLevelTgbot(t)
  63. isAdmin, ok := tb.gateCommand(commandFrom(c.from, c.text))
  64. if ok != c.wantOK || isAdmin != c.wantAdmin {
  65. t.Errorf("gateCommand = (%v, %v), want (%v, %v)", isAdmin, ok, c.wantAdmin, c.wantOK)
  66. }
  67. if n := calls("sendMessage"); n != c.wantSends {
  68. t.Errorf("sendMessage calls = %d, want %d", n, c.wantSends)
  69. }
  70. })
  71. }
  72. }
  73. // Regression test: a stranger's forged callback must be answered, so the button
  74. // stops spinning, and must never reach answerCallback.
  75. func TestGateCallbackStopsStrangers(t *testing.T) {
  76. tb, calls := newLevelTgbot(t)
  77. query := &telego.CallbackQuery{ID: "q1", From: telego.User{ID: 777}, Data: "client_sub_links " + ownerMail}
  78. if _, ok := tb.gateCallback(query); ok {
  79. t.Fatal("gateCallback admitted a stranger")
  80. }
  81. if n := calls("answerCallbackQuery"); n != 1 {
  82. t.Errorf("answerCallbackQuery calls = %d, want 1", n)
  83. }
  84. query.From.ID = ownerTgID
  85. if isAdmin, ok := tb.gateCallback(query); !ok || isAdmin {
  86. t.Errorf("gateCallback(client) = (%v, %v), want (false, true)", isAdmin, ok)
  87. }
  88. }