mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-29 03:26:37 +08:00
71bf60c69c
初始化项目
433 lines
11 KiB
Go
433 lines
11 KiB
Go
package service
|
||
|
||
import "testing"
|
||
|
||
func TestClassifyMediaCategoryMatchesSmartRules(t *testing.T) {
|
||
tests := []struct {
|
||
name string
|
||
input mediaClassifyInput
|
||
want string
|
||
}{
|
||
{
|
||
name: "movie animation first",
|
||
input: mediaClassifyInput{
|
||
MediaType: "movie",
|
||
Title: "Robot Dreams",
|
||
Countries: []string{"ES"},
|
||
Genres: []string{"Animation"},
|
||
},
|
||
want: "动画电影",
|
||
},
|
||
{
|
||
name: "translated tmdb animation title uses genre before title script",
|
||
input: mediaClassifyInput{
|
||
MediaType: "movie",
|
||
Title: "寻龙记",
|
||
Languages: []string{"en"},
|
||
Countries: []string{"NL"},
|
||
Genres: []string{"16"},
|
||
},
|
||
want: "动画电影",
|
||
},
|
||
{
|
||
name: "translated western movie title does not become chinese movie",
|
||
input: mediaClassifyInput{
|
||
MediaType: "movie",
|
||
Title: "大雄兔",
|
||
Languages: []string{"en"},
|
||
Countries: []string{"NL"},
|
||
Genres: []string{"Comedy"},
|
||
},
|
||
want: "欧美电影",
|
||
},
|
||
{
|
||
name: "movie animation source category fallback",
|
||
input: mediaClassifyInput{
|
||
MediaType: "movie",
|
||
Title: "Sintel 2010 1080p",
|
||
Category: "动画电影",
|
||
},
|
||
want: "动画电影",
|
||
},
|
||
{
|
||
name: "tv variety by genre",
|
||
input: mediaClassifyInput{
|
||
MediaType: "tv",
|
||
Title: "声生不息",
|
||
Countries: []string{"CN"},
|
||
Genres: []string{"Reality"},
|
||
},
|
||
want: "综艺",
|
||
},
|
||
{
|
||
name: "anime china",
|
||
input: mediaClassifyInput{
|
||
MediaType: "anime",
|
||
Countries: []string{"CN"},
|
||
Genres: []string{"Animation"},
|
||
},
|
||
want: "国漫",
|
||
},
|
||
{
|
||
name: "tv documentary before region",
|
||
input: mediaClassifyInput{
|
||
MediaType: "tv",
|
||
Countries: []string{"US"},
|
||
Genres: []string{"Documentary"},
|
||
},
|
||
want: "纪录片",
|
||
},
|
||
{
|
||
name: "chinese movie title without metadata",
|
||
input: mediaClassifyInput{
|
||
MediaType: "movie",
|
||
Title: "流浪地球2 2023 2160p",
|
||
},
|
||
want: "华语电影",
|
||
},
|
||
{
|
||
name: "latin movie title without metadata",
|
||
input: mediaClassifyInput{
|
||
MediaType: "movie",
|
||
Title: "Dune 2021 2160p",
|
||
},
|
||
want: "欧美电影",
|
||
},
|
||
{
|
||
name: "chinese tv title without metadata",
|
||
input: mediaClassifyInput{
|
||
MediaType: "tv",
|
||
Title: "狂飙 S01E01 1080p",
|
||
},
|
||
want: "国产剧",
|
||
},
|
||
{
|
||
name: "latin tv title without metadata stays unclassified",
|
||
input: mediaClassifyInput{
|
||
MediaType: "tv",
|
||
Title: "The Last of Us S01E01 1080p",
|
||
},
|
||
want: "未分类",
|
||
},
|
||
{
|
||
name: "latin tv keeps explicit western source category",
|
||
input: mediaClassifyInput{
|
||
MediaType: "tv",
|
||
Title: "Blades.of.the.Guardians.S02E01.1080p",
|
||
Category: "downloads 欧美剧 Blades.of.the.Guardians",
|
||
},
|
||
want: "欧美剧",
|
||
},
|
||
{
|
||
name: "generic tv folder stays unclassified without metadata",
|
||
input: mediaClassifyInput{
|
||
MediaType: "tv",
|
||
Title: "The Last of Us S01E01 1080p",
|
||
Category: "downloads 电视剧",
|
||
},
|
||
want: "未分类",
|
||
},
|
||
{
|
||
name: "gala title overrides wrong western source category",
|
||
input: mediaClassifyInput{
|
||
MediaType: "tv",
|
||
Title: "HNTV Spring Festival Gala 2026 2160p WEB-DL",
|
||
Category: "欧美剧",
|
||
},
|
||
want: "综艺",
|
||
},
|
||
{
|
||
name: "platform token alone leaves romanized drama unclassified",
|
||
input: mediaClassifyInput{
|
||
MediaType: "tv",
|
||
Title: "Motherhood.of.Taihang.S01E01.2026.1080p.iQIYI.WEB-DL",
|
||
},
|
||
want: "未分类",
|
||
},
|
||
{
|
||
name: "metadata classifies romanized chinese drama",
|
||
input: mediaClassifyInput{
|
||
MediaType: "tv",
|
||
Title: "Ashes.to.Crown.S01E15.2160p.YOUKU.WEB-DL",
|
||
Countries: []string{"CN"},
|
||
},
|
||
want: "国产剧",
|
||
},
|
||
{
|
||
name: "genre-only metadata keeps domestic source region",
|
||
input: mediaClassifyInput{
|
||
MediaType: "tv",
|
||
Title: "Archives The Nanyang Mystery",
|
||
Genres: []string{"Drama"},
|
||
Category: "downloads 国产剧",
|
||
},
|
||
want: "国产剧",
|
||
},
|
||
{
|
||
name: "genre-only metadata keeps western source region",
|
||
input: mediaClassifyInput{
|
||
MediaType: "movie",
|
||
Title: "Unknown International Feature",
|
||
Genres: []string{"Drama"},
|
||
Category: "downloads 欧美电影",
|
||
},
|
||
want: "欧美电影",
|
||
},
|
||
{
|
||
name: "english language metadata classifies western tv without country",
|
||
input: mediaClassifyInput{
|
||
MediaType: "tv",
|
||
Title: "The Last of Us",
|
||
Languages: []string{"en"},
|
||
Genres: []string{"Drama"},
|
||
},
|
||
want: "欧美剧",
|
||
},
|
||
{
|
||
name: "gala is variety",
|
||
input: mediaClassifyInput{
|
||
MediaType: "tv",
|
||
Title: "HNTV Spring Festival Gala 2026 2160p WEB-DL",
|
||
},
|
||
want: "综艺",
|
||
},
|
||
{
|
||
name: "japanese anime localized chinese title without metadata falls back to other",
|
||
input: mediaClassifyInput{
|
||
MediaType: "anime",
|
||
Title: "葬送的芙莉莲",
|
||
},
|
||
want: "其他",
|
||
},
|
||
{
|
||
name: "chinese anime explicit marker without metadata",
|
||
input: mediaClassifyInput{
|
||
MediaType: "anime",
|
||
Title: "斗破苍穹 国漫",
|
||
},
|
||
want: "国漫",
|
||
},
|
||
{
|
||
name: "anime with JP country metadata is jp even from wrong source folder",
|
||
input: mediaClassifyInput{
|
||
MediaType: "anime",
|
||
Title: "间谍过家家 SPY×FAMILY",
|
||
Countries: []string{"JP"},
|
||
Genres: []string{"16"},
|
||
Category: "国产剧",
|
||
},
|
||
want: "日番",
|
||
},
|
||
{
|
||
name: "live action metadata overrides wrong anime source folder",
|
||
input: mediaClassifyInput{
|
||
MediaType: "tv",
|
||
Title: "The Last of Us",
|
||
Countries: []string{"US"},
|
||
Languages: []string{"en"},
|
||
Genres: []string{"Drama"},
|
||
Category: "downloads 动漫 日番",
|
||
},
|
||
want: "欧美剧",
|
||
},
|
||
{
|
||
name: "drama metadata overrides wrong documentary source folder",
|
||
input: mediaClassifyInput{
|
||
MediaType: "tv",
|
||
Title: "人世间",
|
||
Countries: []string{"CN"},
|
||
Languages: []string{"zh"},
|
||
Genres: []string{"Drama"},
|
||
Category: "downloads 纪录片",
|
||
},
|
||
want: "国产剧",
|
||
},
|
||
{
|
||
name: "western anime metadata uses us anime category",
|
||
input: mediaClassifyInput{
|
||
MediaType: "anime",
|
||
Title: "Family Guy",
|
||
Countries: []string{"US"},
|
||
Genres: []string{"16"},
|
||
Category: "日番",
|
||
},
|
||
want: "美漫",
|
||
},
|
||
{
|
||
name: "tv animation with western metadata uses us anime category",
|
||
input: mediaClassifyInput{
|
||
MediaType: "tv",
|
||
Title: "The Simpsons",
|
||
Countries: []string{"US"},
|
||
Genres: []string{"Animation"},
|
||
},
|
||
want: "美漫",
|
||
},
|
||
{
|
||
name: "tv animation takes priority over children like MoviePilot rules",
|
||
input: mediaClassifyInput{
|
||
MediaType: "tv",
|
||
Title: "Gourd Brothers",
|
||
Countries: []string{"CN"},
|
||
Languages: []string{"zh"},
|
||
Genres: []string{"16", "10762"},
|
||
},
|
||
want: "国漫",
|
||
},
|
||
{
|
||
name: "western anime legacy source category maps to us anime without metadata",
|
||
input: mediaClassifyInput{
|
||
MediaType: "anime",
|
||
Title: "The Simpsons S01E01 1080p",
|
||
Category: "downloads 欧美动漫",
|
||
},
|
||
want: "美漫",
|
||
},
|
||
{
|
||
name: "anime with CN country metadata is cn",
|
||
input: mediaClassifyInput{
|
||
MediaType: "anime",
|
||
Title: "某番",
|
||
Countries: []string{"CN"},
|
||
Genres: []string{"16"},
|
||
},
|
||
want: "国漫",
|
||
},
|
||
{
|
||
name: "western movie source category remains western movie",
|
||
input: mediaClassifyInput{
|
||
MediaType: "movie",
|
||
Title: "Dune 2021 2160p",
|
||
Category: "downloads 欧美电影",
|
||
},
|
||
want: "欧美电影",
|
||
},
|
||
{
|
||
name: "movie concert by music genre",
|
||
input: mediaClassifyInput{
|
||
MediaType: "movie",
|
||
Title: "Taylor Swift The Eras Tour",
|
||
Genres: []string{"10402"},
|
||
},
|
||
want: "演唱会",
|
||
},
|
||
{
|
||
name: "movie documentary before region",
|
||
input: mediaClassifyInput{
|
||
MediaType: "movie",
|
||
Title: "Planet Earth",
|
||
Languages: []string{"en"},
|
||
Countries: []string{"GB"},
|
||
Genres: []string{"99"},
|
||
},
|
||
want: "纪录片",
|
||
},
|
||
{
|
||
name: "movie korean language uses jk movie",
|
||
input: mediaClassifyInput{
|
||
MediaType: "movie",
|
||
Title: "Parasite",
|
||
Languages: []string{"ko"},
|
||
Countries: []string{"KR"},
|
||
Genres: []string{"18"},
|
||
},
|
||
want: "日韩电影",
|
||
},
|
||
{
|
||
name: "anime korean metadata uses korean anime category",
|
||
input: mediaClassifyInput{
|
||
MediaType: "anime",
|
||
Title: "Korean Animation",
|
||
Countries: []string{"KR"},
|
||
Genres: []string{"16"},
|
||
},
|
||
want: "韩漫",
|
||
},
|
||
{
|
||
name: "jav code is adult",
|
||
input: mediaClassifyInput{
|
||
MediaType: "movie",
|
||
Title: "IPZZ-293-UC 1080p",
|
||
},
|
||
want: "成人",
|
||
},
|
||
}
|
||
|
||
for _, tt := range tests {
|
||
t.Run(tt.name, func(t *testing.T) {
|
||
if got := classifyMediaCategory(tt.input, nil); got != tt.want {
|
||
t.Fatalf("category = %q, want %q", got, tt.want)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
func TestNormalizeMediaTypeAcceptsChineseLibraryTypes(t *testing.T) {
|
||
tests := map[string]string{
|
||
"华语电影": "movie",
|
||
"欧美剧": "tv",
|
||
"国产剧": "tv",
|
||
"日漫": "anime",
|
||
"国漫": "anime",
|
||
"综艺": "variety",
|
||
"成人": "adult",
|
||
}
|
||
for input, want := range tests {
|
||
if got := normalizeMediaType(input, "测试标题", ""); got != want {
|
||
t.Fatalf("normalizeMediaType(%q) = %q, want %q", input, got, want)
|
||
}
|
||
}
|
||
}
|
||
|
||
func TestMergeLocalClassificationMetadataKeepsScraperRegionWhenNFOIsSparse(t *testing.T) {
|
||
input := mediaClassifyInput{
|
||
MediaType: "tv",
|
||
Title: "SPY FAMILY",
|
||
Languages: []string{"ja"},
|
||
Countries: []string{"JP"},
|
||
Genres: []string{"16"},
|
||
}
|
||
mergeLocalClassificationMetadata(&input, &LocalMetadata{
|
||
Title: "间谍过家家 第 1 集",
|
||
HasNFO: true,
|
||
}, "Spy Family", "episode.mkv")
|
||
|
||
if got := classifyMediaCategory(input, nil); got != "日番" {
|
||
t.Fatalf("category=%q, want 日番 after sparse NFO merge; input=%#v", got, input)
|
||
}
|
||
if len(input.Countries) != 1 || input.Countries[0] != "JP" || len(input.Genres) != 1 || input.Genres[0] != "16" {
|
||
t.Fatalf("sparse NFO erased scraper metadata: %#v", input)
|
||
}
|
||
}
|
||
|
||
func TestReconcileOrganizeCategoryMediaTypeKeepsAmbiguousDocumentaryMovie(t *testing.T) {
|
||
if got := reconcileOrganizeCategoryMediaType("movie", "tv"); got != "movie" {
|
||
t.Fatalf("ambiguous documentary type=%q, want movie", got)
|
||
}
|
||
if got := reconcileOrganizeCategoryMediaType("tv", "anime"); got != "anime" {
|
||
t.Fatalf("TV animation subtype=%q, want anime", got)
|
||
}
|
||
if got := reconcileOrganizeCategoryMediaType("movie", "adult"); got != "adult" {
|
||
t.Fatalf("adult override=%q, want adult", got)
|
||
}
|
||
}
|
||
|
||
func TestNormalizeMediaTypeDoesNotTreatReleaseTokensAsTV(t *testing.T) {
|
||
tests := []string{
|
||
"They Will Kill You 2026 1080p HDTV x264",
|
||
"Some Movie 2026 2160p AppleTV WEB-DL",
|
||
"Some Movie 2026 2160p ATVP WEB-DL",
|
||
}
|
||
for _, input := range tests {
|
||
t.Run(input, func(t *testing.T) {
|
||
if got := normalizeMediaType("", input, ""); got != "movie" {
|
||
t.Fatalf("normalizeMediaType(%q) = %q, want movie", input, got)
|
||
}
|
||
})
|
||
}
|
||
|
||
if got := normalizeMediaType("", "The Last of Us", `F:\media\tv\The Last of Us`); got != "tv" {
|
||
t.Fatalf("standalone tv path token = %q, want tv", got)
|
||
}
|
||
}
|