fix: harden real backend workflows and channel connections
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
package control
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConnectChannelCallbacksConnectedState(t *testing.T) {
|
||||
var callback ConnectionStateCallback
|
||||
api := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/api/admin/gateway/connections" {
|
||||
t.Fatalf("unexpected callback path: %s", r.URL.Path)
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&callback); err != nil {
|
||||
t.Fatalf("decode callback: %v", err)
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
defer api.Close()
|
||||
|
||||
handler := handlerWithDial(api.URL+"/api", func(context.Context, ConnectChannelCommand) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodPost, "/connections/connect", strings.NewReader(validConnectCommand()))
|
||||
handler.ServeHTTP(resp, req)
|
||||
|
||||
if resp.Code != http.StatusOK {
|
||||
t.Fatalf("unexpected response status: %d body=%s", resp.Code, resp.Body.String())
|
||||
}
|
||||
if callback.Status != "connected" || callback.CurrentConnections != 2 || callback.DesiredConnections != 2 {
|
||||
t.Fatalf("unexpected callback state: %+v", callback)
|
||||
}
|
||||
if callback.ChannelID != "channel-1" || callback.ConnectionID != "channel-1:primary" {
|
||||
t.Fatalf("unexpected callback identity: %+v", callback)
|
||||
}
|
||||
if callback.LastConnectedAt == "" || callback.LastHeartbeatAt == "" {
|
||||
t.Fatalf("expected connection timestamps: %+v", callback)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConnectChannelCallbacksFailedState(t *testing.T) {
|
||||
var callback ConnectionStateCallback
|
||||
api := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if err := json.NewDecoder(r.Body).Decode(&callback); err != nil {
|
||||
t.Fatalf("decode callback: %v", err)
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
defer api.Close()
|
||||
|
||||
handler := handlerWithDial(api.URL+"/api", func(context.Context, ConnectChannelCommand) error {
|
||||
return errTestDial
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodPost, "/connections/connect", strings.NewReader(validConnectCommand()))
|
||||
handler.ServeHTTP(resp, req)
|
||||
|
||||
if resp.Code != http.StatusOK {
|
||||
t.Fatalf("unexpected response status: %d body=%s", resp.Code, resp.Body.String())
|
||||
}
|
||||
if callback.Status != "failed" || callback.CurrentConnections != 0 || callback.LastError == "" {
|
||||
t.Fatalf("unexpected callback state: %+v", callback)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConnectChannelRejectsInvalidCommand(t *testing.T) {
|
||||
handler := handlerWithDial("", func(context.Context, ConnectChannelCommand) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodPost, "/connections/connect", strings.NewReader(`{"messageType":"SubmitCommand"}`))
|
||||
handler.ServeHTTP(resp, req)
|
||||
|
||||
if resp.Code != http.StatusBadRequest {
|
||||
t.Fatalf("unexpected response status: %d", resp.Code)
|
||||
}
|
||||
}
|
||||
|
||||
type testDialError struct{}
|
||||
|
||||
func (testDialError) Error() string {
|
||||
return "dial failed"
|
||||
}
|
||||
|
||||
var errTestDial testDialError
|
||||
|
||||
func handlerWithDial(apiBaseURL string, dial DialFunc) http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
Register(mux, Server{APIBaseURL: apiBaseURL, Dial: dial})
|
||||
return mux
|
||||
}
|
||||
|
||||
func validConnectCommand() string {
|
||||
return `{
|
||||
"schemaVersion": "v1",
|
||||
"messageType": "ConnectChannel",
|
||||
"traceId": "trace-1",
|
||||
"channelId": "channel-1",
|
||||
"connectionId": "channel-1:primary",
|
||||
"reason": "channel_created",
|
||||
"desiredConnections": 2,
|
||||
"channel": {
|
||||
"code": "CMPP-A",
|
||||
"name": "主通道",
|
||||
"gatewayHost": "127.0.0.1",
|
||||
"gatewayPort": 17890,
|
||||
"account": "sp",
|
||||
"passwordCipher": "secret",
|
||||
"srcId": "10690000",
|
||||
"cmppVersion": "3.0",
|
||||
"rateLimitPerSecond": 100
|
||||
}
|
||||
}`
|
||||
}
|
||||
Reference in New Issue
Block a user