feat: add API routes (POST /downloads, GET /downloads/[uuid], GET /download/[token])

This commit is contained in:
2026-08-10 14:40:44 +02:00
parent ab9235fe57
commit f21089cf76
6 changed files with 275 additions and 0 deletions
@@ -0,0 +1,61 @@
import { POST } from '../route'
import { prisma } from '@/lib/prisma'
import * as rateLimit from '@/lib/rate-limit'
jest.mock('@/lib/prisma', () => ({
prisma: { download: { create: jest.fn() } },
}))
jest.mock('@/lib/rate-limit')
const mockCreate = prisma.download.create as jest.Mock
const mockIsRateLimited = rateLimit.isRateLimited as jest.Mock
function req(body: object, ip = '1.2.3.4') {
return new Request('http://localhost/api/downloads', {
method: 'POST',
headers: { 'content-type': 'application/json', 'x-forwarded-for': ip },
body: JSON.stringify(body),
})
}
describe('POST /api/downloads', () => {
beforeEach(() => {
mockIsRateLimited.mockReturnValue(false)
mockCreate.mockResolvedValue({ uuid: 'test-uuid' })
})
it('returns 429 when rate limited', async () => {
mockIsRateLimited.mockReturnValue(true)
const res = await POST(req({ url: 'https://y.com', format: 'mp4', quality: 'best', subtitles: false }))
expect(res.status).toBe(429)
})
it('returns 400 when url is missing', async () => {
const res = await POST(req({ format: 'mp4', quality: 'best', subtitles: false }))
expect(res.status).toBe(400)
})
it('returns 400 when format is missing', async () => {
const res = await POST(req({ url: 'https://y.com', quality: 'best', subtitles: false }))
expect(res.status).toBe(400)
})
it('returns 201 with uuid on success', async () => {
const res = await POST(req({ url: 'https://youtube.com/watch?v=abc', format: 'mp4', quality: 'best', subtitles: false }))
expect(res.status).toBe(201)
expect(await res.json()).toEqual({ uuid: 'test-uuid' })
})
it('passes correct fields to prisma', async () => {
await POST(req({ url: 'https://y.com/watch?v=x', format: 'mp3', quality: '720p', subtitles: true }, '9.9.9.9'))
expect(mockCreate).toHaveBeenCalledWith({
data: expect.objectContaining({
url: 'https://y.com/watch?v=x',
format: 'mp3',
quality: '720p',
subtitles: true,
ipAddress: '9.9.9.9',
}),
})
})
})