diff --git a/src/sdk.ts b/src/sdk.ts index c7b6ebf6e..629fc716e 100644 --- a/src/sdk.ts +++ b/src/sdk.ts @@ -234,10 +234,10 @@ export class SunbirdSdk { switch (sdkConfig.platform) { case 'cordova': this._container.bind(InjectionTokens.SHARED_PREFERENCES) - .to(SharedPreferencesLocalStorage).inSingletonScope(); + .to(SharedPreferencesAndroid).inSingletonScope(); break; case 'web': this._container.bind(InjectionTokens.SHARED_PREFERENCES) - .to(SharedPreferencesAndroid).inSingletonScope(); + .to(SharedPreferencesLocalStorage).inSingletonScope(); break; default: throw new Error('FATAL_ERROR: Invalid platform'); } diff --git a/src/util/shared-preferences/impl/shared-preferences-android.spec.ts b/src/util/shared-preferences/impl/shared-preferences-android.spec.ts index 9ac567489..00c283485 100644 --- a/src/util/shared-preferences/impl/shared-preferences-android.spec.ts +++ b/src/util/shared-preferences/impl/shared-preferences-android.spec.ts @@ -34,6 +34,32 @@ describe('SharedPreferencesAndroid', () => { }); }); + it('should normalise and resolve from localStorage first', (done) => { + const putStringFunc = jest.fn((a, b, c, d) => { + setTimeout(() => { + c(); + }, 0); + }); + + spyOn(window['plugins'].SharedPreferences, 'getInstance').and.returnValue({ + getString: (a, b, c, d) => { + setTimeout(() => { + c('SOME_VALUE'); + }, 0); + }, + putString: putStringFunc + }); + + sharedPreferences = container.get(InjectionTokens.SHARED_PREFERENCES); + localStorage.setItem('SOME_KEY', 'SOME__LOCALSTORAGE_VALUE'); + + sharedPreferences.getString('SOME_KEY').subscribe((v) => { + expect(v).toBe('SOME__LOCALSTORAGE_VALUE'); + expect(putStringFunc).toBeCalledWith('SOME_KEY', 'SOME__LOCALSTORAGE_VALUE', expect.anything(), expect.anything()) + done(); + }); + }); + it('should delegate to cordova sharedPreferences', (done) => { spyOn(window['plugins'].SharedPreferences, 'getInstance').and.returnValue({ getString: (a, b, c, d) => { @@ -121,6 +147,58 @@ describe('SharedPreferencesAndroid', () => { done(); }); }); + + it('should normalise and resolve from localStorage first for falsy values', (done) => { + const putBooleanFunc = jest.fn((a, b, c, d) => { + setTimeout(() => { + c(true); + }, 0); + }); + + spyOn(window['plugins'].SharedPreferences, 'getInstance').and.returnValue({ + getBoolean: (a, b, c, d) => { + setTimeout(() => { + d('SOME_ERROR'); + }, 0); + }, + putBoolean: putBooleanFunc + }); + + sharedPreferences = container.get(InjectionTokens.SHARED_PREFERENCES); + localStorage.setItem('SOME_KEY', 'falsy_value'); + + sharedPreferences.getBoolean('SOME_KEY').subscribe((v) => { + expect(v).toBe(false); + expect(putBooleanFunc).toBeCalledWith('SOME_KEY', false, expect.anything(), expect.anything()); + done(); + }); + }); + + it('should normalise and resolve from localStorage first for \'true\' values', (done) => { + const putBooleanFunc = jest.fn((a, b, c, d) => { + setTimeout(() => { + c(true); + }, 0); + }); + + spyOn(window['plugins'].SharedPreferences, 'getInstance').and.returnValue({ + getBoolean: (a, b, c, d) => { + setTimeout(() => { + d('SOME_ERROR'); + }, 0); + }, + putBoolean: putBooleanFunc + }); + + sharedPreferences = container.get(InjectionTokens.SHARED_PREFERENCES); + localStorage.setItem('SOME_KEY', 'true'); + + sharedPreferences.getBoolean('SOME_KEY').subscribe((v) => { + expect(v).toBe(true); + expect(putBooleanFunc).toBeCalledWith('SOME_KEY', true, expect.anything(), expect.anything()) + done(); + }); + }); }); describe('putBoolean()', () => { diff --git a/src/util/shared-preferences/impl/shared-preferences-android.ts b/src/util/shared-preferences/impl/shared-preferences-android.ts index 67d03542d..bf1a9597a 100644 --- a/src/util/shared-preferences/impl/shared-preferences-android.ts +++ b/src/util/shared-preferences/impl/shared-preferences-android.ts @@ -1,6 +1,7 @@ import {SharedPreferences} from '..'; import {Observable} from 'rxjs'; import {injectable} from 'inversify'; +import {mapTo} from 'rxjs/operators'; @injectable() export class SharedPreferencesAndroid implements SharedPreferences { @@ -10,14 +11,24 @@ export class SharedPreferencesAndroid implements SharedPreferences { private sharedPreferences = plugins.SharedPreferences.getInstance(SharedPreferencesAndroid.sharedPreferncesName); public getString(key: string): Observable { - return new Observable((observer) => { - this.sharedPreferences.getString(key, '', (value) => { - observer.next(value); - observer.complete(); - }, (e) => { - observer.error(e); + const value = localStorage.getItem(key); + + if (value) { + localStorage.removeItem(key); + + return this.putString(key, value).pipe( + mapTo(value) + ); + } else { + return new Observable((observer) => { + this.sharedPreferences.getString(key, '', (v) => { + observer.next(v); + observer.complete(); + }, (e) => { + observer.error(e); + }); }); - }); + } } public putString(key: string, value: string): Observable { @@ -43,13 +54,23 @@ export class SharedPreferencesAndroid implements SharedPreferences { } public getBoolean(key: string): Observable { - return new Observable((observer) => { - this.sharedPreferences.getBoolean(key, false, (value) => { - observer.next(value); - observer.complete(); - }, (e) => { - observer.error(e); + const value = localStorage.getItem(key); + + if (value) { + localStorage.removeItem(key); + + return this.putBoolean(key, value === 'true').pipe( + mapTo(value === 'true') + ); + } else { + return new Observable((observer) => { + this.sharedPreferences.getBoolean(key, false, (v) => { + observer.next(v); + observer.complete(); + }, (e) => { + observer.error(e); + }); }); - }); + } } } diff --git a/src/util/shared-preferences/impl/shared-preferences-local-storage.ts b/src/util/shared-preferences/impl/shared-preferences-local-storage.ts index 54444e31d..f43baff4e 100644 --- a/src/util/shared-preferences/impl/shared-preferences-local-storage.ts +++ b/src/util/shared-preferences/impl/shared-preferences-local-storage.ts @@ -25,6 +25,8 @@ export class SharedPreferencesLocalStorage implements SharedPreferences { } public getBoolean(key: string): Observable { - return defer(() => of(Boolean(localStorage.getItem(key)))); + return defer(() => of( + localStorage.getItem(key) === 'true' + )); } }