types_test.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package tuic
  2. import (
  3. "testing"
  4. "github.com/mhsanaei/3x-ui/v3/internal/database/model"
  5. )
  6. func TestInstanceFromInbound(t *testing.T) {
  7. t.Run("valid settings", func(t *testing.T) {
  8. ib := &model.Inbound{
  9. Id: 10,
  10. Tag: "tuic-in-1",
  11. Port: 8443,
  12. Listen: "0.0.0.0",
  13. Protocol: model.TUIC,
  14. Settings: `{"certificate":"/etc/cert.pem","private_key":"/etc/key.pem","congestion_control":"bbr","alpn":["h3"],"clients":[{"uuid":"11111111-2222-3333-4444-555555555555","password":"pass1","email":"user1@test","enable":true}]}`,
  15. }
  16. inst, ok := InstanceFromInbound(ib)
  17. if !ok {
  18. t.Fatal("expected ok to be true")
  19. }
  20. if inst.Id != 10 || inst.Port != 8443 || inst.Tag != "tuic-in-1" {
  21. t.Fatalf("unexpected inst header fields: %+v", inst)
  22. }
  23. if inst.Certificate != "/etc/cert.pem" || inst.PrivateKey != "/etc/key.pem" {
  24. t.Fatalf("unexpected cert/key: %s / %s", inst.Certificate, inst.PrivateKey)
  25. }
  26. if len(inst.Clients) != 1 {
  27. t.Fatalf("expected 1 client, got %d", len(inst.Clients))
  28. }
  29. if inst.Clients[0].UUID != "11111111-2222-3333-4444-555555555555" || inst.Clients[0].Password != "pass1" {
  30. t.Fatalf("unexpected client: %+v", inst.Clients[0])
  31. }
  32. })
  33. t.Run("normalizes uuid to lowercase and trims space", func(t *testing.T) {
  34. ib := &model.Inbound{
  35. Id: 12,
  36. Protocol: model.TUIC,
  37. Settings: `{"clients":[{"uuid":" A1B2C3D4-E5F6-7A8B-9C0D-1E2F3A4B5C6D ","password":"p"}]}`,
  38. }
  39. inst, ok := InstanceFromInbound(ib)
  40. if !ok || len(inst.Clients) != 1 {
  41. t.Fatal("expected ok and 1 client")
  42. }
  43. if inst.Clients[0].UUID != "a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d" {
  44. t.Fatalf("expected lowercase trimmed UUID, got %q", inst.Clients[0].UUID)
  45. }
  46. })
  47. t.Run("nil or wrong protocol", func(t *testing.T) {
  48. if _, ok := InstanceFromInbound(nil); ok {
  49. t.Fatal("expected false for nil")
  50. }
  51. if _, ok := InstanceFromInbound(&model.Inbound{Protocol: model.VLESS}); ok {
  52. t.Fatal("expected false for vless")
  53. }
  54. })
  55. t.Run("no enabled clients", func(t *testing.T) {
  56. ib := &model.Inbound{
  57. Id: 11,
  58. Protocol: model.TUIC,
  59. Settings: `{"clients":[{"uuid":"1111","password":"p","enable":false}]}`,
  60. }
  61. inst, ok := InstanceFromInbound(ib)
  62. if !ok {
  63. t.Fatal("expected ok for inbound")
  64. }
  65. if len(inst.Clients) != 0 {
  66. t.Fatalf("expected 0 enabled clients, got %d", len(inst.Clients))
  67. }
  68. })
  69. }
  70. func TestFingerprints(t *testing.T) {
  71. inst1 := Instance{
  72. Id: 1,
  73. Port: 8443,
  74. Certificate: "/path/cert",
  75. PrivateKey: "/path/key",
  76. CongestionControl: "bbr",
  77. Clients: []TuicClientSettings{
  78. {UUID: "u1", Password: "p1", Email: "e1"},
  79. {UUID: "u2", Password: "p2", Email: "e2"},
  80. },
  81. }
  82. inst2 := Instance{
  83. Id: 1,
  84. Port: 8443,
  85. Certificate: "/path/cert",
  86. PrivateKey: "/path/key",
  87. CongestionControl: "bbr",
  88. Clients: []TuicClientSettings{
  89. {UUID: "u2", Password: "p2", Email: "e2"},
  90. {UUID: "u1", Password: "p1", Email: "e1"},
  91. },
  92. }
  93. if inst1.UsersFingerprint() != inst2.UsersFingerprint() {
  94. t.Fatalf("users fingerprint must be stable under reordering: %s vs %s", inst1.UsersFingerprint(), inst2.UsersFingerprint())
  95. }
  96. }
  97. func TestBindTo(t *testing.T) {
  98. tests := []struct {
  99. listen string
  100. want string
  101. }{
  102. {"", "0.0.0.0:8443"},
  103. {"127.0.0.1", "127.0.0.1:8443"},
  104. {"::", "[::]:8443"},
  105. {"2001:db8::1", "[2001:db8::1]:8443"},
  106. }
  107. for _, tc := range tests {
  108. t.Run(tc.listen, func(t *testing.T) {
  109. got := Instance{Listen: tc.listen, Port: 8443}.BindTo()
  110. if got != tc.want {
  111. t.Fatalf("BindTo(%q) = %q, want %q", tc.listen, got, tc.want)
  112. }
  113. })
  114. }
  115. }