Files
Luncher/server/src/tests/restaurants.test.ts
T
batmanisko fe6bb3290e
ci/woodpecker/push/workflow Pipeline was canceled
ci/woodpecker/pr/workflow Pipeline failed
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>
2026-04-29 00:25:22 +02:00

107 lines
3.5 KiB
TypeScript

import { isTextSoupName, capitalize, sanitizeText, parseAllergens } from '../restaurants';
describe('isTextSoupName', () => {
test('rozpozná "polévka"', () => {
expect(isTextSoupName('Polévka dne')).toBe(true);
});
test('rozpozná "česnečka"', () => {
expect(isTextSoupName('Česnečka s krutony')).toBe(true);
});
test('rozpozná "vývar"', () => {
expect(isTextSoupName('Hovězí vývar s nudlemi')).toBe(true);
});
test('rozpozná "slepičí s " (parciální shoda pro slepičí vývar)', () => {
expect(isTextSoupName('Slepičí s nudlemi')).toBe(true);
});
test('neklasifikuje hlavní jídlo jako polévku', () => {
expect(isTextSoupName('Svíčková na smetaně s knedlíky')).toBe(false);
});
test('neklasifikuje prázdný řetězec', () => {
expect(isTextSoupName('')).toBe(false);
});
test('není case-sensitive', () => {
expect(isTextSoupName('POLÉVKA DNEŠKA')).toBe(true);
});
});
describe('capitalize', () => {
test('zformátuje první písmeno na velké', () => {
expect(capitalize('svíčková')).toBe('Svíčková');
});
test('nechá velká písmena beze změny', () => {
expect(capitalize('ABC')).toBe('ABC');
});
test('prázdný řetězec zůstane prázdný', () => {
expect(capitalize('')).toBe('');
});
test('jednoznakový řetězec', () => {
expect(capitalize('a')).toBe('A');
});
});
describe('sanitizeText', () => {
test('odstraní tabulátor (první výskyt)', () => {
// replace('\t', '') odstraní tab bez přidání mezery
expect(sanitizeText('\tKnedlíky')).toBe('Knedlíky');
});
test('nahradí první " , " za ", "', () => {
// replace(' , ', ', ') nahrazuje pouze první výskyt
expect(sanitizeText('Knedlíky , zelí')).toBe('Knedlíky, zelí');
});
test('ořízne okrajové mezery', () => {
expect(sanitizeText(' Jídlo ')).toBe('Jídlo');
});
test('kombinace: tab + mezera okolo čárky', () => {
expect(sanitizeText('\tKnedlíky , zelí ')).toBe('Knedlíky, zelí');
});
});
describe('parseAllergens', () => {
test('extrahuje alergeny na konci řetězce', () => {
const result = parseAllergens('Svíčková 1,3,7');
expect(result.cleanName).toBe('Svíčková');
expect(result.allergens).toEqual([1, 3, 7]);
});
test('toleruje mezery okolo čárek v alergenech', () => {
const result = parseAllergens('Řízek 1, 3, 7');
expect(result.allergens).toEqual([1, 3, 7]);
});
test('vrátí prázdná pole pro jídlo bez alergenů', () => {
const result = parseAllergens('Ovocný salát');
expect(result.cleanName).toBe('Ovocný salát');
expect(result.allergens).toEqual([]);
});
test('nesplete se s číslem uprostřed názvu', () => {
const result = parseAllergens('Jídlo č. 5 bez alergenů');
expect(result.cleanName).toBe('Jídlo č. 5 bez alergenů');
expect(result.allergens).toEqual([]);
});
test('single alergen', () => {
const result = parseAllergens('Houby 7');
expect(result.cleanName).toBe('Houby');
expect(result.allergens).toEqual([7]);
});
test('prázdný řetězec vrátí prázdné výsledky', () => {
const result = parseAllergens('');
expect(result.cleanName).toBe('');
expect(result.allergens).toEqual([]);
});
});