const { test } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); const vm = require('node:vm'); const html = fs.readFileSync('index.html', 'utf8'); const calendar = html.slice(html.indexOf(' function viennaDate('), html.indexOf(" // Today's hours in hero card")); const context = vm.createContext({ Intl, Date }); vm.runInContext(calendar, context); test('closures include boundaries and cross years without repeating annually', () => { const closures = [{ start: '2026-12-28', end: '2027-01-03' }]; for (const date of ['2026-12-28', '2026-12-31', '2027-01-01', '2027-01-03']) { assert.equal(context.isClosureDay(date, closures), true, date); } for (const date of ['2026-12-27', '2027-01-04', '2027-12-28']) { assert.equal(context.isClosureDay(date, closures), false, date); } assert.equal(context.isClosureDay('2026-10-14', []), false); }); test('Vienna date remains correct around midnight and daylight saving time', () => { assert.equal(context.viennaDate(new Date('2026-10-13T22:30:00Z')), '2026-10-14'); assert.equal(context.viennaDate(new Date('2026-12-31T23:30:00Z')), '2027-01-01'); assert.equal(context.viennaDate(new Date('2026-03-29T22:30:00Z')), '2026-03-30'); }); test('national holidays include fixed and movable holidays in 2026 and 2027', () => { for (const date of ['2026-01-01', '2026-01-06', '2026-04-06', '2026-05-01', '2026-05-14', '2026-05-25', '2026-06-04', '2026-08-15', '2026-10-26', '2026-11-01', '2026-12-08', '2026-12-25', '2026-12-26', '2027-03-29', '2027-05-06', '2027-05-17', '2027-05-27']) { assert.equal(context.isPublicHoliday(date), true, date); } for (const date of ['2026-10-14', '2026-04-03', '2026-11-15', '2026-12-24', '2027-04-06']) { assert.equal(context.isPublicHoliday(date), false, date); } }); for (const file of ['index.html', 'impressum.html']) { test(`${file}: scripts work when browser storage is blocked; menu and font states stay accessible`, () => { const source = fs.readFileSync(file, 'utf8'); const elements = new Map(); const getElement = id => { if (!elements.has(id)) elements.set(id, { attrs: { 'aria-expanded': 'false' }, listeners: {}, classList: { toggle() {}, remove() {} }, setAttribute(key, value) { this.attrs[key] = value; }, getAttribute(key) { return this.attrs[key]; }, addEventListener(event, callback) { this.listeners[event] = callback; }, querySelectorAll() { return []; }, focus() { this.focused = true; } }); return elements.get(id); }; const document = { body: getElement('body'), getElementById: getElement, addEventListener() {} }; const sandbox = vm.createContext({ document, Intl, Date, setInterval() {}, localStorage: { getItem() { throw Error('blocked'); }, setItem() { throw Error('blocked'); } }, window: { matchMedia() { return { addEventListener() {} }; } } }); const scripts = [...source.matchAll(/