From: Bartosz DziewoƄski Date: Thu, 30 Apr 2015 23:54:13 +0000 (+0200) Subject: mediawiki.api: Add #badToken for invalidating bad cached tokens X-Git-Tag: 1.31.0-rc.0~11493^2 X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=7b05096bcae04f0b29763e8fd0cfd90b4aff0a08 mediawiki.api: Add #badToken for invalidating bad cached tokens Bug: T71691 Change-Id: I9a270e5ed030513f62dc75ba4e6edc78f4da63a1 --- diff --git a/resources/src/mediawiki.api/mediawiki.api.js b/resources/src/mediawiki.api/mediawiki.api.js index 3a19e021b0..c1fe1879cd 100644 --- a/resources/src/mediawiki.api/mediawiki.api.js +++ b/resources/src/mediawiki.api/mediawiki.api.js @@ -242,11 +242,9 @@ // Error handler function ( code ) { if ( code === 'badtoken' ) { - // Clear from cache - promises[ api.defaults.ajax.url ][ tokenType + 'Token' ] = - params.token = undefined; - + api.badToken( tokenType ); // Try again, once + params.token = undefined; return api.getToken( tokenType, params.assert ).then( function ( token ) { params.token = token; return api.post( params, ajaxOptions ); @@ -281,17 +279,16 @@ d = apiPromise .then( function ( data ) { - // If token type is not available for this user, - // key '...token' is either missing or set to boolean false if ( data.tokens && data.tokens[type + 'token'] ) { return data.tokens[type + 'token']; } + // If token type is not available for this user, + // key '...token' is either missing or set to boolean false return $.Deferred().reject( 'token-missing', data ); }, function () { // Clear promise. Do not cache errors. delete promiseGroup[ type + 'Token' ]; - // Pass on to allow the caller to handle the error return this; } ) @@ -306,6 +303,23 @@ } return d; + }, + + /** + * Indicate that the cached token for a certain action of the API is bad. + * + * Call this if you get a 'badtoken' error when using the token returned by #getToken. + * You may also want to use #postWithToken instead, which invalidates bad cached tokens + * automatically. + * + * @param {string} type Token type + * @since 1.26 + */ + badToken: function ( type ) { + var promiseGroup = promises[ this.defaults.ajax.url ]; + if ( promiseGroup ) { + delete promiseGroup[ type + 'Token' ]; + } } }; diff --git a/tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js b/tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js index b89526fb84..4f199bd3dc 100644 --- a/tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js +++ b/tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js @@ -80,6 +80,7 @@ // Get editToken for local wiki, this should not make // a request as it should be retrieved from user.tokens. + // This means that this test must run before the #badToken test below. api.getToken( 'edit' ) .done( function ( token ) { assert.ok( token.length, 'Got a token' ); @@ -91,6 +92,29 @@ assert.equal( this.server.requests.length, 0, 'Requests made' ); } ); + QUnit.test( 'badToken()', function ( assert ) { + QUnit.expect( 2 ); + + var api = new mw.Api(); + + // Clear the default cached token + api.badToken( 'edit' ); + + api.getToken( 'edit' ) + .done( function ( token ) { + assert.equal( token, '0123abc', 'Got a non-cached token' ); + } ) + .fail( function ( err ) { + assert.equal( '', err, 'API error' ); + } ); + + this.server.requests[0].respond( 200, { 'Content-Type': 'application/json' }, + '{ "tokens": { "edittoken": "0123abc" } }' + ); + + assert.equal( this.server.requests.length, 1, 'Requests made' ); + } ); + QUnit.test( 'getToken()', function ( assert ) { QUnit.expect( 5 );