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.
136 lines
4.0 KiB
JavaScript
136 lines
4.0 KiB
JavaScript
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { saveSession, loadSession, clearSession } from '../src/storage.js';
|
|
import {
|
|
createSession,
|
|
commitAssignment,
|
|
proposeAssignment,
|
|
moveEntry,
|
|
removeEntry,
|
|
} from '../src/session.js';
|
|
import { emptySpec } from '../src/spec.js';
|
|
|
|
function fakeStore() {
|
|
const data = new Map();
|
|
return {
|
|
data,
|
|
getItem: (key) => (data.has(key) ? data.get(key) : null),
|
|
setItem: (key, value) => data.set(key, value),
|
|
removeItem: (key) => data.delete(key),
|
|
};
|
|
}
|
|
|
|
test('leerer Speicher liefert null', () => {
|
|
assert.equal(loadSession(fakeStore()), null);
|
|
});
|
|
|
|
test('Sitzung ueberlebt Sichern und Laden', () => {
|
|
const store = fakeStore();
|
|
const session = createSession();
|
|
commitAssignment(session, { ...emptySpec(), capacityGb: 64 }, 'barcode', 'A');
|
|
saveSession(session, store);
|
|
|
|
const wieder = loadSession(store);
|
|
assert.equal(wieder.stacks.length, 1);
|
|
assert.equal(wieder.stacks[0].count, 1);
|
|
assert.equal(wieder.entries[0].spec.capacityGb, 64);
|
|
assert.equal(wieder.nextEntryId, 2);
|
|
});
|
|
|
|
test('clearSession raeumt auf', () => {
|
|
const store = fakeStore();
|
|
saveSession(createSession(), store);
|
|
clearSession(store);
|
|
assert.equal(loadSession(store), null);
|
|
});
|
|
|
|
test('kaputter Inhalt liefert null statt einer Ausnahme', () => {
|
|
const store = fakeStore();
|
|
store.setItem('ram-sortierhilfe:session', '{kein json');
|
|
assert.equal(loadSession(store), null);
|
|
});
|
|
|
|
test('Sichern ohne funktionierenden Speicher wirft nicht', () => {
|
|
const kaputt = {
|
|
getItem: () => null,
|
|
setItem: () => { throw new Error('quota exceeded'); },
|
|
removeItem: () => {},
|
|
};
|
|
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);
|
|
});
|