From f67be1805c22104a6e356e6e437eb0bd1349f1ac Mon Sep 17 00:00:00 2001 From: maksii <1761348+maksii@users.noreply.github.com> Date: Mon, 13 Jul 2026 11:32:16 +0300 Subject: [PATCH] fix(gui): fetch metadata when the dry run finds no prepared cache The prepared-metadata cache is in-memory, so a restarted GUI session had none and the dry run was refused until the user re-ran the metadata fetch by hand. Fetch it on a cache miss instead, the way the preparation preview already does. Callers outside the GUI still require prepared metadata. --- internal/core/core.go | 10 ++++++++++ internal/core/core_test.go | 41 +++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/internal/core/core.go b/internal/core/core.go index c146f9f8..89429321 100644 --- a/internal/core/core.go +++ b/internal/core/core.go @@ -2268,6 +2268,16 @@ func (c *Core) FetchTrackerDryRunPreview(ctx context.Context, req api.Request) ( } } } + if !ok { + // The prepared-metadata cache is in-memory, so a restarted GUI session has + // none until the metadata is fetched again. Fetch it here instead of + // refusing the dry run: the preview populates the same cache this reads. + c.logger.Debugf("core: tracker dry-run fetching metadata after cache miss for %s", uniquePaths[0]) + if _, err := c.FetchMetadataPreview(ctx, singleReq); err != nil { + return api.TrackerDryRunPreview{}, err + } + meta, ok = c.getDupeCache(uniquePaths[0], signature) + } } else { if !ok { return api.TrackerDryRunPreview{}, fmt.Errorf("core: tracker dry-run requires prepared metadata for %s", uniquePaths[0]) diff --git a/internal/core/core_test.go b/internal/core/core_test.go index 0181232c..a257842a 100644 --- a/internal/core/core_test.go +++ b/internal/core/core_test.go @@ -3741,6 +3741,45 @@ func TestRunUploadPreparedDebugDryRunIgnoresCheckBlocksForArtifacts(t *testing.T } } +func TestFetchTrackerDryRunPreviewFetchesMetadataOnCacheMiss(t *testing.T) { + t.Parallel() + + meta := &stubMeta{} + tracker := &stubTrackers{dryRunEntries: []api.TrackerDryRunEntry{{Tracker: "AITHER", Status: "ready"}}} + core, err := New(api.CoreDependencies{ + Config: config.Config{MainSettings: config.MainSettingsConfig{TMDBAPI: "x"}, ScreenshotHandling: config.ScreenshotHandlingConfig{Screens: 1}}, + Services: api.ServiceSet{ + Filesystem: &stubFS{}, + Metadata: meta, + Torrents: &stubTorrent{}, + Clients: &stubClient{}, + Trackers: tracker, + }, + Repository: &stubRepo{}, + }) + if err != nil { + t.Fatalf("new core: %v", err) + } + + preview, err := core.FetchTrackerDryRunPreview(context.Background(), api.Request{ + Paths: []string{"/tmp/a"}, + Mode: api.ModeGUI, + Trackers: []string{"AITHER"}, + }) + if err != nil { + t.Fatalf("fetch tracker dry-run preview: %v", err) + } + if preview.SourcePath != "/tmp/a" { + t.Fatalf("expected source path /tmp/a, got %q", preview.SourcePath) + } + if meta.calls != 1 { + t.Fatalf("expected metadata to be prepared once on cache miss, got %d calls", meta.calls) + } + if tracker.dryRunCalls != 1 { + t.Fatalf("expected 1 dry-run build call, got %d", tracker.dryRunCalls) + } +} + func TestFetchTrackerDryRunPreviewNoSeedSkipsClient(t *testing.T) { t.Parallel() @@ -3968,7 +4007,7 @@ func TestFetchTrackerDryRunPreviewRequiresCachedMetadata(t *testing.T) { _, err = core.FetchTrackerDryRunPreview(context.Background(), api.Request{ Paths: []string{"/tmp/a"}, - Mode: api.ModeGUI, + Mode: api.ModeCLI, }) assertRequiresPreparedMetadata(t, err, "/tmp/a") }