Betrachter klicken ihren Tag an, wählen ihren Namen, optional Wunschperson und Wunschtag, und schreiben eine Notiz; keine Anmeldung nötig, zehn Anfragen je Stunde und Adresse. Offene Anfragen markieren den Tag im Kalender. Bearbeiter sehen sie unter „Anfragen" mit Zähler und führen den Tausch aus (über Kreuz oder Übernahme), öffnen den Tag oder lehnen ab. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
58 lines
3.4 KiB
JavaScript
58 lines
3.4 KiB
JavaScript
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { validateRequest, applySwap, roleOn } from '../server/requests.js';
|
|
|
|
const persons = [{ id: 'a', active: true }, { id: 'b', active: true }, { id: 'c', active: true }, { id: 'x', active: false }];
|
|
const plan = () => ({
|
|
'2026-10-05': { main: 'a', co: 'b', locked: false },
|
|
'2026-10-06': { main: 'c', co: 'a', locked: false },
|
|
'2026-10-07': { main: 'b', co: 'c', locked: false },
|
|
'2026-10-08': { off: true, main: null, co: null },
|
|
});
|
|
|
|
test('roleOn', () => {
|
|
const p = plan();
|
|
assert.equal(roleOn(p['2026-10-05'], 'a'), 'main');
|
|
assert.equal(roleOn(p['2026-10-05'], 'b'), 'co');
|
|
assert.equal(roleOn(p['2026-10-05'], 'c'), null);
|
|
assert.equal(roleOn(p['2026-10-08'], 'a'), null);
|
|
assert.equal(roleOn(undefined, 'a'), null);
|
|
});
|
|
|
|
test('validateRequest prüft Person, Tag, Einteilung und Partner', () => {
|
|
const p = plan();
|
|
assert.match(validateRequest({}, persons, p).error, /Namen/);
|
|
assert.match(validateRequest({ personId: 'x', date: '2026-10-05' }, persons, p).error, /Namen/);
|
|
assert.match(validateRequest({ personId: 'a', date: 'gestern' }, persons, p).error, /Ungültiger Tag/);
|
|
assert.match(validateRequest({ personId: 'c', date: '2026-10-05' }, persons, p).error, /nicht eingeteilt/);
|
|
assert.match(validateRequest({ personId: 'a', date: '2026-10-05', partnerId: 'a' }, persons, p).error, /selbst/);
|
|
assert.match(validateRequest({ personId: 'a', date: '2026-10-05', partnerDate: '2026-10-07' }, persons, p).error, /Person angeben/);
|
|
assert.match(validateRequest({ personId: 'a', date: '2026-10-05', partnerId: 'b', partnerDate: '2026-10-05' }, persons, p).error, /derselbe/);
|
|
const ok = validateRequest({ personId: 'a', date: '2026-10-05', partnerId: 'c', partnerDate: '2026-10-07', note: ' Zahnarzt ' }, persons, p);
|
|
assert.deepEqual(ok.request, { personId: 'a', date: '2026-10-05', role: 'main', partnerId: 'c', partnerDate: '2026-10-07', note: 'Zahnarzt' });
|
|
const minimal = validateRequest({ personId: 'b', date: '2026-10-05' }, persons, p);
|
|
assert.deepEqual(minimal.request, { personId: 'b', date: '2026-10-05', role: 'co', partnerId: null, partnerDate: null, note: '' });
|
|
});
|
|
|
|
test('applySwap über Kreuz', () => {
|
|
const p = plan();
|
|
const { changes } = applySwap(p, { personId: 'a', date: '2026-10-05', partnerId: 'c', partnerDate: '2026-10-07' });
|
|
assert.equal(p['2026-10-05'].main, 'c');
|
|
assert.equal(p['2026-10-07'].co, 'a');
|
|
assert.equal(changes.length, 2);
|
|
});
|
|
|
|
test('applySwap: Partner übernimmt den Tag', () => {
|
|
const p = plan();
|
|
applySwap(p, { personId: 'b', date: '2026-10-05', partnerId: 'c', partnerDate: null });
|
|
assert.deepEqual([p['2026-10-05'].main, p['2026-10-05'].co], ['a', 'c']);
|
|
});
|
|
|
|
test('applySwap lehnt unmögliche Fälle verständlich ab', () => {
|
|
assert.throws(() => applySwap(plan(), { personId: 'a', date: '2026-10-05', partnerId: null }), /Wunschpartner/);
|
|
assert.throws(() => applySwap(plan(), { personId: 'c', date: '2026-10-05', partnerId: 'b' }), /nicht mehr eingeteilt/);
|
|
assert.throws(() => applySwap(plan(), { personId: 'a', date: '2026-10-05', partnerId: 'b' }), /andere Moderation/);
|
|
assert.throws(() => applySwap(plan(), { personId: 'a', date: '2026-10-05', partnerId: 'c', partnerDate: '2026-10-08' }), /am Wunschtag nicht eingeteilt/);
|
|
assert.throws(() => applySwap(plan(), { personId: 'a', date: '2026-10-05', partnerId: 'c', partnerDate: '2026-10-06' }), /anfragende Person/);
|
|
});
|