101 lines
3.7 KiB
JavaScript
101 lines
3.7 KiB
JavaScript
import { describe, expect, it, vi } from 'vitest';
|
|
|
|
import { AUDIO, STORAGE_KEYS } from '../../app/static/js/config.js';
|
|
import { SafeStorage, Settings } from '../../app/static/js/systems/Settings.js';
|
|
|
|
/** Einfacher localStorage-Ersatz. */
|
|
function memoryBackend(initial = {}) {
|
|
const data = new Map(Object.entries(initial));
|
|
return {
|
|
getItem: (key) => (data.has(key) ? data.get(key) : null),
|
|
setItem: (key, value) => data.set(key, String(value)),
|
|
data,
|
|
};
|
|
}
|
|
|
|
/** localStorage, der jeden Zugriff verweigert (z. B. blockierte Website-Daten). */
|
|
const throwingBackend = {
|
|
getItem: () => {
|
|
throw new Error('SecurityError');
|
|
},
|
|
setItem: () => {
|
|
throw new Error('QuotaExceededError');
|
|
},
|
|
};
|
|
|
|
describe('SafeStorage', () => {
|
|
it('speichert JSON-Werte', () => {
|
|
const storage = new SafeStorage(memoryBackend());
|
|
expect(storage.set('a', { x: 1 })).toBe(true);
|
|
expect(storage.get('a', null)).toEqual({ x: 1 });
|
|
});
|
|
|
|
it('liefert den Standardwert bei fehlenden oder kaputten Einträgen', () => {
|
|
const storage = new SafeStorage(memoryBackend({ kaputt: '{nicht json' }));
|
|
expect(storage.get('fehlt', 42)).toBe(42);
|
|
expect(storage.get('kaputt', 'fallback')).toBe('fallback');
|
|
});
|
|
|
|
it('funktioniert ohne localStorage für die laufende Sitzung weiter', () => {
|
|
for (const backend of [null, throwingBackend]) {
|
|
const storage = new SafeStorage(backend);
|
|
expect(storage.set('k', 'v')).toBe(false);
|
|
expect(storage.get('k', null)).toBe('v');
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('Settings', () => {
|
|
it('merkt sich die Disclaimer-Bestätigung', () => {
|
|
const backend = memoryBackend();
|
|
const settings = new Settings(new SafeStorage(backend));
|
|
expect(settings.isDisclaimerAccepted()).toBe(false);
|
|
settings.acceptDisclaimer();
|
|
expect(new Settings(new SafeStorage(backend)).isDisclaimerAccepted()).toBe(true);
|
|
expect(backend.data.get(STORAGE_KEYS.disclaimerAccepted)).toBe('true');
|
|
});
|
|
|
|
it('startet mit Standardlautstärken und begrenzt Werte auf 0..1', () => {
|
|
const settings = new Settings(new SafeStorage(memoryBackend()));
|
|
expect(settings.getVolume('music')).toBe(AUDIO.defaultVolumes.music);
|
|
settings.setVolume('music', 5);
|
|
expect(settings.getVolume('music')).toBe(1);
|
|
settings.setVolume('sfx', -1);
|
|
expect(settings.getVolume('sfx')).toBe(0);
|
|
settings.setVolume('sfx', Number.NaN);
|
|
expect(settings.getVolume('sfx')).toBe(0);
|
|
});
|
|
|
|
it('ignoriert ungültige gespeicherte Lautstärken', () => {
|
|
const backend = memoryBackend({ [STORAGE_KEYS.volumes]: JSON.stringify({ master: 'laut', music: 0.25, sfx: 9 }) });
|
|
const settings = new Settings(new SafeStorage(backend));
|
|
expect(settings.getVolume('master')).toBe(AUDIO.defaultVolumes.master);
|
|
expect(settings.getVolume('music')).toBe(0.25);
|
|
expect(settings.getVolume('sfx')).toBe(1);
|
|
});
|
|
|
|
it('berechnet die effektive Lautstärke inklusive Gesamtregler', () => {
|
|
const settings = new Settings(new SafeStorage(memoryBackend()));
|
|
settings.setVolume('master', 0.5);
|
|
settings.setVolume('sfx', 0.5);
|
|
expect(settings.effectiveVolume('sfx')).toBeCloseTo(0.25);
|
|
});
|
|
|
|
it('benachrichtigt Zuhörer bei Lautstärkeänderungen', () => {
|
|
const settings = new Settings(new SafeStorage(memoryBackend()));
|
|
const listener = vi.fn();
|
|
const unsubscribe = settings.onVolumeChange(listener);
|
|
settings.setVolume('master', 0.3);
|
|
expect(listener).toHaveBeenCalledWith('master', 0.3);
|
|
unsubscribe();
|
|
settings.setVolume('master', 0.4);
|
|
expect(listener).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('speichert den letzten Namen gekürzt', () => {
|
|
const settings = new Settings(new SafeStorage(memoryBackend()));
|
|
settings.setLastName('A'.repeat(40));
|
|
expect(settings.getLastName()).toHaveLength(16);
|
|
});
|
|
});
|