84 lines
4.6 KiB
JavaScript
84 lines
4.6 KiB
JavaScript
import { test, beforeEach } from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
import { zaehle, zaehleAlle, darfG08, darfK21NichtZugeordnet, resetTermineLimitsForTests } from '../server/services/termine/limits.js'
|
|
|
|
// Grenzen im Speicher: festes Fenster ab dem ersten Ereignis, alle-oder-keine bei mehreren Regeln, Obergrenze der Schluessel.
|
|
const T0 = new Date('2026-10-05T08:00:00.000Z')
|
|
const STUNDE = 60 * 60 * 1000
|
|
const TAG = 24 * STUNDE
|
|
const plus = (ms) => new Date(T0.getTime() + ms)
|
|
|
|
beforeEach(() => resetTermineLimitsForTests())
|
|
|
|
test('zaehle: erlaubt bis max, danach false; das Fenster beginnt mit dem ersten Ereignis und endet nach fensterMs', () => {
|
|
assert.deepEqual([1, 2, 3].map(() => zaehle('a', 3, STUNDE, T0)), [true, true, true])
|
|
assert.equal(zaehle('a', 3, STUNDE, plus(10 * 60000)), false)
|
|
assert.equal(zaehle('a', 3, STUNDE, plus(STUNDE - 1)), false, 'bis zur letzten Millisekunde des Fensters')
|
|
assert.equal(zaehle('b', 3, STUNDE, T0), true, 'andere Schluessel zaehlen getrennt')
|
|
// die abgelehnten Anfragen haben nichts gezaehlt: das neue Fenster (ab plus(STUNDE)) erlaubt wieder drei
|
|
assert.deepEqual([1, 2, 3, 4].map((i) => zaehle('a', 3, STUNDE, plus(STUNDE + i))), [true, true, true, false])
|
|
})
|
|
|
|
test('zaehle: max 0 erlaubt nie, ungueltige Angaben werfen TypeError', () => {
|
|
assert.equal(zaehle('a', 0, STUNDE, T0), false)
|
|
assert.throws(() => zaehle('a', 1.5, STUNDE, T0), TypeError)
|
|
assert.throws(() => zaehle('a', -1, STUNDE, T0), TypeError)
|
|
assert.throws(() => zaehle('a', 1, 0, T0), TypeError)
|
|
assert.throws(() => zaehle('', 1, STUNDE, T0), TypeError)
|
|
assert.throws(() => zaehle('a', 1, STUNDE, undefined), TypeError)
|
|
assert.throws(() => zaehle('a', 1, STUNDE, Date.now()), TypeError)
|
|
assert.throws(() => zaehleAlle([], T0), TypeError)
|
|
})
|
|
|
|
test('zaehleAlle: alle oder keine - scheitert eine Regel, zaehlt keine', () => {
|
|
const regeln = [
|
|
{ schluessel: 'adresse', max: 3, fensterMs: TAG },
|
|
{ schluessel: 'funktion', max: 1, fensterMs: STUNDE },
|
|
]
|
|
assert.equal(zaehleAlle(regeln, T0), true)
|
|
assert.equal(zaehleAlle(regeln, plus(1000)), false, 'die Funktionsgrenze ist erreicht')
|
|
// der Adress-Zaehler wurde dabei nicht verbraucht: nach der Stunde sind noch zwei Ereignisse an diese Adresse frei
|
|
const nurAdresse = [{ schluessel: 'adresse', max: 3, fensterMs: TAG }]
|
|
assert.equal(zaehleAlle(nurAdresse, plus(2 * STUNDE)), true)
|
|
assert.equal(zaehleAlle(nurAdresse, plus(2 * STUNDE)), true)
|
|
assert.equal(zaehleAlle(nurAdresse, plus(2 * STUNDE)), false)
|
|
})
|
|
|
|
test('darfG08: 3 je Adresse und Tag (auch ueber Funktionen), 20 je Funktion und Stunde', () => {
|
|
assert.deepEqual([1, 2, 3, 4].map(() => darfG08('f1', 'max@example.com', T0)), [true, true, true, false])
|
|
assert.equal(darfG08('f2', 'max@example.com', plus(TAG - 1)), false, 'die Adresse zaehlt fuer alle Funktionen zusammen')
|
|
assert.equal(darfG08('f1', 'max@example.com', plus(TAG)), true, 'am naechsten Tag wieder')
|
|
|
|
resetTermineLimitsForTests()
|
|
const erlaubt = Array.from({ length: 22 }, (_, i) => darfG08('f1', `gast${i}@example.com`, T0))
|
|
assert.equal(erlaubt.filter(Boolean).length, 20)
|
|
assert.equal(darfG08('f2', 'neu@example.com', T0), true, 'andere Funktion hat ihr eigenes Kontingent')
|
|
assert.equal(darfG08('f1', 'spaet@example.com', plus(STUNDE)), true, 'nach einer Stunde wieder')
|
|
})
|
|
|
|
test('darfK21NichtZugeordnet: 30 je Funktion und Stunde', () => {
|
|
assert.equal(Array.from({ length: 32 }, () => darfK21NichtZugeordnet('f1', T0)).filter(Boolean).length, 30)
|
|
assert.equal(darfK21NichtZugeordnet('f2', T0), true)
|
|
assert.equal(darfK21NichtZugeordnet('f1', plus(STUNDE)), true)
|
|
})
|
|
|
|
test('Obergrenze: ueber 10 000 Schluessel faellt der aelteste Zaehler weg, die neueren bleiben', () => {
|
|
assert.equal(zaehle('aeltester', 1, TAG, T0), true)
|
|
assert.equal(zaehle('aeltester', 1, TAG, T0), false)
|
|
for (let i = 0; i < 9998; i += 1) zaehle(`k${i}`, 1, TAG, plus(1000))
|
|
assert.equal(zaehle('aeltester', 1, TAG, T0), false, 'bei 9 999 Schluesseln noch da')
|
|
assert.equal(zaehle('k9997', 1, TAG, plus(2000)), false)
|
|
zaehle('neu1', 1, TAG, plus(3000)) // 10 000
|
|
zaehle('neu2', 1, TAG, plus(3000)) // 10 001: der aelteste faellt weg
|
|
assert.equal(zaehle('aeltester', 1, TAG, plus(4000)), true, 'der aelteste Zaehler wurde verdraengt')
|
|
assert.equal(zaehle('neu2', 1, TAG, plus(4000)), false, 'der neueste bleibt')
|
|
assert.equal(zaehle('k9997', 1, TAG, plus(4000)), false, 'die juengeren bleiben')
|
|
})
|
|
|
|
test('resetTermineLimitsForTests leert alles', () => {
|
|
zaehle('a', 1, TAG, T0)
|
|
assert.equal(zaehle('a', 1, TAG, T0), false)
|
|
resetTermineLimitsForTests()
|
|
assert.equal(zaehle('a', 1, TAG, T0), true)
|
|
})
|