feat: přidání testů – Jest unit testy + Playwright E2E + CI pipeline
Server: - Jest unit testy (88 testů): auth, utils, restaurants, service, voting, pizza - in-memory storage mock pro izolaci testů - oprava race condition při inicializaci Redis (storageReady promise) - dev route dostupná i pro NODE_ENV=test - getStatsMock deterministický (nahrazení Math.random) - exporty interních helperů pro testovatelnost - /api/health endpoint pro Playwright readiness check - tsconfig vylučuje test soubory z produkčního buildu E2E (e2e/): - Playwright s Firefoxem + Chromiem - testy: login, menu, výběr jídla, pizza day životní cyklus, QR/nastavení - trusted-header auth bypass pro testy, video + trace při selhání CI (Woodpecker): - pipeline spouštěna na všech větvích a PR (nejen master) - redis-stack-server service pro E2E – čistý Redis per větev automaticky - kroky: unit testy, build, E2E testy (parallel kde možné) - Docker build zůstává pouze pro master Co-Authored-By: Claude Opus (extra usage) 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import { generateToken, verify, getLogin, getTrusted } from '../auth';
|
||||
|
||||
const VALID_SECRET = 'test-secret-min-32-chars-aaaaaaa!';
|
||||
|
||||
beforeEach(() => {
|
||||
process.env.JWT_SECRET = VALID_SECRET;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
delete process.env.JWT_SECRET;
|
||||
});
|
||||
|
||||
describe('generateToken', () => {
|
||||
test('vrátí token pro platný login', () => {
|
||||
const token = generateToken('alice');
|
||||
expect(typeof token).toBe('string');
|
||||
expect(token.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test('vyhodí chybu bez JWT_SECRET', () => {
|
||||
delete process.env.JWT_SECRET;
|
||||
expect(() => generateToken('alice')).toThrow('JWT_SECRET');
|
||||
});
|
||||
|
||||
test('vyhodí chybu pro příliš krátký JWT_SECRET', () => {
|
||||
process.env.JWT_SECRET = 'short';
|
||||
expect(() => generateToken('alice')).toThrow('32');
|
||||
});
|
||||
|
||||
test('vyhodí chybu pro prázdný login', () => {
|
||||
expect(() => generateToken('')).toThrow('login');
|
||||
expect(() => generateToken(' ')).toThrow('login');
|
||||
});
|
||||
|
||||
test('vyhodí chybu pro chybějící login', () => {
|
||||
expect(() => generateToken(undefined)).toThrow('login');
|
||||
});
|
||||
});
|
||||
|
||||
describe('verify', () => {
|
||||
test('vrátí true pro platný token', () => {
|
||||
const token = generateToken('alice');
|
||||
expect(verify(token)).toBe(true);
|
||||
});
|
||||
|
||||
test('vrátí false pro podvrženou signaturu', () => {
|
||||
const token = generateToken('alice');
|
||||
const tampered = token.slice(0, -5) + 'XXXXX';
|
||||
expect(verify(tampered)).toBe(false);
|
||||
});
|
||||
|
||||
test('vrátí false pro token podepsaný jiným secret', () => {
|
||||
process.env.JWT_SECRET = 'other-secret-min-32-chars-bbbbb!';
|
||||
const tokenOther = generateToken('alice');
|
||||
process.env.JWT_SECRET = VALID_SECRET;
|
||||
expect(verify(tokenOther)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getLogin / getTrusted', () => {
|
||||
test('round-trip: getLogin vrátí správný login', () => {
|
||||
const token = generateToken('bob');
|
||||
expect(getLogin(token)).toBe('bob');
|
||||
});
|
||||
|
||||
test('trusted=false je výchozí hodnota', () => {
|
||||
const token = generateToken('alice');
|
||||
expect(getTrusted(token)).toBe(false);
|
||||
});
|
||||
|
||||
test('trusted=true je zachováno', () => {
|
||||
const token = generateToken('alice', true);
|
||||
expect(getTrusted(token)).toBe(true);
|
||||
});
|
||||
|
||||
test('getLogin vyhodí chybu pro chybějící token', () => {
|
||||
expect(() => getLogin(undefined)).toThrow('token');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user