import { instrument , persistState } from '../src' ; import { compose , createStore } from 'redux' ; describe ( 'persistState' , ( ) => { const savedLocalStorage = global . localStorage ; delete global . localStorage ; beforeEach ( ( ) => { global . localStorage = { store : { } , getItem ( key ) { return this . store [ key ] || null ; } , setItem ( key , value ) { this . store [ key ] = value ; } , removeItem ( key ) { delete this . store [ key ] ; } , clear ( ) { this . store = { } ; } , get length ( ) { return this . store . length ; } , key ( index ) { throw new Error ( 'Unimplemented' ) ; } , } ; } ) ; afterAll ( ( ) => { global . localStorage = savedLocalStorage ; } ) ; type Action = { type : 'INCREMENT' ; } | { type : 'DECREMENT' ; } ; const reducer = ( state = 0 , action ) => { switch ( action . type ) { case 'INCREMENT' : return state + 1 ; case 'DECREMENT' : return state - 1 ; default : return state ; } } ; it ( 'should persist state' , ( ) => { const store = createStore ( reducer , compose ( instrument ( ) , persistState ( 'id' ) ) ) ; expect ( store . getState ( ) ) . toBe ( 0 ) ; store . dispatch ( { type : 'INCREMENT' } ) ; store . dispatch ( { type : 'INCREMENT' } ) ; expect ( store . getState ( ) ) . toBe ( 2 ) ; const store2 = createStore ( reducer , compose ( instrument ( ) , persistState ( 'id' ) ) ) ; expect ( store2 . getState ( ) ) . toBe ( 2 ) ; } ) ; it ( 'should not persist state if no session id' , ( ) => { const store = createStore ( reducer , compose ( instrument ( ) , persistState ( ) ) ) ; expect ( store . getState ( ) ) . toBe ( 0 ) ; store . dispatch ( { type : 'INCREMENT' } ) ; store . dispatch ( { type : 'INCREMENT' } ) ; expect ( store . getState ( ) ) . toBe ( 2 ) ; const store2 = createStore ( reducer , compose ( instrument ( ) , persistState ( ) ) ) ; expect ( store2 . getState ( ) ) . toBe ( 0 ) ; } ) ; it ( 'should run with a custom state deserializer' , ( ) => { const oneLess = ( state ) => state === undefined ? - 1 : state - 1 ; const store = createStore ( reducer , compose ( instrument ( ) , persistState ( 'id' , oneLess ) ) ) ; expect ( store . getState ( ) ) . toBe ( 0 ) ; store . dispatch ( { type : 'INCREMENT' } ) ; store . dispatch ( { type : 'INCREMENT' } ) ; expect ( store . getState ( ) ) . toBe ( 2 ) ; const store2 = createStore ( reducer , compose ( instrument ( ) , persistState ( 'id' , oneLess ) ) ) ; expect ( store2 . getState ( ) ) . toBe ( 1 ) ; } ) ; it ( 'should run with a custom action deserializer' , ( ) => { const incToDec = ( action ) => action . type === 'INCREMENT' ? ( { type : 'DECREMENT' } as const ) : action ; const store = createStore ( reducer , compose ( instrument ( ) , persistState ( 'id' , undefined , incToDec ) ) ) ; expect ( store . getState ( ) ) . toBe ( 0 ) ; store . dispatch ( { type : 'INCREMENT' } ) ; store . dispatch ( { type : 'INCREMENT' } ) ; expect ( store . getState ( ) ) . toBe ( 2 ) ; const store2 = createStore ( reducer , compose ( instrument ( ) , persistState ( 'id' , undefined , incToDec ) ) ) ; expect ( store2 . getState ( ) ) . toBe ( - 2 ) ; } ) ; it ( 'should warn if read from localStorage fails' , ( ) => { const spy = jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } ) ; delete global . localStorage . getItem ; createStore ( reducer , compose ( instrument ( ) , persistState ( 'id' ) ) ) ; expect ( spy . mock . calls [ 0 ] ) . toContain ( 'Could not read debug session from localStorage:' ) ; spy . mockReset ( ) ; } ) ; it ( 'should warn if write to localStorage fails' , ( ) => { const spy = jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } ) ; delete global . localStorage . setItem ; const store = createStore ( reducer , compose ( instrument ( ) , persistState ( 'id' ) ) ) ; store . dispatch ( { type : 'INCREMENT' } ) ; expect ( spy . mock . calls [ 0 ] ) . toContain ( 'Could not write debug session to localStorage:' ) ; spy . mockReset ( ) ; } ) ; } ) ;