Tauschanfragen gegen offene Plätze erlauben und Lücken nachbesetzen
Ein Wunschtag ohne Tauschpartner bedeutet jetzt: die Person übernimmt dort einen offenen Platz; ihr alter Platz wird beim Ausführen sofort fair nachbesetzt, ohne sie selbst. Rollen werden bei allen Tauschformen geprüft. Bearbeiter können Person und Wunschtag einer Anfrage nachtragen, etwa aus der Notiz. Der Anfragedialog zeigt, was am Wunschtag los ist. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
e8ab95159e
commit
42d495c54e
7 files changed
+196
-30
No files matched your search
+38
-4
@@ -1,13 +1,15 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { validateRequest, applySwap, roleOn } from '../server/requests.js';
|
||||
import { validateRequest, applySwap, roleOn, openSlotFor, canTake } from '../server/requests.js';
|
||||
|
||||
const persons = [{ id: 'a', active: true }, { id: 'b', active: true }, { id: 'c', active: true }, { id: 'x', active: false }];
|
||||
const persons = [{ id: 'a', active: true }, { id: 'b', active: true }, { id: 'c', active: true }, { id: 'x', active: false }, { id: 'm', active: true, canMain: true, canCo: 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 },
|
||||
'2026-10-09': { main: null, co: 'c', locked: false },
|
||||
'2026-10-12': { main: 'b', co: null, locked: false },
|
||||
});
|
||||
|
||||
test('roleOn', () => {
|
||||
@@ -26,7 +28,11 @@ test('validateRequest prüft Person, Tag, Einteilung und Partner', () => {
|
||||
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', partnerDate: '2026-10-07' }, persons, p).error, /kein Platz frei/);
|
||||
assert.match(validateRequest({ personId: 'a', date: '2026-10-05', partnerDate: '2026-10-08' }, persons, p).error, /kein Meeting/);
|
||||
assert.match(validateRequest({ personId: 'a', date: '2026-10-05', partnerDate: '2026-10-06' }, persons, p).error, /schon eingeteilt/);
|
||||
const open = validateRequest({ personId: 'a', date: '2026-10-05', partnerDate: '2026-10-09' }, persons, p);
|
||||
assert.deepEqual(open.request, { personId: 'a', date: '2026-10-05', role: 'main', partnerId: null, partnerDate: '2026-10-09', note: '' });
|
||||
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' });
|
||||
@@ -48,8 +54,36 @@ test('applySwap: Partner übernimmt den Tag', () => {
|
||||
assert.deepEqual([p['2026-10-05'].main, p['2026-10-05'].co], ['a', 'c']);
|
||||
});
|
||||
|
||||
test('openSlotFor und canTake beachten Rollen', () => {
|
||||
const p = plan();
|
||||
assert.equal(openSlotFor(p['2026-10-09'], { id: 'a', canMain: true, canCo: true }), 'main');
|
||||
assert.equal(openSlotFor(p['2026-10-12'], { id: 'a', canMain: true, canCo: true }), 'co');
|
||||
assert.equal(openSlotFor(p['2026-10-12'], { id: 'm', canMain: true, canCo: false }), null, 'Nur-Haupt bekommt keinen Neben-Platz');
|
||||
assert.equal(openSlotFor(p['2026-10-09'], { id: 'c', canMain: true, canCo: true }), null, 'schon eingeteilt');
|
||||
assert.equal(openSlotFor(p['2026-10-05'], { id: 'c', canMain: true, canCo: true }), null, 'voll');
|
||||
assert.ok(canTake({ id: 'm', canMain: true, canCo: false }, 'main') && !canTake({ id: 'm', canMain: true, canCo: false }, 'co'));
|
||||
assert.ok(!canTake({ id: 'x', active: false }, 'main'));
|
||||
});
|
||||
|
||||
test('applySwap: offenen Platz übernehmen, alter Platz wird frei gemeldet', () => {
|
||||
const p = plan();
|
||||
const { changes, vacated } = applySwap(p, { personId: 'a', date: '2026-10-05', partnerId: null, partnerDate: '2026-10-09' }, persons);
|
||||
assert.equal(p['2026-10-09'].main, 'a');
|
||||
assert.equal(p['2026-10-05'].main, null);
|
||||
assert.deepEqual(vacated, { date: '2026-10-05', role: 'main' });
|
||||
assert.equal(changes.length, 2);
|
||||
assert.throws(() => applySwap(plan(), { personId: 'a', date: '2026-10-05', partnerId: null, partnerDate: '2026-10-07' }, persons), /kein passender Platz/);
|
||||
});
|
||||
|
||||
test('applySwap prüft Rollen der Beteiligten', () => {
|
||||
const p = plan();
|
||||
// m darf keine Nebenmoderation: Übernahme von b's Neben-Platz am 05.10. scheitert
|
||||
assert.throws(() => applySwap(p, { personId: 'b', date: '2026-10-05', partnerId: 'm', partnerDate: null }, persons), /keine Nebenmoderation/);
|
||||
assert.equal(p['2026-10-05'].co, 'b', 'nichts verändert');
|
||||
});
|
||||
|
||||
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: 'a', date: '2026-10-05', partnerId: null }), /Wunschpartner oder Wunschtag/);
|
||||
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/);
|
||||
|
||||
Reference in new issue
Block a user