| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- package tgbot
- import (
- "encoding/json"
- "net/http"
- "net/http/httptest"
- "path/filepath"
- "strings"
- "sync"
- "testing"
- "github.com/mhsanaei/3x-ui/v3/internal/database"
- "github.com/mhsanaei/3x-ui/v3/internal/database/dbtest"
- "github.com/mhsanaei/3x-ui/v3/internal/database/model"
- "github.com/mhsanaei/3x-ui/v3/internal/sub"
- "github.com/mhsanaei/3x-ui/v3/internal/web/service"
- "github.com/mhsanaei/3x-ui/v3/internal/xray"
- )
- // recordingBotServer answers sendMessage and records every text it was asked to send.
- func recordingBotServer(t *testing.T) func() []string {
- t.Helper()
- var mu sync.Mutex
- var texts []string
- srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.URL.Path != "/bot"+testBotToken+"/sendMessage" {
- w.WriteHeader(http.StatusNotFound)
- return
- }
- var body struct {
- Text string `json:"text"`
- }
- _ = json.NewDecoder(r.Body).Decode(&body)
- mu.Lock()
- texts = append(texts, body.Text)
- mu.Unlock()
- w.Header().Set("Content-Type", "application/json")
- _ = json.NewEncoder(w).Encode(map[string]any{"ok": true, "result": map[string]any{
- "message_id": 1, "date": 0, "chat": map[string]any{"id": ownerTgID, "type": "private"},
- }})
- }))
- t.Cleanup(srv.Close)
- swapTestBot(t, srv.URL)
- return func() []string {
- mu.Lock()
- defer mu.Unlock()
- return append([]string(nil), texts...)
- }
- }
- // With no sub or web domain set, the only host the bot knows is the machine
- // name, which need not resolve; the links must not depend on reaching it.
- func TestIndividualLinksDoNotNeedAResolvableHost(t *testing.T) {
- sent := recordingBotServer(t)
- dbtest.InitDB(t, filepath.Join(t.TempDir(), "x-ui.db"))
- service.RegisterSubLinkProvider(sub.NewLinkProvider())
- const uuid = "11111111-2222-4333-8444-555555555555"
- db := database.GetDB()
- ib := &model.Inbound{
- UserId: 1, Tag: "in-443", Enable: true, Listen: "203.0.113.5", Port: 443,
- Protocol: model.VLESS, Remark: "in",
- Settings: `{"clients":[{"id":"` + uuid + `","email":"` + ownerMail + `","tgId":4242,"subId":"sub-owned","enable":true}],"decryption":"none"}`,
- }
- if err := db.Create(ib).Error; err != nil {
- t.Fatalf("seed inbound: %v", err)
- }
- rec := &model.ClientRecord{Email: ownerMail, SubID: "sub-owned", UUID: uuid, TgID: ownerTgID, Enable: true}
- if err := db.Create(rec).Error; err != nil {
- t.Fatalf("seed client: %v", err)
- }
- if err := db.Create(&model.ClientInbound{ClientId: rec.Id, InboundId: ib.Id}).Error; err != nil {
- t.Fatalf("seed client_inbound: %v", err)
- }
- if err := db.Create(&xray.ClientTraffic{InboundId: ib.Id, Email: ownerMail, Enable: true}).Error; err != nil {
- t.Fatalf("seed traffic: %v", err)
- }
- origHost, origRunning := hostname, isRunning
- t.Cleanup(func() { hostname, isRunning = origHost, origRunning })
- hostname, isRunning = "unresolvable-panel-host.invalid", true
- tapClientLinks(t, &Tgbot{}, ownerTgID, "client_individual_links "+ownerMail)
- got := strings.Join(sent(), "\n")
- if !strings.Contains(got, "vless://"+uuid+"@203.0.113.5:443") {
- t.Fatalf("bot sent %q, want the client's vless link", got)
- }
- }
|