Krinkle has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/276927

Change subject: mediawiki.api.test: Refactor to embrace async
......................................................................

mediawiki.api.test: Refactor to embrace async

This is currently using lots of synchronous hacks but this isn't supported in
newer Sinon.JS version (and only worked by accident up until now).

The test will still run pretty quick, but it will yield to some extend because
mw.Api and jQuery.ajax both create XHR objects with async=true.

* Remove redundant QUnit.expect() calls (deprecated).
* Make use of QUnit's new Promise-return feature.
  This simplifies some tests by no longer having to call async() or start()
  manually when only dealing with a single promise.

This blocks upgrade of Sinon.JS.

Change-Id: I08b08ea3c3e8b41f4aea50d86b2c9dc0f579ba67
---
M tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js
1 file changed, 92 insertions(+), 100 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/27/276927/1

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 394f3bd..43ec909 100644
--- a/tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js
+++ b/tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js
@@ -3,11 +3,6 @@
                setup: function () {
                        this.server = this.sandbox.useFakeServer();
                        this.server.respondImmediately = true;
-                       this.clock = this.sandbox.useFakeTimers();
-               },
-               teardown: function () {
-                       // https://github.com/jquery/jquery/issues/2453
-                       this.clock.tick();
                }
        } ) );
 
@@ -29,25 +24,27 @@
                return sequence( bodies );
        }
 
