fix(downloads): prevent subscription readding deleted torrents

This commit is contained in:
ShukeBta
2026-06-07 19:20:10 +08:00
parent a5d061afa6
commit 88ee6d6bb7
7 changed files with 372 additions and 5 deletions
+78
View File
@@ -313,6 +313,84 @@ func TestSubscriptionPendingDownloadAvailabilityIncludesQueuedTasks(t *testing.T
}
}
func TestSubscriptionLocalAvailabilityMatchesMediaPath(t *testing.T) {
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
if err != nil {
t.Fatal(err)
}
if err := db.AutoMigrate(&model.Media{}); err != nil {
t.Fatal(err)
}
repos := repository.New(db)
if err := db.Create(&model.Media{
Title: "Scraped English Title",
Path: "/media/电视剧/国产剧/凡人修仙传/Season 01/凡人修仙传 - S01E146.mkv",
SeasonNum: 1,
EpisodeNum: 146,
}).Error; err != nil {
t.Fatal(err)
}
sub := &model.Subscription{
Name: "凡人修仙传 年番",
Filter: "凡人修仙传",
MediaType: "tv",
TotalEpisodes: 146,
}
availability := SubscriptionLocalAvailability(t.Context(), repos, sub)
if _, ok := availability.ExistingEpisodeKeys[episodeKey(1, 146)]; !ok {
t.Fatalf("missing path-matched E146 key: %#v", availability.ExistingEpisodeKeys)
}
results := []SearchResult{
{Title: "凡人修仙传 年番 - 146 1080p", DownloadURL: "https://pt/download/146", Seeders: 80},
}
got := selectSiteSearchCandidates(results, sub, map[string]struct{}{}, availability)
if len(got) != 0 {
t.Fatalf("selected %#v, want none because path-matched local episode exists", got)
}
}
func TestSubscriptionPendingDownloadAvailabilityIncludesUserDeletedTasks(t *testing.T) {
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
if err != nil {
t.Fatal(err)
}
if err := db.AutoMigrate(&model.DownloadTask{}); err != nil {
t.Fatal(err)
}
repos := repository.New(db)
if err := repos.Download.Create(t.Context(), &model.DownloadTask{
Source: "qbittorrent",
URL: "magnet:?xt=urn:btih:3333333333333333333333333333333333333333",
Title: "间谍过家家 S01E02 1080p",
SavePath: "/downloads/tv",
Status: "deleted",
}); err != nil {
t.Fatal(err)
}
svc := NewSubscriptionService(nil, nil, repos, nil, nil, nil)
sub := &model.Subscription{
Name: "间谍过家家 自动订阅",
Filter: "间谍过家家",
MediaType: "tv",
SavePath: "/downloads/tv",
TotalEpisodes: 3,
}
availability := svc.pendingDownloadAvailability(t.Context(), sub)
if _, ok := availability.ExistingEpisodeKeys[episodeKey(1, 2)]; !ok {
t.Fatalf("missing user-deleted E02 key: %#v", availability.ExistingEpisodeKeys)
}
results := []SearchResult{
{Title: "间谍过家家 S01E02 1080p WEB-DL", DownloadURL: "https://pt/download/2", Seeders: 80},
{Title: "间谍过家家 S01E03 1080p WEB-DL", DownloadURL: "https://pt/download/3", Seeders: 70},
}
got := selectSiteSearchCandidates(results, sub, map[string]struct{}{}, availability)
if len(got) != 1 || got[0].Episode != 3 {
t.Fatalf("selected %#v, want only not-yet-deleted episode 3", got)
}
}
func TestSubscriptionPendingDownloadAvailabilityIncludesLiveQBTorrents(t *testing.T) {
qb := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {