From 334e3536b26bb5a224abb7d3c0504e663c9e1171 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bartosz=20Dziewo=C5=84ski?= Date: Tue, 18 Aug 2015 19:01:34 +0200 Subject: [PATCH] mediawiki.api: Correctly handle boolean parameters Quoting https://www.mediawiki.org/w/api.php#main.2Fdatatypes: Boolean parameters work like HTML checkboxes: if the parameter is specified, regardless of value, it is considered true. For a false value, omit the parameter entirely. Therefore, omit the parameters if the value is `false`. The idea is adapted from MobileFrontend's api.js. Change-Id: I596e14304951f49acc36159cb806b266117fb550 --- resources/src/mediawiki.api/mediawiki.api.js | 32 +++++++++++++++---- .../mediawiki.api/mediawiki.api.test.js | 13 ++++++++ 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/resources/src/mediawiki.api/mediawiki.api.js b/resources/src/mediawiki.api/mediawiki.api.js index 5e3a96225d..cae65c56b1 100644 --- a/resources/src/mediawiki.api/mediawiki.api.js +++ b/resources/src/mediawiki.api/mediawiki.api.js @@ -49,7 +49,7 @@ * console.log( data ); * } ); * - * Multiple values for a parameter can be specified using an array (since MW 1.25): + * Since MW 1.25, multiple values for a parameter can be specified using an array: * * var api = new mw.Api(); * api.get( { @@ -59,6 +59,9 @@ * console.log( data ); * } ); * + * Since MW 1.26, boolean values for a parameter can be specified directly. If the value is + * `false` or `undefined`, the parameter will be omitted from the request, as required by the API. + * * @constructor * @param {Object} [options] See #defaultOptions documentation above. Can also be overridden for * each individual request by passing them to #get or #post (or directly #ajax) later on. @@ -108,6 +111,27 @@ return this.ajax( parameters, ajaxOptions ); }, + /** + * Massage parameters from the nice format we accept into a format suitable for the API. + * + * @private + * @param {Object} parameters (modified in-place) + */ + preprocessParameters: function ( parameters ) { + var key; + // Handle common MediaWiki API idioms for passing parameters + for ( key in parameters ) { + // Multiple values are pipe-separated + if ( $.isArray( parameters[key] ) ) { + parameters[key] = parameters[key].join( '|' ); + } + // Boolean values are only false when not given at all + if ( parameters[key] === false || parameters[key] === undefined ) { + delete parameters[key]; + } + } + }, + /** * Perform the API call. * @@ -130,11 +154,7 @@ delete parameters.token; } - for ( key in parameters ) { - if ( $.isArray( parameters[key] ) ) { - parameters[key] = parameters[key].join( '|' ); - } - } + this.preprocessParameters( parameters ); // If multipart/form-data has been requested and emulation is possible, emulate it if ( 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 de7919828f..26b6f570e6 100644 --- a/tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js +++ b/tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js @@ -90,6 +90,19 @@ 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 ) { + assert.ok( !request.url.match( /foo/ ), 'foo query parameter is not present' ); + assert.ok( request.url.match( /bar=true/ ), 'bar query parameter is present with value true' ); + request.respond( 200, { 'Content-Type': 'application/json' }, '[]' ); + } ); + + api.get( { foo: false, bar: true } ); + } ); + QUnit.test( 'getToken() - cached', function ( assert ) { QUnit.expect( 2 ); var api = new mw.Api(); -- 2.20.1