Files
l-ui/internal/web/service/traffic_test_helpers_test.go
T

122 lines
3.6 KiB
Go

package service
import (
"encoding/json"
"fmt"
"path/filepath"
"slices"
"testing"
"gorm.io/gorm"
"github.com/mhsanaei/3x-ui/v3/internal/database"
"github.com/mhsanaei/3x-ui/v3/internal/database/model"
"github.com/mhsanaei/3x-ui/v3/internal/xray"
)
func assertStringSet(t *testing.T, label string, got, want []string) {
t.Helper()
g := append([]string(nil), got...)
w := append([]string(nil), want...)
slices.Sort(g)
slices.Sort(w)
if !slices.Equal(g, w) {
t.Fatalf("%s = %v, want %v", label, got, want)
}
}
func marshalIps(t *testing.T, entries ...clientIpEntry) string {
t.Helper()
b, err := json.Marshal(entries)
if err != nil {
t.Fatalf("marshal ips: %v", err)
}
return string(b)
}
// readClientIps returns the stored IP entries for an email as a map[ip]timestamp,
// plus whether the row exists at all.
func readClientIps(t *testing.T, email string) (map[string]int64, bool) {
t.Helper()
var row model.InboundClientIps
err := database.GetDB().Where("client_email = ?", email).First(&row).Error
if database.IsNotFound(err) {
return nil, false
}
if err != nil {
t.Fatalf("read ips %q: %v", email, err)
}
var entries []clientIpEntry
if err := json.Unmarshal([]byte(row.Ips), &entries); err != nil {
t.Fatalf("unmarshal ips %q: %v", email, err)
}
out := make(map[string]int64, len(entries))
for _, e := range entries {
out[e.IP] = e.Timestamp
}
return out, true
}
// Shared fixtures for the traffic/node test files. These helpers lived
// in node_client_traffic_sum_test.go until that file's snapshot-merge
// tests were retired with the traditional node sync (B6); the helpers
// themselves serve surviving tests, so they moved here.
func setupClientIpTestDB(t *testing.T) {
t.Helper()
dbDir := t.TempDir()
t.Setenv("XUI_DB_FOLDER", dbDir)
if err := database.InitDB(filepath.Join(dbDir, "x-ui.db")); err != nil {
t.Fatalf("InitDB: %v", err)
}
t.Cleanup(func() { _ = database.CloseDB() })
}
func initTrafficTestDB(t *testing.T) *gorm.DB {
t.Helper()
dbDir := t.TempDir()
t.Setenv("XUI_DB_FOLDER", dbDir)
if err := database.InitDB(filepath.Join(dbDir, "x-ui.db")); err != nil {
t.Fatalf("InitDB: %v", err)
}
t.Cleanup(func() { _ = database.CloseDB() })
return database.GetDB()
}
func createNodeInbound(t *testing.T, db *gorm.DB, nodeID int, tag string, port int) {
t.Helper()
nid := nodeID
ib := &model.Inbound{UserId: 1, Tag: tag, Enable: true, Port: port, Protocol: model.VLESS, NodeID: &nid}
if err := db.Create(ib).Error; err != nil {
t.Fatalf("create node inbound %q: %v", tag, err)
}
}
// createNodeInboundWithClient mirrors createNodeInbound but stores the client
// in the settings JSON.
func createNodeInboundWithClient(t *testing.T, db *gorm.DB, nodeID int, tag string, port int, email string) {
t.Helper()
nid := nodeID
settings := fmt.Sprintf(`{"clients": [{"email": %q, "enable": true}]}`, email)
ib := &model.Inbound{UserId: 1, Tag: tag, Enable: true, Port: port, Protocol: model.VLESS, NodeID: &nid, Settings: settings}
if err := db.Create(ib).Error; err != nil {
t.Fatalf("create node inbound %q: %v", tag, err)
}
}
func readTraffic(t *testing.T, db *gorm.DB, email string) xray.ClientTraffic {
t.Helper()
var ct xray.ClientTraffic
if err := db.Model(xray.ClientTraffic{}).Where("email = ?", email).First(&ct).Error; err != nil {
t.Fatalf("read client_traffics %q: %v", email, err)
}
return ct
}
func assertUpDown(t *testing.T, ct xray.ClientTraffic, wantUp, wantDown int64, when string) {
t.Helper()
if ct.Up != wantUp || ct.Down != wantDown {
t.Errorf("%s: up=%d down=%d, want %d/%d", when, ct.Up, ct.Down, wantUp, wantDown)
}
}