UNPKG

@apptus/esales-api

Version:

Library for making requests to Elevate 4 API v3

273 lines (201 loc) 9.89 kB
import { describe, it, expect } from '#test'; import { localStorageBackedSession, LocalStorageSession, __sessionMetadataCache } from './session.ts'; const uuidv4 = /[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/; const uuidStr = expect.stringMatching(uuidv4); const suite = describe({ name: 'localStorageBackedSession()', beforeEach() { localStorage.clear(); __sessionMetadataCache.clear(); } }); const jsonSuite = describe({ suite, name: 'JSON parsing' }); it(suite, 'should have empty cache and localStorage before reading session', () => { localStorageBackedSession() satisfies LocalStorageSession; expect(localStorage.length).toBe(0); expect(__sessionMetadataCache.size).toBe(0); }); it(suite, 'should return randomized uuid keys for empty storage', () => { const session = localStorageBackedSession(); const result = session(); const { customerKey, sessionKey } = result; expect(result).toEqual({ customerKey: uuidStr, sessionKey: uuidStr }); expect(localStorage.getItem('voyado.session')).toBe(`{"customerKey":"${customerKey}","sessionKey":"${sessionKey}"}`); }); it(suite, 'should return the same cached value when retrieved multiple times', () => { const session = localStorageBackedSession(); const data = session(); localStorage.clear(); expect(data).toBe(session()); expect(data).toBe(session()); }); it(suite, 'should return new random keys when cache and localStorage is cleared', () => { const session = localStorageBackedSession(); const data = session(); localStorage.clear(); __sessionMetadataCache.clear(); expect(data).not.toEqual(session()); }); it(suite, 'should clear cache key when window storage event occurs', () => { const session = localStorageBackedSession('storageEv'); const data = session(); const sizePriorDispatch = __sessionMetadataCache.size; globalThis.dispatchEvent(new StorageEvent('storage', { key: 'storageEv', storageArea: localStorage })); expect(sizePriorDispatch).toBe(1); expect(__sessionMetadataCache.size).toBe(0); expect(data).not.toBe(session()); expect(data).toEqual(session()); }); it(suite, 'should NOT clear cache key when window storage event does not match', () => { const session = localStorageBackedSession('nonStorageEv'); const data = session(); const sizePriorDispatch = __sessionMetadataCache.size; globalThis.dispatchEvent(new StorageEvent('storage', { key: '=== Non-match ===', storageArea: localStorage })); globalThis.dispatchEvent(new StorageEvent('storage', { key: 'nonStorageEv', storageArea: sessionStorage })); globalThis.dispatchEvent(new Event('click')); expect(sizePriorDispatch).toBe(1); expect(__sessionMetadataCache.size).toBe(1); expect(data).toBe(session()); }); it(suite, 'should return new randomized keys when clear is run', () => { const session = localStorageBackedSession('reset'); const a = session(); session.reset(); const b = session(); expect(a).not.toEqual(b); expect(b).toEqual({ customerKey: uuidStr, sessionKey: uuidStr }); expect(localStorage.getItem('reset')).toBe(`{"customerKey":"${b.customerKey}","sessionKey":"${b.sessionKey}"}`); }); it(suite, 'should return the latest set customerKey', () => { const session = localStorageBackedSession('update'); session.updateCustomerKey('Bruce Wayne 🦇'); const result = session(); expect(result).toEqual({ customerKey: 'Bruce Wayne 🦇', sessionKey: uuidStr }); expect(localStorage.getItem('update')).toBe(`{"customerKey":"Bruce Wayne 🦇","sessionKey":"${result.sessionKey}"}`); }); it(jsonSuite, 'should return existing storage keys', () => { const session = localStorageBackedSession('existing'); localStorage.setItem('existing', '{"customerKey":"foo","sessionKey":"bar"}'); const result = session(); expect(result).toEqual({ customerKey: 'foo', sessionKey: 'bar' }); expect(localStorage.getItem('existing')).toBe('{"customerKey":"foo","sessionKey":"bar"}'); }); it(jsonSuite, 'should return randomized uuid keys for invalid JSON', () => { const session = localStorageBackedSession('invalid'); localStorage.setItem('invalid', 'not actually JSON! 😲'); const result = session(); const { customerKey, sessionKey } = result; expect(result).toEqual({ customerKey: uuidStr, sessionKey: uuidStr }); expect(localStorage.getItem('invalid')).toBe(`{"customerKey":"${customerKey}","sessionKey":"${sessionKey}"}`); }); it(jsonSuite, 'should reset data for stored boolean JSON data', () => { const session = localStorageBackedSession('bool'); localStorage.setItem('bool', 'true'); const result = session(); const { customerKey, sessionKey } = result; expect(result).toEqual({ customerKey: uuidStr, sessionKey: uuidStr }); expect(localStorage.getItem('bool')).toBe(`{"customerKey":"${customerKey}","sessionKey":"${sessionKey}"}`); }); it(jsonSuite, 'should reset data for stored number JSON data', () => { const session = localStorageBackedSession('num'); localStorage.setItem('num', '987.123'); const result = session(); const { customerKey, sessionKey } = result; expect(result).toEqual({ customerKey: uuidStr, sessionKey: uuidStr }); expect(localStorage.getItem('num')).toBe(`{"customerKey":"${customerKey}","sessionKey":"${sessionKey}"}`); }); it(jsonSuite, 'should reset data for stored string JSON data', () => { const session = localStorageBackedSession('str'); localStorage.setItem('str', '"Hello there!"'); const result = session(); const { customerKey, sessionKey } = result; expect(result).toEqual({ customerKey: uuidStr, sessionKey: uuidStr }); expect(localStorage.getItem('str')).toBe(`{"customerKey":"${customerKey}","sessionKey":"${sessionKey}"}`); }); it(jsonSuite, 'should reset data for stored null JSON data', () => { const session = localStorageBackedSession('nully'); localStorage.setItem('nully', 'null'); const result = session(); const { customerKey, sessionKey } = result; expect(result).toEqual({ customerKey: uuidStr, sessionKey: uuidStr }); expect(localStorage.getItem('nully')).toBe(`{"customerKey":"${customerKey}","sessionKey":"${sessionKey}"}`); }); it(jsonSuite, 'should reset data for stored array JSON data', () => { const session = localStorageBackedSession('arr'); localStorage.setItem('arr', '["foo", "bar"]'); const result = session(); const { customerKey, sessionKey } = result; expect(result).toEqual({ customerKey: uuidStr, sessionKey: uuidStr }); expect(localStorage.getItem('arr')).toBe(`{"customerKey":"${customerKey}","sessionKey":"${sessionKey}"}`); }); it(jsonSuite, 'should repair broken stored empty metadata on read', () => { const session = localStorageBackedSession('empty'); localStorage.setItem('empty', '{}'); const result = session(); const { customerKey, sessionKey } = result; expect(result).toEqual({ customerKey: uuidStr, sessionKey: uuidStr }); expect(localStorage.getItem('empty')).toBe(`{"customerKey":"${customerKey}","sessionKey":"${sessionKey}"}`); }); it(jsonSuite, 'should repair broken stored partial metadata on read', () => { const session = localStorageBackedSession('repair'); localStorage.setItem('repair', '{"customerKey":"partial"}'); const result = session(); expect(result).toEqual({ customerKey: 'partial', sessionKey: uuidStr }); expect(localStorage.getItem('repair')).toBe(`{"customerKey":"partial","sessionKey":"${result.sessionKey}"}`); }); it(jsonSuite, 'should repair invalid primitive type on "sessionKey"', () => { const session = localStorageBackedSession('s-type'); localStorage.setItem('s-type', '{"customerKey":"abc","sessionKey":99}'); const result = session(); expect(result).toEqual({ customerKey: 'abc', sessionKey: uuidStr }); expect(localStorage.getItem('s-type')).toBe(`{"customerKey":"abc","sessionKey":"${result.sessionKey}"}`); }); it(jsonSuite, 'should repair invalid object type on "sessionKey"', () => { const session = localStorageBackedSession('s-type'); localStorage.setItem('s-type', '{"customerKey":"abc","sessionKey":{}}'); const result = session(); expect(result).toEqual({ customerKey: 'abc', sessionKey: uuidStr }); expect(localStorage.getItem('s-type')).toBe(`{"customerKey":"abc","sessionKey":"${result.sessionKey}"}`); }); it(jsonSuite, 'should repair invalid primitive type on "customerKey"', () => { const session = localStorageBackedSession('c-prim'); localStorage.setItem('c-prim', '{"customerKey":true,"sessionKey":"42"}'); const result = session(); expect(result).toEqual({ customerKey: uuidStr, sessionKey: '42' }); expect(localStorage.getItem('c-prim')).toBe(`{"customerKey":"${result.customerKey}","sessionKey":"42"}`); }); it(jsonSuite, 'should repair invalid object type on "customerKey"', () => { const session = localStorageBackedSession('c-obj'); localStorage.setItem('c-obj', '{"customerKey":{},"sessionKey":"42"}'); const result = session(); expect(result).toEqual({ customerKey: uuidStr, sessionKey: '42' }); expect(localStorage.getItem('c-obj')).toBe(`{"customerKey":"${result.customerKey}","sessionKey":"42"}`); }); it(jsonSuite, 'should discard extraneous properties on stored metadata on read', () => { const session = localStorageBackedSession('extraneous'); localStorage.setItem('extraneous', '{"foo":"foo","customerKey":"123","sessionKey":"321","bar":"bar"}'); const result = session(); expect(result).toEqual({ customerKey: '123', sessionKey: '321' }); expect(localStorage.getItem('extraneous')).toBe(`{"customerKey":"123","sessionKey":"321"}`); }); class StorageEvent extends Event { readonly key: string; readonly storageArea: Storage; constructor(type: string, eventInitDict: StorageEventInit) { super(type, eventInitDict); this.key = eventInitDict.key!; this.storageArea = eventInitDict.storageArea!; } }