const mockStorageData = new Map(); jest.mock('../storage', () => ({ __esModule: true, default: () => ({ hasData: async (key: string) => mockStorageData.has(key), getData: async (key: string) => mockStorageData.get(key) as T, setData: async (key: string, val: T) => void mockStorageData.set(key, val), }), storageReady: Promise.resolve(), })); const mockGetMenuTechTower = jest.fn(); jest.mock('../restaurants', () => ({ ...jest.requireActual('../restaurants'), getMenuTechTower: (...args: any[]) => mockGetMenuTechTower(...args), })); import { getMenuKey, getRestaurantMenu } from '../service'; // Středa 2025-01-08 (týden 2025-02) const STREDA = new Date('2025-01-08T10:00:00'); const HODINA = 60 * 60 * 1000; /** Menu jednoho dne se všemi náležitostmi, aby nevznikala jiná varování. */ const denniMenu = (nazev: string) => [ { amount: '-', name: `Polévka ${nazev}`, price: '30 Kč', isSoup: true }, { amount: '-', name: nazev, price: '150 Kč', isSoup: false }, ]; /** Naplní storage týdenním menu TechTower s předaným příznakem zastaralosti. */ const seedWeekMenu = (isStale: boolean, lastUpdate: number) => { const week = [0, 1, 2, 3, 4].map(i => ({ TECHTOWER: { lastUpdate, closed: false, isStale, food: denniMenu(`Jídlo z minulého týdne ${i}`), }, })); mockStorageData.set(getMenuKey(STREDA), week); }; describe('getRestaurantMenu – obnovení dat z minulého týdne', () => { beforeAll(() => { jest.useFakeTimers(); jest.setSystemTime(STREDA); }); afterAll(() => { jest.useRealTimers(); }); beforeEach(() => { mockStorageData.clear(); mockGetMenuTechTower.mockReset(); }); test('zastaralá data se znovu načtou a varování zmizí', async () => { seedWeekMenu(true, Date.now() - 2 * HODINA); mockGetMenuTechTower.mockResolvedValue([0, 1, 2, 3, 4].map(i => denniMenu(`Aktuální jídlo ${i}`))); const menu = await getRestaurantMenu('TECHTOWER', STREDA); expect(mockGetMenuTechTower).toHaveBeenCalledTimes(1); expect(menu.isStale).toBe(false); expect(menu.food?.[1].name).toBe('Aktuální jídlo 2'); expect(menu.warnings).not.toContain('Data jsou z minulého týdne'); }); test('aktuální data se znovu nenačítají', async () => { seedWeekMenu(false, Date.now() - 2 * HODINA); const menu = await getRestaurantMenu('TECHTOWER', STREDA); expect(mockGetMenuTechTower).not.toHaveBeenCalled(); expect(menu.warnings).toEqual([]); }); test('zastaralá data se neobnovují častěji než jednou za hodinu', async () => { seedWeekMenu(true, Date.now() - 5 * 60 * 1000); const menu = await getRestaurantMenu('TECHTOWER', STREDA); expect(mockGetMenuTechTower).not.toHaveBeenCalled(); expect(menu.warnings).toContain('Data jsou z minulého týdne'); }); });