Files
bricktrack/tests/unit/tokens.test.ts
unknownandClaude Opus 5 b0152b8667 test: unit-tests der kernlogik und playwright-smoke-test
50 Unit-Tests mit Vitest fuer die Stellen, an denen ein Fehler teuer
waere: Besitzstatus, Mehrfachauswahl inklusive Ueberspringen von
Dubletten und bereits besessenen Sets, Token-Erzeugung und -Vergleich,
Cent-Umrechnung und Slugs.

Der Playwright-Smoke-Test laeuft den ganzen Weg: Registrierung des
ersten Nutzers, Hersteller anlegen, Set anlegen, auf eine neue
Wunschliste setzen, Link holen und als Besucher ohne Konto reservieren.
Er nutzt ein eigenes Datenverzeichnis (./data-e2e), das vor jedem Lauf
geleert wird.

Dabei aufgefallen und behoben: eine spontan aus dem Katalog angelegte
Wunschliste war nicht teilbar, weil das Feld isPublic ohne Formular
auf false fiel. Ausserdem ist das Sternchen an Pflichtfeldern jetzt
aria-hidden, damit der zugaengliche Name des Feldes sauber bleibt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-06 23:31:21 +02:00

53 lines
1.7 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { createToken, hashToken, tokensMatch, TOKEN_BYTES } from '@/lib/tokens';
describe('Token-Erzeugung', () => {
it('erzeugt 32 Byte Zufall als base64url', () => {
const token = createToken();
expect(TOKEN_BYTES).toBe(32);
expect(Buffer.from(token, 'base64url')).toHaveLength(32);
// base64url darf nicht in URLs escaped werden muessen.
expect(token).toMatch(/^[A-Za-z0-9_-]+$/);
});
it('erzeugt bei jedem Aufruf einen anderen Token', () => {
const tokens = new Set(Array.from({ length: 500 }, () => createToken()));
expect(tokens.size).toBe(500);
});
});
describe('Token-Hashing', () => {
it('liefert einen stabilen SHA-256-Hex-Hash', () => {
const hash = hashToken('beispiel');
expect(hash).toHaveLength(64);
expect(hash).toMatch(/^[0-9a-f]+$/);
expect(hashToken('beispiel')).toBe(hash);
});
it('speichert den Klartext nirgends im Hash', () => {
expect(hashToken('geheim')).not.toContain('geheim');
});
it('erkennt den passenden Token', () => {
const token = createToken();
expect(tokensMatch(token, hashToken(token))).toBe(true);
});
it('weist einen falschen Token ab', () => {
expect(tokensMatch(createToken(), hashToken(createToken()))).toBe(false);
});
it('weist einen fehlenden Hash ab, statt zu vertrauen', () => {
const token = createToken();
expect(tokensMatch(token, null)).toBe(false);
expect(tokensMatch(token, undefined)).toBe(false);
expect(tokensMatch(token, '')).toBe(false);
});
it('weist einen Hash falscher Laenge ab, ohne zu werfen', () => {
expect(tokensMatch(createToken(), 'abc')).toBe(false);
});
});