mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-14 00:56:37 +08:00
85 lines
3.1 KiB
Go
85 lines
3.1 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// 远程条目自身没有媒体源时(例如把「整部剧」的 ID 当播放目标),远程 Emby 会回
|
|
// 500 + 一句 .NET 异常。异常原文不能直接丢给用户,但要能从日志里查得到。
|
|
func TestProxyVideoStreamOnLineHidesUpstreamException(t *testing.T) {
|
|
const upstreamBody = "Unable to cast object of type 'MediaBrowser.Controller.Entities.TV.Series' to type 'MediaBrowser.Controller.Entities.IHasMediaSources'."
|
|
|
|
var gotPath, gotStatic, gotRange, gotToken string
|
|
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
|
gotPath = req.URL.Path
|
|
gotStatic = req.URL.Query().Get("Static")
|
|
gotRange = req.Header.Get("Range")
|
|
gotToken = req.Header.Get("X-Emby-Token")
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
_, _ = w.Write([]byte(upstreamBody))
|
|
}))
|
|
defer upstream.Close()
|
|
|
|
svc := &EmbyRemoteService{stream: upstream.Client(), log: zap.NewNop()}
|
|
cfg := &EmbyRemoteConfig{BaseURL: upstream.URL, Token: "tok-1"}
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/api/stream/embyremote~acct~222679", nil)
|
|
req.Header.Set("Range", "bytes=0-1023")
|
|
rec := httptest.NewRecorder()
|
|
|
|
err := svc.proxyVideoStreamOnLine(context.Background(), rec, req, cfg, "222679")
|
|
if err == nil {
|
|
t.Fatal("expected an error for upstream 500")
|
|
}
|
|
if gotPath != "/emby/Videos/222679/stream" {
|
|
t.Fatalf("upstream path = %q", gotPath)
|
|
}
|
|
if gotStatic != "true" {
|
|
t.Fatalf("Static = %q, want true", gotStatic)
|
|
}
|
|
if gotRange != "bytes=0-1023" {
|
|
t.Fatalf("Range = %q, want forwarded range", gotRange)
|
|
}
|
|
if gotToken != "tok-1" {
|
|
t.Fatalf("X-Emby-Token = %q", gotToken)
|
|
}
|
|
if rec.Body.Len() != 0 {
|
|
t.Fatalf("nothing should be written to the client on upstream failure, got %q", rec.Body.String())
|
|
}
|
|
|
|
msg := err.Error()
|
|
if strings.Contains(msg, "Unable to cast") || strings.Contains(msg, "MediaBrowser") {
|
|
t.Fatalf("raw upstream exception must not leak to clients: %q", msg)
|
|
}
|
|
if !strings.Contains(msg, "无法播放该条目") {
|
|
t.Fatalf("error should tell the user what to do, got %q", msg)
|
|
}
|
|
}
|
|
|
|
// 4xx(例如远程条目被删除/无权限)保持原有措辞,带着上游说明便于排查。
|
|
func TestProxyVideoStreamOnLineKeepsClientErrorDetail(t *testing.T) {
|
|
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusNotFound)
|
|
_, _ = w.Write([]byte("Item not found"))
|
|
}))
|
|
defer upstream.Close()
|
|
|
|
svc := &EmbyRemoteService{stream: upstream.Client(), log: zap.NewNop()}
|
|
cfg := &EmbyRemoteConfig{BaseURL: upstream.URL, Token: "tok-1"}
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/api/stream/embyremote~acct~404", nil)
|
|
err := svc.proxyVideoStreamOnLine(context.Background(), httptest.NewRecorder(), req, cfg, "404")
|
|
if err == nil {
|
|
t.Fatal("expected an error for upstream 404")
|
|
}
|
|
if !strings.Contains(err.Error(), "404") || !strings.Contains(err.Error(), "Item not found") {
|
|
t.Fatalf("client error detail should be kept, got %q", err.Error())
|
|
}
|
|
}
|