-       QUnit.test( 'Basic functionality', function ( assert ) {
-               QUnit.expect( 2 );
+       QUnit.test( 'get()', function ( assert ) {
                var api = new mw.Api();
 
                this.server.respond( [ 200, { 'Content-Type': 
'application/json' }, '[]' ] );
 
-               api.get( {} )
-                       .done( function ( data ) {
-                               assert.deepEqual( data, [], 'If request 
succeeds without errors, resolve deferred' );
-                       } );
+               return api.get( {} ).then( function ( data ) {
+                       assert.deepEqual( data, [], 'If request succeeds 
without errors, resolve deferred' );
+               } );
+       } );
 
-               api.post( {} )
-                       .done( function ( data ) {
-                               assert.deepEqual( data, [], 'Simple POST 
request' );
-                       } );
+       QUnit.test( 'post()', function ( assert ) {
+               var api = new mw.Api();
+
+               this.server.respond( [ 200, { 'Content-Type': 
'application/json' }, '[]' ] );
+
+               return api.post( {} ).then( function ( data ) {
+                       assert.deepEqual( data, [], 'Simple POST request' );
+               } );
        } );
 
        QUnit.test( 'API error', function ( assert ) {
-               QUnit.expect( 1 );
                var api = new mw.Api();
 
                this.server.respond( [ 200, { 'Content-Type': 
'application/json' },
@@ -57,11 +54,11 @@
                api.get( { action: 'doesntexist' } )
                        .fail( function ( errorCode ) {
                                assert.equal( errorCode, 'unknown_action', 'API 
error should reject the deferred' );
-                       } );
+                       } )
+                       .always( assert.async() );
        } );
 
        QUnit.test( 'FormData support', function ( assert ) {
-               QUnit.expect( 2 );
                var api = new mw.Api();
 
                this.server.respond( function ( request ) {
@@ -75,11 +72,10 @@
                        request.respond( 200, { 'Content-Type': 
'application/json' }, '[]' );
                } );
 
-               api.post( { action: 'test' }, { contentType: 
'multipart/form-data' } );
+               return api.post( { action: 'test' }, { contentType: 
'multipart/form-data' } ).promise();
        } );
 
        QUnit.test( 'Converting arrays to pipe-separated', function ( assert ) {
-               QUnit.expect( 1 );
                var api = new mw.Api();
 
                this.server.respond( function ( request ) {
@@ -87,11 +83,10 @@
                        request.respond( 200, { 'Content-Type': 
'application/json' }, '[]' );
                } );
 
-               api.get( { test: [ 'foo', 'bar', 'baz' ] } );
+               return api.get( { test: [ 'foo', 'bar', 'baz' ] } ).promise();
        } );
 
        QUnit.test( 'Omitting false booleans', function ( assert ) {
-               QUnit.expect( 2 );
                var api = new mw.Api();
 
                this.server.respond( function ( request ) {
@@ -100,29 +95,30 @@
                        request.respond( 200, { 'Content-Type': 
'application/json' }, '[]' );
                } );
 
-               api.get( { foo: false, bar: true } );
+               return api.get( { foo: false, bar: true } ).promise();
        } );
 
        QUnit.test( 'getToken() - cached', function ( assert ) {
-               QUnit.expect( 2 );
-               var api = new mw.Api();
+               var api = new mw.Api(),
+                       test = this;
 
                // Get editToken for local wiki, this should not make
                // a request as it should be retrieved from mw.user.tokens.
-               api.getToken( 'edit' )
-                       .done( function ( token ) {
+               return api.getToken( 'edit' )
+                       .then( function ( token ) {
                                assert.ok( token.length, 'Got a token' );
-                       } )
-                       .fail( function ( err ) {
+                       }, function ( err ) {
                                assert.equal( '', err, 'API error' );
+                       } )
+                       .then( function () {
+                               assert.equal( test.server.requests.length, 0, 
'Requests made' );
                        } );
-
-               assert.equal( this.server.requests.length, 0, 'Requests made' );
        } );
 
        QUnit.test( 'getToken() - uncached', function ( assert ) {
-               QUnit.expect( 3 );
-               var api = new mw.Api();
+               var api = new mw.Api(),
+                       firstDone = assert.async(),
+                       secondDone = assert.async();
 
                this.server.respondWith( /type=testuncached/, [ 200, { 
'Content-Type': 'application/json' },
                        '{ "query": { "tokens": { "testuncachedtoken": "good" } 
} }'
@@ -137,7 +133,8 @@
                        } )
                        .fail( function ( err ) {
                                assert.equal( err, '', 'API error' );
-                       } );
+                       } )
+                       .always( firstDone );
 
                api.getToken( 'testuncached' )
                        .done( function ( token ) {
@@ -145,13 +142,13 @@
                        } )
                        .fail( function ( err ) {
                                assert.equal( err, '', 'API error' );
-                       } );
+                       } )
+                       .always( secondDone );
 
                assert.equal( this.server.requests.length, 1, 'Requests made' );
        } );
 
        QUnit.test( 'getToken() - error', function ( assert ) {
-               QUnit.expect( 2 );
                var api = new mw.Api();
 
                this.server.respondWith( /type=testerror/, sequenceBodies( 200, 
{ 'Content-Type': 'application/json' },
@@ -162,42 +159,40 @@
                ) );
 
                // Don't cache error (bug 65268)
-               api.getToken( 'testerror' ).fail( function ( err ) {
-                       assert.equal( err, 'bite-me', 'Expected error' );
+               return api.getToken( 'testerror' )
+                       .then( null, function ( err ) {
+                               assert.equal( err, 'bite-me', 'Expected error' 
);
 
-                       // Make this request after the first one has finished.
-                       // If we make it simultaneously we still want it to 
share
-                       // the cache, but as soon as it is fulfilled as error we
-                       // reject it so that the next one tries fresh.
-                       api.getToken( 'testerror' ).done( function ( token ) {
+                               return api.getToken( 'testerror' );
+                       } )
+                       .then( function ( token ) {
                                assert.equal( token, 'good', 'The token' );
                        } );
-               } );
        } );
 
        QUnit.test( 'getToken() - deprecated', function ( assert ) {
-               QUnit.expect( 2 );
                // Cache API endpoint from default to avoid cachehit in 
mw.user.tokens
-               var api = new mw.Api( { ajax: { url: '/postWithToken/api.php' } 
} );
+               var api = new mw.Api( { ajax: { url: '/postWithToken/api.php' } 
} ),
+                       test = this;
 
                this.server.respondWith( /type=csrf/, [ 200, { 'Content-Type': 
'application/json' },
                        '{ "query": { "tokens": { "csrftoken": "csrfgood" } } }'
                ] );
 
                // Get a token of a type that is in the legacy map.
-               api.getToken( 'email' )
+               return api.getToken( 'email' )
                        .done( function ( token ) {
                                assert.equal( token, 'csrfgood', 'Token' );
                        } )
                        .fail( function ( err ) {
                                assert.equal( err, '', 'API error' );
+                       } )
+                       .always( function () {
+                               assert.equal( test.server.requests.length, 1, 
'Requests made' );
                        } );
-
-               assert.equal( this.server.requests.length, 1, 'Requests made' );
        } );
 
        QUnit.test( 'badToken()', function ( assert ) {
-               QUnit.expect( 2 );
                var api = new mw.Api(),
                        test = this;
 
@@ -208,7 +203,7 @@
                        ]
                ) );
 
-               api.getToken( 'testbad' )
+               return api.getToken( 'testbad' )
                        .then( function () {
                                api.badToken( 'testbad' );
                                return api.getToken( 'testbad' );
@@ -221,7 +216,6 @@
        } );
 
        QUnit.test( 'badToken( legacy )', function ( assert ) {
-               QUnit.expect( 2 );
                var api = new mw.Api( { ajax: { url: '/badTokenLegacy/api.php' 
} } ),
                        test = this;
 
@@ -232,7 +226,7 @@
                        ]
                ) );
 
-               api.getToken( 'options' )
+               return api.getToken( 'options' )
                        .then( function () {
                                api.badToken( 'options' );
                                return api.getToken( 'options' );
@@ -245,7 +239,6 @@
        } );
 
        QUnit.test( 'postWithToken( tokenType, params )', function ( assert ) {
-               QUnit.expect( 1 );
                var api = new mw.Api( { ajax: { url: '/postWithToken/api.php' } 
} );
 
                this.server.respondWith( 'GET', /type=testpost/, [ 200, { 
'Content-Type': 'application/json' },
@@ -259,65 +252,65 @@
                        }
                } );
 
-               api.postWithToken( 'testpost', { action: 'example', key: 'foo' 
} )
-                       .done( function ( data ) {
+               return api.postWithToken( 'testpost', { action: 'example', key: 
'foo' } )
+                       .then( function ( data ) {
                                assert.deepEqual( data, { example: { foo: 
'quux' } } );
                        } );
        } );
 
        QUnit.test( 'postWithToken( tokenType, params with assert )', function 
( assert ) {
-               QUnit.expect( 2 );
-               var api = new mw.Api( { ajax: { url: '/postWithToken/api.php' } 
} );
+               var api = new mw.Api( { ajax: { url: '/postWithToken/api.php' } 
} ),
+                       test = this;
 
                this.server.respondWith( /assert=user/, [ 200, { 
'Content-Type': 'application/json' },
                        '{ "error": { "code": "assertuserfailed", "info": 
"Assertion failed" } }'
                ] );
 
-               api.postWithToken( 'testassertpost', { action: 'example', key: 
'foo', assert: 'user' } )
-                       .fail( function ( errorCode ) {
+               return api.postWithToken( 'testassertpost', { action: 
'example', key: 'foo', assert: 'user' } )
+                       // Cast error to success and vice versa
+                       .then( function ( ) {
+                               return $.Deferred().reject( 'Unexpected 
success' );
+                       }, function ( errorCode ) {
                                assert.equal( errorCode, 'assertuserfailed', 
'getToken fails assert' );
+                               return $.Deferred().resolve();
+                       } )
+                       .then( function () {
+                               assert.equal( test.server.requests.length, 1, 
'Requests made' );
                        } );
-
-               assert.equal( this.server.requests.length, 1, 'Requests made' );
        } );
 
        QUnit.test( 'postWithToken( tokenType, params, ajaxOptions )', function 
( assert ) {
-               QUnit.expect( 3 );
-               var api = new mw.Api();
+               var api = new mw.Api(),
+                       test = this;
 
                this.server.respond( [ 200, { 'Content-Type': 
'application/json' }, '{ "example": "quux" }' ] );
 
-               api.postWithToken(
-                       'edit',
-                       {
-                               action: 'example'
-                       },
-                       {
-                               headers: {
-                                       'X-Foo': 'Bar'
+               return api.postWithToken( 'edit',
+                               { action: 'example' },
+                               {
+                                       headers: {
+                                               'X-Foo': 'Bar'
+                                       }
                                }
-                       }
-               );
+                       )
+                       .then( function () {
+                               assert.equal( test.server.requests[ 0 
].requestHeaders[ 'X-Foo' ], 'Bar', 'Header sent' );
 
-               api.postWithToken(
-                       'edit',
-                       {
-                               action: 'example'
-                       },
-                       function () {
-                               assert.ok( false, 'This parameter cannot be a 
callback' );
-                       }
-               )
-               .always( function ( data ) {
-                       assert.equal( data.example, 'quux' );
-               } );
+                               return api.postWithToken( 'edit',
+                                       { action: 'example' },
+                                       function () {
+                                               assert.ok( false, 'This 
parameter cannot be a callback' );
+                                       }
+                               );
+                       } )
+                       .then( function ( data ) {
+                               assert.equal( data.example, 'quux' );
 
-               assert.equal( this.server.requests.length, 2, 'Request made' );
-               assert.equal( this.server.requests[ 0 ].requestHeaders[ 'X-Foo' 
], 'Bar', 'Header sent' );
+                               assert.equal( test.server.requests.length, 2, 
'Request made' );
+                       } );
        } );
 
        QUnit.test( 'postWithToken() - badtoken', function ( assert ) {
-               QUnit.expect( 1 );
                var api = new mw.Api();
 
                this.server.respondWith( /type=testbadtoken/, sequenceBodies( 
200, { 'Content-Type': 'application/json' },
@@ -343,14 +336,13 @@
                // - Request: action=example -> badtoken error
                // - Request: new token -> good
                // - Request: action=example -> success
-               api.postWithToken( 'testbadtoken', { action: 'example', key: 
'foo' } )
-                       .done( function ( data ) {
+               return api.postWithToken( 'testbadtoken', { action: 'example', 
key: 'foo' } )
+                       .then( function ( data ) {
                                assert.deepEqual( data, { example: { foo: 
'quux' } } );
                        } );
        } );
 
        QUnit.test( 'postWithToken() - badtoken-cached', function ( assert ) {
-               QUnit.expect( 2 );
                var sequenceA,
                        api = new mw.Api();
 
@@ -378,16 +370,16 @@
 
                // - Request: new token -> A
                // - Request: action=example
-               api.postWithToken( 'testonce', { action: 'example', key: 'foo' 
} )
-                       .done( function ( data ) {
+               return api.postWithToken( 'testonce', { action: 'example', key: 
'foo' } )
+                       .then( function ( data ) {
                                assert.deepEqual( data, { example: { value: 'A' 
} } );
-                       } );
 
-               // - Request: action=example w/ token A -> badtoken error
-               // - Request: new token -> B
-               // - Request: action=example w/ token B -> success
-               api.postWithToken( 'testonce', { action: 'example', key: 'bar' 
} )
-                       .done( function ( data ) {
+                               // - Request: action=example w/ token A -> 
badtoken error
+                               // - Request: new token -> B
+                               // - Request: action=example w/ token B -> 
success
+                               return api.postWithToken( 'testonce', { action: 
'example', key: 'bar' } );
+                       } )
+                       .then( function ( data ) {
                                assert.deepEqual( data, { example: { value: 'B' 
} } );
                        } );
        } );

-- 
To view, visit https://gerrit.wikimedia.org/r/276927
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I08b08ea3c3e8b41f4aea50d86b2c9dc0f579ba67
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Krinkle <krinklem...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to