odoo.define('web_enterprise.relational_fields_mobile_tests', function (require) { "use strict"; var FormView = require('web.FormView'); var testUtils = require('web.test_utils'); var createView = testUtils.createView; QUnit.module('web_enterprise', {}, function () { QUnit.module('relational_fields', { beforeEach: function () { this.data = { partner: { fields: { display_name: { string: "Displayed name", type: "char" }, trululu: {string: "Trululu", type: "many2one", relation: 'partner'}, sibling_ids: {string: "Sibling", type: "many2many", relation: 'partner'}, p: { string: "one2many field", type: "one2many", relation: 'partner', relation_field: 'trululu' }, }, records: [{ id: 1, display_name: "first record", trululu: 4, }, { id: 2, display_name: "second record", trululu: 1, }, { id: 4, display_name: "aaa", }], }, }; } }, function () { QUnit.module('FieldStatus'); QUnit.test('statusbar is rendered correclty on small devices', async function (assert) { assert.expect(7); var form = await createView({ View: FormView, model: 'partner', data: this.data, arch: '
' + '
' + '' + '', res_id: 1, }); assert.strictEqual(form.$('.o_statusbar_status > button:contains(aaa)').length, 1, "should have only one visible status in mobile, the active one"); assert.containsOnce(form, '.o_statusbar_status .dropdown-menu', "should have a dropdown containing all status"); assert.containsNone(form, '.o_statusbar_status .dropdown-menu:visible', "dropdown should be hidden"); // open the dropdown testUtils.dom.click(form.$('.o_statusbar_status > button')); assert.containsOnce(form, '.o_statusbar_status .dropdown-menu:visible', "dropdown should be visible"); assert.containsN(form, '.o_statusbar_status .dropdown-menu button', 3, "should have 3 status"); assert.containsN(form, '.o_statusbar_status button:disabled', 3, "all status should be disabled"); var $activeStatus = form.$('.o_statusbar_status .dropdown-menu button[data-value=4]'); assert.hasClass($activeStatus,'btn-primary', "active status should be btn-primary"); form.destroy(); }); QUnit.test('statusbar with no status on extra small screens', async function (assert) { assert.expect(9); var form = await createView({ View: FormView, model: 'partner', data: this.data, arch:'
' + '
' + '
', res_id: 4, }); assert.hasClass(form.$('.o_statusbar_status'),'o_field_empty', 'statusbar widget should have class o_field_empty'); assert.strictEqual(form.$('.o_statusbar_status').children().length, 2, 'statusbar widget should have two children'); assert.containsOnce(form, '.o_statusbar_status button.dropdown-toggle', 'statusbar widget should have a button'); assert.strictEqual(form.$('.o_statusbar_status button.dropdown-toggle').text().trim(), '', 'statusbar button has no text'); // Behavior as of saas-15, might be improved assert.containsOnce(form, '.o_statusbar_status .dropdown-menu', 'statusbar widget should have a dropdown menu'); assert.containsN(form, '.o_statusbar_status .dropdown-menu button', 3, 'statusbar widget dropdown menu should have 3 buttons'); assert.strictEqual(form.$('.o_statusbar_status .dropdown-menu button').eq(0).text().trim(), 'first record', 'statusbar widget dropdown first button should display the first record display_name'); assert.strictEqual(form.$('.o_statusbar_status .dropdown-menu button').eq(1).text().trim(), 'second record', 'statusbar widget dropdown second button should display the second record display_name'); assert.strictEqual(form.$('.o_statusbar_status .dropdown-menu button').eq(2).text().trim(), 'aaa', 'statusbar widget dropdown third button should display the third record display_name'); form.destroy(); }); QUnit.test('clickable statusbar widget on mobile view', async function (assert) { assert.expect(5); var form = await createView({ View: FormView, model: 'partner', data: this.data, arch:'
' + '
' + '
', res_id: 1, }); var $selectedStatus = form.$('.o_statusbar_status button[data-value="4"]'); assert.hasClass($selectedStatus, 'btn-primary'); assert.hasClass($selectedStatus,'disabled'); var selector = '.o_statusbar_status button.btn-secondary:not(.dropdown-toggle):not(:disabled)'; assert.containsN(form, selector, 2, "other status should be btn-secondary and not disabled"); await testUtils.dom.click(form.$('.o_statusbar_status .dropdown-toggle')); await testUtils.dom.clickFirst(form.$(selector)); var $status = form.$('.o_statusbar_status button[data-value="1"]'); assert.hasClass($status, 'btn-primary'); assert.hasClass($status, 'disabled'); form.destroy(); }); QUnit.module('FieldMany2One'); QUnit.test("many2one in a enterprise environment", async function (assert) { assert.expect(7); var form = await createView({ View: FormView, arch: '
' + '' + '' + '' + '
', archs: { 'partner,false,kanban': '' + '' + '
' + '
' + '
', 'partner,false,search': '', }, data: this.data, model: 'partner', res_id: 2, viewOptions: {mode: 'edit'}, }); var $input = form.$('.o_field_many2one input'); assert.doesNotHaveClass($input, 'ui-autocomplete-input', "autocomplete should not be visible in a mobile environment"); await testUtils.dom.click($input); var $modal = $('.o_modal_full .modal-lg'); assert.equal($modal.length, 1, 'there should be one modal opened in full screen'); assert.containsOnce($modal, '.o_legacy_kanban_view', 'kanban view should be open in SelectCreateDialog'); assert.containsOnce($modal, '.o_cp_searchview', 'should have Search view inside SelectCreateDialog'); assert.containsNone($modal.find(".o_control_panel .o_cp_buttons"), '.o-kanban-button-new', "kanban view in SelectCreateDialog should not have Create button"); assert.strictEqual($modal.find(".o_legacy_kanban_view .o_kanban_record:not(.o_kanban_ghost)").length, 3, "popup should load 3 records in kanban"); await testUtils.dom.click($modal.find('.o_legacy_kanban_view .o_kanban_record:first')); assert.strictEqual($input.val(), 'first record', 'clicking kanban card should select record for many2one field'); form.destroy(); }); QUnit.test("hide/show element using selection_mode in kanban view in a enterprise environment", async function (assert) { assert.expect(5); this.data.partner.fields.foo = {string: "Foo", type: "char", default: "My little Foo Value"}; var form = await createView({ View: FormView, arch: '
' + '' + '' + '' + '
', archs: { 'partner,false,kanban': '' + '' + '
' + '' + '
' + '
' + '' + '
' + '
' + '' + '
' + '
' + '
', 'partner,false,search': '', }, data: this.data, model: 'partner', res_id: 2, viewOptions: {mode: 'edit'}, }); var $input = form.$('.o_field_many2one input'); assert.doesNotHaveClass($input, 'ui-autocomplete-input', "autocomplete should not be visible in a mobile environment"); await testUtils.dom.click($input); var $modal = $('.o_modal_full .modal-lg'); assert.equal($modal.length, 1, 'there should be one modal opened in full screen'); assert.containsOnce($modal, '.o_legacy_kanban_view', 'kanban view should be open in SelectCreateDialog'); assert.containsNone($modal, '.o_legacy_kanban_view .o_sibling_tags', 'o_sibling_tags div should not be available as div have condition on selection_mode'); assert.containsN($modal, '.o_legacy_kanban_view .o_foo', 3, 'o_foo div should be available as div have condition on selection_mode'); form.destroy(); }); QUnit.test("kanban_view_ref attribute opens specific kanban view given as a reference in a mobile environment", async function (assert) { assert.expect(5); var form = await createView({ View: FormView, arch: '
' + '' + '' + '' + '
', archs: { 'partner,1,kanban': '' + '' + '
' + '' + '
' + '
' + '
', 'partner,2,kanban': '' + '' + '
' + '
' + '' + '
' + '
' + '' + '
' + '
' + '
' + '
', 'partner,false,search': '', }, data: this.data, model: 'partner', res_id: 2, viewOptions: {mode: 'edit'}, }); var $input = form.$('.o_field_many2one input'); assert.doesNotHaveClass($input, 'ui-autocomplete-input', "autocomplete should not be visible in a mobile environment"); await testUtils.dom.click($input); var $modal = $('.o_modal_full .modal-lg'); assert.equal($modal.length, 1, 'there should be one modal opened in full screen'); assert.containsOnce($modal, '.o_legacy_kanban_view', 'kanban view should be open in SelectCreateDialog'); assert.hasClass($modal.find('.o_legacy_kanban_view'), 'kanban2', 'kanban view with id 2 should be opened as it is given as kanban_view_ref'); assert.strictEqual($modal.find('.o_legacy_kanban_view .o_kanban_record:first').text(), 'first recordaaa', 'kanban with two fields should be opened'); form.destroy(); }); QUnit.test("many2one dialog on mobile: clear button header", async function (assert) { assert.expect(7); const form = await createView({ View: FormView, arch: `
`, archs: { 'partner,false,kanban': `
`, 'partner,false,search': '', }, data: this.data, model: 'partner', res_id: 2, viewOptions: {mode: 'edit'}, }); let $input = form.$('.o_field_many2one input'); assert.doesNotHaveClass($input, 'ui-autocomplete-input', "autocomplete should not be visible in a mobile environment"); await testUtils.dom.click($input); assert.containsOnce($('body'), '.modal.o_modal_full', "there should be a modal opened in full screen"); assert.containsN($('.modal'), '.o_legacy_kanban_view .o_kanban_record:not(.o_kanban_ghost)', 3, "popup should load 3 records in kanban"); await testUtils.dom.click($('.modal').find('.o_legacy_kanban_view .o_kanban_record:first')); assert.strictEqual($input.val(), 'first record', 'clicking kanban card should select record for many2one field'); await testUtils.dom.click($input); // clear button. assert.containsOnce($('.modal').find('.modal-header'), '.o_clear_button', "there should be a Clear button in the modal header"); await testUtils.dom.click($('.modal').find('.modal-header .o_clear_button')); assert.containsNone($('body'), '.modal', "there should be no more modal"); $input = form.$('.o_field_many2one input'); assert.strictEqual($input.val(), "", "many2one should be cleared"); form.destroy(); }); QUnit.module('FieldMany2Many'); QUnit.test("many2many_tags in a mobile environment", async function (assert) { assert.expect(10); var rpcReadCount = 0; var form = await createView({ View: FormView, arch: '
' + '' + '' + '' + '
', archs: { 'partner,false,kanban': '' + '' + '
' + '
' + '
', 'partner,false,search': '', }, data: this.data, model: 'partner', res_id: 2, viewOptions: {mode: 'edit'}, mockRPC: function (route, args) { if (args.method === "read" && args.model === "partner") { if (rpcReadCount === 0) { assert.deepEqual(args.args[0], [2], "form should initially show partner 2"); } else if (rpcReadCount === 1) { assert.deepEqual(args.args[0], [1], "partner with id 1 should be selected"); } rpcReadCount++; } return this._super.apply(this, arguments); }, }); var $input = form.$(".o_field_widget .o_input"); assert.strictEqual($input.find(".badge").length, 0, "many2many_tags should have no tags"); await testUtils.dom.click($input); var $modal = $('.o_modal_full .modal-lg'); assert.equal($modal.length, 1, 'there should be one modal opened in full screen'); assert.containsOnce($modal, '.o_legacy_kanban_view', 'kanban view should be open in SelectCreateDialog'); assert.containsOnce($modal, '.o_cp_searchview', 'should have Search view inside SelectCreateDialog'); assert.containsNone($modal.find(".o_control_panel .o_cp_buttons"), '.o-kanban-button-new', "kanban view in SelectCreateDialog should not have Create button"); assert.strictEqual($modal.find(".o_legacy_kanban_view .o_kanban_record:not(.o_kanban_ghost)").length, 3, "popup should load 3 records in kanban"); await testUtils.dom.click($modal.find('.o_legacy_kanban_view .o_kanban_record:first')); assert.strictEqual(rpcReadCount, 2, "there should be a read for current form record and selected sibling"); assert.strictEqual(form.$(".o_field_widget.o_input .badge").length, 1, "many2many_tags should have partner coucou3"); form.destroy(); }); QUnit.module('FieldOne2Many'); QUnit.test('one2many on mobile: remove header button', async function (assert) { assert.expect(9); this.data.partner.records[0].p = [1, 2, 4]; const form = await createView({ View: FormView, model: 'partner', data: this.data, arch: `
`, archs: { 'partner,false,form': `
`, 'partner,false,kanban': `
`, }, res_id: 1, mockRPC(route, args) { if (route === '/web/dataset/call_kw/partner/write') { const commands = args.args[1].p; assert.strictEqual(commands.length, 3, 'should have generated three commands'); assert.ok(commands[0][0] === 4 && commands[0][1] === 2, 'should have generated the command 4 (LINK_TO) with id 2'); assert.ok(commands[1][0] === 4 && commands[1][1] === 4, 'should have generated the command 2 (LINK_TO) with id 1'); assert.ok(commands[2][0] === 2 && commands[2][1] === 1, 'should have generated the command 2 (DELETE) with id 2'); } return this._super.apply(this, arguments); }, }); await testUtils.form.clickEdit(form); assert.containsN(form, '.o_legacy_kanban_view .o_kanban_record:not(.o_kanban_ghost)', 3, "should have 3 records in kanban"); await testUtils.dom.click(form.$('.o_legacy_kanban_view .o_kanban_record:first')); assert.containsOnce($('body'), '.modal.o_modal_full', "there should be a modal opened in full screen"); // remove button. assert.containsOnce($('.modal').find('.modal-header'), '.o_btn_remove', "there should be a 'Remove' button in the modal header"); await testUtils.dom.click($('.modal').find('.modal-header .o_btn_remove')); assert.containsNone($('body'), '.modal', "there should be no more modal"); assert.containsN(form, '.o_legacy_kanban_view .o_kanban_record:not(.o_kanban_ghost)', 2, "should have 2 records in kanban"); // save and check that the correct command has been generated await testUtils.form.clickSave(form); form.destroy(); }); }); }); });