From f0dc85ad0bd9e2303dc196740a7a7bf6c97a6582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Fri, 11 Aug 2017 16:39:33 -0700 Subject: [PATCH] Pass storage implementation as an argument Instead of assuming that window.localStorage is always used pass it via arguments --- assets/static/__mocks__/localStorageMock.js | 35 ++++++++++----------- assets/static/filters.js | 14 ++++----- assets/static/filters.test.js | 18 +++++------ assets/static/unsee.js | 12 ++++--- assets/static/unsee.test.js | 4 +-- 5 files changed, 41 insertions(+), 42 deletions(-) diff --git a/assets/static/__mocks__/localStorageMock.js b/assets/static/__mocks__/localStorageMock.js index 9935e1d36..78e61825a 100644 --- a/assets/static/__mocks__/localStorageMock.js +++ b/assets/static/__mocks__/localStorageMock.js @@ -1,22 +1,21 @@ -// source: https://github.com/facebook/jest/issues/2098 +class LocalStorageMock { -var localStorageMock = (function() { - var store = {}; + constructor() { + this.store = {}; + } - return { - getItem: function(key) { - return store[key] || null; - }, - setItem: function(key, value) { - store[key] = value.toString(); - }, - clear: function() { - store = {}; - } - }; + getItem(key) { + return this.store[key] || null; + } -})(); + setItem(key, value) { + this.store[key] = value.toString(); + } -Object.defineProperty(window, "localStorage", { - value: localStorageMock -}); + clear() { + this.store = {}; + } + +} + +module.exports = new LocalStorageMock(); diff --git a/assets/static/filters.js b/assets/static/filters.js index 3a99f6d2b..a6fe35373 100644 --- a/assets/static/filters.js +++ b/assets/static/filters.js @@ -21,6 +21,7 @@ var selectors = { historyMenu: "#historyMenu" }; var appendsEnabled = true; +var historyStorage; const historyKey = "filterHistory"; function addBadge(text) { @@ -69,13 +70,11 @@ function setPause() { } function renderHistory() { - const storage = window.localStorage; - var historicFilters = []; const currentFilterText = getFilters().join(","); - const history = storage.getItem(historyKey); + const history = historyStorage.getItem(historyKey); if (history) { historicFilters = history.split("\n"); } @@ -93,14 +92,12 @@ function appendFilterToHistory(text) { // require non empty text and enabled appends if (!text || !appendsEnabled) return false; - const storage = window.localStorage; - // final filter list we'll save to storage var filterList = [ text ]; // get current history list from storage and append it to our final list // of filters, but avoid duplicates - const history = storage.getItem(historyKey); + const history = historyStorage.getItem(historyKey); if (history) { const historyArr = history.split("\n"); for (var i = 0; i < historyArr.length; i++) { @@ -114,7 +111,7 @@ function appendFilterToHistory(text) { // truncate the history to up to 11 elements filterList = filterList.slice(0, 11); - storage.setItem(historyKey, filterList.join("\n")); + historyStorage.setItem(historyKey, filterList.join("\n")); } function setFilters() { @@ -131,7 +128,8 @@ function setFilters() { unsee.triggerReload(); } -function init() { +function init(historyStore) { + historyStorage = historyStore; var initialFilter; if ($(selectors.filter).data("default-used") == "false" || $(selectors.filter).data("default-used") === false) { diff --git a/assets/static/filters.test.js b/assets/static/filters.test.js index f9fc45edc..d01fb3c1e 100644 --- a/assets/static/filters.test.js +++ b/assets/static/filters.test.js @@ -1,5 +1,5 @@ const $ = window.jQuery = require("jquery"); -require("./__mocks__/localStorageMock"); +const LocalStorageMock = require("./__mocks__/localStorageMock"); test("filters addBadge()", () => { const filters = require("./filters"); @@ -7,7 +7,7 @@ test("filters addBadge()", () => { }); test("default filter should be in history after setting filter to foo", () => { - localStorage.clear(); + LocalStorageMock.clear(); document.body.innerHTML = "
" + "
" + @@ -26,7 +26,7 @@ test("default filter should be in history after setting filter to foo", () => { const filters = require("./filters"); autocomplete.init(); - filters.init(); + filters.init(LocalStorageMock); filters.setFilters(); filters.renderHistory(); @@ -35,11 +35,11 @@ test("default filter should be in history after setting filter to foo", () => { expect(elems.length).toBe(1); expect($(elems[0]).text().trim()).toBe("default"); // we set foo, so that what should be in history - expect(localStorage.getItem("filterHistory")).toBe("foo"); + expect(LocalStorageMock.getItem("filterHistory")).toBe("foo"); }); test("appended filtes should be present in history", () => { - localStorage.clear(); + LocalStorageMock.clear(); document.body.innerHTML = "
" + "
" + @@ -58,7 +58,7 @@ test("appended filtes should be present in history", () => { const filters = require("./filters"); autocomplete.init(); - filters.init(); + filters.init(LocalStorageMock); filters.setFilters(); filters.renderHistory(); @@ -68,7 +68,7 @@ test("appended filtes should be present in history", () => { // default is used but default is always rendered so should be there expect($(elems[0]).text().trim()).toBe("default"); // and that's what history should have - expect(localStorage.getItem("filterHistory")).toBe("default"); + expect(LocalStorageMock.getItem("filterHistory")).toBe("default"); // now we append more filters, so q=default becomes q=default,bar filters.addFilter("bar"); @@ -81,7 +81,7 @@ test("appended filtes should be present in history", () => { expect($(elems[0]).text().trim()).toBe("default"); expect($(elems[1]).text().trim()).toBe("default"); expect( - localStorage.getItem("filterHistory").split("\n") + LocalStorageMock.getItem("filterHistory").split("\n") ).toMatchObject( [ "default,bar", "default" ] ); @@ -98,7 +98,7 @@ test("appended filtes should be present in history", () => { expect($(elems[1]).text().trim()).toBe("default"); expect($(elems[1]).text().trim()).toBe("default"); expect( - localStorage.getItem("filterHistory").split("\n") + LocalStorageMock.getItem("filterHistory").split("\n") ).toMatchObject( [ "default,bar,@state=active", "default,bar", "default" ] ); diff --git a/assets/static/unsee.js b/assets/static/unsee.js index 9157c25c2..49b5e1b9c 100644 --- a/assets/static/unsee.js +++ b/assets/static/unsee.js @@ -304,7 +304,7 @@ function setupPageVisibilityHandler() { } } -function init() { +function init(localStore) { progress.init(); config.init({ @@ -318,7 +318,7 @@ function init() { summary.init(); grid.init(); autocomplete.init(); - filters.init(); + filters.init(localStore); watchdog.init(30, 60*15); // set watchdog to 15 minutes $(selectors.refreshButton).click(function() { @@ -331,7 +331,7 @@ function init() { setupPageVisibilityHandler(); } -function onReady() { +function onReady(localStore) { // wrap all inits so we can handle errors try { // init all elements using bootstrapSwitch @@ -347,7 +347,7 @@ function onReady() { ui.setupModal(); silence.setupSilenceForm(); unsilence.init(); - init(); + init(localStore); // delay initial alert load to allow browser finish rendering setTimeout(function() { @@ -381,4 +381,6 @@ exports.flash = flash; exports.parseAJAXError = parseAJAXError; exports.onReady = onReady; -$(document).ready(onReady); +$(document).ready(function() { + onReady(window.localStorage); +}); diff --git a/assets/static/unsee.test.js b/assets/static/unsee.test.js index 381c37848..c24ceee71 100644 --- a/assets/static/unsee.test.js +++ b/assets/static/unsee.test.js @@ -1,7 +1,7 @@ const $ = require("jquery"); const templatesMock = require("./__mocks__/templatesMock"); const alertsMock = require("./__mocks__/alertsMock"); -require("./__mocks__/localStorageMock"); +const LocalStorageMock = require("./__mocks__/localStorageMock"); jest.useFakeTimers(); @@ -51,7 +51,7 @@ if (alertsServer) { require("bootstrap/js/popover.js"); alertsServer.start(); - unsee.onReady(); + unsee.onReady(LocalStorageMock); unsee.triggerReload(); jest.runOnlyPendingTimers(); // we should have 2 alerts