test: expand endpoint coverage and harden deploy gate
Some checks failed
Code Analysis and Production Deploy / analyze (push) Failing after 15s
Code Analysis and Production Deploy / deploy-production (push) Has been skipped
Code Analysis and Production Deploy / deploy-test (push) Has been skipped

This commit is contained in:
Torsten Schulz (local)
2026-05-21 08:03:59 +02:00
parent 5fce08ab75
commit 19d7aeefb0
10 changed files with 1013 additions and 14 deletions

View File

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