118 lines
3.6 KiB
Go
118 lines
3.6 KiB
Go
|
|
package handlers
|
||
|
|
|
||
|
|
import (
|
||
|
|
"encoding/json"
|
||
|
|
"net/http"
|
||
|
|
"net/http/httptest"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"veza-backend-api/internal/config"
|
||
|
|
|
||
|
|
"github.com/gin-gonic/gin"
|
||
|
|
"github.com/stretchr/testify/assert"
|
||
|
|
"github.com/stretchr/testify/require"
|
||
|
|
)
|
||
|
|
|
||
|
|
func newWebRTCRouter(cfg *config.Config) *gin.Engine {
|
||
|
|
gin.SetMode(gin.TestMode)
|
||
|
|
r := gin.New()
|
||
|
|
r.GET("/config/webrtc", GetWebRTCConfig(cfg))
|
||
|
|
return r
|
||
|
|
}
|
||
|
|
|
||
|
|
func decodeWebRTC(t *testing.T, w *httptest.ResponseRecorder) WebRTCConfigResponse {
|
||
|
|
t.Helper()
|
||
|
|
var resp WebRTCConfigResponse
|
||
|
|
require.NoError(t, json.NewDecoder(w.Body).Decode(&resp))
|
||
|
|
return resp
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestGetWebRTCConfig_StunOnlyWhenNoTurn(t *testing.T) {
|
||
|
|
cfg := &config.Config{
|
||
|
|
WebRTCStunURLs: []string{"stun:stun.example.org:3478"},
|
||
|
|
}
|
||
|
|
r := newWebRTCRouter(cfg)
|
||
|
|
|
||
|
|
w := httptest.NewRecorder()
|
||
|
|
req := httptest.NewRequest(http.MethodGet, "/config/webrtc", nil)
|
||
|
|
r.ServeHTTP(w, req)
|
||
|
|
|
||
|
|
require.Equal(t, http.StatusOK, w.Code)
|
||
|
|
resp := decodeWebRTC(t, w)
|
||
|
|
require.Len(t, resp.IceServers, 1)
|
||
|
|
assert.Equal(t, []string{"stun:stun.example.org:3478"}, resp.IceServers[0].URLs)
|
||
|
|
assert.Empty(t, resp.IceServers[0].Username)
|
||
|
|
assert.Empty(t, resp.IceServers[0].Credential)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestGetWebRTCConfig_EmitsTurnBlockWhenFullyConfigured(t *testing.T) {
|
||
|
|
cfg := &config.Config{
|
||
|
|
WebRTCStunURLs: []string{"stun:stun.example.org:3478"},
|
||
|
|
WebRTCTurnURLs: []string{"turn:turn.veza.local:3478", "turns:turn.veza.local:5349"},
|
||
|
|
WebRTCTurnUsername: "vezauser",
|
||
|
|
WebRTCTurnCredential: "shhhhh",
|
||
|
|
}
|
||
|
|
r := newWebRTCRouter(cfg)
|
||
|
|
|
||
|
|
w := httptest.NewRecorder()
|
||
|
|
req := httptest.NewRequest(http.MethodGet, "/config/webrtc", nil)
|
||
|
|
r.ServeHTTP(w, req)
|
||
|
|
|
||
|
|
require.Equal(t, http.StatusOK, w.Code)
|
||
|
|
resp := decodeWebRTC(t, w)
|
||
|
|
require.Len(t, resp.IceServers, 2)
|
||
|
|
|
||
|
|
assert.Equal(t, []string{"stun:stun.example.org:3478"}, resp.IceServers[0].URLs)
|
||
|
|
assert.Equal(t, []string{"turn:turn.veza.local:3478", "turns:turn.veza.local:5349"}, resp.IceServers[1].URLs)
|
||
|
|
assert.Equal(t, "vezauser", resp.IceServers[1].Username)
|
||
|
|
assert.Equal(t, "shhhhh", resp.IceServers[1].Credential)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestGetWebRTCConfig_OmitsTurnBlockWhenHalfConfigured(t *testing.T) {
|
||
|
|
// Half-configured TURN (URLs but no creds) is worse than missing —
|
||
|
|
// the browser would surface auth failures instead of falling back
|
||
|
|
// cleanly. The handler omits the block in that case.
|
||
|
|
cases := map[string]*config.Config{
|
||
|
|
"missing username": {
|
||
|
|
WebRTCStunURLs: []string{"stun:s.test:3478"},
|
||
|
|
WebRTCTurnURLs: []string{"turn:t.test:3478"},
|
||
|
|
WebRTCTurnCredential: "creds",
|
||
|
|
},
|
||
|
|
"missing credential": {
|
||
|
|
WebRTCStunURLs: []string{"stun:s.test:3478"},
|
||
|
|
WebRTCTurnURLs: []string{"turn:t.test:3478"},
|
||
|
|
WebRTCTurnUsername: "user",
|
||
|
|
},
|
||
|
|
"missing urls": {
|
||
|
|
WebRTCStunURLs: []string{"stun:s.test:3478"},
|
||
|
|
WebRTCTurnUsername: "user",
|
||
|
|
WebRTCTurnCredential: "creds",
|
||
|
|
},
|
||
|
|
}
|
||
|
|
for name, cfg := range cases {
|
||
|
|
t.Run(name, func(t *testing.T) {
|
||
|
|
r := newWebRTCRouter(cfg)
|
||
|
|
w := httptest.NewRecorder()
|
||
|
|
req := httptest.NewRequest(http.MethodGet, "/config/webrtc", nil)
|
||
|
|
r.ServeHTTP(w, req)
|
||
|
|
|
||
|
|
require.Equal(t, http.StatusOK, w.Code)
|
||
|
|
resp := decodeWebRTC(t, w)
|
||
|
|
assert.Len(t, resp.IceServers, 1, "only the STUN entry should be present when TURN is partial")
|
||
|
|
assert.Equal(t, []string{"stun:s.test:3478"}, resp.IceServers[0].URLs)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestGetWebRTCConfig_EmptyConfigReturnsEmptyIceServers(t *testing.T) {
|
||
|
|
cfg := &config.Config{} // no STUN, no TURN
|
||
|
|
r := newWebRTCRouter(cfg)
|
||
|
|
w := httptest.NewRecorder()
|
||
|
|
req := httptest.NewRequest(http.MethodGet, "/config/webrtc", nil)
|
||
|
|
r.ServeHTTP(w, req)
|
||
|
|
|
||
|
|
require.Equal(t, http.StatusOK, w.Code)
|
||
|
|
resp := decodeWebRTC(t, w)
|
||
|
|
assert.Empty(t, resp.IceServers)
|
||
|
|
}
|