Files
MeBox/internal/service/media_discovery_test.go
T
2026-09-22 16:22:29 +08:00

137 lines
4.3 KiB
Go

package service
import (
"context"
"testing"
"go.uber.org/zap"
"github.com/truewhile/MeBox/internal/model"
"github.com/truewhile/MeBox/internal/repository"
)
// newDiscoveryTestDB 建好内存库并返回 repository 容器。
func newDiscoveryTestDB(t *testing.T) *repository.Container {
t.Helper()
return repository.New(newServiceTestDB(t))
}
func seedDiscoveryLibrary(t *testing.T, repos *repository.Container, typ string) string {
t.Helper()
lib := &model.Library{Name: "库-" + typ, Path: "/media/" + typ, Type: typ, Enabled: true}
if err := repos.Library.Create(context.Background(), lib); err != nil {
t.Fatal(err)
}
return lib.ID
}
func seedDiscoveryMedia(t *testing.T, repos *repository.Container, m *model.Media) {
t.Helper()
if err := repos.DB.WithContext(context.Background()).Create(m).Error; err != nil {
t.Fatal(err)
}
}
func findGenre(genres []GenreCount, name string) int {
for _, g := range genres {
if g.Name == name {
return g.Count
}
}
return -1
}
func TestAggregateGenresSplitsAndCounts(t *testing.T) {
repos := newDiscoveryTestDB(t)
libID := seedDiscoveryLibrary(t, repos, "movie")
seedDiscoveryMedia(t, repos, &model.Media{
LibraryID: libID, Title: "A", Path: "/media/movie/a.mkv", Genres: "Action,Drama",
})
seedDiscoveryMedia(t, repos, &model.Media{
LibraryID: libID, Title: "B", Path: "/media/movie/b.mkv", Genres: "action",
})
svc := NewMediaDiscoveryService(zap.NewNop(), repos)
genres, err := svc.AggregateGenres(context.Background(), MediaVisibility{IncludeNSFW: true}, "")
if err != nil {
t.Fatal(err)
}
// 大小写不同视为同一类型,展示名保留首次出现的写法。
if got := findGenre(genres, "Action"); got != 2 {
t.Fatalf("Action count = %d, want 2 (genres=%+v)", got, genres)
}
if got := findGenre(genres, "Drama"); got != 1 {
t.Fatalf("Drama count = %d, want 1 (genres=%+v)", got, genres)
}
}
// 中文全角逗号在刮削结果里同样常见,必须一并切分。
func TestAggregateGenresHandlesFullWidthComma(t *testing.T) {
repos := newDiscoveryTestDB(t)
libID := seedDiscoveryLibrary(t, repos, "movie")
seedDiscoveryMedia(t, repos, &model.Media{
LibraryID: libID, Title: "A", Path: "/media/movie/a.mkv", Genres: "科幻,悬疑",
})
svc := NewMediaDiscoveryService(zap.NewNop(), repos)
genres, err := svc.AggregateGenres(context.Background(), MediaVisibility{IncludeNSFW: true}, "")
if err != nil {
t.Fatal(err)
}
if findGenre(genres, "科幻") != 1 || findGenre(genres, "悬疑") != 1 {
t.Fatalf("genres = %+v, want 科幻:1 and 悬疑:1", genres)
}
}
// libraryID 非空时只统计该库,供媒体库页面的筛选项使用。
func TestAggregateGenresScopedToLibrary(t *testing.T) {
repos := newDiscoveryTestDB(t)
movieLib := seedDiscoveryLibrary(t, repos, "movie")
tvLib := seedDiscoveryLibrary(t, repos, "tv")
seedDiscoveryMedia(t, repos, &model.Media{
LibraryID: movieLib, Title: "A", Path: "/media/movie/a.mkv", Genres: "Action",
})
seedDiscoveryMedia(t, repos, &model.Media{
LibraryID: tvLib, Title: "B", Path: "/media/tv/b.mkv", Genres: "Comedy",
})
svc := NewMediaDiscoveryService(zap.NewNop(), repos)
genres, err := svc.AggregateGenres(context.Background(), MediaVisibility{IncludeNSFW: true}, movieLib)
if err != nil {
t.Fatal(err)
}
if findGenre(genres, "Comedy") != -1 {
t.Fatalf("Comedy must not appear when scoped to the movie library: %+v", genres)
}
if findGenre(genres, "Action") != 1 {
t.Fatalf("Action count = %d, want 1", findGenre(genres, "Action"))
}
}
// 可见性过滤必须生效:不可见的库不应泄漏类型统计。
func TestAggregateGenresRespectsVisibility(t *testing.T) {
repos := newDiscoveryTestDB(t)
allowedLib := seedDiscoveryLibrary(t, repos, "movie")
otherLib := seedDiscoveryLibrary(t, repos, "movie")
seedDiscoveryMedia(t, repos, &model.Media{
LibraryID: allowedLib, Title: "A", Path: "/media/a/a.mkv", Genres: "Action",
})
seedDiscoveryMedia(t, repos, &model.Media{
LibraryID: otherLib, Title: "B", Path: "/media/b/b.mkv", Genres: "Secret",
})
svc := NewMediaDiscoveryService(zap.NewNop(), repos)
genres, err := svc.AggregateGenres(context.Background(),
MediaVisibility{IncludeNSFW: true, AllowedLibraryIDs: []string{allowedLib}}, "")
if err != nil {
t.Fatal(err)
}
if findGenre(genres, "Secret") != -1 {
t.Fatalf("hidden library leaked into genres: %+v", genres)
}
}