jenkins-bot has submitted this change and it was merged. Change subject: move wikibase.api into own module ......................................................................
move wikibase.api into own module Bug: T68419 Change-Id: I97ceba76ba17bfe266dd4541520ef47ed457d1dc --- M composer.json M lib/resources/Resources.php D lib/resources/api/FormatValueCaller.js D lib/resources/api/ParseValueCaller.js D lib/resources/api/RepoApi.js D lib/resources/api/RepoApiError.js D lib/resources/api/getLocationAgnosticMwApi.js D lib/resources/api/namespace.js D lib/resources/api/resources.php D lib/tests/qunit/api/RepoApi.tests.js D lib/tests/qunit/api/RepoApiError.tests.js M lib/tests/qunit/resources.php 12 files changed, 1 insertion(+), 1,663 deletions(-) Approvals: Henning Snater: Looks good to me, approved jenkins-bot: Verified diff --git a/composer.json b/composer.json index 063d098..ba34747 100644 --- a/composer.json +++ b/composer.json @@ -38,6 +38,7 @@ "wikibase/data-model": "~2.4", "wikibase/data-model-javascript": "~1.0", "wikibase/data-model-serialization": "~1.2", + "wikibase/javascript-api": "~1.0", "wikibase/internal-serialization": "~1.3", "wikibase/serialization-javascript": "~2.0", diff --git a/lib/resources/Resources.php b/lib/resources/Resources.php index 61eeceb..fd3e2ec 100644 --- a/lib/resources/Resources.php +++ b/lib/resources/Resources.php @@ -83,7 +83,6 @@ $modules = array_merge( $modules, - include( __DIR__ . '/api/resources.php' ), include( __DIR__ . '/deprecated/resources.php' ), include( __DIR__ . '/jquery.wikibase/resources.php' ), include( __DIR__ . '/jquery.wikibase-shared/resources.php' ) diff --git a/lib/resources/api/FormatValueCaller.js b/lib/resources/api/FormatValueCaller.js deleted file mode 100644 index 9836a1f..0000000 --- a/lib/resources/api/FormatValueCaller.js +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @licence GNU GPL v2+ - * @author H. Snater < mediaw...@snater.com > - */ -( function( wb, $ ) { - 'use strict'; - - var MODULE = wb.api; - - /** - * @constructor - * - * @param {wikibase.api.RepoApi} api - * @param {dataTypes.DataTypeStore} dataTypeStore - */ - var SELF = MODULE.FormatValueCaller = function( api, dataTypeStore ) { - this._api = api; - this._dataTypeStore = dataTypeStore; - }; - - $.extend( SELF.prototype, { - - /** - * @type {wikibase.api.RepoApi} - */ - _api: null, - - /** - * @type {dataTypes.DataTypeStore} - */ - _dataTypeStore: null, - - /** - * Makes a request to the API to format values on the server side. Will return a jQuery.Promise - * which will be resolved if formatting is successful or rejected if it fails or the API cannot - * be reached. - * @since 0.5 - * - * @param {dataValues.DataValue} dataValue - * @param {string} [dataType] - * @param {string} [outputFormat] - * @param {Object} [options] - * @return {jQuery.Promise} - * Resolved parameters: - * - {string} Formatted DataValue. - * Rejected parameters: - * - {wikibase.api.RepoApiError} - */ - formatValue: function( dataValue, dataType, outputFormat, options ) { - - // Evaluate optional arguments: - if( outputFormat === undefined ) { - if( $.isPlainObject( dataType ) ) { - options = dataType; - dataType = undefined; - } else if( !this._dataTypeStore.hasDataType( dataType ) ) { - outputFormat = dataType; - dataType = undefined; - } - } else if( options === undefined ) { - if( $.isPlainObject( outputFormat ) ) { - options = outputFormat; - outputFormat = undefined; - } - } - - var deferred = $.Deferred(); - - this._api.formatValue( - { - value: dataValue.toJSON(), - type: dataValue.getType() - }, - options, - dataType, - outputFormat - ).done( function( apiResult ) { - if( apiResult.result ) { - deferred.resolve( apiResult.result ); - } else { - deferred.reject( new wb.api.RepoApiError( - 'unexpected-result', - 'The formatter API returned an unexpected result' - ) ); - } - } ).fail( function( code, details ) { - deferred.reject( wb.api.RepoApiError.newFromApiResponse( code, details ) ); - } ); - - return deferred.promise(); - } - - } ); - -}( wikibase, jQuery ) ); diff --git a/lib/resources/api/ParseValueCaller.js b/lib/resources/api/ParseValueCaller.js deleted file mode 100644 index 07cb134..0000000 --- a/lib/resources/api/ParseValueCaller.js +++ /dev/null @@ -1,94 +0,0 @@ -/** - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroended...@gmail.com > - * @author H. Snater < mediaw...@snater.com > - */ -( function( wb, $ ) { -'use strict'; - -var MODULE = wb.api; - -/** - * Provides functionality to parse a value using the API. - * @constructor - * @since 0.5 - * - * @param {wikibase.api.RepoApi} api - */ -var SELF = MODULE.ParseValueCaller = function( api ) { - this._api = api; -}; - -$.extend( SELF.prototype, { - - /** - * @type {wikibase.api.RepoApi} - */ - _api: null, - - /** - * Makes a request to the API to parse values on the server side. Will return a jQuery.Promise - * which will be resolved if the call is successful or rejected if the API fails or can't be reached. - * @since 0.5 - * - * @param {string} parser - * @param {string[]} values - * @param {Object} options - * @return {Object} jQuery.Promise - * Resolved parameters: - * - {Object[]} - * Rejected parameters: - * - {wikibase.api.RepoApiError} - */ - parseValues: function( parser, values, options ) { - var deferred = $.Deferred(); - - options = options || {}; - - this._api.parseValue( parser, values, options ).done( function( response ) { - if( !response.results ) { - deferred.reject( new wb.api.RepoApiError( - 'result-unexpected', - 'The parse API returned an unexpected result' - ) ); - return; - } - - var dataValuesSerializations = []; - - for( var i in response.results ) { - var result = response.results[i]; - - if( result.error ) { - // This is a really strange error format, and it's not supported by - // wikibase.api.RepoApiError.newFromApiResponse, so we have to parse it manually here. - // See bug 72947. - deferred.reject( new wb.api.RepoApiError( - result.messages[0].name, - result.messages[0].html['*'] - ) ); - return; - } - - if( !( result.value && result.type ) ) { - deferred.reject( new wb.api.RepoApiError( 'result-unexpected', 'Unknown API error' ) ); - return; - } - - dataValuesSerializations.push( { - type: result.type, - value: result.value - } ); - } - - deferred.resolve( dataValuesSerializations ); - - } ).fail( function( code, details ) { - deferred.reject( wb.api.RepoApiError.newFromApiResponse( code, details ) ); - } ); - - return deferred.promise(); - } -} ); - -}( wikibase, jQuery ) ); diff --git a/lib/resources/api/RepoApi.js b/lib/resources/api/RepoApi.js deleted file mode 100644 index 8b09a27..0000000 --- a/lib/resources/api/RepoApi.js +++ /dev/null @@ -1,540 +0,0 @@ -/** - * @licence GNU GPL v2+ - * @author Daniel Werner < daniel.wer...@wikimedia.de > - * @author Tobias Gritschacher - * @author H. Snater < mediaw...@snater.com > - * @author Marius Hoch < h...@online.de > - */ -( function( wb, $ ) { -'use strict'; - -var MODULE = wb.api; - -/** - * Constructor to create an API object for interaction with the repo Wikibase API. - * @constructor - * @since 0.5 (in 0.4 without constructor parameters, in 0.3 as wikibase.Api - * without support for client usage) - * - * @param {mediaWiki.Api} api - * - * @throws {Error} if parameters are not specified properly. - */ -var SELF = MODULE.RepoApi = function wbRepoApi( api ) { - if( api === undefined ) { - throw new Error( 'Required parameters not specified properly' ); - } - - this._api = api; -}; - -$.extend( SELF.prototype, { - /** - * @type mediaWiki.Api - */ - _api: null, - - /** - * Creates a new entity with the given type and data. - * - * @param {String} type The type of the entity that should be created. - * @param {Object} [data] The entity data (may be omitted to create an empty entity) - * @return {jQuery.Promise} - */ - createEntity: function( type, data ) { - var params = { - action: 'wbeditentity', - data: JSON.stringify( data ), - 'new': type - }; - return this._post( params ); - }, - - /** - * Edits an entity. - * - * @param {String} id Entity id - * @param {Number} baseRevId Revision id the edit shall be performed on - * @param {Object} data The entity's structure - * @param {Boolean} [clear] Whether to clear whole entity before editing (default: false) - * @return {jQuery.Promise} - */ - editEntity: function( id, baseRevId, data, clear ) { - var params = { - action: 'wbeditentity', - id: id, - baserevid: baseRevId, - data: JSON.stringify( data ) - }; - - if ( clear ) { - params.clear = true; - } - - return this._post( params ); - }, - - /** - * Formats values. - * - * @param {Object} dataValue - * @param {Object} [options] - * @param {string} [dataType] - * @param {string} [outputFormat] - * @return {jQuery.Promise} - */ - formatValue: function( dataValue, options, dataType, outputFormat ) { - var params = { - action: 'wbformatvalue', - datavalue: JSON.stringify( dataValue ), - options: JSON.stringify( options || {} ) - }; - - if( dataType ) { - params.datatype = dataType; - } - - if( outputFormat ) { - params.generate = outputFormat; - } - - return this._api.get( params ); - }, - - /** - * Gets one or more Entities. - * - * @param {String[]|String} ids - * @param {String[]|String} [props] Key(s) of property/ies to retrieve from the API - * default: null (will return all properties) - * @param {String[]} [languages] - * default: null (will return results in all languages) - * @param {String[]|String} [sort] Key(s) of property/ies to sort on - * default: null (unsorted) - * @param {String} [dir] Sort direction may be 'ascending' or 'descending' - * default: null (ascending) - * @return {jQuery.Promise} - */ - getEntities: function( ids, props, languages, sort, dir ) { - var params = { - action: 'wbgetentities', - ids: this._normalizeParam( ids ), - props: this._normalizeParam( props ), - languages: this._normalizeParam( languages ), - sort: this._normalizeParam( sort ), - dir: dir || undefined - }; - - return this._api.get( params ); - }, - - /** - * Gets an Entity which is linked with a given page. - * - * @param {String[]|String} [sites] Site(s) the given page is linked on - * @param {String[]|String} [titles] Linked page(s) - * @param {String[]|String} [props] Key(s) of property/ies to retrieve from the API - * default: null (will return all properties) - * @param {String[]} [languages] - * default: null (will return results in all languages) - * @param {String[]|String} [sort] Key(s) of property/ies to sort on - * default: null (unsorted) - * @param {String} [dir] Sort direction may be 'ascending' or 'descending' - * default: null (ascending) - * @param {boolean} [normalize] Whether to normalize titles server side - * @return {jQuery.Promise} - */ - getEntitiesByPage: function( sites, titles, props, languages, sort, dir, normalize ) { - var params = { - action: 'wbgetentities', - sites: this._normalizeParam( sites ), - titles: this._normalizeParam( titles ), - props: this._normalizeParam( props ), - languages: this._normalizeParam( languages ), - sort: this._normalizeParam( sort ), - dir: dir || undefined, - normalize: normalize || undefined - }; - - return this._api.get( params ); - }, - - /** - * Parses values. - * - * @param {string} parser - * @param {string[]} values - * @param {Object} options - * @return {jQuery.Promise} - */ - parseValue: function( parser, values, options ) { - var params = { - action: 'wbparsevalue', - parser: parser, - values: values.join( '|' ), - options: JSON.stringify( options ) - }; - return this._api.get( params ); - }, - - /** - * Searches for entities containing the given text. - * - * @param {String} search search for this text - * @param {String} language search in this language - * @param {String} type search for this entity type - * @param {Number} limit maximum number of results to return - * @param {Number} offset offset where to continue the search - * @return {jQuery.Promise} - */ - searchEntities: function( search, language, type, limit, offset ) { - var params = { - action: 'wbsearchentities', - search: search, - language: language, - type: type, - limit: limit || undefined, - 'continue': offset || undefined - }; - - return this._api.get( params ); - }, - - /** - * Sets the label of an entity via the API. - * - * @param {String} id entity id - * @param {Number} baseRevId revision id - * @param {String} label the label to set - * @param {String} language the language in which the label should be set - * @return {jQuery.Promise} - */ - setLabel: function( id, baseRevId, label, language ) { - var params = { - action: 'wbsetlabel', - id: id, - value: label, - language: language, - baserevid: baseRevId - }; - return this._post( params ); - }, - - /** - * Sets the description of an entity via the API. - * - * @param {String} id entity id - * @param {Number} baseRevId revision id - * @param {String} description the description to set - * @param {String} language the language in which the description should be set - * @return {jQuery.Promise} - */ - setDescription: function( id, baseRevId, description, language ) { - var params = { - action: 'wbsetdescription', - id: id, - value: description, - language: language, - baserevid: baseRevId - }; - return this._post( params ); - }, - - /** - * Adds and/or remove a number of aliases of an item via the API. - * - * @param {String} id entity id - * @param {Number} baseRevId revision id - * @param {String[]|String} add Alias(es) to add - * @param {String[]|String} remove Alias(es) to remove - * @param {String} language the language in which the aliases should be added/removed - * @return {jQuery.Promise} - */ - setAliases: function( id, baseRevId, add, remove, language ) { - add = this._normalizeParam( add ); - remove = this._normalizeParam( remove ); - var params = { - action: 'wbsetaliases', - id: id, - add: add, - remove: remove, - language: language, - baserevid: baseRevId - }; - return this._post( params ); - }, - - /** - * Creates/Updates an entire claim. - * - * @param {object} claim - * @param {number} baseRevId - * @param {number} [index] The claim index. Only needs to be specified if the claim's index - * within the list of all claims of the parent entity shall be changed. - * @return {jQuery.Promise} - */ - setClaim: function( claim, baseRevId, index ) { - var params = { - action: 'wbsetclaim', - claim: JSON.stringify( claim ), - baserevid: baseRevId - }; - - if( index !== undefined ) { - params.index = index; - } - - return this._post( params ); - }, - - /** - * Creates a claim. - * - * @param {string} entityId Entity id - * @param {number} baseRevId revision id - * @param {string} snakType The type of the snak - * @param {string} property Id of the snak's property - * @param {Object|string} value The value to set the datavalue of the claim's main snak to - * @return {jQuery.Promise} - */ - createClaim: function( entityId, baseRevId, snakType, property, value ) { - var params = { - action: 'wbcreateclaim', - entity: entityId, - baserevid: baseRevId, - snaktype: snakType, - property: property - }; - - if ( value ) { - params.value = JSON.stringify( value ); - } - - return this._post( params ); - }, - - /** - * Removes an existing claim. - * - * @param {String} claimGuid The GUID of the Claim to be removed (wikibase.datamodel.Claim.getGuid) - * @param {Number} [claimRevisionId] - * @return {jQuery.Promise} - */ - removeClaim: function( claimGuid, claimRevisionId ) { - return this._post( { - action: 'wbremoveclaims', - claim: claimGuid, - baserevid: claimRevisionId - } ); - }, - - /** - * Returns claims of a specific entity by providing an entity id or a specific claim by - * providing a claim GUID. - * - * @param {string} entityId Entity id - * @param {string} [propertyId] Only return claims featuring this property - * @param {string} claimGuid GUID of the claim to return. Either claimGuid or entityID has to be - * provided. - * @param {string} [rank] Only return claims of this rank - * @param {string} [props] Optional parts of the claims to return - * @return {jQuery.Promise} - */ - getClaims: function( entityId, propertyId, claimGuid, rank, props ) { - var params = { - action: 'wbgetclaims', - entity: entityId, - property: propertyId, - claim: claimGuid, - rank: rank, - props: props - }; - - return this._api.get( params ); - }, - - /** - * Changes the Main Snak of an existing claim. - * - * @param {string} claimGuid The GUID of the Claim to be changed (wikibase.datamodel.Claim.getGuid) - * @param {number} baseRevId - * @param {string} snakType The type of the snak - * @param {string} property Id of the snak's property - * @param {object} value The value to set the datavalue of the the main snak of the claim to - * @return {jQuery.Promise} - */ - setClaimValue: function( claimGuid, baseRevId, snakType, property, value ) { - var params = { - action: 'wbsetclaimvalue', - claim: claimGuid, - baserevid: baseRevId, - snaktype: snakType, - // NOTE: currently 'wbsetclaimvalue' API allows to change snak type but not property, - // set it anyhow. The abstracted API won't propagate the API warning we will get here. - property: property - }; - - if ( value ) { - params.value = JSON.stringify( value ); - } - - return this._post( params ); - }, - - /** - * Adds a new or updates an existing Reference of a Statement. - * - * @since 0.4 - * - * @param {string} statementGuid - * @param {object} snaks - * @param {number} baseRevId - * @param {string} [referenceHash] A hash of the reference that should be updated. - * If not provided, a new reference is created. - * @param {number} [index] The reference index. Only needs to be specified if the reference's - * index within the list of all references of the parent statement shall be changed or - * when the reference should be inserted at a specific position. - * @return {jQuery.Promise} - */ - setReference: function( statementGuid, snaks, baseRevId, referenceHash, index ) { - var params = { - action: 'wbsetreference', - statement: statementGuid, - snaks: JSON.stringify( snaks ), - baserevid: baseRevId - }; - - if( index === undefined && typeof referenceHash === 'number' ) { - index = referenceHash; - referenceHash = undefined; - } - - if( referenceHash ) { - params.reference = referenceHash; - } - - if( index !== undefined ) { - params.index = index; - } - - return this._post( params ); - }, - - /** - * Will remove one or more existing References of a Statement. - * - * @since 0.4 - * - * @param {string} statementGuid - * @param {string|string[]} referenceHashes One or more hashes of the References to be removed. - * @param {number} baseRevId - * @return {jQuery.Promise} - */ - removeReferences: function( statementGuid, referenceHashes, baseRevId ) { - var params = { - action: 'wbremovereferences', - statement: statementGuid, - references: this._normalizeParam( referenceHashes ), - baserevid: baseRevId - }; - - return this._post( params ); - }, - - /** - * Sets a site link for an item via the API. - * - * @param {String} id entity id - * @param {Number} baseRevId revision id - * @param {String} site the site of the link - * @param {String} title the title to link to - * @param {String[]|String} [badges] the list of badges - * @return {jQuery.Promise} - */ - setSitelink: function( id, baseRevId, site, title, badges ) { - var params = { - action: 'wbsetsitelink', - id: id, - linksite: site, - linktitle: title, - baserevid: baseRevId - }; - - if ( badges ) { - params.badges = this._normalizeParam( badges ); - } - - return this._post( params ); - }, - - /** - * Sets a site link for an item via the API. - * - * @param {string} [fromId] The id to merge from - * @param {string} [toId] The id to merge to - * @param {string[]|string} [ignoreConflicts] Elements of the item to ignore conflicts for - * @param {string} [summary] Summary for the edit - * - * @return {jQuery.Promise} - */ - mergeItems: function( fromId, toId, ignoreConflicts, summary ) { - var params = { - action: 'wbmergeitems', - fromid: fromId, - toid: toId - }; - - if ( ignoreConflicts ) { - params.ignoreconflicts = this._normalizeParam( ignoreConflicts ); - } - - if ( summary ) { - params.summary = summary; - } - - return this._post( params ); - }, - - /** - * Converts the given value into a string usable by the API - * - * @since 0.4 - * - * @param {string[]|string} [value] - * @return {string|undefined} - */ - _normalizeParam: function( value ) { - return $.isArray( value ) ? value.join( '|' ) : ( value || undefined ); - }, - - /** - * Submits the AJAX request to the API of the repo and triggers on the response. This will - * automatically add the required 'token' information for editing into the given parameters - * sent to the API. - * @see mediaWiki.Api.post - * - * @param {Object} params parameters for the API call - * @return {jQuery.Promise} - * Resolved parameters: - * - {*} - * Rejected parameters: - * - {string} - * - {*} - * - * @throws {Error} If a parameter is not specified properly - */ - _post: function( params ) { - // Unconditionally set the bot parameter to match the UI behaviour of core - params.bot = 1; - - $.each( params, function( key, value ) { - if ( value === undefined || value === null ) { - throw new Error( 'Parameter "' + key + '" is not specified properly.' ); - } - } ); - - return this._api.postWithToken( 'edit', params ); - } -} ); - -}( wikibase, jQuery ) ); diff --git a/lib/resources/api/RepoApiError.js b/lib/resources/api/RepoApiError.js deleted file mode 100644 index 36a34ce..0000000 --- a/lib/resources/api/RepoApiError.js +++ /dev/null @@ -1,128 +0,0 @@ -/** - * @licence GNU GPL v2+ - * @author H. Snater < mediaw...@snater.com > - */ -( function( mw, wb, util ) { - 'use strict'; - - var MODULE = wb.api; - var PARENT = Error; - - /** - * Wikibase Repo API Error. - * - * @constructor - * @extends Error - * @since 0.4 - * - * @param {string} code Error code (used to determine the actual error message) - * @param {string} detailedMessage Detailed error information - * @param {string} [action] Generic API action (e.g. "save" or "cancel") used to determine a - * specific message - */ - var constructor = function( code, detailedMessage, action ) { - this.code = code; - this.detailedMessage = detailedMessage; - this.action = action; - - // native Error attributes - this.name = 'Wikibase Repo API Error'; - this.message = this.getMessage(); - }; - - var SELF = MODULE.RepoApiError = util.inherit( 'WbRepoApiError', PARENT, constructor, - { - /** - * Message keys of API related error messages. - * @type {Object} - * @constant - */ - API_ERROR_MESSAGE: { - GENERIC: { - DEFAULT: 'wikibase-error-unexpected', - save: 'wikibase-error-save-generic', - remove: 'wikibase-error-remove-generic' - }, - timeout: { - save: 'wikibase-error-save-timeout', - remove: 'wikibase-error-remove-timeout' - }, - 'no-external-page': 'wikibase-error-ui-no-external-page', - 'edit-conflict': 'wikibase-error-ui-edit-conflict' - }, - - /** - * Gets a short message string. - * @since 0.4 - * - * @return {string} - */ - getMessage: function() { - var msgKey = this.API_ERROR_MESSAGE[this.code]; - - if ( !msgKey || typeof msgKey !== 'string' ) { - if ( msgKey && this.action && msgKey[this.action] ) { - msgKey = msgKey[this.action]; - } else if ( this.action && this.API_ERROR_MESSAGE.GENERIC[this.action] ) { - msgKey = this.API_ERROR_MESSAGE.GENERIC[this.action]; - } else { - msgKey = this.API_ERROR_MESSAGE.GENERIC.DEFAULT; - } - } - - return mw.msg( msgKey ); - } - - } - ); - - /** - * Creates a new RepoApiError out of the values returned from the API. - * @since 0.4 - * - * @param {Object} details Object returned from the API containing detailed information - * @param {string} [apiAction] API action (e.g. 'save', 'remove') that may be passed to - * determine a specific message - * @return {wikibase.api.RepoApiError} - */ - SELF.newFromApiResponse = function( details, apiAction ) { - var errorCode = '', - detailedMessage = ''; - - if ( details.error ) { - errorCode = details.error.code; - if( details.error.messages ) { - // HTML message from Wikibase API. - detailedMessage = messagesObjectToHtml( details.error.messages ); - } else { - // Wikibase API no-HTML error message fall-back. - detailedMessage = details.error.info; - } - } else if ( details.exception ) { - // Failed MediaWiki API call. - errorCode = details.textStatus; - detailedMessage = details.exception; - } - - return new SELF( errorCode, detailedMessage, apiAction ); - }; - - /** - * @param {Object} messages Object returned from the API - * @return {string|undefined} HTML list, single message or undefined if no HTML could be found - */ - function messagesObjectToHtml( messages ) { - // Can't use length, it's not an array! - if ( messages[1] && messages[1].html ) { - var html = '<ul>'; - for ( var i = 0; messages[i]; i++ ) { - html += '<li>' + messages[i].html['*'] + '</li>'; - } - return html + '</ul>'; - } - - return messages[0] && messages[0].html && messages[0].html['*'] - || messages.html && messages.html['*']; - } - -}( mediaWiki, wikibase, util ) ); diff --git a/lib/resources/api/getLocationAgnosticMwApi.js b/lib/resources/api/getLocationAgnosticMwApi.js deleted file mode 100644 index dc2cbd9..0000000 --- a/lib/resources/api/getLocationAgnosticMwApi.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * @licence GNU GPL v2+ - * @author Adrian Lang < adrian.l...@wikimedia.de > - */ -( function( mw, wb ) { -'use strict'; - -/** - * @param {string} url - * @return {string} - */ -function getDomainName( url ) { - return url.replace( /.*\/\//, '' ).replace( /\/.*/, '' ); -} - -/** - * Returns a mediaWiki.Api instance which can transparently interact with remote APIs. - * @since 0.5 - * @todo Merge this into mw.Api - * - * @param {string} apiEndpoint - * @return {mediaWiki.Api} - */ -wb.api.getLocationAgnosticMwApi = function( apiEndpoint ) { - var localApiEndpoint = mw.config.get( 'wgServer' ) - + mw.config.get( 'wgScriptPath' ) - + '/api.php'; - - var mwApiOptions = { - ajax: { - url: apiEndpoint - } - }; - - if ( getDomainName( localApiEndpoint ) !== getDomainName( apiEndpoint ) ) { - // Use CORS if the api we want to use is on a different domain. - // But don't if it's not: CORS isn't required if we are on the same domain, thus it - // might not be configured and fail. - var corsOrigin = mw.config.get( 'wgServer' ); - if ( corsOrigin.indexOf( '//' ) === 0 ) { - // The origin parameter musn't be protocol relative - corsOrigin = document.location.protocol + corsOrigin; - } - - mwApiOptions.ajax.xhrFields = { - withCredentials: true - }; - mwApiOptions.ajax.crossDomain = true; - mwApiOptions.parameters = { - origin: corsOrigin - }; - } - - return new mw.Api( mwApiOptions ); -}; - -}( mediaWiki, wikibase ) ); diff --git a/lib/resources/api/namespace.js b/lib/resources/api/namespace.js deleted file mode 100644 index 3991d16..0000000 --- a/lib/resources/api/namespace.js +++ /dev/null @@ -1,5 +0,0 @@ -( function( wb ) { - 'use strict'; - - wb.api = {}; -}( wikibase ) ); diff --git a/lib/resources/api/resources.php b/lib/resources/api/resources.php deleted file mode 100644 index 86ddd23..0000000 --- a/lib/resources/api/resources.php +++ /dev/null @@ -1,87 +0,0 @@ -<?php -/** - * @license GNU GPL v2+ - * @author Adrian Lang <adrian.l...@wikimedia.de> - */ -return call_user_func( function() { - preg_match( '+' . preg_quote( DIRECTORY_SEPARATOR ) . '(?:vendor|extensions)' - . preg_quote( DIRECTORY_SEPARATOR ) . '.*+', __DIR__, $remoteExtPath ); - - $moduleTemplate = array( - 'localBasePath' => __DIR__, - 'remoteExtPath' => '..' . $remoteExtPath[0], - ); - - return array( - - 'wikibase.api.__namespace' => $moduleTemplate + array( - 'scripts' => array( - 'namespace.js' - ), - 'dependencies' => array( - 'wikibase' // For the namespace - ) - ), - - 'wikibase.api.FormatValueCaller' => $moduleTemplate + array( - 'scripts' => array( - 'FormatValueCaller.js', - ), - 'dependencies' => array( - 'wikibase.api.__namespace', - 'wikibase.api.RepoApiError', - ) - ), - - 'wikibase.api.getLocationAgnosticMwApi' => $moduleTemplate + array( - 'scripts' => array( - 'getLocationAgnosticMwApi.js', - ), - 'dependencies' => array( - 'mediawiki.api', - 'wikibase.api.__namespace', - ), - ), - - 'wikibase.api.ParseValueCaller' => $moduleTemplate + array( - 'scripts' => array( - 'ParseValueCaller.js', - ), - 'dependencies' => array( - 'wikibase.api.__namespace', - 'wikibase.api.RepoApiError', - ) - ), - - 'wikibase.api.RepoApi' => $moduleTemplate + array( - 'scripts' => array( - 'RepoApi.js', - ), - 'dependencies' => array( - 'json', - 'wikibase.api.__namespace', - ), - ), - - 'wikibase.api.RepoApiError' => $moduleTemplate + array( - 'scripts' => array( - 'RepoApiError.js', - ), - 'messages' => array( - 'wikibase-error-unexpected', - 'wikibase-error-save-generic', - 'wikibase-error-remove-generic', - 'wikibase-error-save-timeout', - 'wikibase-error-remove-timeout', - 'wikibase-error-ui-no-external-page', - 'wikibase-error-ui-edit-conflict', - ), - 'dependencies' => array( - 'util.inherit', - 'wikibase.api.__namespace', - ), - ), - - ); - -} ); diff --git a/lib/tests/qunit/api/RepoApi.tests.js b/lib/tests/qunit/api/RepoApi.tests.js deleted file mode 100644 index 0ae19f5..0000000 --- a/lib/tests/qunit/api/RepoApi.tests.js +++ /dev/null @@ -1,516 +0,0 @@ -/** - * QUnit tests for wikibase.api.RepoApi - * @see https://www.mediawiki.org/wiki/Extension:Wikibase - * - * @licence GNU GPL v2+ - * @author H. Snater < mediaw...@snater.com > - */ - -( function( mw, wb, $, QUnit, undefined ) { - 'use strict'; - - var mwApi = new mw.Api(); - - /** - * wikibase.api.RepoApi object - * @var {Object} - */ - var api = new wb.api.RepoApi( mwApi ); - - /** - * Queue used run asynchronous tests synchronously. - * @var {jQuery} - */ - var testrun = $( {} ); - - /** - * Queue key naming the queue that all tests are appended to. - * @var {String} - */ - var qkey = 'asyncTests'; - - /** - * Since jQuery.queue does not allow passing parameters, this variable will cache the data - * structures of entities. - * @var {Object} - */ - var entityStack = []; - - /** - * Triggers running the tests attached to the test queue. - */ - var runTest = function() { - QUnit.stop(); - testrun.queue( qkey, function() { - QUnit.start(); // finish test run - } ); - testrun.dequeue( qkey ); // start tests - }; - - /** - * Handles a failing API request. (The details get logged in the console by mw.Api.) - * - * @param {String} code - * @param {Object} details - */ - var onFail = function( code, details ) { - QUnit.assert.ok( - false, - 'API request failed returning code: "' + code + '". See console for details.' - ); - QUnit.start(); // skip all remaining queued tests - }; - - /** - * Creates an entity via the API. - * - * @param {string} [entityType] Either "item" or "property" - * @param {Object} [data] Stringified JSON representing the entity content - */ - var createEntity = function( entityType, data ) { - data = data || {}; - - api.createEntity( entityType, data ).done( function( response ) { - QUnit.assert.equal( - response.success, - 1, - 'Created ' + entityType + '.' - ); - entityStack.push( response.entity ); - testrun.dequeue( qkey ); - } ).fail( onFail ); - }; - - QUnit.module( 'wikibase.api.RepoApi', QUnit.newMwEnvironment( { - teardown: function() { - entityStack = []; - } - } ) ); - - // This test does nothing more than creating an empty entity. It would not need to invoke a - // queue but can be used as basic template for creating other API tests. - QUnit.test( 'Create an empty entity', function( assert ) { - testrun.queue( qkey, function() { createEntity( 'item' ); } ); - // testrun.queue( qkey, function() { ...; testrun.dequeue( qkey ); } ); - runTest(); - } ); - - QUnit.test( 'Create an empty property', function( assert ) { - testrun.queue( qkey, function() { - createEntity( 'property', { datatype: 'string' } ); - } ); - runTest(); - } ); - - QUnit.test( 'Search for an entity', function( assert ) { - var data = { - labels: { de: { - language: 'de', - value: 'de-search-val' - } } - }; - - testrun.queue( qkey, function() { createEntity( 'item', data ); } ); - - testrun.queue( qkey, function() { - api.searchEntities( data.labels.de.value, data.labels.de.language, 'item', 2, 0 ) - .done( function( response ) { - - assert.ok( - response.search.length > 0, - 'Search results returned.' - ); - assert.equal( - response.search[0].label, - data.labels.de.value, - 'Verified item label.' - ); - - testrun.dequeue( qkey ); - } ) - .fail( onFail ); - } ); - - runTest(); - - }); - - QUnit.test( 'Edit an entity', function( assert ) { - testrun.queue( qkey, function() { createEntity( 'item' ); } ); - - testrun.queue( qkey, function() { - var entity = entityStack[0]; - - var data = { - labels: { - de: { - language: 'de', - value: 'de-value' - }, - en: { - language: 'en', - value: 'en-value' - } - } - }; - - api.editEntity( entity.id, entity.lastrevid, data ).done( function( response ) { - - assert.equal( - response.entity.id, - entity.id, - 'Verified entity id.' - ); - - assert.deepEqual( - response.entity.labels, - data.labels, - 'Edited entity.' - ); - - testrun.dequeue( qkey ); - } ).fail( onFail ); - - } ); - - runTest(); - - } ); - - QUnit.test( 'Create a claim (string value)', function( assert ) { - - testrun.queue( qkey, function() { createEntity( 'item' ); } ); - testrun.queue( qkey, function() { createEntity( 'property', { datatype: 'string' } ); } ); - - testrun.queue( qkey, function() { - var entity = entityStack[0], - property = entityStack[1]; - - api.createClaim( - entity.id, - entity.lastrevid, - 'value', - property.id, - 'This claim is true' - ).done( function( response ) { - - assert.equal( - response.claim.mainsnak.property, - property.id, - 'Verified claim\'s property id.' - ); - - testrun.dequeue( qkey ); - - } ).fail( onFail ); - - } ); - - runTest(); - - } ); - - QUnit.test( 'Get claim (string value)', function( assert ) { - - var answer = '42', entity, property; - - testrun.queue( qkey, function() { createEntity( 'item' ); } ); - testrun.queue( qkey, function() { createEntity( 'property', { datatype: 'string' } ); } ); - - testrun.queue( qkey, function() { - entity = entityStack[0]; - property = entityStack[1]; - - api.createClaim( - entity.id, - entity.lastrevid, - 'value', - property.id, - answer - ).done( function( response ) { - testrun.dequeue( qkey ); - } ).fail( onFail ); - - } ); - - testrun.queue( qkey, function() { - api.getClaims( entity.id, property.id ).done( function( response ) { - - assert.ok( - property.id in response.claims, - 'Claim data for given property found.' - ); - - assert.equal( - response.claims[property.id][0].mainsnak.datavalue.value, - answer, - 'Claim value verified.' - ); - - testrun.dequeue( qkey ); - - } ).fail( onFail ); - - } ); - - runTest(); - - } ); - - /** - * Will test the RepoApi's function to set one of the multilingual basic values, e.g. label or - * description. - * - * @param {Object} assert - * @param {string} type E.g. 'label' or 'description' - * @param {string} apiFnName The name of the wikibase.api.RepoApi function to set the value - */ - function testSetBasicMultiLingualValue( assert, type, apiFnName ) { - var entity, - typesApiPropName = type + 's', // API uses plural form of the type: 'label' -> 'labels' - language = 'en', - value = language + '-' + type; // could be anything really - - testrun.queue( qkey, function() { createEntity( 'item' ); } ); - - testrun.queue( qkey, function() { - entity = entityStack[0]; - - api[ apiFnName ]( - entity.id, entity.lastrevid, value, language - ).done( function( response ) { - - assert.deepEqual( - response.entity[ typesApiPropName ].en, - { language: language, value: value }, - type + ' "' + value + '" has been set for language "' + language + '"' - ); - - testrun.dequeue( qkey ); - } ).fail( onFail ); - } ); - - testrun.queue( qkey, function() { - var setTypeApiPromise = api[ apiFnName ]( - entity.id, entity.lastrevid, value, 'non-existent-language' - ); - - assert.ok( // promise is a plain object, so check for 'then' function - $.isFunction( setTypeApiPromise.then ), - 'wikibase.api.RepoApi.' + apiFnName + ' returns a jQuery Promise' - ); - - - setTypeApiPromise.done( function( response ) { - assert.ok( - false, - 'Impossible to set the ' + type + ' for an unknown language' - ); - QUnit.start(); - } ); - - setTypeApiPromise.fail( function( code, details ) { - assert.equal( - code, - 'unknown_language', - 'Failed trying to set the value on an unknown language' - ); - testrun.dequeue( qkey ); - } ); - } ); - - runTest(); - } - - QUnit.test( 'Set label', function( assert ) { - testSetBasicMultiLingualValue( assert, 'label', 'setLabel' ); - } ); - - QUnit.test( 'Set description', function( assert ) { - testSetBasicMultiLingualValue( assert, 'description', 'setDescription' ); - } ); - -// TODO Re-activate test after having solved problem with edit conflict detection added in change -// set I344d76812649781c83814afb8e9386ff66fc9086 (commit 3680cedf87a7a45296320b12590432bc50a46c5a) -/* - QUnit.test( 'Add and remove site links', function( assert ) { - var data = { - sitelinks: { - dewiki: { - site: 'dewiki', - title: 'Königsberg in Bayern', - badges: [], // this relys on config, so for now only an empty array - url: 'http://de.wikipedia.org/wiki/K%C3%B6nigsberg_in_Bayern' - } - } - }; - - var invalidData = { - sitelinks: { - dewiki: { - site: 'doesnotexist', - title: 'doesnotexist' - } - } - }; - - testrun.queue( qkey, function() { createEntity( 'item' ); } ); - - testrun.queue( qkey, function() { - api.setSitelink( - entity.id, - entity.lastrevid, - data.sitelinks.dewiki.site, - data.sitelinks.dewiki.title, - data.sitelinks.dewiki.badges - ).done( function( response ) { - - assert.deepEqual( - response.entity.sitelinks[data.sitelinks.dewiki.site], - data.sitelinks.dewiki, - 'Set site link.' - ); - - testrun.dequeue( qkey ); - } ).fail( onFail ); - } ); - - testrun.queue( qkey, function() { - api.getEntities( entity.id, 'sitelinks' ).done( function( response ) { - - delete data.sitelinks.dewiki.url; - - assert.deepEqual( - response.entities[entity.id].sitelinks, - data.sitelinks, - 'Verified site link.' - ); - - testrun.dequeue( qkey ); - } ).fail( onFail ); - } ); - - testrun.queue( qkey, function() { - api.setSitelink( - entity.id, - entity.lastrevid, - invalidData.sitelinks.dewiki.site, - invalidData.sitelinks.dewiki.title - ).done( function( response ) { - - assert.ok( - false, - 'It is possible to set an invalid site link.' - ); - - QUnit.start(); - } ).fail( function( code, details ) { - assert.equal( - code, - 'unknown_linksite', - 'Failed trying to set an invalid site link.' - ); - testrun.dequeue( qkey ); - } ); - } ); - - testrun.queue( qkey, function() { - api.getEntities( entity.id, 'sitelinks' ).done( function( response ) { - - assert.deepEqual( - response.entities[entity.id].sitelinks, - [], - 'Verified empty site links.' - ); - - testrun.dequeue( qkey ); - } ).fail( onFail ); - } ); - - runTest(); - - } ); -*/ - QUnit.test( 'Set aliases', function( assert ) { - testrun.queue( qkey, function() { createEntity( 'item' ); } ); - - testrun.queue( qkey, function() { - api.setAliases( - entityStack[0].id, entityStack[0].lastrevid, [ 'alias1', 'alias2' ], [], 'en' - ).done( function( response ) { - - assert.deepEqual( - response.entity.aliases.en, - [ - { language: 'en', value: 'alias1' }, - { language: 'en', value: 'alias2' } - ], - 'Added aliases.' - ); - - testrun.dequeue( qkey ); - } ).fail( onFail ); - } ); - - testrun.queue( qkey, function() { - api.setAliases( - entityStack[0].id, entityStack[0].lastrevid, [ 'alias1', 'alias2' ], [], 'doesnotexist' - ).done( function( response ) { - - assert.ok( - false, - 'It is possible to set aliases for an invalid language.' - ); - - QUnit.start(); - } ).fail( function( code, details ) { - assert.equal( - code, - 'unknown_language', - 'Failed trying to set aliases for an invalid language.' - ); - testrun.dequeue( qkey ); - } ); - } ); - -// TODO Re-activate after having solved problem with edit conflict detection added in change -// set I344d76812649781c83814afb8e9386ff66fc9086 (commit 3680cedf87a7a45296320b12590432bc50a46c5a) -/* - testrun.queue( qkey, function() { - api.setAliases( - entityStack[0].id, entityStack[0].lastrevid, 'alias3', 'alias1', 'en' - ).done( function( response ) { - - assert.deepEqual( - response.entity.aliases.en, - [ - { language: 'en', value: 'alias2' }, - { language: 'en', value: 'alias3' } - ], - 'Added and removed aliases.' - ); - - testrun.dequeue( qkey ); - } ).fail( onFail ); - } ); - - testrun.queue( qkey, function() { - api.setAliases( - entityStack[0].id, entityStack[0].lastrevid, '', [ 'alias2', 'alias3' ], 'en' - ).done( function( response ) { - - assert.equal( - response.entity.aliases, - undefined, - 'Removed aliases.' - ); - - testrun.dequeue( qkey ); - } ).fail( onFail ); - } ); -*/ - runTest(); - - } ); - -}( mediaWiki, wikibase, jQuery, QUnit ) ); diff --git a/lib/tests/qunit/api/RepoApiError.tests.js b/lib/tests/qunit/api/RepoApiError.tests.js deleted file mode 100644 index 12a9e66..0000000 --- a/lib/tests/qunit/api/RepoApiError.tests.js +++ /dev/null @@ -1,114 +0,0 @@ -/** - * @licence GNU GPL v2+ - * @author H. Snater < mediaw...@snater.com > - */ - -( function( wb, mw, QUnit ) { - 'use strict'; - - QUnit.module( 'wikibase.api.RepoApiError' ); - - QUnit.test( 'Create and validate errors', function( assert ) { - var error = new wb.api.RepoApiError( 'error-code', 'detailed message' ); - - assert.equal( - error.code, - 'error-code', - 'Validated error code.' - ); - - assert.equal( - error.detailedMessage, - 'detailed message', - 'Validated error message.' - ); - - assert.equal( - error.message, - mw.msg( 'wikibase-error-unexpected' ), - 'Unknown error code: Used default generic error message.' - ); - - error = new wb.api.RepoApiError( 'timeout', 'detailed message', 'remove' ); - - assert.equal( - error.message, - mw.msg( 'wikibase-error-remove-timeout' ), - 'Picked specific message according to passed "action" parameter.' - ); - - } ); - - QUnit.test( 'Validate errors created via factory method', function( assert ) { - var error = wb.api.RepoApiError.newFromApiResponse( { - error: { code: 'error-code', info: 'detailed message' } - } ); - - assert.equal( - error.code, - 'error-code', - 'Created error object via factory method.' - ); - - assert.equal( - error.detailedMessage, - 'detailed message', - 'Validated detailed message of error created via factory method.' - ); - - error = wb.api.RepoApiError.newFromApiResponse( { - error: { code: 'error-code', messages: { html: { '*': "messages.html['*']" } } } - } ); - - assert.equal( - error.detailedMessage, - "messages.html['*']", - 'Non-array-like object structure kept for compatibility reasons' - ); - - error = wb.api.RepoApiError.newFromApiResponse( { - error: { - code: 'error-code', - messages: { 0: { html: { '*': "messages[0].html['*']" } } } - } - } ); - - assert.equal( - error.detailedMessage, - "messages[0].html['*']", - 'Array-like object structure with a single message' - ); - - error = wb.api.RepoApiError.newFromApiResponse( { - error: { code: 'error-code', messages: { - 0: { html: { '*': "messages[0].html['*']" } }, - 1: { html: { '*': "messages[1].html['*']" } } - } } - } ); - - assert.equal( - error.detailedMessage, - "<ul><li>messages[0].html['*']</li><li>messages[1].html['*']</li></ul>", - 'Array-like object structure with multiple messages' - ); - - error = wb.api.RepoApiError.newFromApiResponse( { - textStatus: 'textStatus', exception: 'exception' - } ); - - assert.equal( - error.code, - 'textStatus', - 'Created error via factory method passing an AJAX exception.' - ); - - assert.equal( - error.detailedMessage, - 'exception', - 'Validated detailed message of error created via factory method passing an AJAX ' - + 'exception.' - ); - - } ); - -}( wikibase, mediaWiki, QUnit ) ); diff --git a/lib/tests/qunit/resources.php b/lib/tests/qunit/resources.php index ed255ec..808b63a 100644 --- a/lib/tests/qunit/resources.php +++ b/lib/tests/qunit/resources.php @@ -25,32 +25,6 @@ 'position' => 'top' ), - 'wikibase.api.RepoApi.tests' => $moduleBase + array( - 'scripts' => array( - 'api/RepoApi.tests.js', - ), - 'dependencies' => array( - 'wikibase', - 'wikibase.api.getLocationAgnosticMwApi', - 'wikibase.api.RepoApi', - ), - ), - - 'wikibase.api.RepoApiError.tests' => $moduleBase + array( - 'scripts' => array( - 'api/RepoApiError.tests.js', - ), - 'dependencies' => array( - 'wikibase', - 'wikibase.api.RepoApiError', - ), - 'messages' => array( - 'wikibase-error-unexpected', - 'wikibase-error-remove-timeout', - 'wikibase-error-ui-client-error', - ), - ), - 'wikibase.Site.tests' => $moduleBase + array( 'scripts' => array( 'wikibase.Site.tests.js', -- To view, visit https://gerrit.wikimedia.org/r/175987 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I97ceba76ba17bfe266dd4541520ef47ed457d1dc Gerrit-PatchSet: 3 Gerrit-Project: mediawiki/extensions/Wikibase Gerrit-Branch: master Gerrit-Owner: Adrian Lang <adrian.l...@wikimedia.de> Gerrit-Reviewer: Aude <aude.w...@gmail.com> Gerrit-Reviewer: Daniel Kinzler <daniel.kinz...@wikimedia.de> Gerrit-Reviewer: Henning Snater <henning.sna...@wikimedia.de> Gerrit-Reviewer: Hoo man <h...@online.de> Gerrit-Reviewer: Thiemo Mättig (WMDE) <thiemo.maet...@wikimedia.de> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits