Internationalization
This commit is contained in:
+21
-13
@@ -1,3 +1,4 @@
|
||||
import { loadI18n } from '../test-support/i18n.js';
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
@@ -65,6 +66,7 @@ async function loadStore(filesystem = false) {
|
||||
caches: memoryCaches(), crypto, URL, Response, Headers, Blob, Date
|
||||
};
|
||||
context.globalThis = context;
|
||||
await loadI18n(context);
|
||||
vm.runInNewContext(await fs.readFile(path.join(root, 'public/js/offline-storage.js'), 'utf8'), context, { filename: path.join(root, 'public/js/offline-storage.js') });
|
||||
return { context, directory, store: context.Wegwichtel.OfflineStore };
|
||||
}
|
||||
@@ -120,10 +122,10 @@ for (const filesystem of [false, true]) {
|
||||
assert.equal(await (await store.match('/image.png?v=99')).text(), 'first');
|
||||
assert.equal((await store.match('/image.png')).headers.get('Content-Type'), 'image/png');
|
||||
const failed = await store.create();
|
||||
await assert.rejects(store.put(failed, '/image.png', new Response('missing', { status: 404 })), /Download fehlgeschlagen/);
|
||||
await assert.rejects(store.put(failed, '/image.png', new Response('missing', { status: 404 })), /Teil konnte nicht gespeichert werden/);
|
||||
await store.remove(failed.id);
|
||||
assert.equal(await (await store.match('/image.png')).text(), 'first');
|
||||
assert.throws(() => store.key('https://outside.test/image.png'), /dieser App/);
|
||||
assert.throws(() => store.key('https://outside.test/image.png'), /anderen Seiten/);
|
||||
const second = await store.create();
|
||||
await store.put(second, '/image.png', new Response('second'));
|
||||
await store.commit(second);
|
||||
@@ -150,6 +152,7 @@ async function workerHarness() {
|
||||
skipWaiting: async () => {}, clients: { claim: async () => {} }
|
||||
};
|
||||
context.self = context;
|
||||
await loadI18n(context);
|
||||
vm.runInNewContext(await fs.readFile(path.join(root, 'public/offline-worker.js'), 'utf8'), context, { filename: path.join(root, 'public/offline-worker.js') });
|
||||
async function request(url, options) {
|
||||
let response;
|
||||
@@ -222,6 +225,9 @@ async function managerHarness({ supported = true, saved = false } = {}) {
|
||||
await store.put(stage, '/', new Response('old'));
|
||||
await store.commit(stage);
|
||||
}
|
||||
await loadI18n(context);
|
||||
vm.runInNewContext(await fs.readFile(path.join(root, 'public/js/user-messages.js'), 'utf8'), context, { filename: path.join(root, 'public/js/user-messages.js') });
|
||||
await loadI18n(context);
|
||||
vm.runInNewContext(await fs.readFile(path.join(root, 'public/js/offline-cache.js'), 'utf8'), context, { filename: path.join(root, 'public/js/offline-cache.js') });
|
||||
return { context, store, elements, downloaded, manager: context.Wegwichtel.OfflineCache };
|
||||
}
|
||||
@@ -241,7 +247,7 @@ test('offline switch prepares all resources once, persists opt-in and clears onl
|
||||
assert.equal(downloaded.length, 3, 'duplicate resources must not be stored twice');
|
||||
assert.equal(elements.get('offline-cache-toggle').checked, true);
|
||||
assert.equal(elements.get('offline-cache-refresh').hidden, false);
|
||||
assert.match(elements.get('offline-cache-status').textContent, /3 Dateien sind offline verfügbar/);
|
||||
assert.match(elements.get('offline-cache-status').textContent, /Wegwichtel ist für unterwegs bereit/);
|
||||
assert.ok(await store.match('/image.png'));
|
||||
await manager.disable();
|
||||
assert.equal(await store.state(), null);
|
||||
@@ -257,9 +263,9 @@ test('failed refresh preserves the old snapshot and download can be cancelled wi
|
||||
assert.equal(elements.get('offline-cache-toggle').checked, true);
|
||||
const fetchResource = context.fetch;
|
||||
context.fetch = async (url, options) => url.endsWith('/image.png') ? new Response('missing', { status: 404 }) : fetchResource(url, options);
|
||||
await assert.rejects(manager.download(), /Download fehlgeschlagen/);
|
||||
await assert.rejects(manager.download(), /Teil konnte nicht gespeichert werden/);
|
||||
assert.equal(await (await store.match('/')).text(), 'old');
|
||||
assert.match(elements.get('offline-cache-status').textContent, /bisherige Offline-Stand/);
|
||||
assert.match(elements.get('offline-cache-status').textContent, /vorher gespeichert hast/);
|
||||
let started;
|
||||
const downloading = new Promise(resolve => { started = resolve; });
|
||||
context.fetch = (url, options) => new Promise((resolve, reject) => {
|
||||
@@ -279,14 +285,14 @@ test('offline UI handles unsupported browsers and malformed manifests without en
|
||||
const unsupported = await managerHarness({ supported: false });
|
||||
await unsupported.manager.initialize();
|
||||
assert.equal(unsupported.elements.get('offline-cache-toggle').disabled, true);
|
||||
assert.match(unsupported.elements.get('offline-cache-status').textContent, /nicht verfügbar/);
|
||||
assert.match(unsupported.elements.get('offline-cache-status').textContent, /nicht für unterwegs speichern/);
|
||||
const setup = await managerHarness();
|
||||
await setup.manager.initialize();
|
||||
setup.context.fetch = async () => Response.json({ resources: [] });
|
||||
await assert.rejects(setup.manager.download(), /Ungültige Offline/);
|
||||
await assert.rejects(setup.manager.download(), /nicht für unterwegs geladen/);
|
||||
assert.equal(await setup.store.state(), null);
|
||||
setup.context.fetch = async () => new Response('error', { status: 500 });
|
||||
await assert.rejects(setup.manager.download(), /Liste der Offline-Dateien/);
|
||||
await assert.rejects(setup.manager.download(), /nicht für unterwegs geladen/);
|
||||
assert.equal(setup.elements.get('offline-cache-toggle').checked, false);
|
||||
});
|
||||
|
||||
@@ -300,7 +306,7 @@ for (const filesystem of [false, true]) {
|
||||
const stage = await store.create();
|
||||
await store.put(stage, `/api/routes/${id}`, Response.json({ id }));
|
||||
await store.put(stage, `/api/routes/${id}/gpx`, new Response(`gpx${id}`));
|
||||
await store.commit(stage, { id, name: `Route ${id}`, pois: [], points: [] });
|
||||
await store.commit(stage, { id, name: `Strecke ${id}`, pois: [], points: [] });
|
||||
}
|
||||
assert.equal((await store.routes()).length, 2);
|
||||
assert.deepEqual(await (await store.match('/api/routes/1?_=123')).json(), { id: 1 });
|
||||
@@ -332,7 +338,7 @@ test('explicit route download stores only selected GPX/media and failed refresh
|
||||
assert.equal(await (await store.match('/api/routes/7/gpx')).text(), 'bytes:' + origin + '/api/routes/7/gpx');
|
||||
const previous = (await store.routes())[0].id;
|
||||
context.fetch = async url => url === '/api/routes/7' ? Response.json(route) : new Response('full', { status: 507 });
|
||||
await assert.rejects(manager.saveRoute(route), /Download fehlgeschlagen/);
|
||||
await assert.rejects(manager.saveRoute(route), /Teil konnte nicht gespeichert werden/);
|
||||
assert.equal((await store.routes())[0].id, previous);
|
||||
await manager.disable();
|
||||
assert.equal((await store.routes()).length, 1);
|
||||
@@ -360,6 +366,7 @@ test('API starts from selected offline routes and an empty list for app-only sto
|
||||
const app = await store.create();
|
||||
await store.put(app, '/', new Response('shell'));
|
||||
await store.commit(app);
|
||||
await loadI18n(context);
|
||||
vm.runInNewContext(await fs.readFile(path.join(root, 'public/js/api-client.js'), 'utf8'), context);
|
||||
const api = context.Wegwichtel.Api;
|
||||
assert.equal((await api.health()).offline, true);
|
||||
@@ -388,15 +395,16 @@ test('storage gauge uses browser estimate, separates Local Storage and reports q
|
||||
navigator: { storage: { estimate: async () => ({ usage: 95 * 1024 * 1024, quota: 100 * 1024 * 1024 }) } },
|
||||
localStorage: { length: 1, key: () => 'image', getItem: () => 'x'.repeat(2400000) }
|
||||
};
|
||||
await loadI18n(context);
|
||||
vm.runInNewContext(await fs.readFile(path.join(root, 'public/js/storage-usage.js'), 'utf8'), context);
|
||||
const usage = context.Wegwichtel.StorageUsage;
|
||||
await usage.refresh();
|
||||
assert.equal(elements.get('[data-storage-site-meter]').value, 95 * 1024 * 1024);
|
||||
assert.match(elements.get('[data-storage-site-text]').textContent, /95 %.*5 MiB verfügbar.*fast voll/);
|
||||
assert.match(elements.get('[data-storage-local-text]').textContent, /Richtwert.*tatsächliche Grenze/);
|
||||
assert.match(elements.get('[data-storage-site-text]').textContent, /95 %.*5,2 MB frei.*Fast voll/);
|
||||
assert.match(elements.get('[data-storage-local-text]').textContent, /Richtwert.*wirklich hineinpasst/);
|
||||
usage.reportError({ cause: { name: 'QuotaExceededError' } });
|
||||
await usage.refresh();
|
||||
assert.match(elements.get('[data-storage-warning]').textContent, /Speicher voll/);
|
||||
assert.match(elements.get('[data-storage-warning]').textContent, /Platz ist voll/);
|
||||
context.navigator.storage.estimate = async () => { throw new Error('Unavailable'); };
|
||||
await usage.refresh();
|
||||
assert.equal(elements.get('[data-storage-site-meter]').hidden, true);
|
||||
|
||||
Reference in New Issue
Block a user