230 lines
7.1 KiB
Go
230 lines
7.1 KiB
Go
package arr
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestMapQualityProfile_2160p(t *testing.T) {
|
|
profile := QualityProfile{
|
|
ID: 1,
|
|
Name: "Ultra-HD",
|
|
Cutoff: 31, // 2160p Remux
|
|
Items: []QualityItem{
|
|
{Quality: &Quality{ID: 31, Name: "Remux-2160p", Resolution: 2160}, Allowed: true},
|
|
{Quality: &Quality{ID: 18, Name: "HDTV-2160p", Resolution: 2160}, Allowed: true},
|
|
{Quality: &Quality{ID: 7, Name: "Bluray-1080p", Resolution: 1080}, Allowed: true},
|
|
},
|
|
}
|
|
if got := MapQualityProfile(profile); got != "2160p" {
|
|
t.Errorf("MapQualityProfile = %q, want 2160p", got)
|
|
}
|
|
}
|
|
|
|
func TestMapQualityProfile_1080p(t *testing.T) {
|
|
profile := QualityProfile{
|
|
ID: 2,
|
|
Name: "HD-1080p",
|
|
Cutoff: 7,
|
|
Items: []QualityItem{
|
|
{Quality: &Quality{ID: 7, Name: "Bluray-1080p", Resolution: 1080}, Allowed: true},
|
|
{Quality: &Quality{ID: 3, Name: "HDTV-720p", Resolution: 720}, Allowed: true},
|
|
},
|
|
}
|
|
if got := MapQualityProfile(profile); got != "1080p" {
|
|
t.Errorf("MapQualityProfile = %q, want 1080p", got)
|
|
}
|
|
}
|
|
|
|
func TestMapQualityProfile_720p_fallback(t *testing.T) {
|
|
profile := QualityProfile{
|
|
ID: 3,
|
|
Name: "SD",
|
|
Cutoff: 1,
|
|
Items: []QualityItem{
|
|
{Quality: &Quality{ID: 1, Name: "SDTV", Resolution: 480}, Allowed: true},
|
|
},
|
|
}
|
|
if got := MapQualityProfile(profile); got != "720p" {
|
|
t.Errorf("MapQualityProfile = %q, want 720p", got)
|
|
}
|
|
}
|
|
|
|
func TestMapQualityProfile_NestedGroups(t *testing.T) {
|
|
profile := QualityProfile{
|
|
ID: 4,
|
|
Name: "Any",
|
|
Cutoff: 7,
|
|
Items: []QualityItem{
|
|
{
|
|
Items: []QualityItem{
|
|
{Quality: &Quality{ID: 7, Name: "Bluray-1080p", Resolution: 1080}, Allowed: true},
|
|
{Quality: &Quality{ID: 3, Name: "HDTV-720p", Resolution: 720}, Allowed: true},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
if got := MapQualityProfile(profile); got != "1080p" {
|
|
t.Errorf("MapQualityProfile = %q, want 1080p", got)
|
|
}
|
|
}
|
|
|
|
func TestMostUsedProfile(t *testing.T) {
|
|
profiles := []QualityProfile{
|
|
{ID: 1, Name: "HD-1080p"},
|
|
{ID: 2, Name: "Ultra-HD"},
|
|
{ID: 3, Name: "SD"},
|
|
}
|
|
counts := map[int]int{1: 5, 2: 20, 3: 3}
|
|
|
|
p := MostUsedProfile(counts, profiles)
|
|
if p == nil || p.ID != 2 {
|
|
t.Errorf("MostUsedProfile = %v, want profile ID 2", p)
|
|
}
|
|
}
|
|
|
|
func TestMostUsedProfile_EmptyCounts(t *testing.T) {
|
|
profiles := []QualityProfile{
|
|
{ID: 1, Name: "HD-1080p"},
|
|
}
|
|
p := MostUsedProfile(map[int]int{}, profiles)
|
|
if p == nil || p.ID != 1 {
|
|
t.Errorf("MostUsedProfile with empty counts should return first profile")
|
|
}
|
|
}
|
|
|
|
func TestExtractWantedMovies(t *testing.T) {
|
|
movies := []Movie{
|
|
{TmdbID: 1, Title: "Has file", Monitored: true, HasFile: true},
|
|
{TmdbID: 2, Title: "Wanted", Monitored: true, HasFile: false},
|
|
{TmdbID: 3, Title: "Unmonitored", Monitored: false, HasFile: false},
|
|
{TmdbID: 0, Title: "No TMDB", Monitored: true, HasFile: false}, // no tmdbId
|
|
}
|
|
wanted := ExtractWantedMovies(movies)
|
|
if len(wanted) != 1 {
|
|
t.Fatalf("ExtractWantedMovies = %d items, want 1", len(wanted))
|
|
}
|
|
if wanted[0].TmdbID != 2 || wanted[0].Type != "movie" {
|
|
t.Errorf("ExtractWantedMovies[0] = %+v, want tmdbId=2 type=movie", wanted[0])
|
|
}
|
|
}
|
|
|
|
func TestExtractWantedSeries(t *testing.T) {
|
|
series := []Series{
|
|
{ImdbID: "tt1", Title: "Complete", Monitored: true, Statistics: SeriesStatistics{EpisodeCount: 10, EpisodeFileCount: 10}},
|
|
{ImdbID: "tt2", Title: "Missing eps", Monitored: true, Statistics: SeriesStatistics{EpisodeCount: 10, EpisodeFileCount: 5}},
|
|
{ImdbID: "tt3", Title: "Unmonitored", Monitored: false, Statistics: SeriesStatistics{EpisodeCount: 10, EpisodeFileCount: 0}},
|
|
}
|
|
wanted := ExtractWantedSeries(series)
|
|
if len(wanted) != 1 {
|
|
t.Fatalf("ExtractWantedSeries = %d items, want 1", len(wanted))
|
|
}
|
|
if wanted[0].ImdbID != "tt2" || wanted[0].Type != "show" {
|
|
t.Errorf("ExtractWantedSeries[0] = %+v, want imdbId=tt2 type=show", wanted[0])
|
|
}
|
|
}
|
|
|
|
func TestExtractBlocklistedHashes(t *testing.T) {
|
|
items := []BlocklistItem{
|
|
{Data: BlocklistData{InfoHash: "AAAA"}},
|
|
{Data: BlocklistData{InfoHash: "AAAA"}}, // duplicate
|
|
{Data: BlocklistData{InfoHash: "BBBB"}},
|
|
{Data: BlocklistData{InfoHash: ""}}, // empty
|
|
}
|
|
hashes := ExtractBlocklistedHashes(items)
|
|
if len(hashes) != 2 {
|
|
t.Fatalf("ExtractBlocklistedHashes = %d, want 2", len(hashes))
|
|
}
|
|
}
|
|
|
|
func TestExtractDownloadedHashes(t *testing.T) {
|
|
records := []HistoryRecord{
|
|
{EventType: "downloadFolderImported", Data: HistoryData{InfoHash: "hash1"}},
|
|
{EventType: "grabbed", Data: HistoryData{InfoHash: "hash2"}}, // not imported
|
|
{EventType: "downloadFolderImported", Data: HistoryData{InfoHash: "hash1"}}, // duplicate
|
|
{EventType: "downloadFolderImported", Data: HistoryData{InfoHash: "hash3"}},
|
|
}
|
|
hashes := ExtractDownloadedHashes(records)
|
|
if len(hashes) != 2 {
|
|
t.Fatalf("ExtractDownloadedHashes = %d, want 2", len(hashes))
|
|
}
|
|
}
|
|
|
|
func TestMapRootFolders_MostUsed(t *testing.T) {
|
|
folders := []RootFolder{
|
|
{Path: "/data/movies1"},
|
|
{Path: "/data/movies2"},
|
|
}
|
|
movies := []Movie{
|
|
{RootFolderPath: "/data/movies1"},
|
|
{RootFolderPath: "/data/movies2"},
|
|
{RootFolderPath: "/data/movies2"},
|
|
{RootFolderPath: "/data/movies2"},
|
|
}
|
|
moviesDir, _ := MapRootFolders(folders, nil, movies, nil)
|
|
if moviesDir != "/data/movies2" {
|
|
t.Errorf("MapRootFolders = %q, want /data/movies2", moviesDir)
|
|
}
|
|
}
|
|
|
|
func TestMapRootFolders_SingleFolder(t *testing.T) {
|
|
folders := []RootFolder{{Path: "/data/movies"}}
|
|
moviesDir, _ := MapRootFolders(folders, nil, nil, nil)
|
|
if moviesDir != "/data/movies" {
|
|
t.Errorf("MapRootFolders = %q, want /data/movies", moviesDir)
|
|
}
|
|
}
|
|
|
|
func TestMapRootFolders_Empty(t *testing.T) {
|
|
moviesDir, tvDir := MapRootFolders(nil, nil, nil, nil)
|
|
if moviesDir != "" || tvDir != "" {
|
|
t.Errorf("MapRootFolders empty = %q, %q, want empty", moviesDir, tvDir)
|
|
}
|
|
}
|
|
|
|
func TestHasDockerPaths(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
movies string
|
|
tv string
|
|
expected bool
|
|
}{
|
|
{"docker paths", "/data/media/movies", "/data/media/tv", true},
|
|
{"host paths", "/home/user/Media/Movies", "/home/user/Media/TV", false},
|
|
{"empty", "", "", false},
|
|
{"mixed", "/home/user/movies", "/data/media/tv", true},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
r := &MigrationResult{MoviesDir: tt.movies, TVShowsDir: tt.tv}
|
|
if got := HasDockerPaths(r); got != tt.expected {
|
|
t.Errorf("HasDockerPaths = %v, want %v", got, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestExtractDebridTokens(t *testing.T) {
|
|
clients := []DownloadClient{
|
|
{ID: 1, Name: "TorBox", Enable: true, Implementation: "TorBox", ImplementationName: "TorBox"},
|
|
{ID: 2, Name: "qBittorrent", Enable: true, Implementation: "QBittorrent", ImplementationName: "qBittorrent"},
|
|
{ID: 3, Name: "Disabled Debrid", Enable: false, Implementation: "RealDebrid", ImplementationName: "Real-Debrid"},
|
|
}
|
|
|
|
getFields := func(id int) []Field {
|
|
if id == 1 {
|
|
return []Field{
|
|
{Name: "ApiKey", Value: "tb_test_token_123"},
|
|
{Name: "Host", Value: "torbox.app"},
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
tokens := ExtractDebridTokens(clients, getFields)
|
|
if len(tokens) != 1 {
|
|
t.Fatalf("ExtractDebridTokens = %d tokens, want 1", len(tokens))
|
|
}
|
|
if tokens[0].Provider != "torbox" || tokens[0].Token != "tb_test_token_123" {
|
|
t.Errorf("ExtractDebridTokens[0] = %+v, want torbox with token", tokens[0])
|
|
}
|
|
}
|