tgbot_add_client_picker_test.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package tgbot
  2. import (
  3. "fmt"
  4. "path/filepath"
  5. "slices"
  6. "testing"
  7. "github.com/mhsanaei/3x-ui/v3/internal/database"
  8. "github.com/mhsanaei/3x-ui/v3/internal/database/model"
  9. "github.com/mymmrac/telego"
  10. "github.com/nicksnyder/go-i18n/v2/i18n"
  11. )
  12. func seedPickerInbounds(t *testing.T, protocols ...model.Protocol) {
  13. t.Helper()
  14. if err := database.InitDB(filepath.Join(t.TempDir(), "x-ui.db")); err != nil {
  15. t.Fatalf("InitDB: %v", err)
  16. }
  17. t.Cleanup(func() { _ = database.CloseDB() })
  18. for i, protocol := range protocols {
  19. port := 20000 + i
  20. ib := &model.Inbound{Remark: string(protocol), Enable: true, Port: port, Protocol: protocol, Tag: fmt.Sprintf("inbound-%d", port), Settings: `{}`}
  21. if err := database.GetDB().Create(ib).Error; err != nil {
  22. t.Fatalf("seed %s inbound: %v", protocol, err)
  23. }
  24. }
  25. }
  26. func pickerLabels(keyboard *telego.InlineKeyboardMarkup) []string {
  27. var labels []string
  28. for _, row := range keyboard.InlineKeyboard {
  29. for _, button := range row {
  30. labels = append(labels, button.Text)
  31. }
  32. }
  33. slices.Sort(labels)
  34. return labels
  35. }
  36. // WireGuard and AmneziaWG clients get a generated keypair and address on Create,
  37. // so the wizard offers them; Mixed authenticates per inbound and has no clients.
  38. func TestAddClientPickerOffersWireGuardAndAmneziaWG(t *testing.T) {
  39. seedPickerInbounds(t, model.VLESS, model.WireGuard, model.AmneziaWG, model.Mixed)
  40. keyboard, err := (&Tgbot{}).getInboundsAddClient()
  41. if err != nil {
  42. t.Fatalf("getInboundsAddClient: %v", err)
  43. }
  44. want := []string{"amneziawg - ✅", "vless - ✅", "wireguard - ✅"}
  45. if got := pickerLabels(keyboard); !slices.Equal(got, want) {
  46. t.Fatalf("picker buttons = %q, want %q", got, want)
  47. }
  48. }
  49. // An empty keyboard sent the admin a "choose inbound" prompt with nothing to tap.
  50. func TestAddClientPickerFailsWhenNoInboundTakesClients(t *testing.T) {
  51. draftLocalizer(t, &i18n.Message{ID: "tgbot.answers.getInboundsFailed", Other: "Failed to get inbounds."})
  52. seedPickerInbounds(t, model.Mixed, model.HTTP, model.Tunnel)
  53. keyboard, err := (&Tgbot{}).getInboundsAddClient()
  54. if err == nil || err.Error() != "Failed to get inbounds." {
  55. t.Fatalf("getInboundsAddClient = (%v, %v), want the getInboundsFailed error", keyboard, err)
  56. }
  57. }