Files
ArtPlayer/test/storage.test.js

85 lines
3.3 KiB
JavaScript

import assert from 'node:assert/strict'
// eslint-disable-next-line test/no-import-node-test -- Use the repository Node test runner.
import { test } from 'node:test'
import { loadModules } from './helpers/load.js'
const { Storage } = await loadModules({ Storage: 'packages/artplayer/src/storage' })
function environment(t) {
const descriptor = Object.getOwnPropertyDescriptor(globalThis, 'window')
t.after(() => descriptor ? Object.defineProperty(globalThis, 'window', descriptor) : delete globalThis.window)
const values = new Map()
const native = {
getItem: key => values.get(key) ?? null,
setItem: (key, value) => values.set(key, value),
removeItem: key => values.delete(key),
}
globalThis.window = { localStorage: native }
return { values, native, storage: new Storage() }
}
test('storage preserves envelope, mutable name/settings fields and synchronous returns', (t) => {
const { storage, values } = environment(t)
assert.deepEqual(Object.keys(storage), ['name', 'settings'])
assert.equal(storage.name, 'artplayer_settings')
assert.deepEqual(storage.get(), {})
assert.equal(storage.set('volume', 0.5), undefined)
assert.equal(values.get('artplayer_settings'), '{"volume":0.5}')
storage.set('times', { example: 7 })
assert.deepEqual(storage.get(), { volume: 0.5, times: { example: 7 } })
assert.equal(storage.del('volume'), undefined)
assert.deepEqual(storage.get(), { times: { example: 7 } })
storage.name = 'custom'
storage.set('plugin', true)
assert.equal(values.get('custom'), '{"plugin":true}')
assert.equal(storage.clear(), undefined)
assert.equal(values.has('custom'), false)
assert.equal(values.has('artplayer_settings'), true)
})
test('storage retains truthy key selection and historical JSON payload shapes', (t) => {
const { storage, values } = environment(t)
for (const payload of [[], [1, 2], 'text', 4, true, null]) {
values.set(storage.name, JSON.stringify(payload))
const expected = payload || {}
assert.deepEqual(storage.get(), expected)
assert.deepEqual(storage.get(''), expected)
assert.deepEqual(storage.get(0), expected)
}
storage.settings.fallback = 9
values.set(storage.name, 'bad JSON')
assert.equal(storage.get('fallback'), 9)
assert.equal(storage.get(), storage.settings)
})
test('storage falls back on denied native access and retains in-memory references', (t) => {
const { storage } = environment(t)
Object.defineProperty(window, 'localStorage', { get() {
throw new Error('denied')
} })
const value = { plugin: true }
assert.equal(storage.set('value', value), undefined)
assert.equal(storage.get('value'), value)
storage.del('value')
assert.equal(storage.get('value'), undefined)
const previous = storage.settings
storage.clear()
assert.notEqual(storage.settings, previous)
assert.deepEqual(storage.settings, {})
})
test('storage write failure does not merge fallback into successful native reads', (t) => {
const { storage, native, values } = environment(t)
values.set(storage.name, '{"volume":0.2}')
native.setItem = () => {
throw new Error('quota')
}
storage.set('volume', 0.7)
assert.equal(storage.settings.volume, 0.7)
assert.equal(storage.get('volume'), 0.2)
native.getItem = () => {
throw new Error('denied')
}
assert.equal(storage.get('volume'), 0.7)
})