feat(calendar): show regional holidays and observances
This commit is contained in:
1 parent
87276a051e
commit
533ca2d3a4
23 files changed
+563
-29
No files matched your search
+39
-1
@@ -218,7 +218,7 @@ assert.ok(command('date').message.length > 8);
|
||||
assert.ok(command('time').message.includes(':'));
|
||||
assert.ok(command('datetime').message.length > 12);
|
||||
assert.equal(command('uptime').message, 'terminal.uptime');
|
||||
assert.equal(command('version').message, 'Life OS v1.17.0');
|
||||
assert.equal(command('version').message, 'Life OS v1.18.0');
|
||||
assert.equal(command('status').message, 'terminal.status');
|
||||
assert.match(command('apps').message, /calendar/);
|
||||
assert.equal(command('echo "hello Life OS"').message, 'hello Life OS');
|
||||
@@ -475,4 +475,42 @@ assert.match(await enLogin.text(), /Sign in with ChatGPT/);
|
||||
const localeResponse = await worker.default.fetch(new Request("https://life-os.test/locales/zh-CN.js"), {});
|
||||
assert.equal(localeResponse.status, 200);
|
||||
assert.match(await localeResponse.text(), /window\.LifeOSLocales\['zh-CN'\]/);
|
||||
const invalidHolidays = await worker.default.fetch(new Request('https://life-os.test/api/holidays?country=../../x&year=2026'), {});
|
||||
assert.equal(invalidHolidays.status, 400);
|
||||
const upstreamFetch = globalThis.fetch;
|
||||
const holidayRequests = [];
|
||||
globalThis.fetch = async url => {
|
||||
holidayRequests.push(String(url));
|
||||
if (String(url).endsWith('/countries.json')) return Response.json({ countries: [{ code: 'CN', name: 'China' }, { code: 'FR', name: 'France' }] });
|
||||
return Response.json({ code: 'CN', year: 2026, holidays: [{ date: '2026-10-01', name: 'National Day' }, { date: '2026-10-02', name: 'Day off', observed: true }], working_weekend_days: ['2026-10-10'] });
|
||||
};
|
||||
try {
|
||||
const response = await worker.default.fetch(new Request('https://life-os.test/api/holidays?country=CN&year=2026'), {});
|
||||
assert.equal(response.status, 200);
|
||||
const data = await response.json();
|
||||
assert.equal(data.holidays[1].observed, true);
|
||||
assert.deepEqual(data.workingDays, ['2026-10-10']);
|
||||
assert.equal(holidayRequests[0], 'https://openworkdays.com/api/v1/cn/2026.json');
|
||||
const countryResponse = await worker.default.fetch(new Request('https://life-os.test/api/holiday-countries'), {});
|
||||
assert.equal((await countryResponse.json()).countries[1].code, 'FR');
|
||||
} finally { globalThis.fetch = upstreamFetch; }
|
||||
const holidayStore = makeStorage();
|
||||
const holidayNode = { innerHTML: '' };
|
||||
const holidayContext = vm.createContext({
|
||||
document: { createElement: () => ({}), head: { append() {} } },
|
||||
navigator: { languages: ['en-GB'], language: 'en-GB' }, localStorage: holidayStore,
|
||||
LifeI18n: { t: (key, values = {}) => String(key.split('.').reduce((item, segment) => item?.[segment], assets.localeEn) || key).replace(/\{(\w+)\}/g, (_, name) => values[name] ?? ''), locale: () => 'en-GB', language: () => 'en', dictionaries: { en: assets.localeEn } },
|
||||
mems: () => [], Date, Intl,
|
||||
fetch: async url => ({ ok: true, json: async () => String(url).includes('holiday-countries') ? { countries: [{ code: 'GB', name: 'United Kingdom' }, { code: 'FR', name: 'France' }] } : { holidays: [{ date: '2026-10-01', name: 'National Day' }], workingDays: ['2026-10-10'] } })
|
||||
});
|
||||
holidayContext.window = holidayContext;
|
||||
holidayContext.renderAll = () => holidayContext.calendarApp(holidayNode);
|
||||
vm.runInContext(assets.calendarJs, holidayContext);
|
||||
holidayContext.selectCalendarDate('2026-10-01');
|
||||
await new Promise(resolve => setTimeout(resolve, 0));
|
||||
assert.match(holidayNode.innerHTML, /Auto \(United Kingdom\)/, 'English resolves its browser region');
|
||||
assert.match(holidayNode.innerHTML, /National Day/, 'holiday appears on the selected day');
|
||||
holidayContext.setCalendarHolidayCountry('FR');
|
||||
assert.equal(holidayStore.getItem('lifeos_holiday_country_v1'), 'FR');
|
||||
assert.match(holidayNode.innerHTML, /<option value="FR" selected>/);
|
||||
console.log(`Life OS artifact valid · ${enKeys.length} keys across ${Object.keys(allLocales).length} locales`);
|
||||
Reference in new issue
Block a user