Files
MeBox/internal/service/media_classifier_test.go
truewhile 71bf60c69c 初始化
初始化项目
2026-08-23 22:12:32 +08:00

433 lines
11 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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)
}
}