diff --git a/gameblocks/modules/user-interface/StorageSettingsStore.js b/gameblocks/modules/user-interface/StorageSettingsStore.js index 7f3e52d..65767ba 100644 --- a/gameblocks/modules/user-interface/StorageSettingsStore.js +++ b/gameblocks/modules/user-interface/StorageSettingsStore.js @@ -58,9 +58,10 @@ export class JsonSettingsStore { load() { const saved = readJsonStorageItem(this.storage, this.storageKey, null); + this.settings = { ...this.defaults }; if (saved && typeof saved === 'object') { this.settings = { - ...this.settings, + ...this.defaults, ...saved, }; } diff --git a/gameblocks/modules/user-interface/StorageSettingsStore.test.js b/gameblocks/modules/user-interface/StorageSettingsStore.test.js new file mode 100644 index 0000000..b5c965a --- /dev/null +++ b/gameblocks/modules/user-interface/StorageSettingsStore.test.js @@ -0,0 +1,34 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { JsonSettingsStore } from './StorageSettingsStore.js'; + +function memoryStorage(initial = {}) { + const data = { ...initial }; + return { + getItem(key) { + return Object.prototype.hasOwnProperty.call(data, key) ? data[key] : null; + }, + setItem(key, value) { + data[key] = String(value); + }, + }; +} + +test('load merges saved keys onto defaults, not dirty in-memory settings', () => { + const storage = memoryStorage({ + demo: JSON.stringify({ volume: 0.2 }), + }); + const store = new JsonSettingsStore(storage, 'demo', { volume: 1, muted: false }); + store.update({ volume: 0.9, extra: 'stale' }); + const loaded = store.load(); + assert.equal(loaded.volume, 0.2); + assert.equal(loaded.muted, false); + assert.equal(loaded.extra, undefined); +}); + +test('load with empty storage restores defaults', () => { + const store = new JsonSettingsStore(memoryStorage(), 'demo', { volume: 1 }); + store.update({ volume: 0 }); + const loaded = store.load(); + assert.equal(loaded.volume, 1); +});