verstak-browser-extension/scripts/test-background-i18n.js

142 lines
4.3 KiB
JavaScript

#!/usr/bin/env node
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const vm = require('vm');
const root = path.resolve(__dirname, '..');
const catalogs = {
en: JSON.parse(fs.readFileSync(path.join(root, 'shared', 'locales', 'en.json'), 'utf8')),
ru: JSON.parse(fs.readFileSync(path.join(root, 'shared', 'locales', 'ru.json'), 'utf8')),
};
const state = {
settings: {
receiverUrl: 'http://127.0.0.1:47731/api/browser-inbox/v1/captures',
receiverToken: 'paired-token',
language: 'ru',
},
};
let menuTitles = [];
let installedListener;
let messageListener;
const browser = {
storage: {
local: {
get(key) {
if (typeof key === 'string') return Promise.resolve({ [key]: state[key] });
return Promise.resolve({ ...state });
},
set(patch) {
Object.assign(state, patch || {});
return Promise.resolve();
},
},
},
contextMenus: {
removeAll() {
menuTitles = [];
return Promise.resolve();
},
create(item) {
menuTitles.push(item.title);
},
onClicked: { addListener() {} },
},
runtime: {
getURL(relativePath) { return `extension://${relativePath}`; },
onInstalled: { addListener(listener) { installedListener = listener; } },
onMessage: { addListener(listener) { messageListener = listener; } },
},
i18n: { getUILanguage() { return 'en-US'; } },
tabs: {
query() { return Promise.resolve([{ id: 7, windowId: 1, url: 'https://example.com/private-path', title: 'Private title' }]); },
get() { return Promise.resolve({ id: 7, windowId: 1, url: 'https://example.com/private-path', title: 'Private title' }); },
onActivated: { addListener() {} },
onUpdated: { addListener() {} },
onRemoved: { addListener() {} },
},
};
function fetchCatalog(url) {
const locale = /\/ru\.json$/.test(url) ? 'ru' : 'en';
return Promise.resolve({ ok: true, json: () => Promise.resolve(catalogs[locale]) });
}
const context = vm.createContext({
browser,
console,
Date,
Math,
Promise,
URL,
fetch: fetchCatalog,
setTimeout,
clearTimeout,
});
context.globalThis = context;
for (const file of ['hostname.js', 'activity-tracker.js', 'protocol.js', 'api.js', 'queue.js', 'i18n.js', 'background.js']) {
vm.runInContext(fs.readFileSync(path.join(root, 'shared', file), 'utf8'), context, { filename: file });
}
async function flush() {
for (let i = 0; i < 8; i += 1) await Promise.resolve();
}
function sendMessage(message) {
return new Promise((resolve) => {
messageListener(message, {}, resolve);
});
}
(async () => {
installedListener();
await flush();
assert.deepStrictEqual(menuTitles, [
'Отправить страницу в Верстак',
'Отправить выделение в Верстак',
'Отправить ссылку в Верстак',
]);
const trackingState = await sendMessage({
type: 'verstak.capture',
action: 'saveSettings',
settings: {
receiverUrl: state.settings.receiverUrl,
receiverToken: state.settings.receiverToken,
language: 'en',
passiveActivityEnabled: true,
passiveActivityExcludedDomains: [],
},
});
assert.strictEqual(trackingState.settings.passiveActivityEnabled, true);
assert.ok(trackingState.activityState.activeAccumulator['example.com']);
assert.equal(JSON.stringify(trackingState.activityState).includes('private-path'), false);
assert.equal(JSON.stringify(trackingState.activityState).includes('Private title'), false);
const nextState = await sendMessage({
type: 'verstak.capture',
action: 'saveSettings',
settings: {
receiverUrl: state.settings.receiverUrl,
receiverToken: state.settings.receiverToken,
language: 'en',
},
});
await flush();
assert.strictEqual(state.settings.receiverUrl, 'http://127.0.0.1:47731/api/browser-inbox/v1/captures');
assert.strictEqual(state.settings.receiverToken, 'paired-token');
assert.strictEqual(state.settings.language, 'en');
assert.strictEqual(nextState.settings.language, 'en');
assert.deepStrictEqual(menuTitles, [
'Send page to Verstak',
'Send selection to Verstak',
'Send link to Verstak',
]);
console.log('browser extension background localization tests passed');
})().catch((error) => {
console.error(error);
process.exit(1);
});