mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-12 16:26:36 +08:00
83 lines
2.8 KiB
Go
83 lines
2.8 KiB
Go
package service
|
||
|
||
import (
|
||
"strings"
|
||
"testing"
|
||
|
||
"github.com/truewhile/MeBox/internal/model"
|
||
)
|
||
|
||
// TestLikelyEpisodicPathSQLNormalisesSeparator 守住剧集路径判定的转义差异。
|
||
//
|
||
// 此前 embyLikelyEpisodicPathSQL 会额外生成一份反斜杠模式
|
||
// (strings.ReplaceAll(pattern, "/", `\`))。PostgreSQL 的 LIKE 默认就把反斜杠
|
||
// 当转义符,模式结尾的 `\%` 被解析成「字面百分号」而不是「反斜杠 + 通配符」,
|
||
// 那些模式在 PostgreSQL 下永不命中;SQLite 没有默认转义符所以一直正常。
|
||
// 现在统一在 SQL 里把分隔符归一化成 '/',模式本身不再含反斜杠。
|
||
func TestLikelyEpisodicPathSQLNormalisesSeparator(t *testing.T) {
|
||
clause, args := embyLikelyEpisodicPathSQL()
|
||
if !strings.Contains(clause, "REPLACE(media.path") {
|
||
t.Fatalf("clause no longer normalises the path separator:\n%s", clause)
|
||
}
|
||
if got := strings.Count(clause, "LIKE ?"); got != len(args) {
|
||
t.Fatalf("clause has %d placeholders but %d args:\n%s", got, len(args), clause)
|
||
}
|
||
for _, arg := range args {
|
||
pattern, ok := arg.(string)
|
||
if !ok {
|
||
t.Fatalf("unexpected pattern type %T", arg)
|
||
}
|
||
if strings.Contains(pattern, `\`) {
|
||
t.Fatalf("pattern %q still contains a backslash; PostgreSQL's LIKE would treat it as an escape character", pattern)
|
||
}
|
||
if !strings.Contains(pattern, "/") {
|
||
t.Fatalf("pattern %q lost its separator", pattern)
|
||
}
|
||
}
|
||
}
|
||
|
||
// TestFilterLikelyEpisodicPathsHandlesWindowsStylePaths 验证反斜杠路径(Windows
|
||
// 宿主机入库的媒体)仍然被判成剧集并从电影库查询里排除。
|
||
func TestFilterLikelyEpisodicPathsHandlesWindowsStylePaths(t *testing.T) {
|
||
db := newServiceTestDB(t)
|
||
episodic := model.Media{
|
||
Base: model.Base{ID: "ep-1"},
|
||
Path: `D:\Media\国产剧\我的剧\Season 1\我的剧 - S01E01.mkv`,
|
||
SeasonNum: 1,
|
||
EpisodeNum: 1,
|
||
}
|
||
movie := model.Media{
|
||
Base: model.Base{ID: "mv-1"},
|
||
Path: `D:\Media\电影\某电影\某电影.mkv`,
|
||
}
|
||
if err := db.Create(&episodic).Error; err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
if err := db.Create(&movie).Error; err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
|
||
q := filterLikelyEpisodicPathsFromMovieQuery(
|
||
db.Model(&model.Media{}).Where("season_num > 0 OR episode_num > 0"),
|
||
)
|
||
var rows []model.Media
|
||
if err := q.Find(&rows).Error; err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
if len(rows) != 0 {
|
||
t.Fatalf("windows-style episodic path was not excluded, got %d rows", len(rows))
|
||
}
|
||
|
||
// 反证:电影类型的行必须保留。
|
||
var kept []model.Media
|
||
keepQ := filterLikelyEpisodicPathsFromMovieQuery(
|
||
db.Model(&model.Media{}).Where("path LIKE ?", `D:\Media\电影\%`),
|
||
)
|
||
if err := keepQ.Find(&kept).Error; err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
if len(kept) != 1 || kept[0].ID != "mv-1" {
|
||
t.Fatalf("plain movie row was dropped from the movie query: %+v", kept)
|
||
}
|
||
}
|