feat: API route POST /api/images/upload (TDD)
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import { POST } from '@/app/api/images/upload/route'
|
||||
import { NextRequest } from 'next/server'
|
||||
|
||||
jest.mock('@/lib/shopify', () => ({
|
||||
uploadProductImage: jest.fn(),
|
||||
}))
|
||||
|
||||
import { uploadProductImage } from '@/lib/shopify'
|
||||
const mockUpload = uploadProductImage as jest.Mock
|
||||
|
||||
describe('POST /api/images/upload', () => {
|
||||
beforeEach(() => jest.clearAllMocks())
|
||||
|
||||
it('retourne 400 si shopifyProductId manquant', async () => {
|
||||
const req = new NextRequest('http://localhost/api/images/upload', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ imageBase64: 'abc', filename: 'test.jpg' }),
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
})
|
||||
const res = await POST(req)
|
||||
expect(res.status).toBe(400)
|
||||
})
|
||||
|
||||
it('retourne 400 si imageBase64 manquant', async () => {
|
||||
const req = new NextRequest('http://localhost/api/images/upload', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ shopifyProductId: '123', filename: 'test.jpg' }),
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
})
|
||||
const res = await POST(req)
|
||||
expect(res.status).toBe(400)
|
||||
})
|
||||
|
||||
it('retourne 400 si filename manquant', async () => {
|
||||
const req = new NextRequest('http://localhost/api/images/upload', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ shopifyProductId: '123', imageBase64: 'abc' }),
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
})
|
||||
const res = await POST(req)
|
||||
expect(res.status).toBe(400)
|
||||
})
|
||||
|
||||
it('retourne l\'URL après upload réussi', async () => {
|
||||
mockUpload.mockResolvedValue({ url: 'https://cdn.shopify.com/image.jpg' })
|
||||
const req = new NextRequest('http://localhost/api/images/upload', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
shopifyProductId: '123456',
|
||||
imageBase64: 'base64data==',
|
||||
filename: 'REF-1042.jpg',
|
||||
}),
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
})
|
||||
const res = await POST(req)
|
||||
expect(res.status).toBe(200)
|
||||
expect(await res.json()).toEqual({ url: 'https://cdn.shopify.com/image.jpg' })
|
||||
expect(mockUpload).toHaveBeenCalledWith('123456', 'base64data==', 'REF-1042.jpg')
|
||||
})
|
||||
|
||||
it('retourne 500 en cas d\'erreur Shopify', async () => {
|
||||
mockUpload.mockRejectedValue(new Error('Shopify upload error: 422'))
|
||||
const req = new NextRequest('http://localhost/api/images/upload', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
shopifyProductId: '123',
|
||||
imageBase64: 'abc',
|
||||
filename: 'test.jpg',
|
||||
}),
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
})
|
||||
const res = await POST(req)
|
||||
expect(res.status).toBe(500)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,31 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { uploadProductImage } from '@/lib/shopify'
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
let body: Record<string, unknown>
|
||||
try {
|
||||
body = await req.json()
|
||||
} catch {
|
||||
return NextResponse.json({ error: 'Corps JSON invalide' }, { status: 400 })
|
||||
}
|
||||
|
||||
const { shopifyProductId, imageBase64, filename } = body
|
||||
|
||||
if (!shopifyProductId || typeof shopifyProductId !== 'string') {
|
||||
return NextResponse.json({ error: 'shopifyProductId requis' }, { status: 400 })
|
||||
}
|
||||
if (!imageBase64 || typeof imageBase64 !== 'string') {
|
||||
return NextResponse.json({ error: 'imageBase64 requis' }, { status: 400 })
|
||||
}
|
||||
if (!filename || typeof filename !== 'string') {
|
||||
return NextResponse.json({ error: 'filename requis' }, { status: 400 })
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await uploadProductImage(shopifyProductId, imageBase64, filename)
|
||||
return NextResponse.json(result)
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : 'Erreur inconnue'
|
||||
return NextResponse.json({ error: message }, { status: 500 })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user