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() }) })