d18ada4ee7
Docker Publish / docker (web, apps/web/Dockerfile, web) (push) Failing after 0s
Docker Publish / docker (api, apps/api/Dockerfile, api) (push) Failing after 1s
Publish Extension / detect-version (push) Has been skipped
Publish Extension / submit (push) Has been cancelled
111 lines
3.3 KiB
TypeScript
111 lines
3.3 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
|
|
import { enqueueDownload } from '../src/download/enqueue'
|
|
import type { ContractClient } from '../src/subcommands'
|
|
import type { Task } from '@vidbee/task-queue'
|
|
import { EMPTY_PROGRESS } from '@vidbee/task-queue'
|
|
|
|
function task(id: string, status: Task['status']): Task {
|
|
return {
|
|
id,
|
|
kind: 'yt-dlp-forward',
|
|
parentId: null,
|
|
input: { url: 'https://x', kind: 'yt-dlp-forward' },
|
|
priority: 0,
|
|
groupKey: 'x',
|
|
status,
|
|
prevStatus: null,
|
|
statusReason: null,
|
|
enteredStatusAt: 0,
|
|
attempt: 0,
|
|
maxAttempts: 5,
|
|
nextRetryAt: null,
|
|
progress: { ...EMPTY_PROGRESS },
|
|
output: null,
|
|
lastError: null,
|
|
pid: null,
|
|
pidStartedAt: null,
|
|
createdAt: 0,
|
|
updatedAt: 0
|
|
}
|
|
}
|
|
|
|
function client(initial: Task, transitions: Task[] = []): ContractClient {
|
|
let i = 0
|
|
return {
|
|
list: async () => ({ items: [], nextCursor: null }),
|
|
get: async () => transitions[Math.min(i++, transitions.length - 1)] ?? initial,
|
|
stats: async () => ({}),
|
|
removeFromHistory: async () => {},
|
|
add: async () => ({ id: initial.id, task: initial })
|
|
}
|
|
}
|
|
|
|
describe('enqueueDownload', () => {
|
|
it('detached returns immediately', async () => {
|
|
const t = task('a', 'queued')
|
|
const r = await enqueueDownload({
|
|
client: client(t),
|
|
request: { input: { url: 'https://x', kind: 'yt-dlp-forward' } },
|
|
wait: false
|
|
})
|
|
expect(r.kind).toBe('detached')
|
|
if (r.kind === 'detached') expect(r.task.id).toBe('a')
|
|
})
|
|
|
|
it('wait resolves to wait-success on completed', async () => {
|
|
const t0 = task('a', 'queued')
|
|
const t1 = task('a', 'running')
|
|
const t2 = task('a', 'completed')
|
|
const r = await enqueueDownload({
|
|
client: client(t0, [t1, t2]),
|
|
request: { input: { url: 'https://x', kind: 'yt-dlp-forward' } },
|
|
wait: true,
|
|
delay: async () => {}
|
|
})
|
|
expect(r.kind).toBe('wait-success')
|
|
})
|
|
|
|
it('wait reports retry-scheduled as wait-non-success', async () => {
|
|
const t0 = task('a', 'queued')
|
|
const t1 = task('a', 'retry-scheduled')
|
|
const r = await enqueueDownload({
|
|
client: client(t0, [t1]),
|
|
request: { input: { url: 'https://x', kind: 'yt-dlp-forward' } },
|
|
wait: true,
|
|
delay: async () => {}
|
|
})
|
|
if (r.kind !== 'wait-non-success') throw new Error('expected non-success')
|
|
expect(r.reason).toBe('retry-scheduled')
|
|
})
|
|
|
|
it('wait surfaces failed terminal status', async () => {
|
|
const t0 = task('a', 'queued')
|
|
const t1 = task('a', 'failed')
|
|
const r = await enqueueDownload({
|
|
client: client(t0, [t1]),
|
|
request: { input: { url: 'https://x', kind: 'yt-dlp-forward' } },
|
|
wait: true,
|
|
delay: async () => {}
|
|
})
|
|
if (r.kind !== 'wait-non-success') throw new Error('expected non-success')
|
|
expect(r.reason).toBe('failed')
|
|
})
|
|
|
|
it('throws when transport lacks add()', async () => {
|
|
const c: ContractClient = {
|
|
list: async () => ({ items: [], nextCursor: null }),
|
|
get: async () => task('a', 'queued'),
|
|
stats: async () => ({}),
|
|
removeFromHistory: async () => {}
|
|
}
|
|
await expect(
|
|
enqueueDownload({
|
|
client: c,
|
|
request: { input: { url: 'https://x', kind: 'yt-dlp-forward' } },
|
|
wait: false
|
|
})
|
|
).rejects.toThrow(/transport.*add/)
|
|
})
|
|
})
|