[FIX] web: keep positional args for search_read
The previous code used to create its own args array for the search_read method, replacing the one that was originally given to it. This lead to silent errors since positional arguments to this function were completely ignored in the case of search_read. I took this commit as an opportunity to improve a bit on the current state of these rpc helpers. Namely, the basic args/kwargs priority is the following (top-to-bottom): - kwargs defined in the rpc call - kwargs defined in the kwargs key of the params kwarg of the rpc call - positional arguments are passed as is For read_group and search_read methods, the priority is the following: - kwargs defined in the rpc call - kwargs defined in the params kwarg to the rpc call - kwargs defined in the kwargs key of the params kwarg of the rpc call - positional arguments are passed as is For the /web/dataset/search_read controller, only the params kwarg is supported, resulting in the following priority: - kwargs defined in the rpc call - kwargs defined in the params kwarg to the rpc call - positional arguments are passed as is If both a kwargs and a positional arg is given for the same parameter, it will be sent as is to the server which will crash with a typical "got multiple values for keyword argument" TypeError. However, in the MockServer however, we give priority to kwargs over args in this case. Please note that I also chose to remove unnecessary default values so that the ones actually used are the ones from the server, not the ones that were duplicating those in the rpc js file.
This commit is contained in:
@@ -46,38 +46,44 @@ return {
|
||||
params.args = options.args || [];
|
||||
params.model = options.model;
|
||||
params.method = options.method;
|
||||
params.kwargs = options.kwargs || {};
|
||||
params.kwargs.context = options.context || params.kwargs.context;
|
||||
params.kwargs = _.extend(params.kwargs || {}, options.kwargs);
|
||||
params.kwargs.context = options.context || params.context || params.kwargs.context;
|
||||
}
|
||||
|
||||
if (options.method === 'read_group') {
|
||||
params.kwargs.groupby = options.groupBy || params.kwargs.groupby || [];
|
||||
params.kwargs.domain = options.domain || params.kwargs.domain || [];
|
||||
params.kwargs.fields = options.fields || params.kwargs.fields || [];
|
||||
params.kwargs.lazy = 'lazy' in options ? options.lazy : params.kwargs.lazy;
|
||||
var orderBy = options.orderBy || params.orderBy;
|
||||
params.kwargs.orderby = orderBy ? this._serializeSort(orderBy) : false;
|
||||
params.kwargs.domain = options.domain || params.domain || params.kwargs.domain || [];
|
||||
params.kwargs.fields = options.fields || params.fields || params.kwargs.fields || [];
|
||||
params.kwargs.groupby = options.groupBy || params.groupBy || params.kwargs.groupby || [];
|
||||
params.kwargs.offset = options.offset || params.offset || params.kwargs.offset;
|
||||
params.kwargs.limit = options.limit || params.limit || params.kwargs.limit;
|
||||
// In kwargs, we look for "orderby" rather than "orderBy" (note the absence of capital B),
|
||||
// since the Python argument to the actual function is "orderby".
|
||||
var orderBy = options.orderBy || params.orderBy || params.kwargs.orderby;
|
||||
params.kwargs.orderby = orderBy ? this._serializeSort(orderBy) : orderBy;
|
||||
params.kwargs.lazy = 'lazy' in options ? options.lazy : params.lazy;
|
||||
}
|
||||
|
||||
if (options.method === 'search_read') {
|
||||
// call the model method
|
||||
params.args = [
|
||||
options.domain || [],
|
||||
options.fields || false,
|
||||
options.offset || 0,
|
||||
options.limit || false,
|
||||
this._serializeSort(options.orderBy || params.orderBy || []),
|
||||
];
|
||||
params.kwargs.domain = options.domain || params.domain || params.kwargs.domain;
|
||||
params.kwargs.fields = options.fields || params.fields || params.kwargs.fields;
|
||||
params.kwargs.offset = options.offset || params.offset || params.kwargs.offset;
|
||||
params.kwargs.limit = options.limit || params.limit || params.kwargs.limit;
|
||||
// In kwargs, we look for "order" rather than "orderBy" since the Python
|
||||
// argument to the actual function is "order".
|
||||
var orderBy = options.orderBy || params.orderBy || params.kwargs.order;
|
||||
params.kwargs.order = orderBy ? this._serializeSort(orderBy) : orderBy;
|
||||
}
|
||||
|
||||
if (options.route === '/web/dataset/search_read') {
|
||||
// specifically call the controller
|
||||
params.model = options.model || params.model;
|
||||
params.domain = options.domain || params.domain || [];
|
||||
params.fields = options.fields || params.fields || false;
|
||||
params.domain = options.domain || params.domain;
|
||||
params.fields = options.fields || params.fields;
|
||||
params.limit = options.limit || params.limit;
|
||||
params.offset = options.offset || params.offset ;
|
||||
params.sort = this._serializeSort(options.orderBy || params.orderBy || []);
|
||||
params.offset = options.offset || params.offset;
|
||||
var orderBy = options.orderBy || params.orderBy;
|
||||
params.sort = orderBy ? this._serializeSort(orderBy) : orderBy;
|
||||
params.context = options.context || params.context || {};
|
||||
}
|
||||
|
||||
|
||||
@@ -136,6 +136,33 @@ QUnit.module('core', {}, function () {
|
||||
offset: 2,
|
||||
orderBy: [{name: 'yop', asc: true}, {name: 'aa', asc: false}],
|
||||
});
|
||||
assert.deepEqual(query.params, {
|
||||
args: [],
|
||||
kwargs: {
|
||||
domain: ['a', '=', 1],
|
||||
fields: ['name'],
|
||||
offset: 2,
|
||||
limit: 32,
|
||||
order: 'yop ASC, aa DESC'
|
||||
},
|
||||
method: 'search_read',
|
||||
model: 'partner'
|
||||
}, "should have correct kwargs");
|
||||
});
|
||||
|
||||
QUnit.test('search_read with args', function (assert) {
|
||||
assert.expect(1);
|
||||
var query = rpc.buildQuery({
|
||||
model: 'partner',
|
||||
method: 'search_read',
|
||||
args: [
|
||||
['a', '=', 1],
|
||||
['name'],
|
||||
2,
|
||||
32,
|
||||
'yop ASC, aa DESC',
|
||||
]
|
||||
});
|
||||
assert.deepEqual(query.params, {
|
||||
args: [['a', '=', 1], ['name'], 2, 32, 'yop ASC, aa DESC'],
|
||||
kwargs: {},
|
||||
@@ -165,7 +192,6 @@ QUnit.module('core', {}, function () {
|
||||
fields: ['name'],
|
||||
groupby: ['product_id'],
|
||||
lazy: true,
|
||||
orderby: false,
|
||||
},
|
||||
method: 'read_group',
|
||||
model: 'partner',
|
||||
@@ -195,23 +221,55 @@ QUnit.module('core', {}, function () {
|
||||
fields: ['name'],
|
||||
groupby: ['product_id'],
|
||||
lazy: false,
|
||||
orderby: false,
|
||||
},
|
||||
method: 'read_group',
|
||||
model: 'partner',
|
||||
}, "should have correct args");
|
||||
});
|
||||
|
||||
QUnit.test('read_group with no domain, nor fields', function (assert) {
|
||||
assert.expect(7);
|
||||
var query = rpc.buildQuery({
|
||||
model: 'partner',
|
||||
method: 'read_group',
|
||||
});
|
||||
|
||||
assert.deepEqual(query.params.kwargs.domain, [], "should have [] as default domain");
|
||||
assert.deepEqual(query.params.kwargs.fields, [], "should have false as default fields");
|
||||
assert.deepEqual(query.params.kwargs.groupby, [], "should have false as default groupby");
|
||||
assert.deepEqual(query.params.kwargs.offset, undefined, "should not enforce a default value for offst");
|
||||
assert.deepEqual(query.params.kwargs.limit, undefined, "should not enforce a default value for limit");
|
||||
assert.deepEqual(query.params.kwargs.orderby, undefined, "should not enforce a default value for orderby");
|
||||
assert.deepEqual(query.params.kwargs.lazy, undefined, "should not enforce a default value for lazy");
|
||||
});
|
||||
|
||||
QUnit.test('search_read with no domain, nor fields', function (assert) {
|
||||
assert.expect(2);
|
||||
assert.expect(5);
|
||||
var query = rpc.buildQuery({
|
||||
model: 'partner',
|
||||
method: 'search_read',
|
||||
});
|
||||
|
||||
assert.deepEqual(query.params.kwargs.domain, undefined, "should not enforce a default value for domain");
|
||||
assert.deepEqual(query.params.kwargs.fields, undefined, "should not enforce a default value for fields");
|
||||
assert.deepEqual(query.params.kwargs.offset, undefined, "should not enforce a default value for offset");
|
||||
assert.deepEqual(query.params.kwargs.limit, undefined, "should not enforce a default value for limit");
|
||||
assert.deepEqual(query.params.kwargs.order, undefined, "should not enforce a default value for orderby");
|
||||
});
|
||||
|
||||
QUnit.test('search_read controller with no domain, nor fields', function (assert) {
|
||||
assert.expect(5);
|
||||
var query = rpc.buildQuery({
|
||||
model: 'partner',
|
||||
route: '/web/dataset/search_read',
|
||||
});
|
||||
|
||||
assert.deepEqual(query.params.domain, [], "should have [] as default domain");
|
||||
assert.strictEqual(query.params.fields, false, "should have false as default fields");
|
||||
assert.deepEqual(query.params.domain, undefined, "should not enforce a default value for domain");
|
||||
assert.deepEqual(query.params.fields, undefined, "should not enforce a default value for fields");
|
||||
assert.deepEqual(query.params.offset, undefined, "should not enforce a default value for groupby");
|
||||
assert.deepEqual(query.params.limit, undefined, "should not enforce a default value for limit");
|
||||
assert.deepEqual(query.params.sort, undefined, "should not enforce a default value for order");
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3361,7 +3361,7 @@ QUnit.module('relational_fields', {
|
||||
mockRPC: function (route, args) {
|
||||
if (args.method === 'search_read') {
|
||||
count++;
|
||||
nb_fields_fetched = args.args[1].length;
|
||||
nb_fields_fetched = args.kwargs.fields.length;
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
@@ -3394,7 +3394,7 @@ QUnit.module('relational_fields', {
|
||||
'</form>',
|
||||
mockRPC: function (route, args) {
|
||||
if (args.method === 'search_read') {
|
||||
assert.deepEqual(args.args[0], ['|', ['id', '=', 4], ['user_id', '=', 17]],
|
||||
assert.deepEqual(args.kwargs.domain, ['|', ['id', '=', 4], ['user_id', '=', 17]],
|
||||
"search_read should sent the correct domain");
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
|
||||
@@ -718,11 +718,11 @@ var MockServer = Class.extend({
|
||||
_mockSearchRead: function (model, args, kwargs) {
|
||||
var result = this._mockSearchReadController({
|
||||
model: model,
|
||||
domain: args[0],
|
||||
fields: args[1],
|
||||
offset: args[2],
|
||||
limit: args[3],
|
||||
sort: args[4],
|
||||
domain: kwargs.domain || args[0],
|
||||
fields: kwargs.fields || args[1],
|
||||
offset: kwargs.offset || args[2],
|
||||
limit: kwargs.limit || args[3],
|
||||
order: kwargs.order || args[4],
|
||||
context: kwargs.context,
|
||||
});
|
||||
return result.records;
|
||||
@@ -743,7 +743,7 @@ var MockServer = Class.extend({
|
||||
*/
|
||||
_mockSearchReadController: function (args) {
|
||||
var self = this;
|
||||
var records = this._getRecords(args.model, args.domain);
|
||||
var records = this._getRecords(args.model, args.domain || []);
|
||||
var fields = args.fields || _.keys(this.data[args.model].fields);
|
||||
var nbRecords = records.length;
|
||||
var offset = args.offset || 0;
|
||||
|
||||
Reference in New Issue
Block a user