[FIX] dataset.read_ids should always return records in the order of the parameter ids
authorXavier Morel <xmo@openerp.com>
Tue, 25 Feb 2014 16:28:13 +0000 (17:28 +0100)
committerXavier Morel <xmo@openerp.com>
Tue, 25 Feb 2014 16:28:13 +0000 (17:28 +0100)
BufferedDataSet.read_ids assumes the input and output orders are the same, and
returns wonky results when not the case, which in turns fucks up its cache as
it associates ids and records incorrectly.

bzr revid: xmo@openerp.com-20140225162813-8ofxpiy1012eehgk

addons/web/static/src/js/data.js
addons/web/static/test/data.js

index 24a4dc3..c24d37b 100644 (file)
@@ -448,7 +448,8 @@ instance.web.DataSet =  instance.web.Class.extend(instance.web.PropertiesMixin,
      * Read records.
      *
      * @param {Array} ids identifiers of the records to read
-     * @param {Array} fields fields to read and return, by default all fields are returned
+     * @param {Array} [fields] fields to read and return, by default all fields are returned
+     * @param {Object} [options]
      * @returns {$.Deferred}
      */
     read_ids: function (ids, fields, options) {
@@ -456,10 +457,20 @@ instance.web.DataSet =  instance.web.Class.extend(instance.web.PropertiesMixin,
             return $.Deferred().resolve([]);
             
         options = options || {};
-        // TODO: reorder results to match ids list
         return this._model.call('read',
-            [ids, fields || false],
-            {context: this.get_context(options.context)});
+                [ids, fields || false],
+                {context: this.get_context(options.context)})
+            .then(function (records) {
+                if (records.length <= 1) { return records; }
+                var indexes = {};
+                for (var i = 0; i < ids.length; i++) {
+                    indexes[ids[i]] = i;
+                }
+                records.sort(function (a, b) {
+                    return indexes[a.id] - indexes[b.id];
+                });
+                return records;
+        });
     },
     /**
      * Read a slice of the records represented by this DataSet, based on its
index d7a957a..2228709 100644 (file)
@@ -1,3 +1,32 @@
+openerp.testing.section('data.dataset', {
+    rpc: 'mock',
+    dependencies: ['web.data'],
+}, function (test) {
+    test('read_ids', {asserts: 2}, function (instance, _, mock) {
+        var d = new instance.web.DataSet(null, 'foo');
+        mock('foo:read', function (args) {
+            var ids = args[0];
+            deepEqual(ids, [3, 1, 2]);
+            return [
+                {id: 1, a: 'bar'},
+                {id: 2, a: 'baz'},
+                {id: 3, a: 'foo'}
+            ];
+        });
+
+        return d.read_ids([3, 1, 2]).then(function (records) {
+            deepEqual(
+                records,
+                [
+                    {id: 3, a: 'foo'},
+                    {id: 1, a: 'bar'},
+                    {id: 2, a: 'baz'}
+                ]
+            )
+        });
+    })
+});
+
 openerp.testing.section('data.model.group_by', {
     rpc: 'mock',
     dependencies: ['web.data'],