import test from 'node:test'; import assert from 'node:assert/strict'; import { readFile } from 'node:fs/promises'; async function load(relative) { const source = await readFile(new URL(relative, import.meta.url), 'utf8'); return import('data:text/javascript;base64,' + Buffer.from(source).toString('base64')); } const ui = await load('../common/roomCalendarUi.js'); const normalizer = await load('../common/normalizeApiKeys.js'); const api = await load('../api/roomCalendarApi.js'); const configApi = await load('../api/configApi.js'); const weekdayLabels = ['SUN','MON','TUE','WED','THU','FRI','SAT']; test('API routes preserve auth and request-task options through Daylight transport', async () => { const calls = []; globalThis.uni = { $u: { http: { post: (...args) => { calls.push(['POST',...args]); return Promise.resolve('ok'); }, get: (...args) => { calls.push(['GET',...args]); return Promise.resolve('ok'); } }}}; try { const params = { Property:'MO', RoomType:'SUITE', PlayerId:'123' }; const options = { custom:{auth:true}, getTask:()=>{} }; await api.requestRoomCalendar(params,options); await api.getPlayerRoomQualification(params,options); await api.getPropertiesRoomTypes({},options); await configApi.getCalendarSetting({},options); await configApi.getCfgSettingByKey({keyName:'MACAU_STRING'},options); assert.equal(calls[0][1],'/app/room_calendar/request_room_calendar'); assert.equal(calls[1][1],calls[0][1]); assert.equal(calls[0][2],params); assert.equal(calls[0][3],options); assert.equal(calls[2][1],'/app/room_calendar/get_properties_room_types'); assert.equal(calls[2][2].custom,options.custom); assert.equal(calls[2][2].getTask,options.getTask); assert.equal(calls[3][1],'/app/setting/get_calendar_setting'); assert.equal(calls[3][3],options); assert.equal(calls[4][1],'/web/setting/get_public_setting_by_key'); } finally { delete globalThis.uni; } }); test('PascalCase normalization preserves nested values and input objects', () => { const original = { Records:[{RoomType:'SUITE',RoomCount:0,Nested:{Enabled:false}}],Data:null }; const snapshot = structuredClone(original); assert.deepEqual(normalizer.normalizeApiKeys(original), {records:[{roomType:'SUITE',roomCount:0,nested:{enabled:false}}],data:null}); assert.deepEqual(original,snapshot); assert.deepEqual(normalizer.getApiRecords(original),original.Records); assert.deepEqual(normalizer.getApiRecords({records:[1]}),[1]); assert.deepEqual(normalizer.getApiRecords({Records:{}}),[]); assert.equal(normalizer.normalizeApiKeys(null),null); }); test('cross-year range has unique month-owned weeks and no visible out-of-range dates', () => { const months = ui.buildCalendarDateRange({ today:'2026-12-31',startDate:'2026-12-30',endDate:'2027-01-02',weekdayLabels }); assert.deepEqual(months.map(m=>m.monthKey),['2026-12','2027-01']); const weeks = ui.buildContinuousCalendarWeeks(months); assert.equal(new Set(weeks.map(w=>w.weekId)).size,weeks.length); assert.deepEqual(weeks.flatMap(w=>w.days).filter(d=>!d.isOutsideMonth).map(d=>d.date), ['2026-12-30','2026-12-31','2027-01-01','2027-01-02']); assert.equal(ui.getTodayWeekId(months),'week-2026-12-2026-12-27'); const firstDate = months[0].weeks[0].days[0].date; weeks[0].days[0].date = 'changed'; assert.equal(months[0].weeks[0].days[0].date,firstDate); }); test('leap day is retained and adjacent month cells remain blank', () => { const months = ui.buildCalendarDateRange({ today:'2028-02-29',startDate:'2028-02-28',endDate:'2028-03-01',weekdayLabels }); const days = ui.buildContinuousCalendarWeeks(months).flatMap(w=>w.days); assert.deepEqual(days.filter(d=>!d.isOutsideMonth).map(d=>d.date), ['2028-02-28','2028-02-29','2028-03-01']); assert.equal(days.filter(d=>d.isToday).length,1); assert.ok(days.filter(d=>d.isOutsideMonth).every(d=>d.dayNo==='')); }); test('both response casings map dates counts qualification and leader consistently', () => { const upper = {Date:'2026-09-10T00:00:00',RoomType:'SUITE',RoomCriteria:1200, RoomCount:'2',PropertyLeader:'Leader',BookingDateQualificationFlag:'1'}; const lower = normalizer.normalizeApiKeys(upper); const expected = {'2026-09-10_SUITE':{criteria:'1,200',count:2,leader:'Leader', qualified:true,statusText:'Qualified'}}; assert.deepEqual(ui.mapRoomCalendarQualificationRecords([upper]),expected); assert.deepEqual(ui.mapRoomCalendarQualificationRecords([lower]),expected); assert.deepEqual(ui.mapRoomCalendarQualificationRecords([{Date:'',RoomType:'X'}]),{}); }); test('zero availability and denied qualification are preserved', () => { const mapped = ui.mapRoomCalendarQualificationRecords([{ date:'2026-09-10',roomType:'X',roomCount:0,roomCriteria:null, bookingDateQualificationFlag:0,leader:'Fallback' }])['2026-09-10_X']; assert.equal(mapped.criteria,'-'); assert.equal(mapped.leader,'Fallback'); assert.equal(ui.getAvailabilityStatusClass(mapped),'zero'); assert.equal(ui.getCriteriaStatusClass(mapped),'unqualified'); });