(t *testing.T)
| 171 | } |
| 172 | |
| 173 | func TestUserSupportsMultipleProtocols(t *testing.T) { |
| 174 | mux, ibStore := setupTestMux(t, map[string]func(body any) (json.RawMessage, error){ |
| 175 | "Restart": func(any) (json.RawMessage, error) { |
| 176 | return json.RawMessage(`{"running":true}`), nil |
| 177 | }, |
| 178 | }) |
| 179 | |
| 180 | // 在 node-1 上注册 trojan 和 shadowsocks 入站 |
| 181 | _, _ = ibStore.UpsertInbound(inbounds.Inbound{ |
| 182 | ID: "ib-trojan", |
| 183 | NodeID: "node-1", |
| 184 | Protocol: "trojan", |
| 185 | Tag: "pulse-trojan-node-1", |
| 186 | Port: 443, |
| 187 | }) |
| 188 | _, _ = ibStore.UpsertHost(inbounds.Host{ |
| 189 | ID: "host-trojan", |
| 190 | InboundID: "ib-trojan", |
| 191 | Address: "example.com", |
| 192 | Port: 443, |
| 193 | }) |
| 194 | _, _ = ibStore.UpsertInbound(inbounds.Inbound{ |
| 195 | ID: "ib-ss", |
| 196 | NodeID: "node-1", |
| 197 | Protocol: "shadowsocks", |
| 198 | Tag: "pulse-ss-node-1", |
| 199 | Port: 8443, |
| 200 | Method: "aes-256-gcm", |
| 201 | }) |
| 202 | _, _ = ibStore.UpsertHost(inbounds.Host{ |
| 203 | ID: "host-ss", |
| 204 | InboundID: "ib-ss", |
| 205 | Address: "example.com", |
| 206 | Port: 8443, |
| 207 | }) |
| 208 | |
| 209 | // 创建用户,分别绑定 trojan 和 ss 两个 inbound |
| 210 | userID := createUser(t, mux, `{"id":"user-multi","username":"alice"}`) |
| 211 | trojanAccessID := createUserInbound(t, mux, userID, "ib-trojan") |
| 212 | ssAccessID := createUserInbound(t, mux, userID, "ib-ss") |
| 213 | |
| 214 | // trojan 绑定的订阅只包含 trojan 链接 |
| 215 | rec := httptest.NewRecorder() |
| 216 | req := httptest.NewRequest(http.MethodGet, "/v1/users/"+userID+"/inbounds/"+trojanAccessID+"/subscription", nil) |
| 217 | mux.ServeHTTP(rec, req) |
| 218 | if rec.Code != http.StatusOK { |
| 219 | t.Fatalf("trojan subscription status = %d body=%s", rec.Code, rec.Body.String()) |
| 220 | } |
| 221 | if !strings.Contains(rec.Body.String(), "trojan://") { |
| 222 | t.Fatalf("expected trojan link, got %s", rec.Body.String()) |
| 223 | } |
| 224 | |
| 225 | // ss 绑定的订阅只包含 ss 链接 |
| 226 | rec = httptest.NewRecorder() |
| 227 | req = httptest.NewRequest(http.MethodGet, "/v1/users/"+userID+"/inbounds/"+ssAccessID+"/subscription", nil) |
| 228 | mux.ServeHTTP(rec, req) |
| 229 | if rec.Code != http.StatusOK { |
| 230 | t.Fatalf("ss subscription status = %d body=%s", rec.Code, rec.Body.String()) |
nothing calls this directly
no test coverage detected