fix(downloads): re-resolve options on retry instead of replaying stale ones
A queued item freezes its post-processing options at enqueue time, so retrying a failed download replayed whatever was in effect when it was first added -- a settings change made afterward (e.g. turning SponsorBlock-remove off, which forces a slow, failure-prone software re-encode) never took effect on retry. retry/retryAll now re-resolve a source-tied item's options from the current source profile / global settings (the same precedence enqueue uses) before requeuing it. Manual pastes with no source keep their explicit per-download options untouched, and this is deliberately distinct from the history re-download path, which keeps frozen options on purpose to reproduce an identical file.
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { pickRetryOptions } from '../src/renderer/src/store/retryOptions'
|
||||
import { DEFAULT_DOWNLOAD_OPTIONS, type Source, type MediaProfile } from '../src/shared/ipc'
|
||||
import type { ProfileDefaults } from '../src/shared/profileResolve'
|
||||
|
||||
const source = (over: Partial<Source> = {}): Source => ({
|
||||
id: 'ac8e6608',
|
||||
url: 'https://youtube.com/@NetworkChuck',
|
||||
kind: 'channel',
|
||||
title: 'NetworkChuck',
|
||||
channel: 'NetworkChuck',
|
||||
addedAt: 0,
|
||||
itemCount: 0,
|
||||
...over
|
||||
})
|
||||
|
||||
// Global defaults with SponsorBlock OFF — the state after the user toggled it.
|
||||
const defaults: ProfileDefaults = {
|
||||
kind: 'video',
|
||||
videoQuality: '1080p',
|
||||
audioQuality: 'Best',
|
||||
options: { ...DEFAULT_DOWNLOAD_OPTIONS, sponsorBlock: false },
|
||||
outputTemplate: ''
|
||||
}
|
||||
|
||||
describe('pickRetryOptions', () => {
|
||||
it('re-resolves a source-tied item to the current global options (SponsorBlock now off)', () => {
|
||||
const group = pickRetryOptions('ac8e6608:qkUTB65OfAc', [source()], [], defaults)
|
||||
expect(group?.options?.sponsorBlock).toBe(false)
|
||||
expect(group?.extraArgs).toBeUndefined()
|
||||
expect(group?.collectionOutputTemplate).toBeUndefined()
|
||||
})
|
||||
|
||||
it('returns null for a manual paste (no mediaItemId) so explicit options are kept', () => {
|
||||
expect(pickRetryOptions(undefined, [source()], [], defaults)).toBeNull()
|
||||
})
|
||||
|
||||
it('returns null when the source has since been deleted', () => {
|
||||
expect(pickRetryOptions('deleted99:vid', [source()], [], defaults)).toBeNull()
|
||||
})
|
||||
|
||||
it("prefers the source's Media Profile options over the globals", () => {
|
||||
const profile: MediaProfile = {
|
||||
id: 'p1',
|
||||
name: 'Archive',
|
||||
options: { ...DEFAULT_DOWNLOAD_OPTIONS, sponsorBlock: true, sponsorBlockMode: 'remove' },
|
||||
extraArgs: '--no-mtime'
|
||||
}
|
||||
const group = pickRetryOptions(
|
||||
'ac8e6608:vid',
|
||||
[source({ profileId: 'p1' })],
|
||||
[profile],
|
||||
defaults
|
||||
)
|
||||
expect(group?.options?.sponsorBlock).toBe(true)
|
||||
expect(group?.extraArgs).toBe('--no-mtime')
|
||||
})
|
||||
|
||||
it('falls back to the globals when the source points at a dangling profile id', () => {
|
||||
const group = pickRetryOptions('ac8e6608:vid', [source({ profileId: 'gone' })], [], defaults)
|
||||
expect(group?.options?.sponsorBlock).toBe(false)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user