From: Timo Tijhof Date: Sat, 9 Mar 2019 02:46:38 +0000 (+0000) Subject: mediawiki.cookie: Export config via packageFiles X-Git-Tag: 1.34.0-rc.0~2567^2 X-Git-Url: http://git.cyclocoop.org/data/Luca_Pacioli_%28Gemaelde%29.jpeg?a=commitdiff_plain;h=a0370fe3c9587f5c1ba0a366fd8045e987d61ddb;p=lhc%2Fweb%2Fwiklou.git mediawiki.cookie: Export config via packageFiles * Add a private setDefaults() method to allow mocking from unit tests. * Use matching keys between the data export and the API. * Reduce duplication in the code. * Access the Sinon stub explicitly instead of via the public path. * Remove use of the now-redundant QUnit.newMwEnvironment(). Change-Id: I600332cdb738f0b443549948b9f070f3ccfa12aa --- diff --git a/resources/Resources.php b/resources/Resources.php index cd813639bf..86bca6c6c0 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -1341,7 +1341,17 @@ return [ 'styles' => 'resources/src/mediawiki.checkboxtoggle.styles.css', ], 'mediawiki.cookie' => [ - 'scripts' => 'resources/src/mediawiki.cookie/index.js', + 'localBasePath' => "$IP/resources/src/mediawiki.cookie", + 'remoteBasePath' => "$wgResourceBasePath/resources/src/mediawiki.cookie", + 'packageFiles' => [ + 'index.js', + [ 'name' => 'config.json', 'config' => [ + 'prefix' => 'CookiePrefix', + 'domain' => 'CookieDomain', + 'path' => 'CookiePath', + 'expires' => 'CookieExpiration' + ] ], + ], 'dependencies' => 'jquery.cookie', 'targets' => [ 'desktop', 'mobile' ], ], diff --git a/resources/src/mediawiki.cookie/index.js b/resources/src/mediawiki.cookie/index.js index 76038f6f11..61379aecdb 100644 --- a/resources/src/mediawiki.cookie/index.js +++ b/resources/src/mediawiki.cookie/index.js @@ -1,14 +1,21 @@ ( function () { 'use strict'; + var config = require( './config.json' ), + defaults = { + prefix: config.prefix, + domain: config.domain, + path: config.path, + expires: config.expires, + secure: false + }; + /** - * Provides an API for getting and setting cookies that is - * syntactically and functionally similar to the server-side cookie - * API (`WebRequest#getCookie` and `WebResponse#setcookie`). + * Manage cookies in a way that is syntactically and functionally similar + * to the `WebRequest#getCookie` and `WebResponse#setcookie` methods in PHP. * * @author Sam Smith * @author Matthew Flaschen - * @author Timo Tijhof * * @class mw.cookie * @singleton @@ -18,23 +25,17 @@ /** * Set or delete a cookie. * - * While this is natural in JavaScript, contrary to `WebResponse#setcookie` in PHP, the - * default values for the `options` properties only apply if that property isn't set - * already in your options object (e.g. passing `{ secure: null }` or `{ secure: undefined }` - * overrides the default value for `options.secure`). + * **Note:** If explicitly passing `null` or `undefined` for an options key, + * that will override the default. This is natural in JavaScript, but noted + * here because it is contrary to MediaWiki's `WebResponse#setcookie()` method + * in PHP. * * @param {string} key * @param {string|null} value Value of cookie. If `value` is `null` then this method will * instead remove a cookie by name of `key`. * @param {Object|Date|number} [options] Options object, or expiry date - * @param {Date|number|null} [options.expires] The expiry date of the cookie, or lifetime in seconds. - * - * If `options.expires` is null, then a session cookie is set. - * - * By default cookie expiration is based on `wgCookieExpiration`. Similar to `WebResponse` - * in PHP, we set a session cookie if `wgCookieExpiration` is 0. And for non-zero values - * it is interpreted as lifetime in seconds. - * + * @param {Date|number|null} [options.expires=wgCookieExpiration] The expiry date of the cookie, + * or lifetime in seconds. If `options.expires` is null or 0, then a session cookie is set. * @param {string} [options.prefix=wgCookiePrefix] The prefix of the key * @param {string} [options.domain=wgCookieDomain] The domain attribute of the cookie * @param {string} [options.path=wgCookiePath] The path attribute of the cookie @@ -42,61 +43,35 @@ * (Does **not** use the wgCookieSecure configuration variable) */ set: function ( key, value, options ) { - var config, defaultOptions, date; - - // wgCookieSecure is not used for now, since 'detect' could not work with - // ResourceLoaderStartUpModule, as module cache is not fragmented by protocol. - config = mw.config.get( [ - 'wgCookiePrefix', - 'wgCookieDomain', - 'wgCookiePath', - 'wgCookieExpiration' - ] ); + var date; - defaultOptions = { - prefix: config.wgCookiePrefix, - domain: config.wgCookieDomain, - path: config.wgCookiePath, - secure: false - }; - - // Options argument can also be a shortcut for the expiry - // Expiry can be a Date, number or null - if ( !options || options instanceof Date || typeof options === 'number' ) { - // Also takes care of options = undefined, in which case we also don't need $.extend() - defaultOptions.expires = options; - options = defaultOptions; - } else { - options = $.extend( defaultOptions, options ); + // The 'options' parameter may be a shortcut for the expiry. + if ( arguments.length > 2 && ( !options || options instanceof Date || typeof options === 'number' ) ) { + options = { expires: options }; } + // Apply defaults + options = $.extend( {}, defaults, options ); - // Default to using wgCookieExpiration (lifetime in seconds). - // If wgCookieExpiration is 0, that is considered a special value indicating - // all cookies should be session cookies by default. - if ( options.expires === undefined && config.wgCookieExpiration !== 0 ) { - date = new Date(); - date.setTime( Number( date ) + ( config.wgCookieExpiration * 1000 ) ); - options.expires = date; + // Handle prefix + key = options.prefix + key; + // Don't pass invalid option to $.cookie + delete options.prefix; + + if ( !options.expires ) { + // Session cookie (null or zero) + // Normalize to absent (undefined) for $.cookie. + delete options.expires; } else if ( typeof options.expires === 'number' ) { // Lifetime in seconds date = new Date(); date.setTime( Number( date ) + ( options.expires * 1000 ) ); options.expires = date; - } else if ( options.expires === null ) { - // $.cookie makes a session cookie when options.expires is omitted - delete options.expires; } - // Process prefix - key = options.prefix + key; - delete options.prefix; - - // Process value if ( value !== null ) { value = String( value ); } - // Other options are handled by $.cookie $.cookie( key, value, options ); }, @@ -114,7 +89,7 @@ var result; if ( prefix === undefined || prefix === null ) { - prefix = mw.config.get( 'wgCookiePrefix' ); + prefix = defaults.prefix; } // Was defaultValue omitted? @@ -128,4 +103,13 @@ } }; + if ( window.QUnit ) { + module.exports = { + setDefaults: function ( value ) { + var prev = defaults; + defaults = value; + return prev; + } + }; + } }() ); diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.cookie.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.cookie.test.js index 4606cbd3df..b3f04b705c 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.cookie.test.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.cookie.test.js @@ -2,23 +2,31 @@ var NOW = 9012, // miliseconds DEFAULT_DURATION = 5678, // seconds + jqcookie, + defaults = { + prefix: 'mywiki', + domain: 'example.org', + path: '/path', + expires: DEFAULT_DURATION, + secure: false + }, + setDefaults = require( 'mediawiki.cookie' ).setDefaults, expiryDate = new Date(); expiryDate.setTime( NOW + ( DEFAULT_DURATION * 1000 ) ); - QUnit.module( 'mediawiki.cookie', QUnit.newMwEnvironment( { - setup: function () { - this.stub( $, 'cookie' ).returns( null ); - - this.sandbox.useFakeTimers( NOW ); + QUnit.module( 'mediawiki.cookie', { + beforeEach: function () { + jqcookie = sinon.stub( $, 'cookie' ).returns( null ); + this.clock = sinon.useFakeTimers( NOW ); + this.savedDefaults = setDefaults( defaults ); }, - config: { - wgCookiePrefix: 'mywiki', - wgCookieDomain: 'example.org', - wgCookiePath: '/path', - wgCookieExpiration: DEFAULT_DURATION + afterEach: function () { + jqcookie.restore(); + this.clock.restore(); + setDefaults( this.savedDefaults ); } - } ) ); + } ); QUnit.test( 'set( key, value )', function ( assert ) { var call; @@ -26,7 +34,7 @@ // Simple case mw.cookie.set( 'foo', 'bar' ); - call = $.cookie.lastCall.args; + call = jqcookie.lastCall.args; assert.strictEqual( call[ 0 ], 'mywikifoo' ); assert.strictEqual( call[ 1 ], 'bar' ); assert.deepEqual( call[ 2 ], { @@ -37,19 +45,19 @@ } ); mw.cookie.set( 'foo', null ); - call = $.cookie.lastCall.args; + call = jqcookie.lastCall.args; assert.strictEqual( call[ 1 ], null, 'null removes cookie' ); mw.cookie.set( 'foo', undefined ); - call = $.cookie.lastCall.args; + call = jqcookie.lastCall.args; assert.strictEqual( call[ 1 ], 'undefined', 'undefined is value' ); mw.cookie.set( 'foo', false ); - call = $.cookie.lastCall.args; + call = jqcookie.lastCall.args; assert.strictEqual( call[ 1 ], 'false', 'false is a value' ); mw.cookie.set( 'foo', 0 ); - call = $.cookie.lastCall.args; + call = jqcookie.lastCall.args; assert.strictEqual( call[ 1 ], '0', '0 is value' ); } ); @@ -60,34 +68,34 @@ date.setTime( 1234 ); mw.cookie.set( 'foo', 'bar' ); - options = $.cookie.lastCall.args[ 2 ]; + options = jqcookie.lastCall.args[ 2 ]; assert.deepEqual( options.expires, expiryDate, 'default expiration' ); mw.cookie.set( 'foo', 'bar', date ); - options = $.cookie.lastCall.args[ 2 ]; + options = jqcookie.lastCall.args[ 2 ]; assert.strictEqual( options.expires, date, 'custom expiration as Date' ); date = new Date(); date.setDate( date.getDate() + 1 ); mw.cookie.set( 'foo', 'bar', 86400 ); - options = $.cookie.lastCall.args[ 2 ]; + options = jqcookie.lastCall.args[ 2 ]; assert.deepEqual( options.expires, date, 'custom expiration as lifetime in seconds' ); mw.cookie.set( 'foo', 'bar', null ); - options = $.cookie.lastCall.args[ 2 ]; + options = jqcookie.lastCall.args[ 2 ]; assert.strictEqual( options.expires, undefined, 'null forces session cookie' ); - // Per DefaultSettings.php, when wgCookieExpiration is 0, the default should - // be session cookies - mw.config.set( 'wgCookieExpiration', 0 ); + // Per DefaultSettings.php, if wgCookieExpiration is 0, + // then the default should be session cookies + setDefaults( $.extend( {}, defaults, { expires: 0 } ) ); mw.cookie.set( 'foo', 'bar' ); - options = $.cookie.lastCall.args[ 2 ]; + options = jqcookie.lastCall.args[ 2 ]; assert.strictEqual( options.expires, undefined, 'wgCookieExpiration=0 results in session cookies by default' ); mw.cookie.set( 'foo', 'bar', date ); - options = $.cookie.lastCall.args[ 2 ]; + options = jqcookie.lastCall.args[ 2 ]; assert.strictEqual( options.expires, date, 'custom expiration (with wgCookieExpiration=0)' ); } ); @@ -101,7 +109,7 @@ secure: true } ); - call = $.cookie.lastCall.args; + call = jqcookie.lastCall.args; assert.strictEqual( call[ 0 ], 'myPrefixfoo' ); assert.deepEqual( call[ 2 ], { expires: expiryDate, @@ -121,7 +129,7 @@ secure: true } ); - call = $.cookie.lastCall.args; + call = jqcookie.lastCall.args; assert.strictEqual( call[ 0 ], 'myPrefixfoo' ); assert.deepEqual( call[ 2 ], { expires: date, @@ -136,19 +144,19 @@ mw.cookie.get( 'foo' ); - key = $.cookie.lastCall.args[ 0 ]; + key = jqcookie.lastCall.args[ 0 ]; assert.strictEqual( key, 'mywikifoo', 'Default prefix' ); mw.cookie.get( 'foo', undefined ); - key = $.cookie.lastCall.args[ 0 ]; + key = jqcookie.lastCall.args[ 0 ]; assert.strictEqual( key, 'mywikifoo', 'Use default prefix for undefined' ); mw.cookie.get( 'foo', null ); - key = $.cookie.lastCall.args[ 0 ]; + key = jqcookie.lastCall.args[ 0 ]; assert.strictEqual( key, 'mywikifoo', 'Use default prefix for null' ); mw.cookie.get( 'foo', '' ); - key = $.cookie.lastCall.args[ 0 ]; + key = jqcookie.lastCall.args[ 0 ]; assert.strictEqual( key, 'foo', 'Don\'t use default prefix for empty string' ); value = mw.cookie.get( 'foo' ); @@ -161,7 +169,7 @@ QUnit.test( 'get( key ) - with value', function ( assert ) { var value; - $.cookie.returns( 'bar' ); + jqcookie.returns( 'bar' ); value = mw.cookie.get( 'foo' ); assert.strictEqual( value, 'bar', 'Return value of cookie' ); @@ -172,7 +180,7 @@ mw.cookie.get( 'foo', 'bar' ); - key = $.cookie.lastCall.args[ 0 ]; + key = jqcookie.lastCall.args[ 0 ]; assert.strictEqual( key, 'barfoo' ); } );