141 lines
4.3 KiB
Go
141 lines
4.3 KiB
Go
package jellycompat
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
|
|
"github.com/Silo-Server/silo-server/internal/catalog"
|
|
"github.com/Silo-Server/silo-server/internal/models"
|
|
"github.com/Silo-Server/silo-server/internal/subtitles"
|
|
)
|
|
|
|
type fakeSubtitleRepository struct {
|
|
downloaded map[int][]subtitles.DownloadedSubtitle
|
|
}
|
|
|
|
func (r fakeSubtitleRepository) InsertDownloadedSubtitle(context.Context, *subtitles.DownloadedSubtitle) error {
|
|
panic("unused")
|
|
}
|
|
|
|
func (r fakeSubtitleRepository) GetDownloadedSubtitle(context.Context, int) (*subtitles.DownloadedSubtitle, error) {
|
|
panic("unused")
|
|
}
|
|
|
|
func (r fakeSubtitleRepository) ListDownloadedSubtitles(_ context.Context, mediaFileID int) ([]subtitles.DownloadedSubtitle, error) {
|
|
return r.downloaded[mediaFileID], nil
|
|
}
|
|
|
|
func (r fakeSubtitleRepository) UpdateDownloadedSubtitle(context.Context, int, subtitles.SubtitleMetadataUpdate) (*subtitles.DownloadedSubtitle, error) {
|
|
panic("unused")
|
|
}
|
|
|
|
func (r fakeSubtitleRepository) DeleteDownloadedSubtitle(context.Context, int) (*subtitles.DownloadedSubtitle, error) {
|
|
panic("unused")
|
|
}
|
|
|
|
func (r fakeSubtitleRepository) GetDownloadedSubtitleByS3Key(context.Context, string) (*subtitles.DownloadedSubtitle, error) {
|
|
panic("unused")
|
|
}
|
|
|
|
func (r fakeSubtitleRepository) ListProviderConfigs(context.Context) ([]subtitles.ProviderConfig, error) {
|
|
panic("unused")
|
|
}
|
|
|
|
func (r fakeSubtitleRepository) GetProviderConfig(context.Context, string) (*subtitles.ProviderConfig, error) {
|
|
panic("unused")
|
|
}
|
|
|
|
func (r fakeSubtitleRepository) UpsertProviderConfig(context.Context, *subtitles.ProviderConfig) error {
|
|
panic("unused")
|
|
}
|
|
|
|
func TestHandlePlaybackInfo_AuthenticatesSubtitleDeliveryURLs(t *testing.T) {
|
|
codec := NewResourceIDCodec()
|
|
contentID := "movie-1"
|
|
routeID := codec.EncodeStringID(EncodedIDItem, contentID)
|
|
version := catalog.FileVersion{
|
|
FileID: 42,
|
|
Duration: 3600,
|
|
Container: "mkv",
|
|
Bitrate: 8000,
|
|
VideoTracks: []models.VideoTrack{
|
|
{Codec: "h264", Width: 1920, Height: 1080},
|
|
},
|
|
AudioTracks: []models.AudioTrack{
|
|
{Codec: "aac", Default: true, Title: "Main"},
|
|
},
|
|
SubtitleTracks: []catalog.VersionSubtitleTrack{
|
|
{Index: 2, Codec: "subrip", Language: "eng", Title: "English"},
|
|
{Codec: "srt", Language: "spa", Title: "Spanish", External: true},
|
|
},
|
|
}
|
|
|
|
handler := &PlaybackHandler{
|
|
content: &stubContentService{detail: &upstreamItemDetail{
|
|
ContentID: contentID,
|
|
Versions: []catalog.FileVersion{version},
|
|
}},
|
|
codec: codec,
|
|
deviceProfiles: NewDeviceProfileStore(time.Hour, nil),
|
|
playbackStore: NewPlaybackSessionStore(time.Hour, nil),
|
|
SubtitleRepo: fakeSubtitleRepository{downloaded: map[int][]subtitles.DownloadedSubtitle{
|
|
42: {
|
|
{MediaFileID: 42, Language: "fre", Format: subtitles.FormatSRT, Provider: "opensubtitles"},
|
|
},
|
|
}},
|
|
}
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/Items/"+routeID+"/PlaybackInfo", strings.NewReader(`{}`))
|
|
routeCtx := chi.NewRouteContext()
|
|
routeCtx.URLParams.Add("id", routeID)
|
|
req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, routeCtx))
|
|
req = req.WithContext(context.WithValue(req.Context(), compatSessionKey, &Session{Token: "token-1"}))
|
|
|
|
rr := httptest.NewRecorder()
|
|
handler.HandlePlaybackInfo(rr, req)
|
|
|
|
if rr.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, body = %s", rr.Code, rr.Body.String())
|
|
}
|
|
|
|
var resp playbackInfoResponseDTO
|
|
if err := json.Unmarshal(rr.Body.Bytes(), &resp); err != nil {
|
|
t.Fatalf("unmarshal response: %v", err)
|
|
}
|
|
if len(resp.MediaSources) != 1 {
|
|
t.Fatalf("media sources = %d, want 1", len(resp.MediaSources))
|
|
}
|
|
|
|
subtitleURLs := make([]string, 0, 3)
|
|
for _, stream := range resp.MediaSources[0].MediaStreams {
|
|
if stream.Type == "Subtitle" {
|
|
subtitleURLs = append(subtitleURLs, stream.DeliveryURL)
|
|
}
|
|
}
|
|
if len(subtitleURLs) != 3 {
|
|
t.Fatalf("subtitle URLs = %d, want 3: %#v", len(subtitleURLs), subtitleURLs)
|
|
}
|
|
|
|
for _, rawURL := range subtitleURLs {
|
|
parsed, err := url.Parse(rawURL)
|
|
if err != nil {
|
|
t.Fatalf("parse subtitle URL %q: %v", rawURL, err)
|
|
}
|
|
query := parsed.Query()
|
|
if got := query.Get("api_key"); got != "token-1" {
|
|
t.Fatalf("api_key for %q = %q, want token-1", rawURL, got)
|
|
}
|
|
if got := query.Get("PlaySessionId"); got != resp.PlaySessionID {
|
|
t.Fatalf("PlaySessionId for %q = %q, want %q", rawURL, got, resp.PlaySessionID)
|
|
}
|
|
}
|
|
}
|