Prepare Kalendartool for MPM and disable invites

This commit is contained in:
Kühn
2026-10-08 15:06:22 +02:00
parent bc49c3074e
commit 556202575e
50 changed files with 905 additions and 836 deletions

View File

@@ -1,13 +1,12 @@
/**
* Unit-Tests fuer die Kernlogik (plan.md Abschnitt 6 und 19):
* Kollisionspruefung, Invite-Tokens, Validierung, Berechtigungen.
* Kollisionspruefung, Validierung und Berechtigungen.
*
* Bewusst ohne Datenbank: Die Regeln sind reine Funktionen und
* damit ohne PostgreSQL testbar (schnelle Unit-Tests).
*/
import { describe, expect, it } from 'vitest';
import { intervalsOverlap, findConflicts, validateReservationPeriod } from '@/lib/reservations/conflicts';
import { generateInviteToken, hashInviteToken, isInviteUsable, defaultInviteExpiry } from '@/lib/invites/tokens';
import { createReservationSchema } from '@/lib/validation';
import { formatDuration } from '@/lib/reservations/service';
import {
@@ -136,43 +135,6 @@ describe('validateReservationPeriod', () => {
});
});
// ------------------------------------------------------------------- Invites
describe('Invite-Tokens', () => {
it('erzeugt nicht erratbare Tokens', () => {
const token = generateInviteToken();
expect(token).toHaveLength(43); // 32 Bytes base64url
expect(token).not.toContain('=');
});
it('hasht deterministisch und speichert nie den Klartext', () => {
const token = generateInviteToken();
const hash = hashInviteToken(token);
expect(hash).toHaveLength(64);
expect(hash).not.toBe(token);
expect(hashInviteToken(token)).toBe(hash);
});
it('erkennt abgelaufene und verwendete Invites', () => {
const now = new Date('2026-09-18T12:00:00Z');
expect(
isInviteUsable({ expiresAt: new Date('2026-09-01T00:00:00Z'), usedAt: null }, now),
).toBe(false);
expect(
isInviteUsable({ expiresAt: null, usedAt: new Date('2026-09-01T00:00:00Z') }, now),
).toBe(false);
expect(
isInviteUsable({ expiresAt: new Date('2026-09-30T00:00:00Z'), usedAt: null }, now),
).toBe(true);
});
it('setzt die Standard-Ablaufzeit auf 7 Tage', () => {
const now = new Date('2026-09-18T12:00:00Z');
const expiry = defaultInviteExpiry(now);
expect(expiry.getTime() - now.getTime()).toBe(7 * 24 * 60 * 60 * 1000);
});
});
// ------------------------------------------------------------------ Validierung
describe('createReservationSchema', () => {