test: expand endpoint coverage and harden deploy gate
This commit is contained in:
@@ -51,6 +51,7 @@ const authUtils = await import('../server/utils/auth.js')
|
||||
import uploadHandler from '../server/api/galerie/upload.post.js'
|
||||
import listHandler from '../server/api/galerie/list.get.js'
|
||||
import imageHandler from '../server/api/galerie/[id].get.js'
|
||||
import deleteImageHandler from '../server/api/galerie/[id].delete.js'
|
||||
|
||||
describe('Galerie API Endpoints', () => {
|
||||
beforeEach(() => {
|
||||
@@ -185,5 +186,71 @@ describe('Galerie API Endpoints', () => {
|
||||
expect(response).toBeInstanceOf(Buffer)
|
||||
})
|
||||
})
|
||||
|
||||
describe('DELETE /api/galerie/[id]', () => {
|
||||
it('verlangt Authentifizierung', async () => {
|
||||
const event = createEvent({ method: 'DELETE' })
|
||||
event.context.params = { id: '1' }
|
||||
|
||||
await expect(deleteImageHandler(event)).rejects.toMatchObject({ statusCode: 401 })
|
||||
})
|
||||
|
||||
it('verlangt Admin- oder Vorstand-Rolle', async () => {
|
||||
const event = createEvent({ method: 'DELETE', cookies: { auth_token: 'token' } })
|
||||
event.context.params = { id: '1' }
|
||||
authUtils.verifyToken.mockReturnValue({ id: '1' })
|
||||
authUtils.getUserFromToken.mockResolvedValue({ id: '1', roles: ['mitglied'] })
|
||||
authUtils.hasAnyRole.mockReturnValue(false)
|
||||
|
||||
await expect(deleteImageHandler(event)).rejects.toMatchObject({ statusCode: 403 })
|
||||
})
|
||||
|
||||
it('gibt 400 wenn keine Bild-ID übergeben', async () => {
|
||||
const event = createEvent({ method: 'DELETE', cookies: { auth_token: 'token' } })
|
||||
// kein context.params.id
|
||||
authUtils.verifyToken.mockReturnValue({ id: '1' })
|
||||
authUtils.getUserFromToken.mockResolvedValue({ id: '1', roles: ['admin'] })
|
||||
authUtils.hasAnyRole.mockReturnValue(true)
|
||||
|
||||
await expect(deleteImageHandler(event)).rejects.toMatchObject({ statusCode: 400 })
|
||||
})
|
||||
|
||||
it('gibt 404 wenn Bild nicht in Metadaten gefunden', async () => {
|
||||
const event = createEvent({ method: 'DELETE', cookies: { auth_token: 'token' } })
|
||||
event.context.params = { id: 'unbekannt' }
|
||||
authUtils.verifyToken.mockReturnValue({ id: '1' })
|
||||
authUtils.getUserFromToken.mockResolvedValue({ id: '1', roles: ['admin'] })
|
||||
authUtils.hasAnyRole.mockReturnValue(true)
|
||||
vi.spyOn(fs, 'readFile').mockResolvedValue(JSON.stringify([
|
||||
{ id: 'anderes-bild', filename: 'other.jpg', previewFilename: 'preview_other.jpg' }
|
||||
]))
|
||||
|
||||
await expect(deleteImageHandler(event)).rejects.toMatchObject({ statusCode: 404 })
|
||||
})
|
||||
|
||||
it('löscht Bild und aktualisiert Metadaten', async () => {
|
||||
const event = createEvent({ method: 'DELETE', cookies: { auth_token: 'token' } })
|
||||
event.context.params = { id: 'img-1' }
|
||||
authUtils.verifyToken.mockReturnValue({ id: '1' })
|
||||
authUtils.getUserFromToken.mockResolvedValue({ id: '1', roles: ['admin'] })
|
||||
authUtils.hasAnyRole.mockReturnValue(true)
|
||||
vi.spyOn(fs, 'readFile').mockResolvedValue(JSON.stringify([
|
||||
{ id: 'img-1', filename: 'bild.jpg', previewFilename: 'preview_bild.jpg' },
|
||||
{ id: 'img-2', filename: 'bild2.jpg', previewFilename: 'preview_bild2.jpg' }
|
||||
]))
|
||||
|
||||
const result = await deleteImageHandler(event)
|
||||
|
||||
expect(result.success).toBe(true)
|
||||
expect(fs.writeFile).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
expect.stringContaining('img-2'),
|
||||
expect.any(String)
|
||||
)
|
||||
// img-1 darf nicht mehr in den Metadaten sein
|
||||
const writtenData = JSON.parse((fs.writeFile as any).mock.calls[0][1])
|
||||
expect(writtenData.find((img: any) => img.id === 'img-1')).toBeUndefined()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user