summaryrefslogtreecommitdiff
path: root/addons/web/static/tests/fields
diff options
context:
space:
mode:
authorLucas Perais (lpe) <lpe@odoo.com>2020-08-07 08:48:55 +0000
committerRaphael Collet <rco@odoo.com>2020-08-20 13:39:25 +0000
commit38b7462dcf7541bbcb51ac75cc1f7b6715f13ace (patch)
tree624ff1d52b3dcc253d4b1562510957afcb8ecdcd /addons/web/static/tests/fields
parent488e334fc8fd6601e304635fa577c98b9bfd18e6 (diff)
[REF] web: BasicModel: combine default_get and onchange
This commit adapts the BasicModel to combine calls to `default_get` and (first) `onchange`. When creating a new record, we now only call `onchange`, which thus return default values and potential onchange values. Tests (and the MockServer) have been adapted accordingly. NOTE 1. If the `default_get` within the `onchange` returns a value for a field that is not in the view, we ignore it, and it won't be saved. Before, that value was kept and sent upon save. This change in behavior may prove problematic, although the overall risk is small. Decision has been made to keep heavy comments and code snippets if we were to revert back somehow to the previous situation. NOTE 2. Putting a context on a many2one field may change the value returned by `name_get` for that field. By default, the calls to `name_get` are done by `onchange`. If the context on a field must be used for `name_get`, one has to set the option `always_reload` to `True` on the field. In that case, every `onchange` that changes the value will trigger an extra `name_get`. NOTE 3. Suppose that a one2many field has a list view with field A, and a form view without field A. When adding a line, we now send all known fields (main view and inline views) to the `onchange`, which may return a default value for A. The value will appear on the list view, but not in the form view. The former behavior was to call `default_get` with the fields that occur in the form view only, and therefore field A would be left to value `False`. NOTE 4. A test surprisingly adds an extra call to `read`. The test was actually wrong before. With the changes in MockServer, we now correctly receive a command `[6, false, [1]]`, whereas before we received `[1]`, which isn't a valid command, and which was ignored. As a consequence, an extra `read` is done, whereas the test asserts it shouldn't. But it already didn't work before (I checked by sending the correct command). This needs to be bugfixed elsewhere (task-id-2323491): in a o2m with a onchange and default order records on an other page than the first should not trigger a `read`. Task 2261084 Co-authored-by: Raphael Collet <rco@odoo.com> Co-authored-by: Aaron Bohy <aab@odoo.com>
Diffstat (limited to 'addons/web/static/tests/fields')
-rw-r--r--addons/web/static/tests/fields/relational_fields/field_many2one_tests.js130
-rw-r--r--addons/web/static/tests/fields/relational_fields/field_one2many_tests.js157
-rw-r--r--addons/web/static/tests/fields/relational_fields_tests.js20
3 files changed, 131 insertions, 176 deletions
diff --git a/addons/web/static/tests/fields/relational_fields/field_many2one_tests.js b/addons/web/static/tests/fields/relational_fields/field_many2one_tests.js
index 54abc553c8c..50e7ae2e6cb 100644
--- a/addons/web/static/tests/fields/relational_fields/field_many2one_tests.js
+++ b/addons/web/static/tests/fields/relational_fields/field_many2one_tests.js
@@ -88,6 +88,7 @@ QUnit.module('fields', {}, function () {
},
partner_type: {
fields: {
+ display_name: { string: "Partner Type", type: "char" },
name: { string: "Partner Type", type: "char" },
color: { string: "Color index", type: "integer" },
},
@@ -266,7 +267,7 @@ QUnit.module('fields', {}, function () {
data: this.data,
arch: '<form string="Partners">' +
'<field name="int_field"/>' +
- '<field name="trululu" context="{\'blip\':int_field}"/>' +
+ '<field name="trululu" context="{\'blip\':int_field}" options=\'{"always_reload": True}\'/>' +
'</form>',
mockRPC: function (route, args) {
if (args.method === 'name_get') {
@@ -1393,6 +1394,8 @@ QUnit.module('fields', {}, function () {
QUnit.test('list in form: create with one2many with many2one', async function (assert) {
assert.expect(1);
+ this.data.partner.fields.p.default = [[0, 0, { display_name: 'new record', p: [] }]];
+
var form = await createView({
View: FormView,
model: 'partner',
@@ -1408,13 +1411,8 @@ QUnit.module('fields', {}, function () {
'</sheet>' +
'</form>',
mockRPC: function (route, args) {
- if (args.method === 'default_get') {
- return Promise.resolve({ p: [[0, 0, { display_name: 'new record' }]] });
- } else if (args.method === 'name_get') {
- // This should not be called at all and thus is not accounted for
- // in the assert.expect. If this is called, you broke this test.
- assert.notOk(_.str.startsWith(args.args[0][0], 'virtual_'),
- "should not call name_get for the m2o inside o2m which has no value");
+ if (args.method === 'name_get') {
+ throw new Error('Nameget should not be called');
}
return this._super.apply(this, arguments);
},
@@ -1432,6 +1430,10 @@ QUnit.module('fields', {}, function () {
// which is stupid, but this happens, so we have to handle it
assert.expect(1);
+ this.data.partner.fields.p.default = [
+ [0, 0, { display_name: 'new record', trululu: false, p: [] }]
+ ];
+
var form = await createView({
View: FormView,
model: 'partner',
@@ -1447,13 +1449,8 @@ QUnit.module('fields', {}, function () {
'</sheet>' +
'</form>',
mockRPC: function (route, args) {
- if (args.method === 'default_get') {
- return Promise.resolve({ p: [[0, 0, { display_name: 'new record', trululu: false }]] });
- } else if (args.method === 'name_get') {
- // This should not be called at all and thus is not accounted for
- // in the assert.expect. If this is called, you broke this test.
- assert.notOk(_.str.startsWith(args.args[0][0], 'virtual_'),
- "should not call name_get for the m2o inside o2m which has no value");
+ if (args.method === 'name_get') {
+ throw new Error('Nameget should not be called');
}
return this._super.apply(this, arguments);
},
@@ -1472,6 +1469,10 @@ QUnit.module('fields', {}, function () {
// abandonned, since it has been added (even though it is a new record).
assert.expect(8);
+ this.data.partner.fields.p.default = [
+ [0, 0, { display_name: 'new record', trululu: false, p: [] }]
+ ];
+
var form = await createView({
View: FormView,
model: 'partner',
@@ -1486,12 +1487,6 @@ QUnit.module('fields', {}, function () {
'</field>' +
'</sheet>' +
'</form>',
- mockRPC: function (route, args) {
- if (args.method === 'default_get') {
- return Promise.resolve({ p: [[0, 0, { display_name: 'new record', trululu: false }]] });
- }
- return this._super.apply(this, arguments);
- },
});
assert.strictEqual($('tr.o_data_row').length, 1,
@@ -1524,9 +1519,13 @@ QUnit.module('fields', {}, function () {
});
QUnit.test('list in form: name_get with unique ids (default_get)', async function (assert) {
- assert.expect(2);
+ assert.expect(1);
this.data.partner.records[0].display_name = "MyTrululu";
+ this.data.partner.fields.p.default = [
+ [0, 0, { trululu: 1, p: [] }],
+ [0, 0, { trululu: 1, p: [] }]
+ ];
var form = await createView({
View: FormView,
@@ -1542,17 +1541,8 @@ QUnit.module('fields', {}, function () {
'</sheet>' +
'</form>',
mockRPC: function (route, args) {
- if (args.method === 'default_get') {
- return Promise.resolve({
- p: [
- [0, 0, { trululu: 1 }],
- [0, 0, { trululu: 1 }]
- ]
- });
- }
if (args.method === 'name_get') {
- assert.deepEqual(args.args[0], _.uniq(args.args[0]),
- "should not have duplicates in name_get rpc");
+ throw new Error('should not call name_get');
}
return this._super.apply(this, arguments);
},
@@ -1567,6 +1557,11 @@ QUnit.module('fields', {}, function () {
QUnit.test('list in form: show name of many2one fields in multi-page (default_get)', async function (assert) {
assert.expect(4);
+ this.data.partner.fields.p.default = [
+ [0, 0, { display_name: 'record1', trululu: 1, p: [] }],
+ [0, 0, { display_name: 'record2', trululu: 2, p: [] }]
+ ];
+
var form = await createView({
View: FormView,
model: 'partner',
@@ -1581,17 +1576,6 @@ QUnit.module('fields', {}, function () {
'</field>' +
'</sheet>' +
'</form>',
- mockRPC: function (route, args) {
- if (args.method === 'default_get') {
- return Promise.resolve({
- p: [
- [0, 0, { display_name: 'record1', trululu: 1 }],
- [0, 0, { display_name: 'record2', trululu: 2 }]
- ]
- });
- }
- return this._super.apply(this, arguments);
- },
});
assert.strictEqual(form.$('td.o_data_cell').first().text(),
@@ -1620,6 +1604,7 @@ QUnit.module('fields', {}, function () {
var M2O_DELAY = relationalFields.FieldMany2One.prototype.AUTOCOMPLETE_DELAY;
relationalFields.FieldMany2One.prototype.AUTOCOMPLETE_DELAY = 0;
+ this.data.partner.fields.product_id.default = 37;
this.data.partner.onchanges = {
product_id: function (obj) {
if (obj.product_id === 37) {
@@ -1641,14 +1626,6 @@ QUnit.module('fields', {}, function () {
'</tree>' +
'</field>' +
'</form>',
- mockRPC: function (route, args) {
- if (args.method === 'default_get') {
- return Promise.resolve({
- product_id: 37,
- });
- }
- return this._super.apply(this, arguments);
- },
});
// check that there is a record in the editable list with empty string as required field
@@ -1859,17 +1836,12 @@ QUnit.module('fields', {}, function () {
});
QUnit.test('list in form: default_get with x2many create', async function (assert) {
- assert.expect(5);
-
+ assert.expect(3);
+ this.data.partner.fields.timmy.default = [
+ [0, 0, { display_name: 'brandon is the new timmy', name: 'brandon' }]
+ ];
var displayName = 'brandon is the new timmy';
this.data.partner.onchanges.timmy = function (obj) {
- assert.deepEqual(
- obj.timmy,
- [
- [6, false, []],
- [0, obj.timmy[1][1], { display_name: displayName, name: 'brandon' }]
- ],
- "should have properly created the x2many command list");
obj.int_field = obj.timmy.length;
};
@@ -1888,15 +1860,18 @@ QUnit.module('fields', {}, function () {
'</sheet>' +
'</form>',
mockRPC: function (route, args) {
- if (args.method === 'default_get') {
- return Promise.resolve({ timmy: [[0, 0, { display_name: 'brandon is the new timmy', name: 'brandon' }]] });
- }
if (args.method === 'create') {
assert.deepEqual(args.args[0], {
int_field: 2,
timmy: [
[6, false, []],
- [0, args.args[0].timmy[1][1], { display_name: displayName, name: 'brandon' }],
+ // LPE TODO 1 taskid-2261084: remove this entire comment including code snippet
+ // when the change in behavior has been thoroughly tested.
+ // We can't distinguish a value coming from a default_get
+ // from one coming from the onchange, and so we can either store and
+ // send it all the time, or never.
+ // [0, args.args[0].timmy[1][1], { display_name: displayName, name: 'brandon' }],
+ [0, args.args[0].timmy[1][1], { display_name: displayName }],
],
}, "should send the correct values to create");
}
@@ -1906,7 +1881,7 @@ QUnit.module('fields', {}, function () {
assert.strictEqual($('td.o_data_cell:first').text(), 'brandon is the new timmy',
"should have created the new record in the m2m with the correct name");
- assert.strictEqual($('input.o_field_integer').val(), '2',
+ assert.strictEqual($('input.o_field_integer').val(), '1',
"should have called and executed the onchange properly");
// edit the subrecord and save
@@ -1919,17 +1894,9 @@ QUnit.module('fields', {}, function () {
});
QUnit.test('list in form: default_get with x2many create and onchange', async function (assert) {
- assert.expect(2);
+ assert.expect(1);
- this.data.partner.onchanges.turtles = function (obj) {
- assert.deepEqual(
- obj.turtles,
- [
- [4, 2, false],
- [4, 3, false],
- ],
- "should have properly created the x2many command list");
- };
+ this.data.partner.fields.turtles.default = [[6, 0, [2, 3]]];
var form = await createView({
View: FormView,
@@ -1946,9 +1913,6 @@ QUnit.module('fields', {}, function () {
'</sheet>' +
'</form>',
mockRPC: function (route, args) {
- if (args.method === 'default_get') {
- return Promise.resolve({ turtles: [[6, 0, [2, 3]]] });
- }
if (args.method === 'create') {
assert.deepEqual(args.args[0].turtles, [
[4, 2, false],
@@ -2187,14 +2151,14 @@ QUnit.module('fields', {}, function () {
'</form>',
mockRPC: function (route, args) {
count++;
- if (args.method === 'name_get' && args.args[0][0] === 2) {
+ if (args.method === 'name_get' && args.args[0] === 2) {
return Promise.resolve([[2, "hello world\nso much noise"]]);
}
return this._super(route, args);
},
});
- assert.strictEqual(count, 3, "should have done 3 rpcs (default_get, onchange, name_get)");
+ assert.strictEqual(count, 2, "should have done 2 rpcs (onchange and name_get)");
assert.strictEqual(form.$('.o_field_widget[name=trululu] input').val(), 'hello world',
"should have taken the correct display name");
form.destroy();
@@ -2896,7 +2860,7 @@ QUnit.module('fields', {}, function () {
});
assert.verifySteps([
- 'default_get',
+ 'onchange',
'name_search', // to display results in the dropdown
'load_views', // list view in dialog
'/web/dataset/search_read', // to display results in the dialog
@@ -2950,7 +2914,7 @@ QUnit.module('fields', {}, function () {
await testUtils.dom.click($('.modal .o_cp_searchview .o_facet_remove'));
assert.verifySteps([
- 'default_get',
+ 'onchange',
'name_search', // empty search, triggered when the user clicks in the input
'name_search', // to display results in the dropdown
'name_search', // to get preselected ids matching the search
@@ -3063,7 +3027,7 @@ QUnit.module('fields', {}, function () {
$modal.find('tbody tr').first(), { position: 'top' });
assert.verifySteps([
- 'default_get',
+ 'onchange',
'name_search', // to display results in the dropdown
'load_views', // list view in dialog
'/web/dataset/search_read', // to display results in the dialog
diff --git a/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js b/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js
index c3f43289c40..6cb765b6feb 100644
--- a/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js
+++ b/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js
@@ -164,7 +164,7 @@ QUnit.module('fields', {}, function () {
QUnit.module('FieldOne2Many');
QUnit.test('New record with a o2m also with 2 new records, ordered, and resequenced', async function (assert) {
- assert.expect(3);
+ assert.expect(2);
// Needed to have two new records in a single stroke
this.data.partner.onchanges = {
@@ -208,9 +208,7 @@ QUnit.module('fields', {}, function () {
{ position: 'top' }
);
- // Only those two should have been called
- // name_get on trululu would trigger an traceback
- assert.verifySteps(['default_get partner', 'onchange partner']);
+ assert.verifySteps(['onchange partner']);
form.destroy();
});
@@ -1077,21 +1075,20 @@ QUnit.module('fields', {}, function () {
model: 'partner',
data: data,
arch: '<form string="Partners">' +
- '<sheet>' +
- '<group>' +
- '<field name="turtles">' +
- '<tree editable="bottom" default_order="turtle_int" limit="10">' +
- '<field name="turtle_int" widget="handle"/>' +
- '<field name="turtle_foo"/>' +
- '<field name="turtle_qux" attrs="{\'readonly\': [(\'turtle_foo\', \'=\', False)]}"/>' +
- '</tree>' +
- '</field>' +
- '</group>' +
- '</sheet>' +
+ '<sheet>' +
+ '<group>' +
+ '<field name="turtles">' +
+ '<tree editable="bottom" default_order="turtle_int" limit="10">' +
+ '<field name="turtle_int" widget="handle"/>' +
+ '<field name="turtle_foo"/>' +
+ '<field name="turtle_qux" attrs="{\'readonly\': [(\'turtle_foo\', \'=\', False)]}"/>' +
+ '</tree>' +
+ '</field>' +
+ '</group>' +
+ '</sheet>' +
'</form>',
res_id: 1,
});
-
await testUtils.form.clickEdit(form);
assert.equal(form.$('.o_field_one2many .o_list_char').text(), "#20#21#22#23#24#25#26#27#28#29",
@@ -2298,27 +2295,27 @@ QUnit.module('fields', {}, function () {
model: 'partner',
data: this.data,
arch: '<form string="Partners">' +
- '<field name="p">' +
- '<kanban>' +
- // color will be in the kanban but not in the form
- '<field name="color"/>' +
- '<field name="display_name"/>' +
- '<templates>' +
- '<t t-name="kanban-box">' +
- '<div class="oe_kanban_global_click">' +
- '<a t-if="!read_only_mode" type="delete" class="fa fa-times float-right delete_icon"/>' +
- '<span><t t-esc="record.display_name.value"/></span>' +
- '<span><t t-esc="record.color.value"/></span>' +
- '</div>' +
- '</t>' +
- '</templates>' +
- '</kanban>' +
- '<form string="Partners">' +
- '<field name="display_name"/>' +
- // foo will be in the form but not in the kanban
- '<field name="foo"/>' +
- '</form>' +
- '</field>' +
+ '<field name="p">' +
+ '<kanban>' +
+ // color will be in the kanban but not in the form
+ '<field name="color"/>' +
+ '<field name="display_name"/>' +
+ '<templates>' +
+ '<t t-name="kanban-box">' +
+ '<div class="oe_kanban_global_click">' +
+ '<a t-if="!read_only_mode" type="delete" class="fa fa-times float-right delete_icon"/>' +
+ '<span><t t-esc="record.display_name.value"/></span>' +
+ '<span><t t-esc="record.color.value"/></span>' +
+ '</div>' +
+ '</t>' +
+ '</templates>' +
+ '</kanban>' +
+ '<form string="Partners">' +
+ '<field name="display_name"/>' +
+ // foo will be in the form but not in the kanban
+ '<field name="foo"/>' +
+ '</form>' +
+ '</field>' +
'</form>',
res_id: 1,
mockRPC: function (route, args) {
@@ -2375,7 +2372,7 @@ QUnit.module('fields', {}, function () {
await testUtils.dom.clickFirst($('.modal .modal-footer .btn-primary'));
assert.strictEqual(form.$('.o_kanban_record:not(.o_kanban_ghost)').length, 2,
'should contain 2 records');
- assert.strictEqual(form.$('.o_kanban_record:nth(1) span').text(), 'new subrecord 1',
+ assert.strictEqual(form.$('.o_kanban_record:nth(1) span').text(), 'new subrecord 1Red',
'value of newly created subrecord should be "new subrecord 1"');
// create two new subrecords
@@ -2867,7 +2864,7 @@ QUnit.module('fields', {}, function () {
assert.containsNone(form, 'tr.o_data_row',
"should still have 0 data rows");
- assert.verifySteps(['read', 'default_get', 'default_get']);
+ assert.verifySteps(['read', 'onchange', 'onchange']);
form.destroy();
});
@@ -3133,12 +3130,12 @@ QUnit.module('fields', {}, function () {
await testUtils.fields.triggerKeydown(form.$('input[name="turtle_foo"]'), 'enter');
assert.hasClass(form.$('input[name="turtle_foo"]'), 'o_field_invalid',
"input should be marked invalid");
- assert.verifySteps(['read', 'default_get']);
+ assert.verifySteps(['read', 'onchange']);
form.destroy();
});
QUnit.test('editing a o2m, with required field and onchange', async function (assert) {
- assert.expect(12);
+ assert.expect(11);
this.data.turtle.fields.turtle_foo.required = true;
delete this.data.turtle.fields.turtle_foo.default;
@@ -3189,7 +3186,7 @@ QUnit.module('fields', {}, function () {
assert.strictEqual(form.$('.o_data_row td:contains(9)').length, 1,
"should have one row with turtle_int value");
- assert.verifySteps(['read', 'default_get', 'onchange', 'onchange', 'write', 'read', 'read']);
+ assert.verifySteps(['read', 'onchange', 'onchange', 'write', 'read', 'read']);
form.destroy();
});
@@ -3222,7 +3219,7 @@ QUnit.module('fields', {}, function () {
await testUtils.fields.triggerKeydown(form.$('input[name="turtle_foo"]'), 'escape');
assert.containsNone(form, 'tr.o_data_row',
"data row should have been discarded");
- assert.verifySteps(['read', 'default_get']);
+ assert.verifySteps(['read', 'onchange']);
form.destroy();
});
@@ -3257,7 +3254,7 @@ QUnit.module('fields', {}, function () {
await testUtils.fields.triggerKeydown(form.$('input[name="turtle_foo"]'), 'escape');
assert.containsNone(form, 'tr.o_data_row',
"data row should have been discarded");
- assert.verifySteps(['read', 'default_get']);
+ assert.verifySteps(['read', 'onchange']);
form.destroy();
});
@@ -3921,6 +3918,7 @@ QUnit.module('fields', {}, function () {
QUnit.test('one2many list with a many2one', async function (assert) {
assert.expect(5);
+ let checkOnchange = false;
this.data.partner.records[0].p = [2];
this.data.partner.records[1].product_id = 37;
this.data.partner.onchanges.p = function (obj) {
@@ -3949,7 +3947,7 @@ QUnit.module('fields', {}, function () {
'<form string="Partner"><field name="product_id"/></form>',
},
mockRPC: function (route, args) {
- if (args.method === 'onchange') {
+ if (args.method === 'onchange' && checkOnchange) {
assert.deepEqual(args.args[1].p, [[4, 2, false], [0, args.args[1].p[1][1], { product_id: 41 }]],
"should trigger onchange with correct parameters");
}
@@ -3966,6 +3964,7 @@ QUnit.module('fields', {}, function () {
await testUtils.dom.click(form.$('tbody td.o_field_x2many_list_row_add a'));
+ checkOnchange = true;
await testUtils.fields.many2one.clickOpenDropdown('product_id');
testUtils.fields.many2one.clickItem('product_id', 'xpad');
@@ -4006,7 +4005,7 @@ QUnit.module('fields', {}, function () {
mockRPC: function (route, args) {
if (args.method === 'write') {
assert.deepEqual(args.args[1].p, [[0, args.args[1].p[0][1], {
- foo: false, int_field: 123, product_id: 41,
+ foo: "My little Foo Value", int_field: 123, product_id: 41,
}]]);
}
return this._super(route, args);
@@ -4202,7 +4201,7 @@ QUnit.module('fields', {}, function () {
'</form>',
res_id: 2,
mockRPC: function (route, args) {
- if (args.method === 'default_get') {
+ if (args.method === 'onchange') {
assert.strictEqual(args.kwargs.context.date, '2017-01-25',
"should have properly evaluated date key in context");
}
@@ -4236,7 +4235,7 @@ QUnit.module('fields', {}, function () {
'</form>',
res_id: 1,
mockRPC: function (route, args) {
- if (args.method === 'default_get') {
+ if (args.method === 'onchange') {
var expected = counter === 0 ?
[[4, 2, false]] :
[[4, 2, false], [0, args.kwargs.context.turtles[1][1], { turtle_foo: 'hammer' }]];
@@ -4310,7 +4309,7 @@ QUnit.module('fields', {}, function () {
'</form>',
res_id: 1,
mockRPC: function (route, args) {
- if (args.method === 'default_get') {
+ if (args.method === 'onchange') {
var context = args.kwargs.context;
assert.strictEqual(context.hello, "world");
assert.strictEqual(context.abc, 10);
@@ -4497,7 +4496,7 @@ QUnit.module('fields', {}, function () {
'</field>' +
'</form>',
mockRPC: function (route, args) {
- if (args.method === 'default_get') {
+ if (args.method === 'onchange') {
n++;
if (n === 2) {
var context = args.kwargs.context;
@@ -4546,7 +4545,7 @@ QUnit.module('fields', {}, function () {
});
QUnit.test('parent data is properly sent on an onchange rpc, new record', async function (assert) {
- assert.expect(6);
+ assert.expect(4);
this.data.turtle.onchanges = { turtle_bar: function () { } };
var form = await createView({
@@ -4572,7 +4571,7 @@ QUnit.module('fields', {}, function () {
},
});
await testUtils.dom.click(form.$('tbody td.o_field_x2many_list_row_add a'));
- assert.verifySteps(['default_get', 'onchange', 'default_get', 'onchange']);
+ assert.verifySteps(['onchange', 'onchange']);
form.destroy();
});
@@ -5370,6 +5369,11 @@ QUnit.module('fields', {}, function () {
QUnit.test('nested x2many default values', async function (assert) {
assert.expect(3);
+ this.data.partner.fields.turtles.default = [
+ [0, 0, { partner_ids: [[6, 0, [4]]] }],
+ [0, 0, { partner_ids: [[6, 0, [1]]] }],
+ ];
+
var form = await createView({
View: FormView,
model: 'partner',
@@ -5381,17 +5385,6 @@ QUnit.module('fields', {}, function () {
'</tree>' +
'</field>' +
'</form>',
- mockRPC: function (route, args) {
- if (args.model === 'partner' && args.method === 'default_get') {
- return Promise.resolve({
- turtles: [
- [0, 0, { partner_ids: [[6, 0, [4]]] }],
- [0, 0, { partner_ids: [[6, 0, [1]]] }],
- ],
- });
- }
- return this._super.apply(this, arguments);
- },
});
assert.containsN(form, '.o_list_view .o_data_row', 2,
@@ -5978,7 +5971,7 @@ QUnit.module('fields', {}, function () {
form.destroy();
});
- QUnit.test('one2many list editable, no onchange when required field is not set', async function (assert) {
+ QUnit.test('one2many list editable, onchange and required field', async function (assert) {
assert.expect(8);
this.data.turtle.fields.turtle_foo.required = true;
@@ -6017,7 +6010,7 @@ QUnit.module('fields', {}, function () {
assert.strictEqual(form.$('.o_field_widget[name="int_field"]').val(), "0",
"int_field should still be 0 (no onchange should have been done yet");
- assert.verifySteps(['read', 'default_get'], "no onchange should have been applied");
+ assert.verifySteps(['read', 'onchange']);
await testUtils.fields.editInput(form.$('.o_field_widget[name="turtle_foo"]'), "some text");
assert.verifySteps(['onchange']);
@@ -6080,7 +6073,7 @@ QUnit.module('fields', {}, function () {
await testUtils.dom.click(form.$('.o_field_x2many_list_row_add a'));
assert.strictEqual(form.$('.o_field_widget[name="int_field"]').val(), "0",
"int_field should still be 0 (no onchange should have been done yet)");
- assert.verifySteps(['load_views', 'read', 'default_get'], "no onchange should have been applied");
+ assert.verifySteps(['load_views', 'read', 'onchange']);
// fill turtle_foo field
await testUtils.fields.editInput(form.$('.o_field_widget[name="turtle_foo"]'), "some text");
@@ -6578,7 +6571,7 @@ QUnit.module('fields', {}, function () {
// triggers an onchange on partner, because the new record is valid
await testUtils.dom.click(form.$('.o_field_x2many_list_row_add a'));
- assert.verifySteps(['read', 'default_get', 'onchange']);
+ assert.verifySteps(['read', 'onchange', 'onchange']);
form.destroy();
});
@@ -6670,7 +6663,7 @@ QUnit.module('fields', {}, function () {
assert.containsN(form, 'tr.o_data_row', 40);
- assert.verifySteps(['read', 'read', 'default_get', 'write', 'read', 'read']);
+ assert.verifySteps(['read', 'read', 'onchange', 'write', 'read', 'read']);
form.destroy();
});
@@ -6765,7 +6758,7 @@ QUnit.module('fields', {}, function () {
assert.containsN(form, 'tr.o_data_row', 40);
- assert.verifySteps(['read', 'read', 'read', 'default_get', 'write', 'read', 'read']);
+ assert.verifySteps(['read', 'read', 'read', 'onchange', 'write', 'read', 'read']);
form.destroy();
});
@@ -7058,7 +7051,7 @@ QUnit.module('fields', {}, function () {
mockRPC: function (route, args) {
assert.strictEqual(args.kwargs.context.flutter, 'shy',
'view context key should be used for every rpcs');
- if (args.method === 'default_get') {
+ if (args.method === 'onchange') {
if (args.model === 'partner') {
assert.strictEqual(args.kwargs.context.default_flutter, 'why',
"should have default_* values in context for form view RPCs");
@@ -7506,7 +7499,7 @@ QUnit.module('fields', {}, function () {
form.destroy();
});
- QUnit.test('one2many with several pages, onchange and default order', async function (assert) {
+ QUnit.skip('one2many with several pages, onchange and default order', async function (assert) {
// This test reproduces a specific scenario where a one2many is displayed
// over several pages, and has a default order such that a record that
// would normally be on page 1 is actually on another page. Moreover,
@@ -7575,6 +7568,14 @@ QUnit.module('fields', {}, function () {
'read [2,3]', // one2many (all fields in view, records of first page)
'read [2,4]', // many2many inside one2many (partner_ids), first page only
'onchange',
+ 'read [1]', // AAB FIXME 4 (draft fixing taskid-2323491):
+ // this test's purpose is to assert that this rpc isn't
+ // done, but yet it is. Actually, it wasn't before because mockOnChange
+ // returned [1] as command list, instead of [[6, false, [1]]], so basically
+ // this value was ignored. Now that mockOnChange properly works, the value
+ // is taken into account but the basicmodel doesn't care it concerns a
+ // record of the second page, and does the read. I don't think we
+ // introduced a regression here, this test was simply wrong...
]);
form.destroy();
@@ -7689,7 +7690,7 @@ QUnit.module('fields', {}, function () {
});
QUnit.test('onchange in a one2many with non inline view on a new record', async function (assert) {
- assert.expect(8);
+ assert.expect(6);
this.data.turtle.onchanges = {
display_name: function (obj) {
@@ -7725,9 +7726,7 @@ QUnit.module('fields', {}, function () {
assert.verifySteps([
'load_views', // load sub list
- 'default_get', // main record
'onchange', // main record
- 'default_get', // sub record
'onchange', // sub record
'onchange', // edition of display_name of sub record
]);
@@ -8314,9 +8313,9 @@ QUnit.module('fields', {}, function () {
assert.strictEqual(form.$('.o_data_row').text(), 'some foo value',
"foo field should have correct value");
assert.verifySteps([
- 'default_get', // main record
- 'default_get', // line 1
- 'default_get', // line 2
+ 'onchange', // main record
+ 'onchange', // line 1
+ 'onchange', // line 2
'create',
'read', // main record
'read', // line 1
@@ -8770,7 +8769,7 @@ QUnit.module('fields', {}, function () {
});
QUnit.test('many2manys inside a one2many are fetched in batch after onchange', async function (assert) {
- assert.expect(7);
+ assert.expect(6);
this.data.partner.onchanges = {
turtles: function (obj) {
@@ -8815,7 +8814,7 @@ QUnit.module('fields', {}, function () {
assert.strictEqual(form.$('.o_field_widget[name="partner_ids"]').text().replace(/\s/g, ''),
"secondrecordsecondrecordaaa");
- assert.verifySteps(['default_get', 'onchange', 'read']);
+ assert.verifySteps(['onchange', 'read']);
form.destroy();
});
diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js
index bbbf74f5b7b..56bb564880f 100644
--- a/addons/web/static/tests/fields/relational_fields_tests.js
+++ b/addons/web/static/tests/fields/relational_fields_tests.js
@@ -197,16 +197,12 @@ QUnit.module('relational_fields', {
});
QUnit.test('do not call name_get if display_name already known', async function (assert) {
- // default_get only returns the id for many2one fields
- // onchange returns an array with the id and the display_name
- // thus, when an onchange is performed, there is no need to call
- // name_get as the display_name is alreay available
- assert.expect(6);
+ assert.expect(4);
this.data.partner.fields.product_id.default = 37;
this.data.partner.onchanges = {
trululu: function (obj) {
- obj.trululu = [1, 'first record'];
+ obj.trululu = 1;
},
};
@@ -223,11 +219,7 @@ QUnit.module('relational_fields', {
assert.strictEqual(form.$('.o_field_widget[name=trululu] input').val(), 'first record');
assert.strictEqual(form.$('.o_field_widget[name=product_id] input').val(), 'xphone');
- assert.verifySteps([
- 'default_get on partner',
- 'onchange on partner',
- 'name_get on product',
- ]);
+ assert.verifySteps(['onchange on partner']);
form.destroy();
});
@@ -530,9 +522,9 @@ QUnit.module('relational_fields', {
assert.verifySteps([
'read partner',
'read turtle',
- 'default_get turtle',
+ 'onchange turtle',
'onchange partner',
- 'default_get turtle',
+ 'onchange turtle',
'onchange partner',
]);
form.destroy();
@@ -2784,7 +2776,7 @@ QUnit.module('relational_fields', {
this.data.partner.fields.reference.default = 'product,37';
this.data.partner.onchanges = {
int_field: function (obj) {
- if (obj.int_field !== 0) {
+ if (obj.int_field) {
obj.reference = 'partner_type,' + obj.int_field;
}
},