Files
OneCAD-Draft/scripts/test_site.cjs

58 lines
3.0 KiB
JavaScript

// Run with node scripts/test_site.cjs dist/site.js.
const assert = require('node:assert/strict');
const fs = require('node:fs');
const vm = require('node:vm');
const source = fs.readFileSync(process.argv[2] || 'dist/site.js', 'utf8');
function visit(language, pathname = '/', saved, blocked = false) {
let redirected, menuOpen = true, focused = false;
const handlers = {};
const picker = { removeAttribute: () => { menuOpen = false; }, querySelector: () => ({ focus: () => { focused = true; } }) };
const context = {
navigator: { language },
location: { pathname, search: '?ref=test', hash: '#formats', replace: url => { redirected = url; } },
document: { addEventListener: (type, listener) => { handlers[type] = listener; }, querySelector: () => menuOpen ? picker : null },
localStorage: {
getItem: () => { if (blocked) throw new Error('Storage disabled'); return saved; },
setItem: (key, value) => { if (blocked) throw new Error('Storage disabled'); saved = value; },
},
};
vm.runInNewContext(source, context);
return { context, redirected, choose: tag => handlers.click({ target: { closest: () => ({ hreflang: tag }) } }), saved: () => saved,
dismiss: () => handlers.click({ target: { closest: () => null } }), escape: () => handlers.keydown({ key: 'Escape' }),
menuOpen: () => menuOpen, focused: () => focused };
}
for (const [language, expected] of Object.entries({
'tr-TR': 'tr-TR', 'tr-CY': 'tr-TR', 'TR': 'tr-TR', 'pt-PT': 'pt-BR',
'zh-Hant': 'zh-TW', 'zh-Hant-HK': 'zh-TW', 'zh-HK': 'zh-TW', 'zh-MO': 'zh-TW',
'zh-Hans-SG': 'zh-CN', 'en-GB': 'en-US', 'sv-SE': 'en-US', '': 'en-US',
})) {
const result = visit(language);
assert.equal(result.context.preferredLocale(language), expected);
assert.equal(result.redirected, expected === 'en-US' ? undefined : `/${expected}/?ref=test#formats`);
}
const context = visit('en-US').context;
for (const locale of vm.runInNewContext('SITE_LOCALES', context)) {
assert.equal(context.preferredLocale(locale), locale);
}
assert.equal(visit('tr-TR', '/', 'en-US').redirected, undefined);
assert.equal(visit('sv-SE', '/', 'tr-TR').redirected, '/tr-TR/?ref=test#formats');
assert.equal(visit('tr-TR', '/', '../../unsafe').redirected, '/tr-TR/?ref=test#formats');
assert.equal(visit('tr-TR', '/en-US/', undefined, true).redirected, undefined);
assert.equal(visit('en-US', '/tr-TR/').redirected, undefined);
assert.equal(visit('tr-TR', '/', undefined, true).redirected, '/tr-TR/?ref=test#formats');
assert.equal(visit('tr-TR', '/index.html').redirected, '/tr-TR/?ref=test#formats');
const choice = visit('en-US');
choice.choose('tr-TR');
assert.equal(choice.saved(), 'tr-TR');
visit('en-US', '/', undefined, true).choose('en-US');
const outside = visit('en-US');
outside.dismiss();
assert.equal(outside.menuOpen(), false);
const keyboard = visit('en-US');
keyboard.escape();
assert.equal(keyboard.menuOpen(), false);
assert.equal(keyboard.focused(), true);
console.log('Website language matching, redirects, manual choices and blocked storage passed');