75 lines
2.3 KiB
TypeScript
75 lines
2.3 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
import { NextRequest } from 'next/server'
|
|
|
|
const mockFetch = vi.fn()
|
|
global.fetch = mockFetch
|
|
|
|
beforeEach(() => {
|
|
vi.resetAllMocks()
|
|
process.env.DIRECTUS_URL = 'https://cms.achmad.dev'
|
|
process.env.DIRECTUS_TOKEN = 'test-token'
|
|
mockFetch.mockResolvedValue({
|
|
ok: true,
|
|
body: new ReadableStream(),
|
|
headers: new Headers({ 'Content-Type': 'image/jpeg' }),
|
|
})
|
|
})
|
|
|
|
async function getImage(id: string, width?: string) {
|
|
const { GET } = await import('@/app/api/image/[id]/route')
|
|
let url = `http://localhost/api/image/${id}`
|
|
if (width) url += `?width=${width}`
|
|
return GET(new NextRequest(url), { params: Promise.resolve({ id }) })
|
|
}
|
|
|
|
describe('GET /api/image/[id]', () => {
|
|
it('proxies the image from Directus', async () => {
|
|
const res = await getImage('uuid-123')
|
|
expect(res.status).toBe(200)
|
|
expect(mockFetch).toHaveBeenCalledWith(
|
|
expect.stringContaining('/assets/uuid-123'),
|
|
expect.objectContaining({
|
|
headers: { Authorization: 'Bearer test-token' },
|
|
}),
|
|
)
|
|
})
|
|
|
|
it('sets Content-Type from upstream response', async () => {
|
|
const res = await getImage('uuid-123')
|
|
expect(res.headers.get('Content-Type')).toBe('image/jpeg')
|
|
})
|
|
|
|
it('sets immutable cache headers', async () => {
|
|
const res = await getImage('uuid-123')
|
|
expect(res.headers.get('Cache-Control')).toBe('public, max-age=31536000, immutable')
|
|
})
|
|
|
|
it('returns 404 when upstream returns non-ok status', async () => {
|
|
mockFetch.mockResolvedValue({
|
|
ok: false,
|
|
status: 404,
|
|
json: () => Promise.resolve({ error: 'Not found' }),
|
|
})
|
|
const res = await getImage('bad-id')
|
|
expect(res.status).toBe(404)
|
|
const body = await res.json()
|
|
expect(body.error).toBe('Image not found')
|
|
})
|
|
|
|
it('returns 502 when fetch throws an error', async () => {
|
|
mockFetch.mockRejectedValue(new Error('Network failure'))
|
|
const res = await getImage('uuid-123')
|
|
expect(res.status).toBe(502)
|
|
const body = await res.json()
|
|
expect(body.error).toBe('Failed to fetch image')
|
|
})
|
|
|
|
it('passes width and quality query params to Directus', async () => {
|
|
await getImage('uuid-123', '400')
|
|
expect(mockFetch).toHaveBeenCalledWith(
|
|
expect.stringContaining('width=400'),
|
|
expect.any(Object),
|
|
)
|
|
})
|
|
})
|