service_orphaned_stats_test.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. package sub
  2. import (
  3. "path/filepath"
  4. "testing"
  5. "github.com/mhsanaei/3x-ui/v3/internal/database"
  6. "github.com/mhsanaei/3x-ui/v3/internal/database/model"
  7. "github.com/mhsanaei/3x-ui/v3/internal/xray"
  8. )
  9. // statsForClient recovers a client's usage by email when the client_traffics row
  10. // is orphaned — its inbound_id points at an inbound that was deleted and
  11. // recreated, so the preloaded ClientStats and the statsByEmail index both miss.
  12. // Before the email fallback, {{TRAFFIC_USED}} stayed at 0 for such pre-existing
  13. // clients while the sub-info header was correct (#5567).
  14. func TestStatsForClient_OrphanedInboundIdFallback(t *testing.T) {
  15. dbDir := t.TempDir()
  16. t.Setenv("XUI_DB_FOLDER", dbDir)
  17. if err := database.InitDB(filepath.Join(dbDir, "x-ui.db")); err != nil {
  18. t.Fatalf("InitDB: %v", err)
  19. }
  20. t.Cleanup(func() { _ = database.CloseDB() })
  21. const email = "[email protected]"
  22. const total = int64(100) * gb
  23. db := database.GetDB()
  24. if err := db.Create(&xray.ClientTraffic{
  25. InboundId: 999,
  26. Email: email,
  27. Up: 15 * gb,
  28. Down: 5 * gb,
  29. Total: total,
  30. Enable: true,
  31. }).Error; err != nil {
  32. t.Fatalf("seed orphaned traffic: %v", err)
  33. }
  34. s := &SubService{statsByEmail: map[string]xray.ClientTraffic{}}
  35. inbound := &model.Inbound{Id: 1, Remark: "DE"}
  36. client := model.Client{Email: email, TotalGB: total, Enable: true}
  37. st := s.statsForClient(inbound, client)
  38. if used := st.Up + st.Down; used != 20*gb {
  39. t.Fatalf("statsForClient used = %d, want %d (email fallback)", used, 20*gb)
  40. }
  41. if _, ok := s.statsByEmail[email]; !ok {
  42. t.Fatalf("email fallback must cache the row into statsByEmail")
  43. }
  44. if got := remarkVarValue("TRAFFIC_USED", remarkContext{stats: st}); got != "20.00GB" {
  45. t.Fatalf("TRAFFIC_USED = %q, want 20.00GB", got)
  46. }
  47. }