Validiere Inhalt in loadSession statt nur Array-Form

loadSession pruefte bisher nur, ob stacks/entries Arrays sind, nicht
deren Inhalt. Ein fremder oder verfaelschter Eintrag unter dem
gleichen Schluessel kam dadurch als vermeintlich gueltige Sitzung
durch und liess die App beim naechsten Scan mit TypeError abstuerzen
(stack.spec fehlte). Falsch typisierte Felder (nextEntryId als String,
stack.count als String) wurden ebenfalls durchgereicht und verdarben
die Sitzung lautlos (doppelte entryIds, "3" + 1 = "31").

loadSession verlangt jetzt, dass nextEntryId eine endliche Zahl ist
und dass jeder Stapel/Eintrag ein echtes Objekt (kein Array, nicht
null) mit den Feldern ist, die session.js tatsaechlich weiterverwendet.
Schlaegt eine Pruefung fehl, liefert loadSession null - ein halb
brauchbarer Zustand wird nicht repariert oder teilweise uebernommen.
This commit is contained in:
vchuser
2026-07-28 16:03:23 +02:00
parent 4d896702d1
commit 5fea22a8c1
2 changed files with 121 additions and 2 deletions
+82 -1
View File
@@ -1,7 +1,13 @@
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { saveSession, loadSession, clearSession } from '../src/storage.js';
import { createSession, commitAssignment } from '../src/session.js';
import {
createSession,
commitAssignment,
proposeAssignment,
moveEntry,
removeEntry,
} from '../src/session.js';
import { emptySpec } from '../src/spec.js';
function fakeStore() {
@@ -52,3 +58,78 @@ test('Sichern ohne funktionierenden Speicher wirft nicht', () => {
};
assert.doesNotThrow(() => saveSession(createSession(), kaputt));
});
test('stacks mit Nicht-Objekten liefert null', () => {
const store = fakeStore();
store.setItem('ram-sortierhilfe:session', JSON.stringify({
stacks: ['x', 'y'],
entries: [],
nextEntryId: 1,
}));
assert.equal(loadSession(store), null);
});
test('fehlender nextEntryId liefert null', () => {
const store = fakeStore();
store.setItem('ram-sortierhilfe:session', JSON.stringify({
stacks: [],
entries: [],
}));
assert.equal(loadSession(store), null);
});
test('nextEntryId als Zeichenkette liefert null', () => {
const store = fakeStore();
store.setItem('ram-sortierhilfe:session', JSON.stringify({
stacks: [],
entries: [],
nextEntryId: '2',
}));
assert.equal(loadSession(store), null);
});
test('Stapel mit Zaehler als Zeichenkette liefert null', () => {
const store = fakeStore();
store.setItem('ram-sortierhilfe:session', JSON.stringify({
stacks: [{ id: 'A', count: '3', spec: emptySpec() }],
entries: [],
nextEntryId: 1,
}));
assert.equal(loadSession(store), null);
});
test('Eintrag ohne Spec liefert null', () => {
const store = fakeStore();
store.setItem('ram-sortierhilfe:session', JSON.stringify({
stacks: [],
entries: [{ entryId: 1, stackId: 'A' }],
nextEntryId: 2,
}));
assert.equal(loadSession(store), null);
});
test('nach Sichern und Laden funktioniert Weiterarbeiten weiterhin', () => {
const store = fakeStore();
const session = createSession();
const spec = { ...emptySpec(), capacityGb: 64 };
commitAssignment(session, spec, 'barcode', 'A');
const zweiterEintrag = commitAssignment(session, spec, 'barcode', 'A');
saveSession(session, store);
const wieder = loadSession(store);
const vorschlag = proposeAssignment(wieder, spec);
assert.equal(vorschlag.kind, 'match');
assert.equal(vorschlag.stackId, 'A');
commitAssignment(wieder, spec, 'barcode', vorschlag.stackId);
assert.equal(wieder.stacks[0].count, 3);
assert.equal(wieder.nextEntryId, 4);
moveEntry(wieder, zweiterEintrag.entryId, 'B');
assert.equal(wieder.stacks.find((s) => s.id === 'A').count, 2);
assert.equal(wieder.stacks.find((s) => s.id === 'B').count, 1);
removeEntry(wieder, zweiterEintrag.entryId);
assert.equal(wieder.entries.find((e) => e.entryId === zweiterEintrag.entryId), undefined);
assert.equal(wieder.stacks.find((s) => s.id === 'B'), undefined);
});