1
0

service_exclude_from_sub_test.go 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package sub
  2. import (
  3. "strings"
  4. "testing"
  5. "github.com/mhsanaei/3x-ui/v3/internal/database"
  6. "github.com/mhsanaei/3x-ui/v3/internal/xray"
  7. )
  8. // An excluded inbound keeps serving its clients, so every renderer must drop
  9. // its links yet still count its clients' usage in the Subscription-Userinfo header.
  10. func TestExcludedInboundHidesLinksButKeepsUsage(t *testing.T) {
  11. seedSubDB(t)
  12. db := database.GetDB()
  13. shown := seedSubInbound(t, "sub-excl", "shown", 24401, 1, `{"network":"tcp","security":"none"}`)
  14. hidden := seedSubInbound(t, "sub-excl", "hidden", 24402, 2, `{"network":"tcp","security":"none"}`)
  15. if err := db.Model(hidden).Update("exclude_from_sub", true).Error; err != nil {
  16. t.Fatalf("mark excluded: %v", err)
  17. }
  18. for _, row := range []*xray.ClientTraffic{
  19. {InboundId: shown.Id, Email: "shown@e", Up: 100, Down: 200, Enable: true},
  20. {InboundId: hidden.Id, Email: "hidden@e", Up: 1000, Down: 2000, Enable: true},
  21. } {
  22. if err := db.Create(row).Error; err != nil {
  23. t.Fatalf("seed traffic %s: %v", row.Email, err)
  24. }
  25. }
  26. const wantHeader = "upload=1100; download=2200; "
  27. assertOnlyShown := func(t *testing.T, out string) {
  28. t.Helper()
  29. if !strings.Contains(out, "24401") {
  30. t.Fatalf("output lost the shown inbound:\n%s", out)
  31. }
  32. if strings.Contains(out, "24402") {
  33. t.Fatalf("output leaked the excluded inbound:\n%s", out)
  34. }
  35. }
  36. t.Run("raw", func(t *testing.T) {
  37. links, _, _, traffic, err := NewSubService("").GetSubs("sub-excl", "req.example.com")
  38. if err != nil {
  39. t.Fatalf("GetSubs: %v", err)
  40. }
  41. if len(links) != 1 {
  42. t.Fatalf("links = %q, want only the shown inbound's link", links)
  43. }
  44. assertOnlyShown(t, links[0])
  45. if traffic.Up != 1100 || traffic.Down != 2200 {
  46. t.Fatalf("usage = up %d/down %d, want 1100/2200 including the excluded inbound's client", traffic.Up, traffic.Down)
  47. }
  48. })
  49. t.Run("clash", func(t *testing.T) {
  50. out, header, err := NewSubClashService(false, "", NewSubService("")).GetClash("sub-excl", "req.example.com")
  51. if err != nil {
  52. t.Fatalf("GetClash: %v", err)
  53. }
  54. assertOnlyShown(t, out)
  55. if !strings.HasPrefix(header, wantHeader) {
  56. t.Fatalf("header = %q, want prefix %q", header, wantHeader)
  57. }
  58. })
  59. t.Run("json", func(t *testing.T) {
  60. out, header, err := NewSubJsonService("", "", "", "", NewSubService("")).GetJson("sub-excl", "req.example.com", false)
  61. if err != nil {
  62. t.Fatalf("GetJson: %v", err)
  63. }
  64. assertOnlyShown(t, out)
  65. if !strings.HasPrefix(header, wantHeader) {
  66. t.Fatalf("header = %q, want prefix %q", header, wantHeader)
  67. }
  68. })
  69. }