mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-11-13 00:14:22 +08:00
b26e9ee9e4
* fix: keep user and limit drag handles beside names * fix: show live node and tunnel deployment progress in list view
99 lines
3.0 KiB
Go
99 lines
3.0 KiB
Go
package contract_test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"go-backend/internal/auth"
|
|
)
|
|
|
|
func TestTunnelRedeployStreamContract(t *testing.T) {
|
|
const secret = "contract-jwt-secret"
|
|
router, _ := setupContractRouter(t, secret)
|
|
token, err := auth.GenerateToken(1, "admin_user", 0, secret)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/tunnel/batch-redeploy/stream", strings.NewReader(`{"ids":[999998,999999]}`))
|
|
req.Header.Set("Authorization", token)
|
|
res := httptest.NewRecorder()
|
|
router.ServeHTTP(res, req)
|
|
if !strings.HasPrefix(res.Header().Get("Content-Type"), "application/x-ndjson") {
|
|
t.Fatalf("expected streamed progress, got %s: %s", res.Header().Get("Content-Type"), res.Body.String())
|
|
}
|
|
decoder := json.NewDecoder(res.Body)
|
|
for _, want := range []string{"start", "processing", "item", "processing", "item", "done"} {
|
|
var event struct {
|
|
Type string `json:"type"`
|
|
Data json.RawMessage `json:"data"`
|
|
}
|
|
if err := decoder.Decode(&event); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if event.Type != want {
|
|
t.Fatalf("got %s, want %s", event.Type, want)
|
|
}
|
|
if want == "item" {
|
|
var data struct{ Result map[string]interface{} }
|
|
if err := json.Unmarshal(event.Data, &data); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, ok := data.Result["name"].(string); !ok {
|
|
t.Fatalf("item name must be a string, including missing tunnels: %s", event.Data)
|
|
}
|
|
}
|
|
if want == "done" {
|
|
var data struct {
|
|
Progress struct{ Total, Completed, Success, Failed int }
|
|
Result struct {
|
|
SuccessCount, FailCount int
|
|
Failures []struct {
|
|
ID int64
|
|
Reason string
|
|
}
|
|
}
|
|
}
|
|
if err := json.Unmarshal(event.Data, &data); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if data.Progress.Total != 2 || data.Progress.Completed != 2 || data.Progress.Failed != 2 || data.Progress.Success != 0 || data.Result.FailCount != 2 || len(data.Result.Failures) != 2 {
|
|
t.Fatalf("incorrect completion: %+v", data)
|
|
}
|
|
if data.Result.Failures[0].Reason == "" {
|
|
t.Fatal("missing failure detail")
|
|
}
|
|
}
|
|
}
|
|
if !res.Flushed {
|
|
t.Fatal("stream did not flush")
|
|
}
|
|
}
|
|
|
|
func TestTunnelRedeployStreamAuthorizationContract(t *testing.T) {
|
|
const secret = "contract-jwt-secret"
|
|
router, repository := setupContractRouter(t, secret)
|
|
seedLegacyUser(t, repository, 9111, "stream-normal-user", "password")
|
|
token, err := auth.GenerateToken(9111, "stream-normal-user", 1, secret)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, tc := range []struct {
|
|
name, token string
|
|
code int
|
|
}{{"anonymous", "", 401}, {"non-admin", token, 403}} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/tunnel/batch-redeploy/stream", strings.NewReader(`{"ids":[999999]}`))
|
|
req.Header.Set("Authorization", tc.token)
|
|
res := httptest.NewRecorder()
|
|
router.ServeHTTP(res, req)
|
|
assertCode(t, res, tc.code)
|
|
if strings.Contains(res.Body.String(), `"type":"start"`) {
|
|
t.Fatal("unauthorized request started stream")
|
|
}
|
|
})
|
|
}
|
|
}
|