summaryrefslogtreecommitdiff
path: root/tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js
diff options
context:
space:
mode:
Diffstat (limited to 'tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js')
-rw-r--r--tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js312
1 files changed, 312 insertions, 0 deletions
diff --git a/tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js b/tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js
new file mode 100644
index 00000000..f156c728
--- /dev/null
+++ b/tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js
@@ -0,0 +1,312 @@
+( function ( mw ) {
+ QUnit.module( 'mediawiki.api', QUnit.newMwEnvironment( {
+ setup: function () {
+ this.server = this.sandbox.useFakeServer();
+ }
+ } ) );
+
+ QUnit.test( 'Basic functionality', function ( assert ) {
+ QUnit.expect( 2 );
+
+ var api = new mw.Api();
+
+ api.get( {} )
+ .done( function ( data ) {
+ assert.deepEqual( data, [], 'If request succeeds without errors, resolve deferred' );
+ } );
+
+ api.post( {} )
+ .done( function ( data ) {
+ assert.deepEqual( data, [], 'Simple POST request' );
+ } );
+
+ this.server.respond( function ( request ) {
+ request.respond( 200, { 'Content-Type': 'application/json' }, '[]' );
+ } );
+ } );
+
+ QUnit.test( 'API error', function ( assert ) {
+ QUnit.expect( 1 );
+
+ var api = new mw.Api();
+
+ api.get( { action: 'doesntexist' } )
+ .fail( function ( errorCode ) {
+ assert.equal( errorCode, 'unknown_action', 'API error should reject the deferred' );
+ } );
+
+ this.server.respond( function ( request ) {
+ request.respond( 200, { 'Content-Type': 'application/json' },
+ '{ "error": { "code": "unknown_action" } }'
+ );
+ } );
+ } );
+
+ QUnit.test( 'FormData support', function ( assert ) {
+ QUnit.expect( 2 );
+
+ var api = new mw.Api();
+
+ api.post( { action: 'test' }, { contentType: 'multipart/form-data' } );
+
+ this.server.respond( function ( request ) {
+ if ( window.FormData ) {
+ assert.ok( !request.url.match( /action=/), 'Request has no query string' );
+ assert.ok( request.requestBody instanceof FormData, 'Request uses FormData body' );
+ } else {
+ assert.ok( !request.url.match( /action=test/), 'Request has no query string' );
+ assert.equal( request.requestBody, 'action=test&format=json', 'Request uses query string body' );
+ }
+ request.respond( 200, { 'Content-Type': 'application/json' }, '[]' );
+ } );
+ } );
+
+ QUnit.test( 'Deprecated callback methods', function ( assert ) {
+ QUnit.expect( 3 );
+
+ var api = new mw.Api();
+
+ this.suppressWarnings();
+
+ api.get( {}, function () {
+ assert.ok( true, 'Function argument treated as success callback.' );
+ } );
+
+ api.get( {}, {
+ ok: function () {
+ assert.ok( true, '"ok" property treated as success callback.' );
+ }
+ } );
+
+ api.get( { action: 'doesntexist' }, {
+ err: function () {
+ assert.ok( true, '"err" property treated as error callback.' );
+ }
+ } );
+
+ this.restoreWarnings();
+
+ this.server.respondWith( /action=query/, function ( request ) {
+ request.respond( 200, { 'Content-Type': 'application/json' }, '[]' );
+ } );
+
+ this.server.respondWith( /action=doesntexist/, function ( request ) {
+ request.respond( 200, { 'Content-Type': 'application/json' },
+ '{ "error": { "code": "unknown_action" } }'
+ );
+ } );
+
+ this.server.respond();
+ } );
+
+ QUnit.test( 'getToken( pre-populated )', function ( assert ) {
+ QUnit.expect( 2 );
+
+ var api = new mw.Api();
+
+ // Get editToken for local wiki, this should not make
+ // a request as it should be retrieved from user.tokens.
+ api.getToken( 'edit' )
+ .done( function ( token ) {
+ assert.ok( token.length, 'Got a token' );
+ } )
+ .fail( function ( err ) {
+ assert.equal( '', err, 'API error' );
+ } );
+
+ assert.equal( this.server.requests.length, 0, 'Requests made' );
+ } );
+
+ QUnit.test( 'getToken()', function ( assert ) {
+ QUnit.expect( 5 );
+
+ var test = this,
+ api = new mw.Api();
+
+ // Get a token of a type that isn't prepopulated by user.tokens.
+ // Could use "block" or "delete" here, but those could in theory
+ // be added to user.tokens, use a fake one instead.
+ api.getToken( 'testaction' )
+ .done( function ( token ) {
+ assert.ok( token.length, 'Got testaction token' );
+ } )
+ .fail( function ( err ) {
+ assert.equal( err, '', 'API error' );
+ } );
+ api.getToken( 'testaction' )
+ .done( function ( token ) {
+ assert.ok( token.length, 'Got testaction token (cached)' );
+ } )
+ .fail( function ( err ) {
+ assert.equal( err, '', 'API error' );
+ } );
+
+ // Don't cache error (bug 65268)
+ api.getToken( 'testaction2' )
+ .fail( function ( err ) {
+ assert.equal( err, 'bite-me', 'Expected error' );
+ } )
+ .always( function () {
+ // 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( 'testaction2' )
+ .done( function ( token ) {
+ assert.ok( token.length, 'Got testaction2 token (error was not be cached)' );
+ } )
+ .fail( function ( err ) {
+ assert.equal( err, '', 'API error' );
+ } );
+
+ assert.equal( test.server.requests.length, 3, 'Requests made' );
+
+ test.server.requests[2].respond( 200, { 'Content-Type': 'application/json' },
+ '{ "tokens": { "testaction2token": "0123abc" } }'
+ );
+ } );
+
+ this.server.requests[0].respond( 200, { 'Content-Type': 'application/json' },
+ '{ "tokens": { "testactiontoken": "0123abc" } }'
+ );
+
+ this.server.requests[1].respond( 200, { 'Content-Type': 'application/json' },
+ '{ "error": { "code": "bite-me", "info": "Smite me, O Mighty Smiter" } }'
+ );
+ } );
+
+ QUnit.test( 'postWithToken( tokenType, params )', function ( assert ) {
+ QUnit.expect( 1 );
+
+ var api = new mw.Api( { ajax: { url: '/postWithToken/api.php' } } );
+
+ // - Requests token
+ // - Performs action=example
+ api.postWithToken( 'testsimpletoken', { action: 'example', key: 'foo' } )
+ .done( function ( data ) {
+ assert.deepEqual( data, { example: { foo: 'quux' } } );
+ } );
+
+ this.server.requests[0].respond( 200, { 'Content-Type': 'application/json' },
+ '{ "tokens": { "testsimpletokentoken": "a-bad-token" } }'
+ );
+
+ this.server.requests[1].respond( 200, { 'Content-Type': 'application/json' },
+ '{ "example": { "foo": "quux" } }'
+ );
+ } );
+
+ QUnit.test( 'postWithToken( tokenType, params, ajaxOptions )', function ( assert ) {
+ QUnit.expect( 3 );
+
+ var api = new mw.Api();
+
+ api.postWithToken(
+ 'edit',
+ {
+ action: 'example'
+ },
+ {
+ headers: {
+ 'X-Foo': 'Bar'
+ }
+ }
+ );
+
+ api.postWithToken(
+ 'edit',
+ {
+ action: 'example'
+ },
+ function () {
+ assert.ok( false, 'This parameter cannot be a callback' );
+ }
+ )
+ .always( 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' );
+
+ this.server.respond( function ( request ) {
+ request.respond( 200, { 'Content-Type': 'application/json' }, '{ "example": "quux" }' );
+ } );
+ } );
+
+ QUnit.test( 'postWithToken() - badtoken', function ( assert ) {
+ QUnit.expect( 1 );
+
+ var api = new mw.Api();
+
+ // - Request: token
+ // - Request: action=example -> badtoken error
+ // - Request: new token
+ // - Request: action=example
+ api.postWithToken( 'testbadtoken', { action: 'example', key: 'foo' } )
+ .done( function ( data ) {
+ assert.deepEqual( data, { example: { foo: 'quux' } } );
+ } );
+
+ this.server.requests[0].respond( 200, { 'Content-Type': 'application/json' },
+ '{ "tokens": { "testbadtokentoken": "a-bad-token" } }'
+ );
+
+ this.server.requests[1].respond( 200, { 'Content-Type': 'application/json' },
+ '{ "error": { "code": "badtoken" } }'
+ );
+
+ this.server.requests[2].respond( 200, { 'Content-Type': 'application/json' },
+ '{ "tokens": { "testbadtokentoken": "a-good-token" } }'
+ );
+
+ this.server.requests[3].respond( 200, { 'Content-Type': 'application/json' },
+ '{ "example": { "foo": "quux" } }'
+ );
+
+ } );
+
+ QUnit.test( 'postWithToken() - badtoken-cached', function ( assert ) {
+ QUnit.expect( 2 );
+
+ var api = new mw.Api();
+
+ // - Request: token
+ // - Request: action=example
+ api.postWithToken( 'testbadtokencache', { action: 'example', key: 'foo' } )
+ .done( function ( data ) {
+ assert.deepEqual( data, { example: { foo: 'quux' } } );
+ } );
+
+ // - Cache: Try previously cached token
+ // - Request: action=example -> badtoken error
+ // - Request: new token
+ // - Request: action=example
+ api.postWithToken( 'testbadtokencache', { action: 'example', key: 'bar' } )
+ .done( function ( data ) {
+ assert.deepEqual( data, { example: { bar: 'quux' } } );
+ } );
+
+ this.server.requests[0].respond( 200, { 'Content-Type': 'application/json' },
+ '{ "tokens": { "testbadtokencachetoken": "a-good-token-once" } }'
+ );
+
+ this.server.requests[1].respond( 200, { 'Content-Type': 'application/json' },
+ '{ "example": { "foo": "quux" } }'
+ );
+
+ this.server.requests[2].respond( 200, { 'Content-Type': 'application/json' },
+ '{ "error": { "code": "badtoken" } }'
+ );
+
+ this.server.requests[3].respond( 200, { 'Content-Type': 'application/json' },
+ '{ "tokens": { "testbadtokencachetoken": "a-good-new-token" } }'
+ );
+
+ this.server.requests[4].respond( 200, { 'Content-Type': 'application/json' },
+ '{ "example": { "bar": "quux" } }'
+ );
+
+ } );
+
+}( mediaWiki ) );