feat: initial commit — unarr CLI
Search, inspect, stream, and download torrents from the terminal. Replaces the entire *arr stack with a single binary.
This commit is contained in:
commit
29cf0a0126
85 changed files with 10178 additions and 0 deletions
141
internal/engine/resolve_test.go
Normal file
141
internal/engine/resolve_test.go
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
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")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue