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

Reply via email to