Files
streamrip-go/internal/provider/soundcloud/client_test.go
Joren b2688ce949 add CLI parity flags and expand provider support
This brings the Go CLI closer to upstream behavior with global flag handling and clearer resolve failures, while adding Tidal video downloads plus initial Deezer and SoundCloud no-account flows for broader end-to-end coverage.
2026-04-20 00:56:10 +02:00

107 lines
3.5 KiB
Go

package soundcloud
import (
"context"
"fmt"
"strings"
"testing"
"streamrip-go/internal/config"
)
func TestGetTrackMetadataAndDownloadable(t *testing.T) {
cfgData := config.DefaultConfigData()
c := New(&config.Config{File: cfgData, Session: cfgData})
c.loggedIn = true
c.run = func(_ context.Context, _ string, args ...string) ([]byte, error) {
joined := strings.Join(args, " ")
if strings.Contains(joined, "--no-playlist") {
return []byte(`{"title":"Lean On","uploader":"Major Lazer","url":"https://cdn.example/audio.m4a","ext":"m4a","thumbnail":"https://img.example/cover.jpg"}`), nil
}
return nil, fmt.Errorf("unexpected args: %v", args)
}
meta, err := c.GetMetadata(context.Background(), "https://soundcloud.com/a/b", "track")
if err != nil {
t.Fatalf("GetMetadata() error = %v", err)
}
if stringFromAny(meta["title"]) != "Lean On" {
t.Fatalf("title = %q, want Lean On", stringFromAny(meta["title"]))
}
d, err := c.GetDownloadable(context.Background(), "https://soundcloud.com/a/b", 0)
if err != nil {
t.Fatalf("GetDownloadable() error = %v", err)
}
if d.URL != "https://cdn.example/audio.m4a" || d.Extension != "m4a" {
t.Fatalf("unexpected downloadable: %+v", d)
}
}
func TestGetPlaylistMetadata(t *testing.T) {
cfgData := config.DefaultConfigData()
c := New(&config.Config{File: cfgData, Session: cfgData})
c.loggedIn = true
c.run = func(_ context.Context, _ string, args ...string) ([]byte, error) {
joined := strings.Join(args, " ")
if strings.Contains(joined, "--skip-download") && !strings.Contains(joined, "--no-playlist") {
return []byte(`{"title":"Road Trip","entries":[{"webpage_url":"https://soundcloud.com/a/t1"},{"url":"https://soundcloud.com/a/t2"}]}`), nil
}
return nil, fmt.Errorf("unexpected args: %v", args)
}
meta, err := c.GetMetadata(context.Background(), "https://soundcloud.com/a/sets/road-trip", "playlist")
if err != nil {
t.Fatalf("GetMetadata() error = %v", err)
}
if stringFromAny(meta["name"]) != "Road Trip" {
t.Fatalf("name = %q, want Road Trip", stringFromAny(meta["name"]))
}
tracksMap, ok := meta["tracks"].(map[string]any)
if !ok {
t.Fatalf("tracks missing")
}
items := asAnySlice(tracksMap["items"])
if len(items) != 2 {
t.Fatalf("playlist items len = %d, want 2", len(items))
}
}
func TestSearchTrack(t *testing.T) {
cfgData := config.DefaultConfigData()
c := New(&config.Config{File: cfgData, Session: cfgData})
c.loggedIn = true
c.run = func(_ context.Context, _ string, args ...string) ([]byte, error) {
joined := strings.Join(args, " ")
if strings.Contains(joined, "scsearch2:lean on") {
return []byte(`{"entries":[{"title":"Lean On","uploader":"Major Lazer","webpage_url":"https://soundcloud.com/a/b"}]}`), nil
}
return nil, fmt.Errorf("unexpected args: %v", args)
}
pages, err := c.Search(context.Background(), "track", "lean on", 2)
if err != nil {
t.Fatalf("Search() error = %v", err)
}
if len(pages) != 1 {
t.Fatalf("pages len = %d, want 1", len(pages))
}
items := asAnySlice(pages[0]["items"])
if len(items) != 1 {
t.Fatalf("items len = %d, want 1", len(items))
}
}
func TestLoginShowsYtDlpHint(t *testing.T) {
cfgData := config.DefaultConfigData()
c := New(&config.Config{File: cfgData, Session: cfgData})
c.bin = "definitely-not-a-real-yt-dlp-bin"
err := c.Login(context.Background())
if err == nil {
t.Fatalf("expected login error")
}
if !strings.Contains(strings.ToLower(err.Error()), "yt-dlp is required") {
t.Fatalf("expected yt-dlp hint in error, got: %v", err)
}
}