85 lines
2.5 KiB
Go
85 lines
2.5 KiB
Go
package cloudflare
|
||
|
||
import (
|
||
"encoding/json"
|
||
"io"
|
||
"net/http"
|
||
"net/http/httptest"
|
||
"strings"
|
||
"testing"
|
||
)
|
||
|
||
// 用 httptest 校验 Cloudflare Realtime REST 的请求契约(路径 / Bearer / body 形状),
|
||
// 无需真实凭证即可验证主 SFU 的集成代码路径。
|
||
func TestClientSessionAndTracks(t *testing.T) {
|
||
var gotAuth string
|
||
var gotBody TrackRequest
|
||
|
||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
body, _ := io.ReadAll(r.Body)
|
||
gotAuth = r.Header.Get("Authorization")
|
||
_ = json.Unmarshal(body, &gotBody)
|
||
switch {
|
||
case strings.HasSuffix(r.URL.Path, "/sessions/new"):
|
||
w.Write([]byte(`{"sessionId":"sess-pub"}`))
|
||
case strings.HasSuffix(r.URL.Path, "/tracks/new"):
|
||
w.Write([]byte(`{"sessionDescription":{"type":"answer","sdp":"v=0"},"tracks":[]}`))
|
||
case r.Method == http.MethodDelete:
|
||
w.WriteHeader(http.StatusOK)
|
||
default:
|
||
w.WriteHeader(http.StatusNotFound)
|
||
}
|
||
}))
|
||
defer srv.Close()
|
||
|
||
c := NewClient("app1", "secret1", srv.URL+"/v1")
|
||
if c.appID != "app1" {
|
||
t.Fatalf("appID = %q", c.appID)
|
||
}
|
||
|
||
sid, err := c.CreateSession("room1")
|
||
if err != nil {
|
||
t.Fatalf("CreateSession: %v", err)
|
||
}
|
||
if sid != "sess-pub" {
|
||
t.Fatalf("sessionId = %q", sid)
|
||
}
|
||
if gotAuth != "Bearer secret1" {
|
||
t.Fatalf("auth = %q", gotAuth)
|
||
}
|
||
|
||
// 发布:location=local
|
||
resp, err := c.AddTracks(sid, &TrackRequest{
|
||
SessionDescription: &SessionDescription{Type: "offer", SDP: "v=0"},
|
||
Tracks: []TrackSpec{{Location: "local", TrackName: "video", Kind: "video"}},
|
||
AutoDiscover: true,
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("AddTracks publish: %v", err)
|
||
}
|
||
if resp.SessionDescription == nil || resp.SessionDescription.Type != "answer" {
|
||
t.Fatalf("unexpected answer: %+v", resp.SessionDescription)
|
||
}
|
||
if len(gotBody.Tracks) != 1 || gotBody.Tracks[0].Location != "local" {
|
||
t.Fatalf("publish track location = %+v", gotBody.Tracks)
|
||
}
|
||
if !gotBody.AutoDiscover {
|
||
t.Fatalf("autodiscover not set")
|
||
}
|
||
|
||
// 订阅:location=remote + 发布者 sessionId
|
||
_, err = c.AddTracks("sess-view", &TrackRequest{
|
||
Tracks: []TrackSpec{{Location: "remote", SessionID: "sess-pub", TrackName: "video"}},
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("AddTracks subscribe: %v", err)
|
||
}
|
||
if len(gotBody.Tracks) != 1 || gotBody.Tracks[0].Location != "remote" || gotBody.Tracks[0].SessionID != "sess-pub" {
|
||
t.Fatalf("subscribe track = %+v", gotBody.Tracks)
|
||
}
|
||
|
||
if err := c.DeleteSession("sess-pub"); err != nil {
|
||
t.Fatalf("DeleteSession: %v", err)
|
||
}
|
||
}
|