jenkins-bot has submitted this change and it was merged.
Change subject: mediawiki.api.test: Refactor to embrace async
......................................................................
mediawiki.api.test: Refactor to embrace async
This was using lots of synchronous hacks but those don't work in newer
versions of Sinon.JS (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(-)
Approvals:
Gilles: Looks good to me, approved
Jforrester: Looks good to me, but someone else must approve
Esanders: Looks good to me, but someone else must approve
jenkins-bot: Verified
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..520db42 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' } );
} );
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' ] } );
} );
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 } );
} );
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: merged
Gerrit-Change-Id: I08b08ea3c3e8b41f4aea50d86b2c9dc0f579ba67
Gerrit-PatchSet: 5
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Krinkle <[email protected]>
Gerrit-Reviewer: Bartosz DziewoĆski <[email protected]>
Gerrit-Reviewer: Esanders <[email protected]>
Gerrit-Reviewer: Gilles <[email protected]>
Gerrit-Reviewer: Jforrester <[email protected]>
Gerrit-Reviewer: Krinkle <[email protected]>
Gerrit-Reviewer: Legoktm <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits