Files
harheimertc/tests/termine-manage-endpoints.spec.ts
Torsten Schulz (local) 19d7aeefb0
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
test: expand endpoint coverage and harden deploy gate
2026-05-21 08:03:59 +02:00

150 lines
5.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { createEvent, mockSuccessReadBody } from './setup'
vi.mock('../server/utils/auth.js', () => ({
verifyToken: vi.fn(),
getUserById: vi.fn(),
hasAnyRole: vi.fn((user, ...roles) => {
if (!user) return false
const userRoles = Array.isArray(user.roles) ? user.roles : (user.role ? [user.role] : [])
return roles.some(r => userRoles.includes(r))
})
}))
vi.mock('../server/utils/termine.js', () => ({
readTermine: vi.fn(),
saveTermin: vi.fn(),
deleteTermin: vi.fn()
}))
const authUtils = await import('../server/utils/auth.js')
const termineUtils = await import('../server/utils/termine.js')
import termineGetHandler from '../server/api/termine-manage.get.js'
import terminePostHandler from '../server/api/termine-manage.post.js'
import termineDeleteHandler from '../server/api/termine-manage.delete.js'
describe('Termine-Manage API Endpoints', () => {
beforeEach(() => {
vi.clearAllMocks()
})
const adminEvent = () => {
const event = createEvent({ cookies: { auth_token: 'token' } })
authUtils.verifyToken.mockReturnValue({ id: '1' })
authUtils.getUserById.mockResolvedValue({ id: '1', roles: ['admin'] })
authUtils.hasAnyRole.mockReturnValue(true)
return event
}
describe('GET /api/termine-manage', () => {
it('verlangt Authentifizierung', async () => {
const event = createEvent()
await expect(termineGetHandler(event)).rejects.toMatchObject({ statusCode: 401 })
})
it('lehnt ungültiges Token ab', async () => {
const event = createEvent({ cookies: { auth_token: 'bad' } })
authUtils.verifyToken.mockReturnValue(null)
await expect(termineGetHandler(event)).rejects.toMatchObject({ statusCode: 401 })
})
it('verlangt Admin- oder Vorstand-Rolle', async () => {
const event = createEvent({ cookies: { auth_token: 'token' } })
authUtils.verifyToken.mockReturnValue({ id: '1' })
authUtils.getUserById.mockResolvedValue({ id: '1', roles: ['mitglied'] })
authUtils.hasAnyRole.mockReturnValue(false)
await expect(termineGetHandler(event)).rejects.toMatchObject({ statusCode: 403 })
})
it('liefert Terminliste', async () => {
const event = adminEvent()
termineUtils.readTermine.mockResolvedValue([
{ datum: '2025-06-01', titel: 'Hauptversammlung', kategorie: 'Verein' }
])
const result = await termineGetHandler(event)
expect(result.success).toBe(true)
expect(result.termine).toHaveLength(1)
expect(result.termine[0].titel).toBe('Hauptversammlung')
})
})
describe('POST /api/termine-manage', () => {
it('verlangt Authentifizierung', async () => {
const event = createEvent()
mockSuccessReadBody({})
await expect(terminePostHandler(event)).rejects.toMatchObject({ statusCode: 401 })
})
it('verlangt Admin- oder Vorstand-Rolle', async () => {
const event = createEvent({ cookies: { auth_token: 'token' } })
authUtils.verifyToken.mockReturnValue({ id: '1' })
authUtils.getUserById.mockResolvedValue({ id: '1', roles: ['mitglied'] })
authUtils.hasAnyRole.mockReturnValue(false)
mockSuccessReadBody({ datum: '2025-06-01', titel: 'Test' })
await expect(terminePostHandler(event)).rejects.toMatchObject({ statusCode: 403 })
})
it('validiert Pflichtfelder kein Titel', async () => {
const event = adminEvent()
mockSuccessReadBody({ datum: '2025-06-01' })
await expect(terminePostHandler(event)).rejects.toMatchObject({ statusCode: 400 })
})
it('validiert Pflichtfelder kein Datum', async () => {
const event = adminEvent()
mockSuccessReadBody({ titel: 'Training' })
await expect(terminePostHandler(event)).rejects.toMatchObject({ statusCode: 400 })
})
it('speichert Termin erfolgreich', async () => {
const event = adminEvent()
termineUtils.saveTermin.mockResolvedValue(undefined)
mockSuccessReadBody({ datum: '2025-06-01', titel: 'Hauptversammlung', kategorie: 'Verein', uhrzeit: '19:00' })
const result = await terminePostHandler(event)
expect(result.success).toBe(true)
expect(termineUtils.saveTermin).toHaveBeenCalledWith(
expect.objectContaining({ datum: '2025-06-01', titel: 'Hauptversammlung' })
)
})
})
describe('DELETE /api/termine-manage', () => {
it('verlangt Authentifizierung', async () => {
const event = createEvent()
await expect(termineDeleteHandler(event)).rejects.toMatchObject({ statusCode: 401 })
})
it('verlangt Admin- oder Vorstand-Rolle', async () => {
const event = createEvent({ cookies: { auth_token: 'token' } })
authUtils.verifyToken.mockReturnValue({ id: '1' })
authUtils.getUserById.mockResolvedValue({ id: '1', roles: ['mitglied'] })
authUtils.hasAnyRole.mockReturnValue(false)
await expect(termineDeleteHandler(event)).rejects.toMatchObject({ statusCode: 403 })
})
it('validiert Pflichtfelder datum und titel fehlen', async () => {
const event = adminEvent()
// __query ist leer → keine datum/titel
await expect(termineDeleteHandler(event)).rejects.toMatchObject({ statusCode: 400 })
})
it('löscht Termin erfolgreich', async () => {
const event = adminEvent()
event.__query = { datum: '2025-06-01', titel: 'Hauptversammlung', kategorie: 'Verein' }
termineUtils.deleteTermin.mockResolvedValue(undefined)
const result = await termineDeleteHandler(event)
expect(result.success).toBe(true)
expect(termineUtils.deleteTermin).toHaveBeenCalledWith(
expect.objectContaining({ datum: '2025-06-01', titel: 'Hauptversammlung' })
)
})
})
})