Files
harheimertc/tests/public-endpoints.spec.ts

143 lines
4.9 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest'
import { createEvent, mockSuccessReadBody } from './setup'
import fsPromises from 'fs/promises'
import { promises as fs } from 'fs'
vi.mock('nodemailer', () => {
const sendMail = vi.fn().mockResolvedValue(true)
const createTransport = vi.fn(() => ({ sendMail }))
return {
default: { createTransport },
createTransport
}
})
vi.mock('../server/utils/news.js', () => ({
readNews: vi.fn()
}))
const nodemailer = await import('nodemailer')
const newsUtils = await import('../server/utils/news.js')
import contactHandler from '../server/api/contact.post.js'
import galerieHandler from '../server/api/galerie.get.js'
import newsPublicHandler from '../server/api/news-public.get.js'
import termineHandler from '../server/api/termine.get.js'
import spielplaeneHandler from '../server/api/spielplaene.get.js'
describe('Öffentliche API-Endpunkte', () => {
beforeEach(() => {
vi.restoreAllMocks()
vi.clearAllMocks()
})
describe('POST /api/contact', () => {
it('validiert Pflichtfelder', async () => {
const event = createEvent()
mockSuccessReadBody({})
await expect(contactHandler(event)).rejects.toMatchObject({ statusCode: 400 })
})
it('validiert E-Mail-Adresse', async () => {
const event = createEvent()
mockSuccessReadBody({ name: 'Max', email: 'invalid', subject: 'Hi', message: 'Test' })
await expect(contactHandler(event)).rejects.toMatchObject({ statusCode: 400 })
})
it('sendet E-Mail bei gültigen Daten', async () => {
const event = createEvent()
mockSuccessReadBody({ name: 'Max', email: 'max@example.com', subject: 'Frage', message: 'Hallo' })
const response = await contactHandler(event)
expect(response.success).toBe(true)
expect(nodemailer.default.createTransport).toHaveBeenCalled()
})
})
describe('GET /api/galerie', () => {
it('liefert leeres Array, wenn Verzeichnis fehlt', async () => {
vi.spyOn(fs, 'access').mockRejectedValue(new Error('not found'))
const result = await galerieHandler(createEvent())
expect(result).toEqual([])
})
it('filtert nur Bilddateien', async () => {
vi.spyOn(fs, 'access').mockResolvedValue(undefined)
vi.spyOn(fs, 'readdir').mockResolvedValue(['foto-1.jpg', 'readme.md'])
const result = await galerieHandler(createEvent())
expect(result).toHaveLength(1)
expect(result[0].filename).toBe('foto-1.jpg')
})
})
describe('GET /api/news-public', () => {
it('filtert nicht öffentliche News', async () => {
const now = new Date()
newsUtils.readNews.mockResolvedValue([
{ id: 1, isPublic: true, isHidden: false, created: now.toISOString(), title: 'ok' },
{ id: 2, isPublic: false, isHidden: false, created: now.toISOString() },
{ id: 3, isPublic: true, isHidden: true, created: now.toISOString() }
])
const response = await newsPublicHandler(createEvent())
expect(response.success).toBe(true)
expect(response.news).toHaveLength(1)
expect(response.news[0].id).toBe(1)
})
it('begrenzt Ergebnis auf drei Einträge', async () => {
const now = Date.now()
newsUtils.readNews.mockResolvedValue(
Array.from({ length: 5 }).map((_, index) => ({
id: index + 1,
isPublic: true,
isHidden: false,
created: new Date(now - index * 1000).toISOString()
}))
)
const response = await newsPublicHandler(createEvent())
expect(response.news).toHaveLength(3)
expect(response.news[0].id).toBe(1)
})
})
describe('GET /api/termine', () => {
it('parst CSV-Dateien', async () => {
const csv = 'Datum,Uhrzeit,Titel,Beschreibung,Kategorie\n2025-01-01,19:00,Training,Beschreibung,Sport'
vi.spyOn(fsPromises, 'readFile').mockResolvedValue(csv)
const response = await termineHandler(createEvent())
expect(response.success).toBe(true)
expect(response.termine[0]).toMatchObject({ titel: 'Training', kategorie: 'Sport' })
})
it('gibt leeres Array bei Fehlern zurück', async () => {
vi.spyOn(fsPromises, 'readFile').mockRejectedValue(new Error('kaputt'))
const response = await termineHandler(createEvent())
expect(response.termine).toEqual([])
})
})
describe('GET /api/spielplaene', () => {
it('filtert nur erlaubte Dateitypen', async () => {
vi.spyOn(fs, 'access').mockResolvedValue(undefined)
vi.spyOn(fs, 'readdir').mockResolvedValue(['plan.pdf', 'notizen.txt'])
const result = await spielplaeneHandler(createEvent())
expect(result).toEqual(['plan.pdf'])
})
it('gibt leeres Array zurück, wenn Verzeichnis fehlt', async () => {
vi.spyOn(fs, 'access').mockRejectedValue(new Error('not found'))
const result = await spielplaeneHandler(createEvent())
expect(result).toEqual([])
})
})
})