feat(admin): add adminAlerts module shell with thresholds and signature helper

This commit is contained in:
Jennie Robinson Faber 2026-04-08 11:06:02 +01:00
parent 7544424484
commit d3a961f765
2 changed files with 125 additions and 0 deletions

View file

@ -0,0 +1,86 @@
import { describe, it, expect, vi, beforeEach } from 'vitest'
vi.mock('../../../server/utils/mongoose.js', () => ({
connectDB: vi.fn()
}))
vi.mock('../../../server/models/member.js', () => ({
default: {
find: vi.fn(),
countDocuments: vi.fn()
}
}))
vi.mock('../../../server/models/event.js', () => ({
default: {
find: vi.fn()
}
}))
vi.mock('../../../server/models/preRegistration.js', () => ({
default: {
find: vi.fn()
}
}))
vi.mock('../../../server/models/tagSuggestion.js', () => ({
default: {
find: vi.fn()
}
}))
vi.mock('../../../server/models/adminAlertDismissal.js', () => ({
default: {
find: vi.fn()
},
ADMIN_ALERT_TYPES: [
'slack_invite_failed',
'no_slack_handle_week',
'stuck_pending_payment',
'member_suspended',
'preregistrant_selected_not_invited',
'preregistrant_expired',
'event_draft_imminent',
'event_near_capacity',
'tag_suggestions_pending'
]
}))
import { ALERT_THRESHOLDS, computeSignature } from '../../../server/utils/adminAlerts.js'
describe('adminAlerts module shell', () => {
describe('ALERT_THRESHOLDS', () => {
it('exposes the four documented thresholds', () => {
expect(ALERT_THRESHOLDS.NO_SLACK_DAYS).toBe(7)
expect(ALERT_THRESHOLDS.STUCK_PAYMENT_DAYS).toBe(7)
expect(ALERT_THRESHOLDS.PREREG_SELECTED_DAYS).toBe(3)
expect(ALERT_THRESHOLDS.DRAFT_IMMINENT_DAYS).toBe(14)
expect(ALERT_THRESHOLDS.NEAR_CAPACITY_RATIO).toBe(0.8)
})
})
describe('computeSignature', () => {
it('returns a hex string', () => {
const sig = computeSignature(['a', 'b', 'c'])
expect(typeof sig).toBe('string')
expect(sig).toMatch(/^[a-f0-9]+$/)
})
it('is order-independent', () => {
expect(computeSignature(['a', 'b', 'c'])).toBe(computeSignature(['c', 'a', 'b']))
})
it('changes when membership changes', () => {
expect(computeSignature(['a', 'b'])).not.toBe(computeSignature(['a', 'b', 'c']))
})
it('returns a stable empty-set signature', () => {
expect(computeSignature([])).toBe(computeSignature([]))
})
it('coerces non-string ids to strings', () => {
expect(computeSignature([{ toString: () => 'x' }, 'y']))
.toBe(computeSignature(['x', 'y']))
})
})
})