Files
MeBox/internal/service/subscription_site_search_enqueue_test.go
T
2026-06-26 20:31:11 +08:00

157 lines
5.1 KiB
Go

package service
import (
"testing"
"go.uber.org/zap"
"github.com/ShukeBta/MediaStationGo/internal/model"
"github.com/ShukeBta/MediaStationGo/internal/repository"
)
func TestEnqueueSiteSearchDedupMarksEnglishRangeAvailableForChineseSubscription(t *testing.T) {
db := newServiceTestDB(t, &model.DownloadTask{}, &model.Setting{})
repos := repository.New(db)
if err := repos.Download.Create(t.Context(), &model.DownloadTask{
UserID: "u1",
Source: "qbittorrent",
URL: "https://pt.example/download?id=old",
Title: "Archives The Nanyang Mystery 2026 S01E07-S01E08 2160p WEB-DL",
SavePath: "/downloads/国产剧",
Status: "queued",
Progress: 0.1,
}); err != nil {
t.Fatal(err)
}
site := NewSiteService(zap.NewNop(), repos, "")
downloads := NewDownloadService(zap.NewNop(), repos, NewHub(zap.NewNop()), nil)
svc := NewSubscriptionService(nil, zap.NewNop(), repos, downloads, site, NewHub(zap.NewNop()))
sub := &model.Subscription{
Base: model.Base{ID: "sub-nanyang"},
UserID: "u1",
Name: "南部档案 自动订阅",
Filter: "南部档案 2026",
MediaType: "tv",
MediaCategory: "国产剧",
SavePath: "/downloads",
TotalEpisodes: 33,
}
state := &siteSearchRunState{
Keyword: "南部档案 2026",
SeenSet: map[string]struct{}{},
Availability: LocalAvailability{
TotalEpisodes: 33,
ExistingEpisodeKeys: map[string]struct{}{},
MissingEpisodeKeys: map[string]struct{}{},
},
}
candidate := siteSearchCandidate{
Item: SearchResult{
Title: "Archives The Nanyang Mystery 2026 S01E07-S01E08 2160p WEB-DL",
DownloadURL: "https://pt.example/download?id=new",
},
Download: "https://pt.example/download?id=new",
GUID: "site|m-team|nanyang-7-8",
Season: 1,
Episode: 7,
Episodes: []int{7, 8},
Pack: true,
}
title, err := svc.enqueueSiteSearchCandidate(t.Context(), sub, candidate, state)
if err != nil {
t.Fatalf("enqueueSiteSearchCandidate returned %v, want dedup skip without error", err)
}
if title != "" {
t.Fatalf("title = %q, want empty because candidate was deduped", title)
}
for _, episode := range []int{7, 8} {
if _, ok := state.Availability.ExistingEpisodeKeys[episodeKey(1, episode)]; !ok {
t.Fatalf("availability missing E%d after dedup range: %#v", episode, state.Availability.ExistingEpisodeKeys)
}
}
if _, ok := state.SeenSet[candidate.GUID]; !ok {
t.Fatalf("seen set missing candidate guid after dedup")
}
}
func TestEnqueueSiteSearchDedupLinksEnglishHistoryTaskToChineseSubscription(t *testing.T) {
db := newServiceTestDB(t, &model.DownloadTask{}, &model.Setting{})
repos := repository.New(db)
if err := repos.Download.Create(t.Context(), &model.DownloadTask{
UserID: "u1",
Source: "qbittorrent",
URL: "https://pt.example/download?id=history",
Title: "The Heir 2026 S01E33-E34 2160p WEB-DL",
SavePath: "/downloads/国产剧",
Status: "queued",
Progress: 0.2,
}); err != nil {
t.Fatal(err)
}
site := NewSiteService(zap.NewNop(), repos, "")
downloads := NewDownloadService(zap.NewNop(), repos, NewHub(zap.NewNop()), nil)
svc := NewSubscriptionService(nil, zap.NewNop(), repos, downloads, site, NewHub(zap.NewNop()))
sub := &model.Subscription{
Base: model.Base{ID: "sub-heir"},
UserID: "u1",
Name: "家业 自动订阅",
Filter: "家业 2026",
MediaType: "tv",
MediaCategory: "国产剧",
SavePath: "/downloads",
TotalEpisodes: 42,
}
state := &siteSearchRunState{
Keyword: "家业 2026",
SeenSet: map[string]struct{}{},
Availability: LocalAvailability{
TotalEpisodes: 42,
ExistingEpisodeKeys: map[string]struct{}{},
MissingEpisodeKeys: map[string]struct{}{},
},
}
candidate := siteSearchCandidate{
Item: SearchResult{
Title: "The Heir 2026 S01E33-E34 2160p WEB-DL",
DownloadURL: "https://pt.example/download?id=new",
},
Download: "https://pt.example/download?id=new",
GUID: "site|m-team|heir-33-34",
Season: 1,
Episode: 33,
Episodes: []int{33, 34},
Pack: true,
}
title, err := svc.enqueueSiteSearchCandidate(t.Context(), sub, candidate, state)
if err != nil {
t.Fatalf("enqueueSiteSearchCandidate returned %v, want dedup skip without error", err)
}
if title != "" {
t.Fatalf("title = %q, want empty because candidate was deduped", title)
}
var rows []model.DownloadTask
if err := db.Find(&rows).Error; err != nil {
t.Fatal(err)
}
if len(rows) != 1 {
t.Fatalf("download rows = %d, want 1", len(rows))
}
if rows[0].SubscriptionID != sub.ID {
t.Fatalf("history task subscription_id = %q, want %q", rows[0].SubscriptionID, sub.ID)
}
if rows[0].MediaType != "tv" || rows[0].MediaCategory != "国产剧" {
t.Fatalf("history task metadata = (%q, %q), want (tv, 国产剧)", rows[0].MediaType, rows[0].MediaCategory)
}
availability := svc.pendingDownloadAvailability(t.Context(), sub)
for _, episode := range []int{33, 34} {
if _, ok := availability.ExistingEpisodeKeys[episodeKey(1, episode)]; !ok {
t.Fatalf("linked history task missing E%d availability: %#v", episode, availability.ExistingEpisodeKeys)
}
}
}