Files
silo-server/internal/api/handlers/playback_session_missing_test.go
T

183 lines
4.9 KiB
Go

package handlers
import (
"bytes"
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/go-chi/chi/v5"
"github.com/Silo-Server/silo-server/internal/playback"
)
func TestPlaybackSessionMissingResponsesUseStableErrorCode(t *testing.T) {
const missingSessionID = "missing-session"
sessionMgr := playback.NewSessionManager(0, 0)
playbackHandler := NewPlaybackHandler(sessionMgr)
playbackHandler.RealtimeHub = playback.NewRealtimeHub()
streamHandler := NewStreamHandler(sessionMgr, testPlaybackFileResolver{})
tests := []struct {
name string
request func() *http.Request
handle func(http.ResponseWriter, *http.Request)
}{
{
name: "progress",
request: func() *http.Request {
return playbackTestRequest(
http.MethodPost,
"/api/v1/playback/"+missingSessionID+"/progress",
[]byte(`{"position":12,"is_paused":false}`),
map[string]string{"session_id": missingSessionID},
)
},
handle: playbackHandler.HandleUpdateProgress,
},
{
name: "stop",
request: func() *http.Request {
return playbackTestRequest(
http.MethodDelete,
"/api/v1/playback/"+missingSessionID,
nil,
map[string]string{"session_id": missingSessionID},
)
},
handle: playbackHandler.HandleStopPlayback,
},
{
name: "audio",
request: func() *http.Request {
return playbackTestRequest(
http.MethodPatch,
"/api/v1/playback/"+missingSessionID+"/audio",
[]byte(`{"audio_track_index":1}`),
map[string]string{"session_id": missingSessionID},
)
},
handle: playbackHandler.HandleChangeAudioTrack,
},
{
name: "websocket",
request: func() *http.Request {
return playbackTestRequest(
http.MethodGet,
"/api/v1/playback/sessions/"+missingSessionID+"/control/ws",
nil,
map[string]string{"session_id": missingSessionID},
)
},
handle: playbackHandler.HandleSessionWebSocket,
},
{
name: "stream",
request: func() *http.Request {
return playbackTestRequest(
http.MethodGet,
"/api/v1/stream/"+missingSessionID,
nil,
map[string]string{"session_id": missingSessionID},
)
},
handle: streamHandler.HandleStream,
},
{
name: "subtitle",
request: func() *http.Request {
return playbackTestRequest(
http.MethodGet,
"/api/v1/stream/"+missingSessionID+"/subtitles/0.vtt",
nil,
map[string]string{"session_id": missingSessionID, "track": "0.vtt"},
)
},
handle: streamHandler.HandleSubtitle,
},
{
name: "transcode start",
request: func() *http.Request {
return playbackTestRequest(
http.MethodPost,
"/api/v1/playback/transcode/start",
[]byte(`{"session_id":"`+missingSessionID+`","seek_seconds":0,"target_bitrate_kbps":0,"segment_duration":2,"subtitle_track_index":-1,"subtitle_burn_in":false}`),
nil,
)
},
handle: playbackHandler.HandleStartTranscode,
},
{
name: "transcode manifest",
request: func() *http.Request {
return playbackTestRequest(
http.MethodGet,
"/api/v1/playback/transcode/"+missingSessionID+"/master.m3u8",
nil,
map[string]string{"session_id": missingSessionID},
)
},
handle: playbackHandler.HandleGetTranscodeManifest,
},
{
name: "transcode segment",
request: func() *http.Request {
return playbackTestRequest(
http.MethodGet,
"/api/v1/playback/transcode/"+missingSessionID+"/segment/000.ts",
nil,
map[string]string{"session_id": missingSessionID, "name": "000.ts"},
)
},
handle: playbackHandler.HandleGetTranscodeSegment,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
rr := httptest.NewRecorder()
tt.handle(rr, tt.request())
assertPlaybackSessionMissingResponse(t, rr)
})
}
}
func playbackTestRequest(method, target string, body []byte, params map[string]string) *http.Request {
var reader *bytes.Reader
if body == nil {
reader = bytes.NewReader(nil)
} else {
reader = bytes.NewReader(body)
}
req := httptest.NewRequest(method, target, reader)
req = req.WithContext(newAuthorizedPlaybackContext())
if len(params) == 0 {
return req
}
routeCtx := chi.NewRouteContext()
for key, value := range params {
routeCtx.URLParams.Add(key, value)
}
return req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, routeCtx))
}
func assertPlaybackSessionMissingResponse(t *testing.T, rr *httptest.ResponseRecorder) {
t.Helper()
if rr.Code != http.StatusNotFound {
t.Fatalf("status = %d, body = %s", rr.Code, rr.Body.String())
}
var resp errorResponse
if err := json.Unmarshal(rr.Body.Bytes(), &resp); err != nil {
t.Fatalf("decode error response: %v; body = %s", err, rr.Body.String())
}
if resp.Error != playbackSessionNotFoundErrorCode {
t.Fatalf("error = %q, want %q; body = %s", resp.Error, playbackSessionNotFoundErrorCode, rr.Body.String())
}
if resp.Message != "Playback session not found" {
t.Fatalf("message = %q", resp.Message)
}
}