Files
downlink/app/api/download/route.test.ts

150 lines
4.3 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest'
import { POST } from './route'
import { NextRequest } from 'next/server'
vi.mock('@/lib/youtube', () => ({
downloadVideo: vi.fn(),
}))
import { downloadVideo } from '@/lib/youtube'
const mockDownloadVideo = vi.mocked(downloadVideo)
function createRequest(body: object): NextRequest {
return new NextRequest('http://localhost:3000/api/download', {
method: 'POST',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
})
}
describe('POST /api/download', () => {
beforeEach(() => {
vi.clearAllMocks()
})
it('returns 400 when url is missing', async () => {
const request = createRequest({ format: 'mp4', formatType: 'video' })
const response = await POST(request)
const data = await response.json()
expect(response.status).toBe(400)
expect(data.success).toBe(false)
expect(data.error).toBe('Missing required fields')
})
it('returns 400 when format is missing', async () => {
const request = createRequest({ url: 'https://youtube.com/watch?v=abc', formatType: 'video' })
const response = await POST(request)
const data = await response.json()
expect(response.status).toBe(400)
expect(data.success).toBe(false)
expect(data.error).toBe('Missing required fields')
})
it('returns 400 when formatType is missing', async () => {
const request = createRequest({ url: 'https://youtube.com/watch?v=abc', format: 'mp4' })
const response = await POST(request)
const data = await response.json()
expect(response.status).toBe(400)
expect(data.success).toBe(false)
expect(data.error).toBe('Missing required fields')
})
it('returns 400 for invalid YouTube URL', async () => {
const request = createRequest({
url: 'https://vimeo.com/123',
format: 'mp4',
formatType: 'video',
})
const response = await POST(request)
const data = await response.json()
expect(response.status).toBe(400)
expect(data.success).toBe(false)
expect(data.error).toBe('Invalid YouTube URL')
})
it('returns 500 when download fails', async () => {
mockDownloadVideo.mockResolvedValue({
success: false,
error: 'Download failed',
})
const request = createRequest({
url: 'https://youtube.com/watch?v=dQw4w9WgXcQ',
format: 'mp4',
formatType: 'video',
})
const response = await POST(request)
const data = await response.json()
expect(response.status).toBe(500)
expect(data.success).toBe(false)
expect(data.error).toBe('Download failed')
})
it('returns download result on success', async () => {
const mockResult = {
success: true,
downloadUrl: '/downloads/123.mp4',
filename: 'video.mp4',
}
mockDownloadVideo.mockResolvedValue(mockResult)
const request = createRequest({
url: 'https://youtube.com/watch?v=dQw4w9WgXcQ',
format: 'mp4',
formatType: 'video',
})
const response = await POST(request)
const data = await response.json()
expect(response.status).toBe(200)
expect(data.success).toBe(true)
expect(data.downloadUrl).toBe('/downloads/123.mp4')
expect(data.filename).toBe('video.mp4')
})
it('passes correct parameters to downloadVideo', async () => {
mockDownloadVideo.mockResolvedValue({
success: true,
downloadUrl: '/downloads/123.mp3',
filename: 'audio.mp3',
})
const request = createRequest({
url: 'https://youtube.com/watch?v=dQw4w9WgXcQ',
format: 'mp3',
formatType: 'audio',
})
await POST(request)
expect(mockDownloadVideo).toHaveBeenCalledWith({
url: 'https://youtube.com/watch?v=dQw4w9WgXcQ',
format: 'mp3',
formatType: 'audio',
})
})
it('handles exceptions gracefully', async () => {
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
mockDownloadVideo.mockRejectedValue(new Error('Unexpected error'))
const request = createRequest({
url: 'https://youtube.com/watch?v=dQw4w9WgXcQ',
format: 'mp4',
formatType: 'video',
})
const response = await POST(request)
const data = await response.json()
expect(response.status).toBe(500)
expect(data.success).toBe(false)
expect(data.error).toBe('Unexpected error')
consoleSpy.mockRestore()
})
})