mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-08 21:56:08 +00:00
f431e9cc03
* fix(inbounds): apply runtime changes after commit * ci: fix staticcheck findings
89 lines
2.9 KiB
Go
89 lines
2.9 KiB
Go
package service
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"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"
|
|
)
|
|
|
|
// The node-page client breakdown must classify by EMAIL, not by
|
|
// client_traffics.inbound_id — that column goes stale after an inbound is
|
|
// delete+recreated, so filtering by it drops almost every row and undercounts
|
|
// active/disabled/ended. Here the traffic rows carry a bogus inbound_id (999)
|
|
// yet must still be matched to the node's clients by email.
|
|
func TestGetAll_ClientBreakdownMatchesByEmailNotStaleInboundId(t *testing.T) {
|
|
setupConflictDB(t)
|
|
db := database.GetDB()
|
|
svc := NodeService{}
|
|
|
|
if err := db.Create(&model.Node{Id: 1, Name: "n", Address: "10.0.0.1", Port: 2053, ApiToken: "t", Guid: "g"}).Error; err != nil {
|
|
t.Fatalf("create node: %v", err)
|
|
}
|
|
nid := 1
|
|
ib := &model.Inbound{Tag: "n1-in", Enable: true, Port: 443, Protocol: model.VLESS, Settings: `{"clients":[]}`, NodeID: &nid}
|
|
if err := db.Create(ib).Error; err != nil {
|
|
t.Fatalf("create inbound: %v", err)
|
|
}
|
|
|
|
mk := func(id int, email string, enable bool) {
|
|
if err := db.Create(&model.ClientRecord{Id: id, Email: email, Enable: enable}).Error; err != nil {
|
|
t.Fatalf("create client %s: %v", email, err)
|
|
}
|
|
if !enable {
|
|
// Enable has gorm:"default:true", so a zero-value (false) create is
|
|
// dropped and the DB applies true — force the disabled state explicitly.
|
|
if err := db.Model(&model.ClientRecord{}).Where("id = ?", id).Update("enable", false).Error; err != nil {
|
|
t.Fatalf("disable client %s: %v", email, err)
|
|
}
|
|
}
|
|
if err := db.Create(&model.ClientInbound{ClientId: id, InboundId: ib.Id}).Error; err != nil {
|
|
t.Fatalf("attach client %s: %v", email, err)
|
|
}
|
|
}
|
|
mk(1, "active@x", true)
|
|
mk(2, "disabled@x", false)
|
|
mk(3, "depleted@x", true)
|
|
|
|
// Traffic rows carry a STALE inbound_id (999), unrelated to the node inbound.
|
|
const staleInboundID = 999
|
|
rows := []*xray.ClientTraffic{
|
|
{InboundId: staleInboundID, Email: "active@x", Enable: true},
|
|
{InboundId: staleInboundID, Email: "disabled@x", Enable: false},
|
|
{InboundId: staleInboundID, Email: "depleted@x", Enable: true, Total: 100, Up: 60, Down: 60}, // exhausted
|
|
}
|
|
for _, r := range rows {
|
|
if err := db.Create(r).Error; err != nil {
|
|
t.Fatalf("create traffic %s: %v", r.Email, err)
|
|
}
|
|
}
|
|
|
|
nodes, err := svc.GetAll()
|
|
if err != nil {
|
|
t.Fatalf("GetAll: %v", err)
|
|
}
|
|
var n *model.Node
|
|
for _, x := range nodes {
|
|
if x.Id == 1 {
|
|
n = x
|
|
}
|
|
}
|
|
if n == nil {
|
|
t.Fatal("node 1 not found")
|
|
return
|
|
}
|
|
if n.ClientCount != 3 {
|
|
t.Errorf("ClientCount = %d, want 3", n.ClientCount)
|
|
}
|
|
if n.ActiveCount != 1 {
|
|
t.Errorf("ActiveCount = %d, want 1 (matched by email despite stale inbound_id)", n.ActiveCount)
|
|
}
|
|
if n.DisabledCount != 1 {
|
|
t.Errorf("DisabledCount = %d, want 1", n.DisabledCount)
|
|
}
|
|
if n.DepletedCount != 1 {
|
|
t.Errorf("DepletedCount = %d, want 1", n.DepletedCount)
|
|
}
|
|
}
|