unarr/internal/engine/resolve_test.go
Deivid Soto 29cf0a0126 feat: initial commit — unarr CLI
Search, inspect, stream, and download torrents from the terminal.
Replaces the entire *arr stack with a single binary.
2026-03-28 11:29:42 +01:00

141 lines
4.2 KiB
Go

package engine
import (
"context"
"fmt"
"testing"
)
// mockDownloader implements Downloader for testing.
type mockDownloader struct {
method DownloadMethod
available bool
err error
}
func (m *mockDownloader) Method() DownloadMethod { return m.method }
func (m *mockDownloader) Available(_ context.Context, _ *Task) (bool, error) {
return m.available, m.err
}
func (m *mockDownloader) Download(_ context.Context, _ *Task, _ string, _ chan<- Progress) (*Result, error) {
return &Result{Method: m.method, FileName: "test.mkv", FilePath: "/tmp/test.mkv"}, nil
}
func (m *mockDownloader) Pause(_ string) error { return nil }
func (m *mockDownloader) Cancel(_ string) error { return nil }
func (m *mockDownloader) Shutdown(_ context.Context) error { return nil }
func TestResolveMethodAuto(t *testing.T) {
downloaders := map[DownloadMethod]Downloader{
MethodTorrent: &mockDownloader{method: MethodTorrent, available: true},
MethodDebrid: &mockDownloader{method: MethodDebrid, available: true},
}
task := &Task{PreferredMethod: "auto"}
method, err := resolveMethod(context.Background(), task, downloaders)
if err != nil {
t.Fatal(err)
}
// Torrent is first in auto order
if method != MethodTorrent {
t.Errorf("method = %q, want torrent (first in auto order)", method)
}
}
func TestResolveMethodSpecific(t *testing.T) {
downloaders := map[DownloadMethod]Downloader{
MethodTorrent: &mockDownloader{method: MethodTorrent, available: true},
MethodDebrid: &mockDownloader{method: MethodDebrid, available: true},
}
task := &Task{PreferredMethod: "debrid"}
method, err := resolveMethod(context.Background(), task, downloaders)
if err != nil {
t.Fatal(err)
}
if method != MethodDebrid {
t.Errorf("method = %q, want debrid", method)
}
}
func TestResolveMethodSkipsTried(t *testing.T) {
downloaders := map[DownloadMethod]Downloader{
MethodTorrent: &mockDownloader{method: MethodTorrent, available: true},
MethodDebrid: &mockDownloader{method: MethodDebrid, available: true},
}
task := &Task{
PreferredMethod: "auto",
TriedMethods: []DownloadMethod{MethodTorrent},
}
method, err := resolveMethod(context.Background(), task, downloaders)
if err != nil {
t.Fatal(err)
}
if method != MethodDebrid {
t.Errorf("method = %q, want debrid (torrent already tried)", method)
}
}
func TestResolveMethodNoneAvailable(t *testing.T) {
downloaders := map[DownloadMethod]Downloader{
MethodTorrent: &mockDownloader{method: MethodTorrent, available: false},
}
task := &Task{PreferredMethod: "auto"}
_, err := resolveMethod(context.Background(), task, downloaders)
if err == nil {
t.Error("expected error when no method available")
}
}
func TestResolveMethodAvailabilityError(t *testing.T) {
downloaders := map[DownloadMethod]Downloader{
MethodTorrent: &mockDownloader{method: MethodTorrent, available: false, err: fmt.Errorf("network error")},
MethodDebrid: &mockDownloader{method: MethodDebrid, available: true},
}
task := &Task{ID: "test-resolve-err", PreferredMethod: "auto"}
method, err := resolveMethod(context.Background(), task, downloaders)
if err != nil {
t.Fatal(err)
}
// Should fallback to debrid when torrent has error
if method != MethodDebrid {
t.Errorf("method = %q, want debrid (torrent errored)", method)
}
}
func TestTryFallbackAutoMode(t *testing.T) {
downloaders := map[DownloadMethod]Downloader{
MethodTorrent: &mockDownloader{method: MethodTorrent, available: true},
MethodDebrid: &mockDownloader{method: MethodDebrid, available: true},
}
task := &Task{
PreferredMethod: "auto",
ResolvedMethod: MethodTorrent,
}
if !tryFallback(task, downloaders) {
t.Error("should have fallback available")
}
if len(task.TriedMethods) != 1 || task.TriedMethods[0] != MethodTorrent {
t.Error("torrent should be in tried methods")
}
}
func TestTryFallbackSpecificMode(t *testing.T) {
downloaders := map[DownloadMethod]Downloader{
MethodTorrent: &mockDownloader{method: MethodTorrent, available: true},
MethodDebrid: &mockDownloader{method: MethodDebrid, available: true},
}
task := &Task{
PreferredMethod: "torrent",
ResolvedMethod: MethodTorrent,
}
if tryFallback(task, downloaders) {
t.Error("should not fallback in specific mode")
}
}