Files
Luncher/server/src/tests/service.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

79 lines
2.7 KiB
TypeScript

const mockStorageData = new Map<string, any>();
jest.mock('../storage', () => ({
__esModule: true,
default: () => ({
hasData: async (key: string) => mockStorageData.has(key),
getData: async <T>(key: string) => mockStorageData.get(key) as T,
setData: async <T>(key: string, val: T) => void mockStorageData.set(key, val),
}),
storageReady: Promise.resolve(),
}));
import { getDateForWeekIndex, getMenuKey, getEmptyData } from '../service';
import { formatDate } from '../utils';
// MOCK_DATA=true pins "today" to 2025-01-10 (Friday, week 2)
// Monday of that week = 2025-01-06, ..., Friday = 2025-01-10
describe('getDateForWeekIndex', () => {
test('index 0 (pondělí) vrátí 2025-01-06', () => {
expect(formatDate(getDateForWeekIndex(0))).toBe('2025-01-06');
});
test('index 4 (pátek) vrátí 2025-01-10', () => {
expect(formatDate(getDateForWeekIndex(4))).toBe('2025-01-10');
});
test('index 2 (středa) vrátí 2025-01-08', () => {
expect(formatDate(getDateForWeekIndex(2))).toBe('2025-01-08');
});
test('neplatný index (-1) vrátí dnešek bez vyhození chyby', () => {
const result = getDateForWeekIndex(-1);
expect(result).toBeInstanceOf(Date);
});
test('neplatný index (5) vrátí dnešek bez vyhození chyby', () => {
const result = getDateForWeekIndex(5);
expect(result).toBeInstanceOf(Date);
});
});
describe('getMenuKey', () => {
test('vrátí klíč ve tvaru menu_RRRR_TT', () => {
const date = new Date('2025-01-10');
const key = getMenuKey(date);
expect(key).toMatch(/^menu_\d{4}_\d+$/);
});
test('dvě data ve stejném týdnu mají stejný klíč', () => {
expect(getMenuKey(new Date('2025-01-06'))).toBe(getMenuKey(new Date('2025-01-10')));
});
test('dvě data z různých týdnů mají různé klíče', () => {
expect(getMenuKey(new Date('2025-01-06'))).not.toBe(getMenuKey(new Date('2025-01-13')));
});
});
describe('getEmptyData', () => {
test('vrátí strukturu s prázdnými choices', () => {
const data = getEmptyData(new Date('2025-01-10'));
expect(data.choices).toEqual({});
});
test('vrátí dayIndex=4 pro pátek', () => {
const data = getEmptyData(new Date('2025-01-10'));
expect(data.dayIndex).toBe(4);
});
test('isWeekend=false pro pracovní den', () => {
const data = getEmptyData(new Date('2025-01-10'));
expect(data.isWeekend).toBe(false);
});
test('isWeekend=true pro víkend', () => {
const data = getEmptyData(new Date('2025-01-11'));
expect(data.isWeekend).toBe(true);
});
});