From aa2951f4362ef9f174a636daa3b33f1cf6b50068 Mon Sep 17 00:00:00 2001 From: Simon Legner Date: Sat, 10 Aug 2024 14:17:30 +0200 Subject: [PATCH] Use mw.storage directly Bug: T77349 Change-Id: I8a494f20b4d9f4930fa89681857990416c0e840c --- resources/mmv.bootstrap/mmv.Config.js | 22 ++--- resources/mmv.bootstrap/mmv.bootstrap.js | 8 +- resources/mmv/mmv.lightboxinterface.js | 12 +-- resources/mmv/ui/mmv.ui.metadataPanel.js | 12 +-- .../mmv/ui/mmv.ui.metadataPanelScroller.js | 12 +-- tests/qunit/mmv/mmv.Config.test.js | 95 ++++++++++--------- .../qunit/mmv/ui/mmv.ui.metadataPanel.test.js | 20 ++-- .../ui/mmv.ui.metadataPanelScroller.test.js | 32 ++++--- 8 files changed, 98 insertions(+), 115 deletions(-) diff --git a/resources/mmv.bootstrap/mmv.Config.js b/resources/mmv.bootstrap/mmv.Config.js index f5409b740..095eba977 100644 --- a/resources/mmv.bootstrap/mmv.Config.js +++ b/resources/mmv.bootstrap/mmv.Config.js @@ -26,9 +26,12 @@ class Config { * @param {mw.Map} mwConfig * @param {Object} mwUser * @param {mw.Api} api - * @param {mw.SafeStorage} localStorage */ - constructor( viewerConfig, mwConfig, mwUser, api, localStorage ) { + constructor( + viewerConfig = mw.config.get( 'wgMultimediaViewer', {} ), + mwConfig = mw.config, + mwUser = mw.user, + api = new mw.Api() ) { /** * A plain object storing MediaViewer-specific settings * @@ -56,13 +59,6 @@ class Config { * @type {mw.Api} */ this.api = api; - - /** - * The localStorage object, for dependency injection - * - * @type {mw.SafeStorage} - */ - this.localStorage = localStorage; } /** @@ -73,7 +69,7 @@ class Config { * @return {string|null} stored value or fallback or null if neither exists */ getFromLocalStorage( key, fallback ) { - const value = this.localStorage.get( key ); + const value = mw.storage.get( key ); // localStorage will only store strings; if values `null`, `false` or // `0` are set, they'll come out as `"null"`, `"false"` or `"0"`, so we @@ -98,7 +94,7 @@ class Config { * @return {boolean} whether storing the item was successful */ setInLocalStorage( key, value ) { - return this.localStorage.set( key, value ); + return mw.storage.set( key, value ); } /** @@ -108,7 +104,7 @@ class Config { * @return {boolean} whether storing the item was successful */ removeFromLocalStorage( key ) { - this.localStorage.remove( key ); + mw.storage.remove( key ); // mw.storage.remove catches all exceptions and returns false if any // occur, so we can't distinguish between actual issues, and @@ -187,7 +183,7 @@ class Config { * @return {boolean} */ shouldShowStatusInfo() { - return !isMediaViewerEnabledOnClick( this.mwConfig, this.mwUser, this.localStorage ) && this.getFromLocalStorage( 'mmv-showStatusInfo' ) === '1'; + return !isMediaViewerEnabledOnClick( this.mwConfig, this.mwUser, mw.storage ) && this.getFromLocalStorage( 'mmv-showStatusInfo' ) === '1'; } /** diff --git a/resources/mmv.bootstrap/mmv.bootstrap.js b/resources/mmv.bootstrap/mmv.bootstrap.js index 7193d98bc..c78ecd141 100644 --- a/resources/mmv.bootstrap/mmv.bootstrap.js +++ b/resources/mmv.bootstrap/mmv.bootstrap.js @@ -38,13 +38,7 @@ class MultimediaViewerBootstrap { // TODO lazy-load config and htmlUtils /** @property {Config} config - */ - this.config = new Config( - mw.config.get( 'wgMultimediaViewer', {} ), - mw.config, - mw.user, - new mw.Api(), - mw.storage - ); + this.config = new Config(); this.validExtensions = this.config.extensions(); diff --git a/resources/mmv/mmv.lightboxinterface.js b/resources/mmv/mmv.lightboxinterface.js index 1ba5629e6..545f1a008 100644 --- a/resources/mmv/mmv.lightboxinterface.js +++ b/resources/mmv/mmv.lightboxinterface.js @@ -63,20 +63,12 @@ class LightboxInterface extends UiElement { super( $wrapper ); this.$wrapper = $wrapper; - this.localStorage = mw.storage; - // When opening we might override the theme-color, so remember the original value const metaElement = document.querySelector( 'meta[name="theme-color"]' ); this.originalThemeColor = metaElement ? metaElement.getAttribute( 'content' ) : null; /** @property {Config} config - */ - this.config = new Config( - mw.config.get( 'wgMultimediaViewer', {} ), - mw.config, - mw.user, - new mw.Api(), - this.localStorage - ); + this.config = new Config(); /** * @property {ThumbnailWidthCalculator} @@ -118,7 +110,7 @@ class LightboxInterface extends UiElement { this.setupCanvasButtons(); - this.panel = new MetadataPanel( this.$postDiv, this.$aboveFold, this.localStorage, this.config ); + this.panel = new MetadataPanel( this.$postDiv, this.$aboveFold, this.config ); this.buttons = new CanvasButtons( this.$preDiv, this.$closeButton, this.$fullscreenButton ); this.canvas = new Canvas( this.$innerWrapper, this.$imageWrapper, this.$wrapper ); diff --git a/resources/mmv/ui/mmv.ui.metadataPanel.js b/resources/mmv/ui/mmv.ui.metadataPanel.js index 7683403e2..3a8c40bb3 100644 --- a/resources/mmv/ui/mmv.ui.metadataPanel.js +++ b/resources/mmv/ui/mmv.ui.metadataPanel.js @@ -33,10 +33,9 @@ class MetadataPanel extends UiElement { * @param {jQuery} $aboveFold The brighter headline of the metadata panel (.mw-mmv-above-fold). * Called "aboveFold" for historical reasons, but actually a part of the next sibling of the element * is also above the fold (bottom of the screen). - * @param {mw.SafeStorage} localStorage the localStorage object, for dependency injection * @param {Config} config A configuration object. */ - constructor( $container, $aboveFold, localStorage, config ) { + constructor( $container, $aboveFold, config ) { super( $container ); this.$aboveFold = $aboveFold; @@ -44,7 +43,7 @@ class MetadataPanel extends UiElement { /** @property {Config} config - */ this.config = config; - this.initializeHeader( localStorage ); + this.initializeHeader(); this.initializeImageMetadata(); this.initializeAboutLinks(); } @@ -165,14 +164,11 @@ class MetadataPanel extends UiElement { /* Initialization methods */ /** * Initializes the header, which contains the title, credit, and license elements. - * - * @param {mw.SafeStorage} localStorage the localStorage object, for dependency injection */ - initializeHeader( localStorage ) { + initializeHeader() { this.progressBar = new ProgressBar( this.$aboveFold ); - this.scroller = new MetadataPanelScroller( this.$container, this.$aboveFold, - localStorage ); + this.scroller = new MetadataPanelScroller( this.$container, this.$aboveFold ); this.$titleDiv = $( '
' ) .addClass( 'mw-mmv-title-contain' ) diff --git a/resources/mmv/ui/mmv.ui.metadataPanelScroller.js b/resources/mmv/ui/mmv.ui.metadataPanelScroller.js index c763bc2a9..d98f1f28d 100644 --- a/resources/mmv/ui/mmv.ui.metadataPanelScroller.js +++ b/resources/mmv/ui/mmv.ui.metadataPanelScroller.js @@ -24,16 +24,12 @@ class MetadataPanelScroller extends UiElement { /** * @param {jQuery} $container The container for the panel (.mw-mmv-post-image). * @param {jQuery} $aboveFold The control bar element (.mw-mmv-above-fold). - * @param {mw.SafeStorage} localStorage the localStorage object, for dependency injection */ - constructor( $container, $aboveFold, localStorage ) { + constructor( $container, $aboveFold ) { super( $container ); this.$aboveFold = $aboveFold; - /** @property {mw.SafeStorage} localStorage */ - this.localStorage = localStorage; - /** @property {boolean} panelWasOpen state flag which will be used to detect open <-> closed transitions */ this.panelWasOpen = null; @@ -66,9 +62,9 @@ class MetadataPanelScroller extends UiElement { }, 250 ) ); this.$container.on( 'mmv-metadata-open', () => { - if ( !this.hasOpenedMetadata && this.localStorage.store ) { + if ( !this.hasOpenedMetadata && mw.storage.store ) { this.hasOpenedMetadata = true; - this.localStorage.set( 'mmv.hasOpenedMetadata', '1' ); + mw.storage.set( 'mmv.hasOpenedMetadata', '1' ); } } ); @@ -133,7 +129,7 @@ class MetadataPanelScroller extends UiElement { } initialize() { - const value = this.localStorage.get( 'mmv.hasOpenedMetadata' ); + const value = mw.storage.get( 'mmv.hasOpenedMetadata' ); // localStorage will only store strings; if values `null`, `false` or // `0` are set, they'll come out as `"null"`, `"false"` or `"0"`, so we diff --git a/tests/qunit/mmv/mmv.Config.test.js b/tests/qunit/mmv/mmv.Config.test.js index 8856991a0..d2cbe02f9 100644 --- a/tests/qunit/mmv/mmv.Config.test.js +++ b/tests/qunit/mmv/mmv.Config.test.js @@ -18,9 +18,14 @@ const { isMediaViewerEnabledOnClick } = require( 'mmv.head' ); const { Config } = require( 'mmv.bootstrap' ); const { createLocalStorage, getDisabledLocalStorage, getFakeLocalStorage, getUnsupportedLocalStorage } = require( './mmv.testhelpers.js' ); +const storage = mw.storage; ( function () { - QUnit.module( 'mmv.Config', QUnit.newMwEnvironment() ); + QUnit.module( 'mmv.Config', QUnit.newMwEnvironment( { + afterEach: function () { + mw.storage = storage; + } + } ) ); QUnit.test( 'constructor', ( assert ) => { const config = new Config( {}, {}, {}, {}, null ); @@ -28,112 +33,112 @@ const { createLocalStorage, getDisabledLocalStorage, getFakeLocalStorage, getUns } ); QUnit.test( 'getFromLocalStorage', function ( assert ) { - let localStorage, config; + let config; - localStorage = getUnsupportedLocalStorage(); // no browser support - config = new Config( {}, {}, {}, {}, localStorage ); + mw.storage = getUnsupportedLocalStorage(); // no browser support + config = new Config( {}, {}, {}, {} ); assert.strictEqual( config.getFromLocalStorage( 'foo' ), null, 'Returns null when not supported' ); assert.strictEqual( config.getFromLocalStorage( 'foo', 'bar' ), 'bar', 'Returns fallback when not supported' ); - localStorage = getDisabledLocalStorage(); // browser supports it but disabled - config = new Config( {}, {}, {}, {}, localStorage ); + mw.storage = getDisabledLocalStorage(); // browser supports it but disabled + config = new Config( {}, {}, {}, {} ); assert.strictEqual( config.getFromLocalStorage( 'foo' ), null, 'Returns null when disabled' ); assert.strictEqual( config.getFromLocalStorage( 'foo', 'bar' ), 'bar', 'Returns fallback when disabled' ); - localStorage = createLocalStorage( { getItem: this.sandbox.stub() } ); - config = new Config( {}, {}, {}, {}, localStorage ); + mw.storage = createLocalStorage( { getItem: this.sandbox.stub() } ); + config = new Config( {}, {}, {}, {} ); - localStorage.store.getItem.withArgs( 'foo' ).returns( null ); + mw.storage.store.getItem.withArgs( 'foo' ).returns( null ); assert.strictEqual( config.getFromLocalStorage( 'foo' ), null, 'Returns null when key not set' ); assert.strictEqual( config.getFromLocalStorage( 'foo', 'bar' ), 'bar', 'Returns fallback when key not set' ); - localStorage.store.getItem.reset(); - localStorage.store.getItem.withArgs( 'foo' ).returns( 'boom' ); + mw.storage.store.getItem.reset(); + mw.storage.store.getItem.withArgs( 'foo' ).returns( 'boom' ); assert.strictEqual( config.getFromLocalStorage( 'foo' ), 'boom', 'Returns correct value' ); assert.strictEqual( config.getFromLocalStorage( 'foo', 'bar' ), 'boom', 'Returns correct value ignoring fallback' ); } ); QUnit.test( 'setInLocalStorage', function ( assert ) { - let localStorage, config; + let config; - localStorage = getUnsupportedLocalStorage(); // no browser support - config = new Config( {}, {}, {}, {}, localStorage ); + mw.storage = getUnsupportedLocalStorage(); // no browser support + config = new Config( {}, {}, {}, {} ); assert.strictEqual( config.setInLocalStorage( 'foo', 'bar' ), false, 'Returns false when not supported' ); - localStorage = getDisabledLocalStorage(); // browser supports it but disabled - config = new Config( {}, {}, {}, {}, localStorage ); + mw.storage = getDisabledLocalStorage(); // browser supports it but disabled + config = new Config( {}, {}, {}, {} ); assert.strictEqual( config.setInLocalStorage( 'foo', 'bar' ), false, 'Returns false when disabled' ); - localStorage = createLocalStorage( { setItem: this.sandbox.stub(), removeItem: this.sandbox.stub() } ); - config = new Config( {}, {}, {}, {}, localStorage ); + mw.storage = createLocalStorage( { setItem: this.sandbox.stub(), removeItem: this.sandbox.stub() } ); + config = new Config( {}, {}, {}, {} ); assert.strictEqual( config.setInLocalStorage( 'foo', 'bar' ), true, 'Returns true when works' ); - localStorage.store.setItem.throwsException( 'localStorage full!' ); + mw.storage.store.setItem.throwsException( 'localStorage full!' ); assert.strictEqual( config.setInLocalStorage( 'foo', 'bar' ), false, 'Returns false on error' ); } ); QUnit.test( 'Localstorage remove', function ( assert ) { - let localStorage, config; + let config; - localStorage = getUnsupportedLocalStorage(); // no browser support - config = new Config( {}, {}, {}, {}, localStorage ); + mw.storage = getUnsupportedLocalStorage(); // no browser support + config = new Config( {}, {}, {}, {} ); assert.strictEqual( config.removeFromLocalStorage( 'foo' ), true, 'Returns true when not supported' ); - localStorage = getDisabledLocalStorage(); // browser supports it but disabled - config = new Config( {}, {}, {}, {}, localStorage ); + mw.storage = getDisabledLocalStorage(); // browser supports it but disabled + config = new Config( {}, {}, {}, {} ); assert.strictEqual( config.removeFromLocalStorage( 'foo' ), true, 'Returns true when disabled' ); - localStorage = createLocalStorage( { removeItem: this.sandbox.stub() } ); - config = new Config( {}, {}, {}, {}, localStorage ); + mw.storage = createLocalStorage( { removeItem: this.sandbox.stub() } ); + config = new Config( {}, {}, {}, {} ); assert.strictEqual( config.removeFromLocalStorage( 'foo' ), true, 'Returns true when works' ); } ); QUnit.test( 'isMediaViewerEnabledOnClick', function ( assert ) { - const localStorage = createLocalStorage( { getItem: this.sandbox.stub() } ); + mw.storage = createLocalStorage( { getItem: this.sandbox.stub() } ); const mwConfig = { get: this.sandbox.stub() }; const mwUser = { isNamed: this.sandbox.stub() }; mwUser.isNamed.returns( true ); mwConfig.get.withArgs( 'wgMediaViewer' ).returns( true ); mwConfig.get.withArgs( 'wgMediaViewerOnClick' ).returns( true ); - assert.strictEqual( isMediaViewerEnabledOnClick( mwConfig, mwUser, localStorage ), true, 'Returns true for logged-in with standard settings' ); + assert.strictEqual( isMediaViewerEnabledOnClick( mwConfig, mwUser ), true, 'Returns true for logged-in with standard settings' ); mwUser.isNamed.returns( true ); mwConfig.get.withArgs( 'wgMediaViewer' ).returns( false ); mwConfig.get.withArgs( 'wgMediaViewerOnClick' ).returns( true ); - assert.strictEqual( isMediaViewerEnabledOnClick( mwConfig, mwUser, localStorage ), false, 'Returns false if opted out via user JS flag' ); + assert.strictEqual( isMediaViewerEnabledOnClick( mwConfig, mwUser ), false, 'Returns false if opted out via user JS flag' ); mwUser.isNamed.returns( true ); mwConfig.get.withArgs( 'wgMediaViewer' ).returns( true ); mwConfig.get.withArgs( 'wgMediaViewerOnClick' ).returns( false ); - assert.strictEqual( isMediaViewerEnabledOnClick( mwConfig, mwUser, localStorage ), false, 'Returns false if opted out via preferences' ); + assert.strictEqual( isMediaViewerEnabledOnClick( mwConfig, mwUser ), false, 'Returns false if opted out via preferences' ); mwUser.isNamed.returns( false ); mwConfig.get.withArgs( 'wgMediaViewer' ).returns( false ); mwConfig.get.withArgs( 'wgMediaViewerOnClick' ).returns( true ); - assert.strictEqual( isMediaViewerEnabledOnClick( mwConfig, mwUser, localStorage ), false, 'Returns false if anon user opted out via user JS flag' ); + assert.strictEqual( isMediaViewerEnabledOnClick( mwConfig, mwUser ), false, 'Returns false if anon user opted out via user JS flag' ); mwUser.isNamed.returns( false ); mwConfig.get.withArgs( 'wgMediaViewer' ).returns( true ); mwConfig.get.withArgs( 'wgMediaViewerOnClick' ).returns( false ); - assert.strictEqual( isMediaViewerEnabledOnClick( mwConfig, mwUser, localStorage ), false, 'Returns false if anon user opted out in some weird way' ); // apparently someone created a browser extension to do this + assert.strictEqual( isMediaViewerEnabledOnClick( mwConfig, mwUser ), false, 'Returns false if anon user opted out in some weird way' ); // apparently someone created a browser extension to do this mwUser.isNamed.returns( false ); mwConfig.get.withArgs( 'wgMediaViewer' ).returns( true ); mwConfig.get.withArgs( 'wgMediaViewerOnClick' ).returns( true ); - localStorage.store.getItem.withArgs( 'wgMediaViewerOnClick' ).returns( null ); - assert.strictEqual( isMediaViewerEnabledOnClick( mwConfig, mwUser, localStorage ), true, 'Returns true for anon with standard settings' ); + mw.storage.store.getItem.withArgs( 'wgMediaViewerOnClick' ).returns( null ); + assert.strictEqual( isMediaViewerEnabledOnClick( mwConfig, mwUser ), true, 'Returns true for anon with standard settings' ); mwUser.isNamed.returns( false ); mwConfig.get.withArgs( 'wgMediaViewer' ).returns( true ); mwConfig.get.withArgs( 'wgMediaViewerOnClick' ).returns( true ); - localStorage.store.getItem.withArgs( 'wgMediaViewerOnClick' ).returns( '0' ); - assert.strictEqual( isMediaViewerEnabledOnClick( mwConfig, mwUser, localStorage ), false, 'Returns true for anon opted out via localSettings' ); + mw.storage.store.getItem.withArgs( 'wgMediaViewerOnClick' ).returns( '0' ); + assert.strictEqual( isMediaViewerEnabledOnClick( mwConfig, mwUser ), false, 'Returns true for anon opted out via localSettings' ); } ); QUnit.test( 'setMediaViewerEnabledOnClick sense check', function ( assert ) { - const localStorage = createLocalStorage( { + mw.storage = createLocalStorage( { getItem: this.sandbox.stub(), setItem: this.sandbox.stub(), removeItem: this.sandbox.stub() @@ -142,7 +147,7 @@ const { createLocalStorage, getDisabledLocalStorage, getFakeLocalStorage, getUns const mwConfig = new mw.Map(); mwConfig.set( 'wgMediaViewerEnabledByDefault', false ); const api = { saveOption: this.sandbox.stub().returns( $.Deferred().resolve() ) }; - const config = new Config( {}, mwConfig, mwUser, api, localStorage ); + const config = new Config( {}, mwConfig, mwUser, api ); mwUser.isNamed.returns( true ); api.saveOption.returns( $.Deferred().resolve() ); @@ -151,16 +156,16 @@ const { createLocalStorage, getDisabledLocalStorage, getFakeLocalStorage, getUns mwUser.isNamed.returns( false ); config.setMediaViewerEnabledOnClick( false ); - assert.true( localStorage.store.setItem.called, 'For anons, opt-out is set in localStorage' ); + assert.true( mw.storage.store.setItem.called, 'For anons, opt-out is set in localStorage' ); mwUser.isNamed.returns( false ); config.setMediaViewerEnabledOnClick( true ); - assert.true( localStorage.store.removeItem.called, 'For anons, opt-in means clearing localStorage' ); + assert.true( mw.storage.store.removeItem.called, 'For anons, opt-in means clearing localStorage' ); } ); QUnit.test( 'shouldShowStatusInfo', function ( assert ) { const mwConfig = new mw.Map(); - const fakeLocalStorage = getFakeLocalStorage(); + mw.storage = getFakeLocalStorage(); const mwUser = { isNamed: this.sandbox.stub() }; const api = { saveOption: this.sandbox.stub().returns( $.Deferred().resolve() ) }; @@ -169,7 +174,7 @@ const { createLocalStorage, getDisabledLocalStorage, getFakeLocalStorage, getUns wgMediaViewerOnClick: true, wgMediaViewerEnabledByDefault: true } ); - const config = new Config( {}, mwConfig, mwUser, api, fakeLocalStorage ); + let config = new Config( {}, mwConfig, mwUser, api ); mwUser.isNamed.returns( true ); assert.strictEqual( config.shouldShowStatusInfo(), false, 'Status info is not shown by default' ); @@ -187,14 +192,16 @@ const { createLocalStorage, getDisabledLocalStorage, getFakeLocalStorage, getUns assert.strictEqual( config.shouldShowStatusInfo(), false, 'Further status changes have no effect #2' ); // make sure disabling calls maybeEnableStatusInfo() for logged-in as well - config.localStorage = getFakeLocalStorage(); + mw.storage = getFakeLocalStorage(); + config = new Config( {}, mwConfig, mwUser, api ); mwUser.isNamed.returns( false ); assert.strictEqual( config.shouldShowStatusInfo(), false, 'Status info is not shown by default for logged-in users' ); config.setMediaViewerEnabledOnClick( false ); assert.strictEqual( config.shouldShowStatusInfo(), true, 'Status info is shown after MMV is disabled the first time for logged-in users' ); // make sure popup is not shown immediately on disabled-by-default sites, but still works otherwise - config.localStorage = getFakeLocalStorage(); + mw.storage = getFakeLocalStorage(); + config = new Config( {}, mwConfig, mwUser, api ); mwConfig.set( 'wgMediaViewerEnabledByDefault', false ); assert.strictEqual( config.shouldShowStatusInfo(), false, 'Status info is not shown by default #2' ); config.setMediaViewerEnabledOnClick( true ); diff --git a/tests/qunit/mmv/ui/mmv.ui.metadataPanel.test.js b/tests/qunit/mmv/ui/mmv.ui.metadataPanel.test.js index 7adcd8d5f..b7329bb02 100644 --- a/tests/qunit/mmv/ui/mmv.ui.metadataPanel.test.js +++ b/tests/qunit/mmv/ui/mmv.ui.metadataPanel.test.js @@ -8,8 +8,7 @@ QUnit.test( '.empty()', ( assert ) => { const panel = new MetadataPanel( $qf, $( '
' ).appendTo( $qf ), - mw.storage, - new Config( {}, mw.config, mw.user, new mw.Api(), mw.storage ) + new Config( {}, mw.config, mw.user, new mw.Api() ) ); panel.empty(); @@ -39,8 +38,7 @@ QUnit.test( '.setLocationData()', ( assert ) => { const panel = new MetadataPanel( $qf, $( '
' ).appendTo( $qf ), - mw.storage, - new Config( {}, mw.config, mw.user, new mw.Api(), mw.storage ) + new Config( {}, mw.config, mw.user, new mw.Api() ) ); const fileName = 'Foobar.jpg'; let latitude = 12.3456789; @@ -107,8 +105,7 @@ QUnit.test( '.setImageInfo()', function ( assert ) { const panel = new MetadataPanel( $qf, $( '
' ).appendTo( $qf ), - mw.storage, - new Config( {}, mw.config, mw.user, new mw.Api(), mw.storage ) + new Config( {}, mw.config, mw.user, new mw.Api() ) ); const title = 'Foo bar'; const image = { @@ -178,8 +175,7 @@ QUnit.skip( 'Setting permission information works as expected', ( assert ) => { const panel = new MetadataPanel( $qf, $( '
' ).appendTo( $qf ), - mw.storage, - new Config( {}, mw.config, mw.user, new mw.Api(), mw.storage ) + new Config( {}, mw.config, mw.user, new mw.Api() ) ); // make sure license is visible as it contains the permission @@ -193,8 +189,7 @@ QUnit.test( 'Date formatting', ( assert ) => { const panel = new MetadataPanel( $qf, $( '
' ).appendTo( $qf ), - mw.storage, - new Config( {}, mw.config, mw.user, new mw.Api(), mw.storage ) + new Config( {}, mw.config, mw.user, new mw.Api() ) ); const date1 = 'Garbage'; const result = panel.formatDate( date1 ); @@ -207,7 +202,10 @@ QUnit.test( 'About links', function ( assert ) { this.sandbox.stub( mw.user, 'isAnon' ); // eslint-disable-next-line no-new - new MetadataPanel( $qf.empty(), $( '
' ).appendTo( $qf ), mw.storage, new Config( {}, mw.config, mw.user, new mw.Api(), mw.storage ) ); + new MetadataPanel( + $qf.empty(), $( '
' ).appendTo( $qf ), + new Config( {}, mw.config, mw.user, new mw.Api() ) + ); assert.strictEqual( $qf.find( '.mw-mmv-about-link' ).length, 1, 'About link is created.' ); } ); diff --git a/tests/qunit/mmv/ui/mmv.ui.metadataPanelScroller.test.js b/tests/qunit/mmv/ui/mmv.ui.metadataPanelScroller.test.js index 8cae66398..b11dbebd0 100644 --- a/tests/qunit/mmv/ui/mmv.ui.metadataPanelScroller.test.js +++ b/tests/qunit/mmv/ui/mmv.ui.metadataPanelScroller.test.js @@ -17,18 +17,22 @@ const { createLocalStorage, getFakeLocalStorage, getUnsupportedLocalStorage } = require( '../mmv.testhelpers.js' ); const { MetadataPanelScroller } = require( 'mmv' ); +const storage = mw.storage; ( function () { QUnit.module( 'mmv.ui.metadataPanelScroller', QUnit.newMwEnvironment( { beforeEach: function () { this.clock = this.sandbox.useFakeTimers(); + }, + afterEach: function () { + mw.storage = storage; } } ) ); QUnit.test( 'empty()', ( assert ) => { const $qf = $( '#qunit-fixture' ); - const localStorage = getFakeLocalStorage(); - const scroller = new MetadataPanelScroller( $qf, $( '
' ).appendTo( $qf ), localStorage ); + mw.storage = getFakeLocalStorage(); + const scroller = new MetadataPanelScroller( $qf, $( '
' ).appendTo( $qf ) ); scroller.empty(); assert.strictEqual( scroller.$container.hasClass( 'invite' ), false, 'We successfully reset the invite' ); @@ -37,7 +41,7 @@ const { MetadataPanelScroller } = require( 'mmv' ); QUnit.test( 'Metadata div is only animated once', ( assert ) => { const $qf = $( '#qunit-fixture' ); let displayCount = null; // pretend it doesn't exist at first - const localStorage = createLocalStorage( { + mw.storage = createLocalStorage( { // We simulate localStorage to avoid test side-effects getItem: function () { return displayCount; @@ -49,7 +53,7 @@ const { MetadataPanelScroller } = require( 'mmv' ); displayCount = null; } } ); - const scroller = new MetadataPanelScroller( $qf, $( '
' ).appendTo( $qf ), localStorage ); + const scroller = new MetadataPanelScroller( $qf, $( '
' ).appendTo( $qf ) ); scroller.attach(); @@ -81,8 +85,8 @@ const { MetadataPanelScroller } = require( 'mmv' ); QUnit.test( 'No localStorage', function ( assert ) { const $qf = $( '#qunit-fixture' ); - const localStorage = getUnsupportedLocalStorage(); - const scroller = new MetadataPanelScroller( $qf, $( '
' ).appendTo( $qf ), localStorage ); + mw.storage = getUnsupportedLocalStorage(); + const scroller = new MetadataPanelScroller( $qf, $( '
' ).appendTo( $qf ) ); this.sandbox.stub( $.fn, 'scrollTop', () => 10 ); @@ -93,12 +97,12 @@ const { MetadataPanelScroller } = require( 'mmv' ); QUnit.test( 'localStorage is full', function ( assert ) { const $qf = $( '#qunit-fixture' ); - const localStorage = createLocalStorage( { + mw.storage = createLocalStorage( { getItem: this.sandbox.stub().returns( null ), setItem: this.sandbox.stub().throwsException( 'I am full' ), removeItem: this.sandbox.stub() } ); - const scroller = new MetadataPanelScroller( $qf, $( '
' ).appendTo( $qf ), localStorage ); + const scroller = new MetadataPanelScroller( $qf, $( '
' ).appendTo( $qf ) ); this.sandbox.stub( $.fn, 'scrollTop', () => 10 ); @@ -110,7 +114,7 @@ const { MetadataPanelScroller } = require( 'mmv' ); scroller.scroll(); - assert.true( localStorage.store.setItem.calledOnce, 'localStorage only written once' ); + assert.true( mw.storage.store.setItem.calledOnce, 'localStorage only written once' ); scroller.unattach(); } ); @@ -149,17 +153,17 @@ const { MetadataPanelScroller } = require( 'mmv' ); const $qf = $( '#qunit-fixture' ); const $container = $( '
' ).css( 'height', 100 ).appendTo( $qf ); const $aboveFold = $( '
' ).css( 'height', 50 ).appendTo( $container ); - const fakeLocalStorage = createLocalStorage( { + mw.storage = createLocalStorage( { getItem: this.sandbox.stub().returns( null ), setItem: function () {}, removeItem: function () {} } ); - const scroller = new MetadataPanelScroller( $container, $aboveFold, fakeLocalStorage ); + const scroller = new MetadataPanelScroller( $container, $aboveFold ); const keydown = $.Event( 'keydown' ); stubScrollFunctions( this.sandbox, scroller ); - this.sandbox.stub( fakeLocalStorage.store, 'setItem' ); + this.sandbox.stub( mw.storage.store, 'setItem' ); // First phase of the test: up and down arrows @@ -169,12 +173,12 @@ const { MetadataPanelScroller } = require( 'mmv' ); assert.strictEqual( $window.scrollTop(), 0, 'scrollTop should be set to 0' ); - assert.strictEqual( fakeLocalStorage.store.setItem.called, false, 'The metadata hasn\'t been open yet, no entry in localStorage' ); + assert.strictEqual( mw.storage.store.setItem.called, false, 'The metadata hasn\'t been open yet, no entry in localStorage' ); keydown.which = 38; // Up arrow scroller.keydown( keydown ); - assert.strictEqual( fakeLocalStorage.store.setItem.calledWithExactly( 'mmv.hasOpenedMetadata', '1' ), true, 'localStorage knows that the metadata has been open' ); + assert.strictEqual( mw.storage.store.setItem.calledWithExactly( 'mmv.hasOpenedMetadata', '1' ), true, 'localStorage knows that the metadata has been open' ); keydown.which = 40; // Down arrow scroller.keydown( keydown );