mirror of
https://git.sr.ht/~joren/streamrip-go
synced 2026-06-17 15:05:39 +02:00
harden manifest detection and downloader failure coverage
This commit is contained in:
@@ -8,8 +8,11 @@ import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/blowfish"
|
||||
)
|
||||
@@ -46,9 +49,15 @@ func TestManifestDetection(t *testing.T) {
|
||||
if !isManifestResponse("application/dash+xml", []byte("x")) {
|
||||
t.Fatalf("expected dash content-type to be manifest")
|
||||
}
|
||||
if !isManifestResponse("application/vnd.apple.mpegurl", []byte("x")) {
|
||||
t.Fatalf("expected mpegurl content-type to be manifest")
|
||||
}
|
||||
if !isManifestResponse("application/octet-stream", []byte("<?xml version='1.0'?><MPD></MPD>")) {
|
||||
t.Fatalf("expected MPD XML body to be manifest")
|
||||
}
|
||||
if !isManifestResponse("application/octet-stream", []byte("<MPD type='static'></MPD>")) {
|
||||
t.Fatalf("expected MPD body without xml prolog to be manifest")
|
||||
}
|
||||
if !isManifestResponse("text/plain", []byte("#EXTM3U\n#EXT-X-VERSION:3")) {
|
||||
t.Fatalf("expected HLS body to be manifest")
|
||||
}
|
||||
@@ -158,3 +167,67 @@ func TestFileDeezerEncryptedTruncatedResponseRemovesPartialFile(t *testing.T) {
|
||||
t.Fatalf("expected no partial file, stat err=%v", statErr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileDeezerEncryptedBadStatus(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
d := NewWithOptions(true, false)
|
||||
out := filepath.Join(t.TempDir(), "x", "a.flac")
|
||||
err := d.FileDeezerEncrypted(context.Background(), ts.URL, out, "3135556")
|
||||
if err == nil || !strings.Contains(err.Error(), "status=403") {
|
||||
t.Fatalf("expected status error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDownloaderFileContextCancellationRemovesPartialFile(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/octet-stream")
|
||||
_, _ = w.Write([]byte("partial-data"))
|
||||
if f, ok := w.(http.Flusher); ok {
|
||||
f.Flush()
|
||||
}
|
||||
<-r.Context().Done()
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
d := NewWithOptions(true, false)
|
||||
out := filepath.Join(t.TempDir(), "x", "cancel.bin")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Millisecond)
|
||||
defer cancel()
|
||||
err := d.File(ctx, ts.URL, out)
|
||||
if err == nil {
|
||||
t.Fatalf("expected context cancellation error")
|
||||
}
|
||||
if _, statErr := os.Stat(out); !errors.Is(statErr, os.ErrNotExist) {
|
||||
t.Fatalf("expected no partial file, stat err=%v", statErr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStreamManifestWithFFmpegMissing(t *testing.T) {
|
||||
d := NewWithOptions(true, false)
|
||||
t.Setenv("PATH", "")
|
||||
err := d.streamManifestWithFFmpeg(context.Background(), "https://example.com/live.m3u8", filepath.Join(t.TempDir(), "out.m4a"), false)
|
||||
if err == nil || !strings.Contains(strings.ToLower(err.Error()), "ffmpeg not found") {
|
||||
t.Fatalf("expected ffmpeg missing error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStreamManifestWithFFmpegFailureRemovesPartialFile(t *testing.T) {
|
||||
if _, err := exec.LookPath("ffmpeg"); err != nil {
|
||||
t.Skip("ffmpeg not installed")
|
||||
}
|
||||
d := NewWithOptions(true, false)
|
||||
out := filepath.Join(t.TempDir(), "out.m4a")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
err := d.streamManifestWithFFmpeg(ctx, "https://127.0.0.1:1/unreachable.m3u8", out, false)
|
||||
if err == nil || !strings.Contains(err.Error(), "ffmpeg stream copy failed") {
|
||||
t.Fatalf("expected ffmpeg failure error, got %v", err)
|
||||
}
|
||||
if _, statErr := os.Stat(out); !errors.Is(statErr, os.ErrNotExist) {
|
||||
t.Fatalf("expected no partial file after ffmpeg failure, stat err=%v", statErr)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user