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) } }