diff --git a/src/storageManager.js b/src/storageManager.js index b54175e16e6..493c44f056e 100644 --- a/src/storageManager.js +++ b/src/storageManager.js @@ -88,27 +88,6 @@ export function newStorageManager({moduleName, moduleType} = {}, {isAllowed = is return schedule(cb, STORAGE_TYPE_COOKIES, done); }; - /** - * @returns {boolean} - */ - const localStorageIsEnabled = function (done) { - let cb = function (result) { - if (result && result.valid) { - try { - localStorage.setItem('prebid.cookieTest', '1'); - return localStorage.getItem('prebid.cookieTest') === '1'; - } catch (error) { - } finally { - try { - localStorage.removeItem('prebid.cookieTest'); - } catch (error) {} - } - } - return false; - } - return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); - } - /** * @returns {boolean} */ @@ -122,137 +101,69 @@ export function newStorageManager({moduleName, moduleType} = {}, {isAllowed = is return schedule(cb, STORAGE_TYPE_COOKIES, done); } - /** - * @param {string} key - * @param {string} value - */ - const setDataInLocalStorage = function (key, value, done) { - let cb = function (result) { - if (result && result.valid && hasLocalStorage()) { - window.localStorage.setItem(key, value); - } - } - return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); - } - - /** - * @param {string} key - * @returns {(string|null)} - */ - const getDataFromLocalStorage = function (key, done) { - let cb = function (result) { - if (result && result.valid && hasLocalStorage()) { - return window.localStorage.getItem(key); - } - return null; - } - return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); - } - - /** - * @param {string} key - */ - const removeDataFromLocalStorage = function (key, done) { - let cb = function (result) { - if (result && result.valid && hasLocalStorage()) { - window.localStorage.removeItem(key); - } - } - return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); - } - - /** - * @returns {boolean} - */ - const hasLocalStorage = function (done) { - let cb = function (result) { - if (result && result.valid) { - try { - return !!window.localStorage; - } catch (e) { - logError('Local storage api disabled'); - } - } - return false; - } - return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); - } + function storageMethods(name) { + const capName = name.charAt(0).toUpperCase() + name.substring(1); + const backend = () => window[name]; - /** - * @returns {boolean} - */ - const sessionStorageIsEnabled = function (done) { - let cb = function (result) { - if (result && result.valid) { - try { - sessionStorage.setItem('prebid.cookieTest', '1'); - return sessionStorage.getItem('prebid.cookieTest') === '1'; - } catch (error) { - } finally { + const hasStorage = function (done) { + let cb = function (result) { + if (result && result.valid) { try { - sessionStorage.removeItem('prebid.cookieTest'); - } catch (error) {} + return !!backend(); + } catch (e) { + logError(`${name} api disabled`); + } } + return false; } - return false; + return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); } - return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); - } - /** - * @param {string} key - * @param {string} value - */ - const setDataInSessionStorage = function (key, value, done) { - let cb = function (result) { - if (result && result.valid && hasSessionStorage()) { - window.sessionStorage.setItem(key, value); - } - } - return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); - } - - /** - * @param {string} key - * @returns {(string|null)} - */ - const getDataFromSessionStorage = function (key, done) { - let cb = function (result) { - if (result && result.valid && hasSessionStorage()) { - return window.sessionStorage.getItem(key); - } - return null; - } - return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); - } - - /** - * @param {string} key - */ - const removeDataFromSessionStorage = function (key, done) { - let cb = function (result) { - if (result && result.valid && hasSessionStorage()) { - window.sessionStorage.removeItem(key); - } - } - return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); - } - - /** - * @returns {boolean} - */ - const hasSessionStorage = function (done) { - let cb = function (result) { - if (result && result.valid) { - try { - return !!window.sessionStorage; - } catch (e) { - logError('Session storage api disabled'); + return { + [`has${capName}`]: hasStorage, + [`${name}IsEnabled`](done) { + let cb = function (result) { + if (result && result.valid) { + try { + backend().setItem('prebid.cookieTest', '1'); + return backend().getItem('prebid.cookieTest') === '1'; + } catch (error) { + } finally { + try { + backend().removeItem('prebid.cookieTest'); + } catch (error) {} + } + } + return false; + } + return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); + }, + [`setDataIn${capName}`](key, value, done) { + let cb = function (result) { + if (result && result.valid && hasStorage()) { + backend().setItem(key, value); + } + } + return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); + }, + [`getDataFrom${capName}`](key, done) { + let cb = function (result) { + if (result && result.valid && hasStorage()) { + return backend().getItem(key); + } + return null; } + return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); + }, + [`removeDataFrom${capName}`](key, done) { + let cb = function (result) { + if (result && result.valid && hasStorage()) { + backend().removeItem(key); + } + } + return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); } - return false; } - return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); } /** @@ -288,17 +199,9 @@ export function newStorageManager({moduleName, moduleType} = {}, {isAllowed = is return { setCookie, getCookie, - localStorageIsEnabled, cookiesAreEnabled, - setDataInLocalStorage, - getDataFromLocalStorage, - removeDataFromLocalStorage, - hasLocalStorage, - sessionStorageIsEnabled, - setDataInSessionStorage, - getDataFromSessionStorage, - removeDataFromSessionStorage, - hasSessionStorage, + ...storageMethods('localStorage'), + ...storageMethods('sessionStorage'), findSimilarCookies } } diff --git a/test/spec/unit/core/storageManager_spec.js b/test/spec/unit/core/storageManager_spec.js index 7ce1d817418..25471a80677 100644 --- a/test/spec/unit/core/storageManager_spec.js +++ b/test/spec/unit/core/storageManager_spec.js @@ -26,15 +26,15 @@ describe('storage manager', function() { hook.ready(); }); - beforeEach(function() { + beforeEach(function () { resetData(); }); - afterEach(function() { + afterEach(function () { config.resetConfig(); }) - it('should allow to set cookie for core modules without checking gdpr enforcements', function() { + it('should allow to set cookie for core modules without checking gdpr enforcements', function () { const coreStorage = getCoreStorageManager(); let date = new Date(); date.setTime(date.getTime() + (24 * 60 * 60 * 1000)); @@ -43,7 +43,7 @@ describe('storage manager', function() { expect(coreStorage.getCookie('hello')).to.equal('world'); }); - it('should add done callbacks to storageCallbacks array', function() { + it('should add done callbacks to storageCallbacks array', function () { let noop = sinon.spy(); const coreStorage = newStorageManager(); @@ -63,7 +63,7 @@ describe('storage manager', function() { expect(storageCallbacks.length).to.equal(12); }); - it('should allow bidder to access device if gdpr enforcement module is not included', function() { + it('should allow bidder to access device if gdpr enforcement module is not included', function () { let deviceAccessSpy = sinon.spy(utils, 'hasDeviceAccess'); const storage = newStorageManager(); storage.setCookie('foo1', 'baz1'); @@ -91,14 +91,16 @@ describe('storage manager', function() { })); }); - it('should deny access if activity is denied', () => { - isAllowed.returns(false); - const mgr = mkManager(MODULE_TYPE_PREBID, 'mockMod'); - mgr.setDataInLocalStorage('testKey', 'val'); - expect(mgr.getDataFromLocalStorage('testKey')).to.not.exist; - mgr.setDataInSessionStorage('testKeySession', 'val'); - expect(mgr.getDataFromSessionStorage('testKeySession')).to.not.exist; - }); + ['Local', 'Session'].forEach(type => { + describe(`${type} storage`, () => { + it('should deny access if activity is denied', () => { + isAllowed.returns(false); + const mgr = mkManager(MODULE_TYPE_PREBID, 'mockMod'); + mgr[`setDataIn${type}Storage`]('testKey', 'val'); + expect(mgr[`getDataFrom${type}Storage`]('testKey')).to.not.exist; + }); + }) + }) it('should use bidder aliases when possible', () => { adapterManager.registerBidAdapter({callBids: sinon.stub(), getSpec: () => ({})}, 'mockBidder'); @@ -109,109 +111,66 @@ describe('storage manager', function() { [ACTIVITY_PARAM_COMPONENT_NAME]: 'mockAlias' })) }) - }) - - describe('localstorage forbidden access in 3rd-party context', function() { - let errorLogSpy; - let originalLocalStorage; - const localStorageMock = { get: () => { throw Error } }; - - beforeEach(function() { - originalLocalStorage = window.localStorage; - Object.defineProperty(window, 'localStorage', localStorageMock); - errorLogSpy = sinon.spy(utils, 'logError'); - }); - - afterEach(function() { - Object.defineProperty(window, 'localStorage', { get: () => originalLocalStorage }); - errorLogSpy.restore(); - }) - - it('should not throw if the localstorage is not accessible when setting/getting/removing from localstorage', function() { - const coreStorage = newStorageManager(); - - coreStorage.setDataInLocalStorage('key', 'value'); - const val = coreStorage.getDataFromLocalStorage('key'); - coreStorage.removeDataFromLocalStorage('key'); - - expect(val).to.be.null; - sinon.assert.calledThrice(errorLogSpy); - }) - }) - - describe('sessionstorage forbidden access in 3rd-party context', function() { - let errorLogSpy; - let originalSessionStorage; - const sessionStorageMock = { get: () => { throw Error } }; - - beforeEach(function() { - originalSessionStorage = window.sessionStorage; - Object.defineProperty(window, 'sessionStorage', sessionStorageMock); - errorLogSpy = sinon.spy(utils, 'logError'); - }); - - afterEach(function() { - Object.defineProperty(window, 'sessionStorage', { get: () => originalSessionStorage }); - errorLogSpy.restore(); - }) - - it('should not throw if the sessionStorage is not accessible when setting/getting/removing from sessionStorage', function() { - const coreStorage = newStorageManager(); + }); - coreStorage.setDataInSessionStorage('key', 'value'); - const val = coreStorage.getDataFromSessionStorage('key'); - coreStorage.removeDataFromSessionStorage('key'); + ['localStorage', 'sessionStorage'].forEach(storage => { + const Storage = storage.charAt(0).toUpperCase() + storage.substring(1); - expect(val).to.be.null; - sinon.assert.calledThrice(errorLogSpy); - }) - }) - - describe('localstorage is enabled', function() { - let localStorage; + describe(`${storage} forbidden access in 3rd-party context`, function () { + let errorLogSpy; + let originalStorage; + const storageMock = { + get: () => { + throw Error + } + }; - beforeEach(function() { - localStorage = window.localStorage; - localStorage.clear(); - }); + beforeEach(function () { + originalStorage = window[storage]; + Object.defineProperty(window, storage, storageMock); + errorLogSpy = sinon.spy(utils, 'logError'); + }); - afterEach(function() { - localStorage.clear(); - }) + afterEach(function () { + Object.defineProperty(window, storage, {get: () => originalStorage}); + errorLogSpy.restore(); + }) - it('should remove side-effect after checking', function () { - const storage = newStorageManager(); + it('should not throw if storage is not accessible when setting/getting/removing', function () { + const coreStorage = newStorageManager(); - localStorage.setItem('unrelated', 'dummy'); - const val = storage.localStorageIsEnabled(); + coreStorage[`setDataIn${Storage}`]('key', 'value'); + const val = coreStorage[`getDataFrom${Storage}`]('key'); + coreStorage[`removeDataFrom${Storage}`]('key'); - expect(val).to.be.true; - expect(localStorage.length).to.be.eq(1); - expect(localStorage.getItem('unrelated')).to.be.eq('dummy'); + expect(val).to.be.null; + sinon.assert.calledThrice(errorLogSpy); + }); }); }); - describe('sessionStorage is enabled', function() { - let sessionStorage; - - beforeEach(function() { - sessionStorage = window.sessionStorage; - sessionStorage.clear(); - }); + ['localStorage', 'sessionStorage'].forEach(storage => { + describe(`${storage} is enabled`, function () { + let store; + beforeEach(function () { + store = window[storage]; + store.clear(); + }); - afterEach(function() { - sessionStorage.clear(); - }) + afterEach(function () { + store.clear(); + }) - it('should remove side-effect after checking', function () { - const storage = newStorageManager(); + it('should remove side-effect after checking', function () { + const storageMgr = newStorageManager(); - sessionStorage.setItem('unrelated', 'dummy'); - const val = storage.sessionStorageIsEnabled(); + store.setItem('unrelated', 'dummy'); + const val = storageMgr[`${storage}IsEnabled`](); - expect(val).to.be.true; - expect(sessionStorage.length).to.be.eq(1); - expect(sessionStorage.getItem('unrelated')).to.be.eq('dummy'); + expect(val).to.be.true; + expect(store.length).to.be.eq(1); + expect(store.getItem('unrelated')).to.be.eq('dummy'); + }); }); });