JGonera has submitted this change and it was merged.
Change subject: Bug 45516: Rewrite getToken function
......................................................................
Bug 45516: Rewrite getToken function
It now returns a deferred object which is passed undefined, false or the token
Change-Id: Ib0fd3da664239bdb7866433acdbb452bfa28c89d
---
M javascripts/common/mf-api.js
M javascripts/modules/mf-photo.js
M javascripts/modules/mf-watchstar.js
M tests/js/test_mf-api.js
4 files changed, 137 insertions(+), 53 deletions(-)
Approvals:
JGonera: Verified; Looks good to me, approved
jenkins-bot: Checked
diff --git a/javascripts/common/mf-api.js b/javascripts/common/mf-api.js
index e3b2c87..0f58091 100644
--- a/javascripts/common/mf-api.js
+++ b/javascripts/common/mf-api.js
@@ -113,15 +113,26 @@
} );
};
- Api.prototype.getToken = function( tokenType, callback, endpoint ) {
- var data;
+ /**
+ * Retrieves a token for a given endpoint
+ *
+ * @param {String} tokenType: Name of the type of token needed e.g.
edit, upload - defaults to edit
+ * @param {String} endpoint: Optional alternative host to query via CORS
+ * @return {jQuery.Deferred} Object returned by $.ajax(), callback will
be passed
+ * the token string, false if the user is anon or undefined where not
available or a warning is set
+ */
+ Api.prototype.getToken = function( tokenType, endpoint ) {
+ var data, d = $.Deferred();
+
+ tokenType = tokenType || 'edit';
+
if ( !this.tokenCache[ endpoint ] ) {
this.tokenCache[ endpoint ] = {};
}
if ( !M.isLoggedIn() ) {
- callback( {} ); // return no token
+ return d.reject( 'Token requested when not logged in.'
);
} else if ( this.tokenCache[ endpoint ].hasOwnProperty(
tokenType ) ) {
- this.tokenCache[ endpoint ][ tokenType ].done( callback
);
+ return this.tokenCache[ endpoint ][ tokenType ];
} else {
data = {
action: 'tokens',
@@ -130,10 +141,24 @@
if ( endpoint ) {
data.origin = M.getOrigin();
}
- this.tokenCache[ endpoint ][ tokenType ] = this.ajax(
data, {
- url: endpoint || M.getApiUrl(),
- xhrFields: { 'withCredentials': true }
- } ).done( callback );
+ this.ajax( data, {
+ url: endpoint || M.getApiUrl(),
+ xhrFields: { withCredentials: true }
+ } ).then( function( tokenData ) {
+ var token;
+ if ( tokenData && tokenData.tokens &&
!tokenData.warnings ) {
+ token = tokenData.tokens[
tokenType + 'token' ];
+ if ( token && token !== '+\\' )
{
+ d.resolve( token );
+ } else {
+ d.reject( 'Anonymous
token.' );
+ }
+ } else {
+ d.reject( 'Bad token name.' );
+ }
+ } );
+ this.tokenCache[ endpoint ][ tokenType ] = d;
+ return d;
}
};
diff --git a/javascripts/modules/mf-photo.js b/javascripts/modules/mf-photo.js
index 71b6031..c0f163c 100644
--- a/javascripts/modules/mf-photo.js
+++ b/javascripts/modules/mf-photo.js
@@ -66,11 +66,11 @@
PhotoApi = Api.extend( {
updatePage: function( options, callback ) {
var self = this;
- self.getToken( 'edit', function( tokenData ) {
+ self.getToken().done( function( token ) {
self.post( {
action: 'edit',
title: options.pageTitle,
- token: tokenData.tokens.edittoken,
+ token: token,
summary: mw.msg(
'mobile-frontend-photo-upload-comment' ),
prependtext: '[[File:' +
options.fileName + '|thumbnail|' + options.description + ']]\n\n'
} ).done( callback );
@@ -149,19 +149,11 @@
}
} );
}
- self.getToken( 'edit', function( tokenData ) {
- var token;
- if ( tokenData && tokenData.tokens ) {
- token = tokenData.tokens.edittoken;
- if ( token && token !== '+\\' ) { //
ensure not anonymous..
- doUpload( token );
- } else {
- result.reject( 'Anonymous or
absent token' );
- }
- } else {
- result.reject( 'Missing token' );
- }
- }, endpoint );
+ self.getToken( 'edit', endpoint ).done( function( token
) {
+ doUpload( token );
+ } ).fail( function( err ) {
+ result.reject( err );
+ } );
return result;
}
diff --git a/javascripts/modules/mf-watchstar.js
b/javascripts/modules/mf-watchstar.js
index 609ff4d..b1c162b 100644
--- a/javascripts/modules/mf-watchstar.js
+++ b/javascripts/modules/mf-watchstar.js
@@ -76,8 +76,8 @@
}
function toggleWatchStatus( unwatch ) {
- api.getToken( 'watch', function( data ) {
- toggleWatch( title, data.tokens.watchtoken,
unwatch, success, enable );
+ api.getToken( 'watch' ).done( function( token ) {
+ toggleWatch( title, token, unwatch, success,
enable );
} );
}
@@ -142,24 +142,22 @@
function initWatchListIcon( container, title ) {
var drawer = new nav.CtaDrawer( { content: mw.msg(
'mobile-frontend-watchlist-cta' ) } );
- api.getToken( 'watch', function( data ) {
- if( data.tokens && !data.warnings ) { // then user is
logged in
- lastToken = data.tokens.watchtoken;
- checkWatchStatus( [ title ], function( status )
{
- createWatchListButton( container,
title, status[ title ] );
- } );
- } else {
- $( createButton( container ) ).click( function(
ev ) {
- if ( !drawer.isVisible() ) {
- // log if enabled
- logWatchEvent( 2 );
- drawer.show();
- } else {
- drawer.hide();
- }
- ev.stopPropagation();
- } );
- }
+ api.getToken( 'watch' ).done( function( token ) {
+ lastToken = token;
+ checkWatchStatus( [ title ], function( status ) {
+ createWatchListButton( container, title,
status[ title ] );
+ } );
+ } ).fail( function() {
+ $( createButton( container ) ).click( function( ev ) {
+ if ( !drawer.isVisible() ) {
+ // log if enabled
+ logWatchEvent( 2 );
+ drawer.show();
+ } else {
+ drawer.hide();
+ }
+ ev.stopPropagation();
+ } );
} );
}
@@ -184,17 +182,15 @@
createWatchListButton( this, title, true );
} );
} else {
- api.getToken( 'watch', function( data ) {
- if( data.tokens && !data.warnings ) {
- lastToken = data.tokens.watchtoken;
+ api.getToken( 'watch' ).done( function( token ) {
+ lastToken = token;
- checkWatchStatus( titles, function(
status ) {
- $container.find( 'li' ).each(
function() {
- var title = $( this
).attr( 'title' );
- createWatchListButton(
this, title, status[ title ] );
- } );
+ checkWatchStatus( titles, function( status ) {
+ $container.find( 'li' ).each(
function() {
+ var title = $( this ).attr(
'title' );
+ createWatchListButton( this,
title, status[ title ] );
} );
- }
+ } );
} );
}
}
diff --git a/tests/js/test_mf-api.js b/tests/js/test_mf-api.js
index c59e8db..534713b 100644
--- a/tests/js/test_mf-api.js
+++ b/tests/js/test_mf-api.js
@@ -1,6 +1,6 @@
( function ( M, $ ) {
-var Api = M.require( 'api' ).Api;
+var Api = M.require( 'api' ).Api, stub;
module( 'MobileFrontend api', {
setup: function() {
@@ -100,4 +100,75 @@
} );
} );
+module( 'MobileFrontend api.getToken', {
+ setup: function() {
+ var params, corsParams, corsData,
+ editDeferred = $.Deferred().resolve( { tokens: {
'edittoken': '123' } } ),
+ uploadAnonDeferred = $.Deferred().resolve( { tokens: {
'uploadtoken': '+\\' } } ),
+ corsDeferred = $.Deferred().resolve( { tokens: {
'watchtoken': 'zyx' } } ),
+ warningDeferred = $.Deferred().resolve( { warning: 'you
passed a bad watch token' } );
+
+ this.api = new Api();
+ stub = sinon.stub( this.api , 'ajax' );
+ params = {
+ url: M.getApiUrl(),
+ xhrFields: { withCredentials: true }
+ };
+ corsData = { action: 'tokens', type: 'watch',
+ origin: M.getOrigin()
+ };
+ corsParams = {
+ url: 'http://commons.wikimedia.org/w/api.php',
+ xhrFields: { withCredentials: true }
+ };
+
+ stub.withArgs( { action: 'tokens', type: 'rainbows' }, params
).returns( warningDeferred );
+ stub.withArgs( { action: 'tokens', type: 'edit' }, params
).returns( editDeferred );
+ stub.withArgs( { action: 'tokens', type: 'upload' }, params
).returns( uploadAnonDeferred );
+ stub.withArgs( corsData, corsParams ).returns( corsDeferred );
+ },
+ teardown: function() {
+ stub.restore();
+ }
+} );
+
+test( '#getToken - successful edit token', function() {
+ this.api.getToken( 'edit' ).done( function( token ) {
+ strictEqual( token, '123', 'Got token' );
+ } );
+} );
+
+test( '#getToken - load from cache', function() {
+ this.api.getToken( 'edit' );
+ this.api.getToken( 'edit' ).done( function( token ) { // this comes via
cache
+ strictEqual( token, '123', 'Test for bad token name' );
+ } );
+
+ strictEqual( stub.getCall( 1 ), null, 'Ajax stub was only called once'
);
+} );
+
+test( '#getToken - cors edit token', function() {
+ this.api.getToken( 'watch', 'http://commons.wikimedia.org/w/api.php'
).done( function( token ) {
+ strictEqual( token, 'zyx', 'Correctly passed via cors' );
+ } );
+} );
+
+test( '#getToken - default to edit', function() {
+ this.api.getToken().done( function( token ) {
+ strictEqual( token, '123', 'We get an edit token by default
(most common)' );
+ } );
+} );
+
+test( '#getToken - get anon token', function() {
+ this.api.getToken( 'upload' ).fail( function( msg ) {
+ strictEqual( msg, 'Anonymous token.', 'No token given - user
must be anon' );
+ } );
+} );
+
+test( '#getToken - bad type of token', function() {
+ this.api.getToken( 'rainbows' ).fail( function( msg ) {
+ strictEqual( msg, 'Bad token name.', 'Test for bad token name'
);
+ } );
+} );
+
}( mw.mobileFrontend, jQuery ) );
--
To view, visit https://gerrit.wikimedia.org/r/52317
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ib0fd3da664239bdb7866433acdbb452bfa28c89d
Gerrit-PatchSet: 5
Gerrit-Project: mediawiki/extensions/MobileFrontend
Gerrit-Branch: master
Gerrit-Owner: Jdlrobson <[email protected]>
Gerrit-Reviewer: JGonera <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits