Henning Snater has submitted this change and it was merged.

Change subject: Changes wb.RepoApi.getEntities to promise a collection of 
wb.Entity
......................................................................


Changes wb.RepoApi.getEntities to promise a collection of wb.Entity

Would promise a collection of raw data before.

* changed jQuery.wikibase.snakview to make use of the change (rather than 
break).
* simple refactoring and adjustment of some API test

Change-Id: If80ca6c9048cd9d6880a9c790240fdb4e81cbcc0
---
M lib/resources/Resources.php
M lib/resources/jquery.wikibase/jquery.wikibase.snakview/snakview.js
M lib/resources/wikibase.store/wikibase.RepoApi.js
M lib/tests/qunit/wikibase.store/wikibase.RepoApi.tests.js
4 files changed, 118 insertions(+), 130 deletions(-)

Approvals:
  Henning Snater: Verified; Looks good to me, approved



diff --git a/lib/resources/Resources.php b/lib/resources/Resources.php
index 71d75fa..823a42a 100644
--- a/lib/resources/Resources.php
+++ b/lib/resources/Resources.php
@@ -133,6 +133,7 @@
                                'jquery.json',
                                'user.tokens',
                                'wikibase.datamodel',
+                               'wikibase.serialization.entities',
                                'wikibase.repoAccess',
                                'wikibase.RepoApiError',
                                'mediawiki.Title',
diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.snakview/snakview.js 
b/lib/resources/jquery.wikibase/jquery.wikibase.snakview/snakview.js
index 0e2eb04..878c348 100644
--- a/lib/resources/jquery.wikibase/jquery.wikibase.snakview/snakview.js
+++ b/lib/resources/jquery.wikibase/jquery.wikibase.snakview/snakview.js
@@ -202,7 +202,8 @@
                .on( 'entityselectorselect', function( e, ui ) {
                        // entity chosen in entity selector but we still need 
the data type of the entity, so
                        // we have to make a separate API call:
-                       var api = new wb.RepoApi();
+                       var api = new wb.RepoApi(),
+                               entityId = ui.item.id;
 
                        // Display spinner as long as the value view is 
loading. There is no need to display the
                        // spinner when the selected item actually has not 
changed since the variation will stay
@@ -213,24 +214,16 @@
                                );
                        }
 
-                       api.getEntities( ui.item.id, null ).done( function( 
response ) {
-                               var entityId = ui.item.id,
-                                       entity = response.entities[ entityId ],
-                                       dataTypeId = entity.datatype,
-                                       dataType = dt.getDataType( dataTypeId ),
-                                       label;
-
-                               if( entity.labels && entity.labels[ language ] 
) {
-                                       label = entity.labels[ language ].value;
-                               }
+                       api.getEntities( entityId, null, [ language ] ).done( 
function( entities ) {
+                               var entity = entities[ entityId ];
 
                                // update local store with newest information 
about selected property
                                // TODO: create more sophisticated local store 
interface rather than accessing
                                //       wb.entities directly
                                wb.entities[ entityId ] = {
                                        id: entityId,
-                                       label: label,
-                                       datatype: dataType.getId(),
+                                       label: entity.getLabel(),
+                                       datatype: entity.getDataType().getId(),
                                        url: ui.item.url
                                };
 
diff --git a/lib/resources/wikibase.store/wikibase.RepoApi.js 
b/lib/resources/wikibase.store/wikibase.RepoApi.js
index 463ff5a..aa9c0d6 100644
--- a/lib/resources/wikibase.store/wikibase.RepoApi.js
+++ b/lib/resources/wikibase.store/wikibase.RepoApi.js
@@ -75,7 +75,7 @@
        },
 
        /**
-        * Gets one or more entities.
+        * Gets one or more Entities.
         *
         * @param {String[]|String} ids
         * @param {String[]|String} [props] Key(s) of property/ies to retrieve 
from the API
@@ -86,7 +86,12 @@
         *                          default: null (unsorted)
         * @param {String}          [dir] Sort direction may be 'ascending' or 
'descending'
         *                          default: null (ascending)
-        * @return {jQuery.Promise}
+        * @return {jQuery.Promise} If successful, the first parameter of the 
done callbacks will be
+        *         an object with keys of the entity's IDs and values of the 
requested entities
+        *         represented as wb.Entity objects. If a requested Entity does 
not exist, it will not
+        *         be represented in the result.
+        *
+        * @todo Requires tests!
         */
        getEntities: function( ids, props, languages, sort, dir ) {
                var params = {
@@ -98,11 +103,25 @@
                        dir: dir || undefined
                };
 
-               return this.get( params );
+               return this._getAndPromiseWithAbstraction( params, function( 
result ) {
+                       var entities = {},
+                               unserializer = ( new 
wb.serialization.SerializerFactory() ).newUnserializerFor( wb.Entity );
+
+                       $.each( result.entities, function( id, entityData ) {
+                               if( !entityData.id ) {
+                                       return; // missing entity
+                               }
+
+                               var entity = unserializer.unserialize( 
entityData );
+                               entities[ entity.getId() ] = entity;
+                       } );
+
+                       return [ entities ];
+               } );
        },
 
        /**
-        * Gets an entitiy which is linked with a given page.
+        * 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)
@@ -490,31 +509,6 @@
                }
        },
 
-       /**
-        * Same as post() but will return a jQuery.Promise which will resolve 
with some different
-        * arguments, specified in a callback.
-        *
-        * @since 0.4
-        *
-        * @param params
-        * @param {Function} callbackForAbstraction Called when post request is 
resolved, will get all
-        *        parameters the original resolved post promise gets. Can 
return an array whose members
-        *        will then serve as parameters for the public promise.
-        * @return jQuery.Promise
-        */
-       _postAndPromiseWithAbstraction: function( params, 
callbackForAbstraction ) {
-               var deferred = $.Deferred(),
-                       self = this;
-
-               this.post( params )
-               .done( function() {
-                       var args = callbackForAbstraction.apply( self, 
arguments );
-                       deferred.resolve.apply( deferred, args );
-               } )
-               .fail( deferred.reject );
-
-               return deferred.promise();
-       },
 
        /**
         * Performs an API get request.
@@ -528,8 +522,48 @@
                this._extendRepoCallParams( params, options );
 
                return this._api.get( params, options );
-       }
+       },
 
+       /**
+        * Same as post() or get() but will return a jQuery.Promise which will 
resolve with some
+        * different arguments, specified in a callback.
+        *
+        * @since 0.4
+        *
+        * @param {string} method Either 'post' or 'get'
+        * @param params
+        * @param {Function} callbackForAbstraction Called when post request is 
resolved, will get all
+        *        parameters the original resolved post promise gets. Can 
return an array whose members
+        *        will then serve as parameters for the public promise.
+        * @return jQuery.Promise
+        */
+       _requestAndPromiseWithAbstraction: function( method, params, 
callbackForAbstraction ) {
+               var deferred = $.Deferred(),
+                       self = this;
+
+               this[ method ]( params )
+               .done( function() {
+                       var args = callbackForAbstraction.apply( self, 
arguments );
+                       deferred.resolve.apply( deferred, args );
+               } )
+               .fail( deferred.reject );
+
+               return deferred.promise();
+       },
+
+       /**
+        * @see _requestAndPromiseWithAbstraction
+        */
+       _postAndPromiseWithAbstraction: function( params, 
callbackForAbstraction ) {
+               return this._requestAndPromiseWithAbstraction( 'post', params, 
callbackForAbstraction );
+       },
+
+       /**
+        * @see _requestAndPromiseWithAbstraction
+        */
+       _getAndPromiseWithAbstraction: function( params, callbackForAbstraction 
) {
+               return this._requestAndPromiseWithAbstraction( 'get', params, 
callbackForAbstraction );
+       }
 } );
 
        // TODO: step by step implementation of the store, starting with basic 
claim stuff
diff --git a/lib/tests/qunit/wikibase.store/wikibase.RepoApi.tests.js 
b/lib/tests/qunit/wikibase.store/wikibase.RepoApi.tests.js
index 324d20f..12789af 100644
--- a/lib/tests/qunit/wikibase.store/wikibase.RepoApi.tests.js
+++ b/lib/tests/qunit/wikibase.store/wikibase.RepoApi.tests.js
@@ -131,27 +131,30 @@
 
        } );
 
-       QUnit.test( 'Set label', function( assert ) {
-               var data = {
-                       labels: {
-                               en: {
-                                       language: 'en',
-                                       value: 'en-value'
-                               }
-                       }
-               };
+       /**
+        * 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 wb.RepoApi function to set 
the value
+        */
+       function testSetBasicMultiLingualValue( assert, type, apiFnName ) {
+               var 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() { createItem(); } );
 
                testrun.queue( qkey, function() {
-                       api.setLabel(
-                               entity.id, entity.lastrevid, 
data.labels.en.value, data.labels.en.language
+                       api[ apiFnName ](
+                               entity.id, entity.lastrevid, value, language
                        ).done( function( response ) {
 
                                assert.deepEqual(
-                                       response.entity.labels.en,
-                                       data.labels.en,
-                                       'Set label.'
+                                       response.entity[ typesApiPropName ].en,
+                                       { language: language, value: value },
+                                       type + ' "' + value + '" has been set 
for language "' + language + '"'
                                );
 
                                testrun.dequeue( qkey );
@@ -159,33 +162,48 @@
                } );
 
                testrun.queue( qkey, function() {
-                       api.setLabel(
-                               entity.id, entity.lastrevid, 
data.labels.en.value, 'doesnotexist'
-                       ).done( function( response ) {
+                       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 ),
+                               'wb.RepoApi.' + apiFnName + ' returns a jQuery 
Promise'
+                       );
+
+
+                       setTypeApiPromise.done( function( response ) {
                                assert.ok(
                                        false,
-                                       'It is possible to set te label for an 
invalid language.'
+                                       'Impossible to set the ' + type + ' for 
an unknown language'
                                );
-
                                QUnit.start();
-                       } ).fail( function( code, details ) {
+                       } );
+
+                       setTypeApiPromise.fail( function( code, details ) {
                                assert.equal(
                                        code,
                                        'unknown_language',
-                                       'Failed trying to set the label on an 
invalid language.'
+                                       'Failed trying to set the value on an 
unknown language'
                                );
                                testrun.dequeue( qkey );
                        } );
                } );
 
                testrun.queue( qkey, function() {
-                       api.getEntities( entity.id, 'labels' ).done( function( 
response ) {
+                       api.getEntities( entity.id, typesApiPropName ).done( 
function( entities ) {
 
+                               assert.ok(
+                                       entities[ entity.id ] instanceof 
wb.Entity,
+                                       'Entity "' + entity.id + '", the ' + 
type + ' has been set for, has been' +
+                                               'returned by 
wb.RepoApi.getEntities.'
+                               );
+
+                               var entityData = entities[ entity.id ].toMap();
                                assert.deepEqual(
-                                       response.entities[entity.id].labels,
-                                       data.labels,
-                                       'Verified labels.'
+                                       entityData[ type ] && entityData[ type 
][ language ],
+                                       value,
+                                       'Verified that ' + type + ' "' + value 
+ '" has been set for language "' + language + '"'
                                );
 
                                testrun.dequeue( qkey );
@@ -193,72 +211,14 @@
                } );
 
                runTest();
+       }
 
+       QUnit.test( 'Set label', function( assert ) {
+               testSetBasicMultiLingualValue( assert, 'label', 'setLabel' );
        } );
 
        QUnit.test( 'Set description', function( assert ) {
-               var data = {
-                       descriptions: {
-                               en: {
-                                       language: 'en',
-                                       value: 'en-value'
-                               }
-                       }
-               };
-
-               testrun.queue( qkey, function() { createItem(); } );
-
-               testrun.queue( qkey, function() {
-                       api.setDescription(
-                               entity.id, entity.lastrevid, 
data.descriptions.en.value, data.descriptions.en.language
-                       ).done( function( response ) {
-
-                               assert.deepEqual(
-                                       response.entity.descriptions.en,
-                                       data.descriptions.en,
-                                       'Set description.'
-                               );
-
-                               testrun.dequeue( qkey );
-                       } ).fail( onFail );
-               } );
-
-               testrun.queue( qkey, function() {
-                       api.setDescription(
-                               'invalidid', entity.lastrevid, 
data.descriptions.en.value, data.descriptions.en.language
-                       ).done( function( response ) {
-
-                               assert.ok(
-                                       false,
-                                       'It is possible to pass an invalid id.'
-                               );
-
-                               QUnit.start();
-                       } ).fail( function( code, details ) {
-                               assert.equal(
-                                       code,
-                                       'no-such-entity-id',
-                                       'Failed trying to set a description 
with an invalid id.'
-                               );
-                               testrun.dequeue( qkey );
-                       } );
-               } );
-
-               testrun.queue( qkey, function() {
-                       api.getEntities( entity.id, 'descriptions' ).done( 
function( response ) {
-
-                               assert.deepEqual(
-                                       
response.entities[entity.id].descriptions,
-                                       data.descriptions,
-                                       'Verified descriptions.'
-                               );
-
-                               testrun.dequeue( qkey );
-                       } ).fail( onFail );
-               } );
-
-               runTest();
-
+               testSetBasicMultiLingualValue( assert, 'description', 
'setDescription' );
        } );
 
 // TODO Re-activate test after having solved problem with edit conflict 
detection added in change

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

Gerrit-MessageType: merged
Gerrit-Change-Id: If80ca6c9048cd9d6880a9c790240fdb4e81cbcc0
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Daniel Werner <daniel.wer...@wikimedia.de>
Gerrit-Reviewer: Henning Snater <henning.sna...@wikimedia.de>
Gerrit-Reviewer: jenkins-bot

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

Reply via email to