95 lines
3.0 KiB
JavaScript
95 lines
3.0 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs/promises';
|
|
import path from 'node:path';
|
|
import test from 'node:test';
|
|
import vm from 'node:vm';
|
|
|
|
const root = path.resolve(import.meta.dirname, '..');
|
|
|
|
class MemoryStorage {
|
|
constructor() {
|
|
this.values = new Map();
|
|
}
|
|
|
|
getItem(key) {
|
|
return this.values.has(key) ? this.values.get(key) : null;
|
|
}
|
|
|
|
setItem(key, value) {
|
|
this.values.set(key, String(value));
|
|
}
|
|
|
|
removeItem(key) {
|
|
this.values.delete(key);
|
|
}
|
|
}
|
|
|
|
async function loadModule() {
|
|
const source = await fs.readFile(path.join(root, 'public/js/privacy-storage.js'), 'utf8');
|
|
const localStorage = new MemoryStorage();
|
|
const context = {
|
|
Wegwichtel: {},
|
|
localStorage,
|
|
document: { cookie: '' },
|
|
Date,
|
|
JSON,
|
|
Number,
|
|
Set,
|
|
String,
|
|
Promise,
|
|
setTimeout,
|
|
clearTimeout
|
|
};
|
|
context.globalThis = context;
|
|
vm.runInNewContext(source, context, { filename: path.join(root, 'public/js/privacy-storage.js') });
|
|
return { storage: context.Wegwichtel.PrivacyStorage, localStorage };
|
|
}
|
|
|
|
test('route progress storage is opt-in and deleting the option removes progress data', async () => {
|
|
const { storage, localStorage } = await loadModule();
|
|
assert.equal(storage.isProgressStorageEnabled(), false);
|
|
assert.equal(storage.activateRoute({ id: 7, name: 'Testweg' }), null);
|
|
|
|
storage.setProgressStorageEnabled(true);
|
|
storage.activateRoute({ id: 7, name: 'Testweg' });
|
|
storage.markVisited(7, 11);
|
|
storage.markViewed(7, 12);
|
|
storage.markAudioPlayed(7, 12);
|
|
storage.saveRouteState({ id: 7, name: 'Testweg' }, 'paused', 23, [11], [12], [12]);
|
|
|
|
const route = storage.loadRoute(7);
|
|
assert.equal(route.routeState, 'paused');
|
|
assert.equal(route.routeProgressIndex, 23);
|
|
assert.deepEqual([...route.visitedPoiIds], [11]);
|
|
assert.deepEqual([...route.viewedPoiIds], [12]);
|
|
assert.deepEqual([...route.playedAudioPoiIds], [12]);
|
|
|
|
storage.setProgressStorageEnabled(false);
|
|
assert.equal(storage.isProgressStorageEnabled(), false);
|
|
assert.equal(localStorage.getItem(storage.PROGRESS_KEY), null);
|
|
});
|
|
|
|
test('route progress older than 24 hours is removed with visible loop progress', async () => {
|
|
const { storage, localStorage } = await loadModule();
|
|
storage.setProgressStorageEnabled(true);
|
|
|
|
const oldTimestamp = new Date(Date.now() - storage.MAX_PROGRESS_AGE_MS - 1000).toISOString();
|
|
const freshTimestamp = new Date().toISOString();
|
|
localStorage.setItem(storage.PROGRESS_KEY, JSON.stringify({
|
|
version: 1,
|
|
currentRouteId: 1,
|
|
routes: {
|
|
1: { routeId: 1, routeName: 'Alt', updatedAt: oldTimestamp },
|
|
2: { routeId: 2, routeName: 'Neu', updatedAt: freshTimestamp }
|
|
}
|
|
}));
|
|
|
|
const updates = [];
|
|
const result = await storage.cleanupExpired((removed, total) => updates.push(`${removed} / ${total}`));
|
|
assert.equal(result.removed, 1);
|
|
assert.equal(result.total, 1);
|
|
assert.deepEqual(updates, ['0 / 1', '1 / 1']);
|
|
assert.equal(storage.loadRoute(1), null);
|
|
assert.equal(storage.loadRoute(2).routeName, 'Neu');
|
|
});
|