service_sort_test.go 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package sub
  2. import (
  3. "fmt"
  4. "path/filepath"
  5. "testing"
  6. "github.com/mhsanaei/3x-ui/v3/internal/database"
  7. "github.com/mhsanaei/3x-ui/v3/internal/database/dbtest"
  8. "github.com/mhsanaei/3x-ui/v3/internal/database/model"
  9. )
  10. // TestGetSubs_OrdersBySubSortIndexThenId verifies that subscription output
  11. // lists inbound links ordered by sub_sort_index ASC, breaking ties by id ASC.
  12. // The same query feeds the raw body, the HTML sub page, and the JSON/Clash
  13. // formats, so asserting on GetSubs covers all of them.
  14. func TestGetSubs_OrdersBySubSortIndexThenId(t *testing.T) {
  15. dbDir := t.TempDir()
  16. t.Setenv("XUI_DB_FOLDER", dbDir)
  17. dbtest.InitDB(t, filepath.Join(dbDir, "x-ui.db"))
  18. const subId = "sub-sort"
  19. db := database.GetDB()
  20. seed := []struct {
  21. tag string
  22. port int
  23. subSortIndex int
  24. email string
  25. uuid string
  26. }{
  27. // Created in this order on purpose: without the ORDER BY the links
  28. // would come out s3, s1, s2a, s2b (creation order).
  29. {"sort-3", 42101, 3, "[email protected]", "0d68a695-4be1-4d92-a9c3-8c0f1c2cf001"},
  30. {"sort-1", 42102, 1, "[email protected]", "0d68a695-4be1-4d92-a9c3-8c0f1c2cf002"},
  31. {"sort-2a", 42103, 2, "[email protected]", "0d68a695-4be1-4d92-a9c3-8c0f1c2cf003"},
  32. {"sort-2b", 42104, 2, "[email protected]", "0d68a695-4be1-4d92-a9c3-8c0f1c2cf004"},
  33. }
  34. for _, s := range seed {
  35. settings := fmt.Sprintf(`{"clients": [{"id": %q, "email": %q, "subId": %q, "enable": true}]}`, s.uuid, s.email, subId)
  36. ib := &model.Inbound{
  37. UserId: 1,
  38. Tag: s.tag,
  39. Enable: true,
  40. Port: s.port,
  41. Protocol: model.VLESS,
  42. Settings: settings,
  43. StreamSettings: `{"network": "tcp", "security": "none"}`,
  44. SubSortIndex: s.subSortIndex,
  45. }
  46. if err := db.Create(ib).Error; err != nil {
  47. t.Fatalf("seed inbound %s: %v", s.tag, err)
  48. }
  49. client := &model.ClientRecord{Email: s.email, SubID: subId, UUID: s.uuid, Enable: true}
  50. if err := db.Create(client).Error; err != nil {
  51. t.Fatalf("seed client %s: %v", s.email, err)
  52. }
  53. if err := db.Create(&model.ClientInbound{ClientId: client.Id, InboundId: ib.Id}).Error; err != nil {
  54. t.Fatalf("seed client_inbound %s: %v", s.email, err)
  55. }
  56. }
  57. s := NewSubService("")
  58. links, emails, _, _, err := s.GetSubs(subId, "sub.example.com")
  59. if err != nil {
  60. t.Fatalf("GetSubs: %v", err)
  61. }
  62. if len(links) != len(seed) {
  63. t.Fatalf("links = %d, want %d", len(links), len(seed))
  64. }
  65. want := []string{"[email protected]", "[email protected]", "[email protected]", "[email protected]"}
  66. for i, email := range want {
  67. if emails[i] != email {
  68. t.Fatalf("emails order = %v, want %v (sub_sort_index ASC, id ASC)", emails, want)
  69. }
  70. }
  71. }