Files
harheimertc/tests/notification-scheduler.spec.ts
Torsten Schulz (local) 77aabef4a9
Some checks failed
Code Analysis and Production Deploy / analyze (push) Failing after 7m53s
Code Analysis and Production Deploy / deploy-production (push) Has been skipped
Code Analysis and Production Deploy / deploy-test (push) Has been skipped
Benachrichtigungen erweitert
Emails korrigiert
2026-06-14 01:05:19 +02:00

94 lines
3.5 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest'
import fs from 'fs/promises'
vi.mock('../server/utils/auth.js', () => ({
readUsers: vi.fn(),
isHiddenUser: vi.fn(user => user?.hidden === true || user?.invisible === true || user?.isHidden === true || user?.systemAccount === true)
}))
vi.mock('../server/utils/members.js', () => ({
readMembers: vi.fn()
}))
vi.mock('../server/utils/termine.js', () => ({
readTermine: vi.fn().mockResolvedValue([])
}))
vi.mock('../server/utils/news.js', () => ({
readNews: vi.fn().mockResolvedValue([])
}))
vi.mock('../server/utils/spielplan-data.js', () => ({
getDefaultSpielplanSeason: vi.fn().mockResolvedValue('25--26'),
readSpielplanData: vi.fn().mockResolvedValue({ data: [] })
}))
vi.mock('../server/utils/push-notifications.js', () => ({
sendPushToUsers: vi.fn().mockResolvedValue({ sent: 1, failed: 0, removed: 0, recipients: 1, tokenCount: 1, skipped: false })
}))
vi.mock('../server/utils/logger.js', () => ({
error: vi.fn(),
info: vi.fn(),
warn: vi.fn()
}))
const authUtils = await import('../server/utils/auth.js')
const memberUtils = await import('../server/utils/members.js')
const pushUtils = await import('../server/utils/push-notifications.js')
const { runNotificationSchedulerTick } = await import('../server/utils/notification-scheduler.js')
const schedulerNow = new Date('2026-06-14T07:00:00.000Z')
const recipient = {
id: 'recipient',
name: 'Push Empfaenger',
active: true,
notificationSettings: {
birthdays: true,
notificationTime: '09:00'
}
}
describe('Notification Scheduler', () => {
beforeEach(() => {
vi.clearAllMocks()
vi.spyOn(fs, 'readFile').mockRejectedValue(Object.assign(new Error('ENOENT'), { code: 'ENOENT' }))
vi.spyOn(fs, 'mkdir').mockResolvedValue(undefined)
vi.spyOn(fs, 'writeFile').mockResolvedValue(undefined)
memberUtils.readMembers.mockResolvedValue([])
authUtils.readUsers.mockResolvedValue([recipient])
})
it('sendet Geburtstags-Push nur fuer Mitglieder mit expliziter Geburtstagsfreigabe', async () => {
memberUtils.readMembers.mockResolvedValue([
{ firstName: 'Erlaubt', lastName: 'Person', active: true, geburtsdatum: '1990-06-14', visibility: { showBirthday: true } },
{ firstName: 'Privat', lastName: 'Person', active: true, geburtsdatum: '1990-06-14', visibility: { showBirthday: false } },
{ firstName: 'Unklar', lastName: 'Person', active: true, geburtsdatum: '1990-06-14' }
])
await runNotificationSchedulerTick(schedulerNow)
expect(pushUtils.sendPushToUsers).toHaveBeenCalledTimes(1)
expect(pushUtils.sendPushToUsers).toHaveBeenCalledWith(expect.objectContaining({
title: 'Geburtstage heute',
body: 'Erlaubt Person hat heute Geburtstag.',
data: { type: 'birthdays', date: '2026-06-14' }
}))
})
it('nennt bei mehreren Geburtstags-Pushes nur Namen und kein Alter', async () => {
memberUtils.readMembers.mockResolvedValue([
{ firstName: 'Anna', lastName: 'Beispiel', active: true, geburtsdatum: '1980-06-14', visibility: { showBirthday: true } },
{ firstName: 'Bert', lastName: 'Beispiel', active: true, geburtsdatum: '2010-06-14', visibility: { showBirthday: true } }
])
await runNotificationSchedulerTick(schedulerNow)
const payload = pushUtils.sendPushToUsers.mock.calls[0][0]
expect(payload.body).toBe('Geburtstage heute: Anna Beispiel, Bert Beispiel.')
expect(payload.body).not.toMatch(/\b\d+\b/)
expect(payload.body).not.toContain('Jahre')
})
})