[REF] *: Adapt all module tests to the new control panel
Use of the new control panel helpers to increase consistency and change the assertions according to the new DOM/behaviour (e.g. components removed instead of turning invisible). Part of task 2196029 Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com>
This commit is contained in:
co-authored by
Mathieu Duckerts-Antoine
parent
bb8eb766a8
commit
804507ef49
@@ -20,7 +20,7 @@ odoo.define('account.dashboard.setup.tour', function (require) {
|
||||
}, {
|
||||
trigger: '.o_control_panel button:contains("' + _t('Print') + '")',
|
||||
}, {
|
||||
trigger: '.o_control_panel div.o_dropdown_menu a:contains("' + _t('Invoices without Payment') + '")',
|
||||
trigger: '.o_control_panel .o_dropdown_menu a:contains("' + _t('Invoices without Payment') + '")',
|
||||
}, {
|
||||
trigger: 'iframe .o_report_layout_standard h2',
|
||||
content: 'Primary color is correct',
|
||||
|
||||
@@ -8,6 +8,7 @@ var testUtils = require('web.test_utils');
|
||||
var ListRenderer = require('web.ListRenderer');
|
||||
var pyUtils = require('web.py_utils');
|
||||
|
||||
const cpHelpers = testUtils.controlPanel;
|
||||
var createActionManager = testUtils.createActionManager;
|
||||
var createView = testUtils.createView;
|
||||
|
||||
@@ -701,7 +702,7 @@ QUnit.test('save actions to dashboard', async function (assert) {
|
||||
var result = this._super.apply(this, arguments);
|
||||
result.context = {
|
||||
'fire': 'on the bayou',
|
||||
}
|
||||
};
|
||||
return result;
|
||||
}
|
||||
});
|
||||
@@ -733,7 +734,7 @@ QUnit.test('save actions to dashboard', async function (assert) {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
await actionManager.doAction({
|
||||
@@ -750,15 +751,16 @@ QUnit.test('save actions to dashboard', async function (assert) {
|
||||
await testUtils.dom.click($('.o_column_sortable'));
|
||||
|
||||
// Group It
|
||||
await testUtils.dom.click($('.o_search_options .o_dropdown button:contains(Group By)'));
|
||||
await testUtils.dom.click($('.o_search_options .o_group_by_menu button'));
|
||||
await testUtils.dom.click($('.o_search_options .o_group_by_menu button.o_apply_group'));
|
||||
await cpHelpers.toggleGroupByMenu(actionManager);
|
||||
await cpHelpers.toggleAddCustomGroup(actionManager);
|
||||
await cpHelpers.applyGroup(actionManager);
|
||||
|
||||
// add this action to dashboard
|
||||
await testUtils.dom.click($('.o_search_options .o_dropdown button:contains(Favorites)'));
|
||||
await testUtils.dom.click($('.o_add_to_board.o_menu_header'));
|
||||
testUtils.fields.editInput($('input.o_add_to_board_input'), 'a name');
|
||||
await testUtils.dom.click($('.o_add_to_board_confirm_button'));
|
||||
await cpHelpers.toggleFavoriteMenu(actionManager);
|
||||
|
||||
await testUtils.dom.click($('.o_add_to_board > button'));
|
||||
await testUtils.fields.editInput($('.o_add_to_board input'), 'a name');
|
||||
await testUtils.dom.click($('.o_add_to_board div button'));
|
||||
|
||||
testUtils.unpatch(ListController);
|
||||
|
||||
@@ -802,38 +804,28 @@ QUnit.test('save two searches to dashboard', async function (assert) {
|
||||
|
||||
var filter_count = 0;
|
||||
// Add a first filter
|
||||
await testUtils.dom.click(actionManager.$('.o_filters_menu_button'));
|
||||
await testUtils.dom.click(actionManager.$('.o_add_custom_filter'));
|
||||
actionManager.$('.o_searchview_extended_prop_value .o_input').val('a');
|
||||
await testUtils.dom.click(actionManager.$('.o_apply_filter'));
|
||||
await cpHelpers.toggleFilterMenu(actionManager);
|
||||
await cpHelpers.toggleAddCustomFilter(actionManager);
|
||||
await testUtils.fields.editInput(actionManager.el.querySelector('.o_generator_menu_value .o_input'), 'a');
|
||||
await cpHelpers.applyFilter(actionManager);
|
||||
|
||||
// Add it to dashboard
|
||||
await testUtils.dom.click(actionManager.$('.o_favorites_menu_button'));
|
||||
$('.o_search_options .dropdown-menu.o_favorites_menu').one('click', function (ev) {
|
||||
// This handler is on the webClient
|
||||
// But since the test suite doesn't have one
|
||||
// We manually set it here
|
||||
ev.stopPropagation();
|
||||
});
|
||||
await testUtils.dom.click(actionManager.$('.o_add_to_board'));
|
||||
await testUtils.dom.click(actionManager.$('.o_add_to_board_confirm_button'));
|
||||
await cpHelpers.toggleFavoriteMenu(actionManager);
|
||||
await testUtils.dom.click($('.o_add_to_board > button'));
|
||||
await testUtils.dom.click($('.o_add_to_board div button'));
|
||||
|
||||
// Remove it
|
||||
await testUtils.dom.click(actionManager.$('.o_facet_remove'));
|
||||
await testUtils.dom.click(actionManager.el.querySelector('.o_facet_remove'));
|
||||
|
||||
// Add the second filter
|
||||
await testUtils.dom.click(actionManager.$('.o_filters_menu_button'));
|
||||
await testUtils.dom.click(actionManager.$('.o_add_custom_filter'));
|
||||
actionManager.$('.o_searchview_extended_prop_value .o_input').val('b');
|
||||
await testUtils.dom.click(actionManager.$('.o_apply_filter'));
|
||||
await cpHelpers.toggleFilterMenu(actionManager);
|
||||
await cpHelpers.toggleAddCustomFilter(actionManager);
|
||||
await testUtils.fields.editInput(actionManager.el.querySelector('.o_generator_menu_value .o_input'), "b");
|
||||
await cpHelpers.applyFilter(actionManager);
|
||||
// Add it to dashboard
|
||||
await testUtils.dom.click(actionManager.$('.o_favorites_menu_button'));
|
||||
$('.o_search_options .dropdown-menu.o_favorites_menu').one('click', function (ev) {
|
||||
// This handler is on the webClient
|
||||
// But since the test suite doesn't have one
|
||||
// We manually set it here
|
||||
ev.stopPropagation();
|
||||
});
|
||||
await testUtils.dom.click(actionManager.$('.o_add_to_board'));
|
||||
await testUtils.dom.click(actionManager.$('.o_add_to_board_confirm_button'));
|
||||
await cpHelpers.toggleFavoriteMenu(actionManager);
|
||||
await testUtils.dom.click(actionManager.el.querySelector('.o_add_to_board > button'));
|
||||
await testUtils.dom.click(actionManager.el.querySelector('.o_add_to_board div button'));
|
||||
|
||||
actionManager.destroy();
|
||||
});
|
||||
@@ -846,7 +838,7 @@ QUnit.test('save a action domain to dashboard', async function (assert) {
|
||||
var filter_domain = ["display_name", "ilike", "b"];
|
||||
|
||||
// The filter domain already contains the view domain, but is always added by dashboard..,
|
||||
var expected_domain = ['&', '&', view_domain, view_domain, filter_domain]
|
||||
var expected_domain = ['&', '&', view_domain, view_domain, filter_domain];
|
||||
|
||||
var actionManager = await createActionManager({
|
||||
data: this.data,
|
||||
@@ -873,14 +865,18 @@ QUnit.test('save a action domain to dashboard', async function (assert) {
|
||||
});
|
||||
|
||||
// Add a filter
|
||||
await testUtils.dom.click(actionManager.$('.o_filters_menu_button'));
|
||||
await testUtils.dom.click(actionManager.$('.o_add_custom_filter'));
|
||||
actionManager.$('.o_searchview_extended_prop_value .o_input').val('b');
|
||||
await testUtils.dom.click(actionManager.$('.o_apply_filter'));
|
||||
await cpHelpers.toggleFilterMenu(actionManager);
|
||||
await cpHelpers.toggleAddCustomFilter(actionManager);
|
||||
await testUtils.fields.editInput(
|
||||
actionManager.el.querySelector('.o_generator_menu_value .o_input'),
|
||||
"b"
|
||||
);
|
||||
await cpHelpers.applyFilter(actionManager);
|
||||
// Add it to dashboard
|
||||
await testUtils.dom.click(actionManager.$('.o_favorites_menu_button'));
|
||||
await testUtils.dom.click(actionManager.$('.o_add_to_board'));
|
||||
await testUtils.dom.click(actionManager.$('.o_add_to_board_confirm_button'));
|
||||
await cpHelpers.toggleFavoriteMenu(actionManager);
|
||||
await testUtils.dom.click(actionManager.el.querySelector('.o_add_to_board > button'));
|
||||
// add
|
||||
await testUtils.dom.click(actionManager.el.querySelector('.o_add_to_board div button'));
|
||||
|
||||
actionManager.destroy();
|
||||
});
|
||||
|
||||
@@ -1,166 +1,129 @@
|
||||
odoo.define('google_drive.gdrive_integration', function (require) {
|
||||
"use strict";
|
||||
//rebuild
|
||||
var FormView = require('web.FormView');
|
||||
var testUtils = require('web.test_utils');
|
||||
var GoogleDriveSideBar = require('google_drive.sidebar');
|
||||
"use strict";
|
||||
|
||||
var createView = testUtils.createView;
|
||||
const FormView = require('web.FormView');
|
||||
const testUtils = require('web.test_utils');
|
||||
|
||||
/*
|
||||
* @override
|
||||
* Avoid breaking other tests because of the new route
|
||||
* that the module introduces
|
||||
*/
|
||||
var _addGoogleDocItemsOriginal = GoogleDriveSideBar.prototype._addGoogleDocItems;
|
||||
const cpHelpers = testUtils.controlPanel;
|
||||
|
||||
var _addGoogleDocItemsMocked = function (model, resID) {
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
GoogleDriveSideBar.prototype._addGoogleDocItems = _addGoogleDocItemsMocked;
|
||||
|
||||
QUnit.module('gdrive_integration', {
|
||||
beforeEach: function () {
|
||||
// For our test to work, the _addGoogleDocItems function needs to be the original
|
||||
GoogleDriveSideBar.prototype._addGoogleDocItems = _addGoogleDocItemsOriginal;
|
||||
|
||||
this.data = {
|
||||
partner: {
|
||||
fields: {
|
||||
display_name: {string: "Displayed name", type: "char", searchable: true},
|
||||
QUnit.module('Google Drive Integration', {
|
||||
beforeEach() {
|
||||
this.data = {
|
||||
partner: {
|
||||
fields: {
|
||||
display_name: { string: "Displayed name", type: "char", searchable: true },
|
||||
},
|
||||
records: [
|
||||
{ id: 1, display_name: "Locomotive Breath" },
|
||||
{ id: 2, display_name: "Hey Macarena" },
|
||||
],
|
||||
},
|
||||
records: [{
|
||||
id: 1,
|
||||
display_name: "Locomotive Breath",
|
||||
}, {
|
||||
id: 2,
|
||||
display_name: "Hey Macarena",
|
||||
}],
|
||||
},
|
||||
'google.drive.config': {
|
||||
fields: {
|
||||
model_id: {string: 'Model', type: 'int'},
|
||||
name: {string: 'Name', type: 'char'},
|
||||
google_drive_resource_id: {string: 'Resource ID', type: 'char'},
|
||||
};
|
||||
},
|
||||
}, function () {
|
||||
|
||||
QUnit.module('Google Drive ActionMenus');
|
||||
|
||||
QUnit.test('rendering of the google drive attachments in action menus', async function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
const form = await testUtils.createView({
|
||||
actionMenusRegistry: true,
|
||||
arch:
|
||||
`<form string="Partners">
|
||||
<field name="display_name"/>
|
||||
</form>`,
|
||||
data: this.data,
|
||||
async mockRPC(route, args) {
|
||||
switch (route) {
|
||||
case '/web/dataset/call_kw/google.drive.config/get_google_drive_config':
|
||||
assert.deepEqual(args.args, ['partner', 1],
|
||||
'The route to get google drive config should have been called');
|
||||
return [{
|
||||
id: 27,
|
||||
name: 'Cyberdyne Systems',
|
||||
}];
|
||||
case '/web/dataset/call_kw/google.drive.config/search_read':
|
||||
return [{
|
||||
google_drive_resource_id: "T1000",
|
||||
google_drive_client_id: "cyberdyne.org",
|
||||
id: 1,
|
||||
}];
|
||||
case '/web/dataset/call_kw/google.drive.config/get_google_drive_url':
|
||||
assert.deepEqual(args.args, [27, 1, 'T1000'],
|
||||
'The route to get the Google url should have been called');
|
||||
return; // do not return anything or it will open a new tab.
|
||||
}
|
||||
},
|
||||
records: [{
|
||||
id: 27,
|
||||
name: 'Cyberdyne Systems',
|
||||
model_id: 1,
|
||||
google_drive_resource_id: 'T1000',
|
||||
}],
|
||||
},
|
||||
'ir.attachment': {
|
||||
fields: {
|
||||
name: {string: 'Name', type:'char'}
|
||||
model: 'partner',
|
||||
res_id: 1,
|
||||
View: FormView,
|
||||
viewOptions: {
|
||||
hasActionMenus: true,
|
||||
},
|
||||
records: [],
|
||||
}
|
||||
};
|
||||
},
|
||||
});
|
||||
await cpHelpers.toggleActionMenu(form);
|
||||
|
||||
afterEach: function() {
|
||||
GoogleDriveSideBar.prototype._addGoogleDocItems = _addGoogleDocItemsMocked;
|
||||
}
|
||||
assert.containsOnce(form, '.oe_share_gdoc_item',
|
||||
"The button to the google action should be present");
|
||||
|
||||
}, function () {
|
||||
QUnit.module('Google Drive Sidebar');
|
||||
await cpHelpers.toggleMenuItem(form, "Cyberdyne Systems");
|
||||
|
||||
QUnit.test('rendering of the google drive attachments in Sidebar', async function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
var form = await createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch: '<form string="Partners">' +
|
||||
'<field name="display_name"/>' +
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
viewOptions: {hasSidebar: true},
|
||||
mockRPC: function (route, args) {
|
||||
if (route === '/web/dataset/call_kw/google.drive.config/get_google_drive_config') {
|
||||
assert.deepEqual(args.args, ['partner', 1],
|
||||
'The route to get google drive config should have been called');
|
||||
return Promise.resolve([{id: 27, name: 'Cyberdyne Systems'}]);
|
||||
}
|
||||
if (route === '/web/dataset/call_kw/google.drive.config/search_read'){
|
||||
return Promise.resolve([{google_drive_resource_id: "T1000",
|
||||
google_drive_client_id: "cyberdyne.org",
|
||||
id: 1}]);
|
||||
}
|
||||
if (route === '/web/dataset/call_kw/google.drive.config/get_google_drive_url') {
|
||||
assert.deepEqual(args.args, [27, 1, 'T1000'],
|
||||
'The route to get the Google url should have been called');
|
||||
// We don't return anything useful, otherwise it will open a new tab
|
||||
return Promise.resolve();
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
var $googleAction = form.sidebar.$('.oe_share_gdoc');
|
||||
QUnit.test('click on the google drive attachments after switching records', async function (assert) {
|
||||
assert.expect(4);
|
||||
|
||||
assert.strictEqual($googleAction.length, 1,
|
||||
'The button to the google action should be present');
|
||||
let currentID;
|
||||
const form = await testUtils.createView({
|
||||
actionMenusRegistry: true,
|
||||
arch:
|
||||
`<form string="Partners">
|
||||
<field name="display_name"/>
|
||||
</form>`,
|
||||
data: this.data,
|
||||
async mockRPC(route, args) {
|
||||
switch (route) {
|
||||
case '/web/dataset/call_kw/google.drive.config/get_google_drive_config':
|
||||
assert.deepEqual(args.args, ['partner', currentID],
|
||||
'The route to get google drive config should have been called');
|
||||
return [{
|
||||
id: 27,
|
||||
name: 'Cyberdyne Systems',
|
||||
}];
|
||||
case '/web/dataset/call_kw/google.drive.config/search_read':
|
||||
return [{
|
||||
google_drive_resource_id: "T1000",
|
||||
google_drive_client_id: "cyberdyne.org",
|
||||
id: 1,
|
||||
}];
|
||||
case '/web/dataset/call_kw/google.drive.config/get_google_drive_url':
|
||||
assert.deepEqual(args.args, [27, currentID, 'T1000'],
|
||||
'The route to get the Google url should have been called');
|
||||
return; // do not return anything or it will open a new tab.
|
||||
}
|
||||
},
|
||||
model: 'partner',
|
||||
res_id: 1,
|
||||
View: FormView,
|
||||
viewOptions: {
|
||||
hasActionMenus: true,
|
||||
ids: [1, 2],
|
||||
index: 0,
|
||||
},
|
||||
});
|
||||
currentID = 1;
|
||||
await cpHelpers.toggleActionMenu(form);
|
||||
await cpHelpers.toggleMenuItem(form, "Cyberdyne Systems");
|
||||
|
||||
// click on gdrive sidebar item
|
||||
await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
|
||||
await testUtils.dom.click($googleAction);
|
||||
await cpHelpers.pagerNext(form);
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
currentID = 2;
|
||||
await cpHelpers.toggleActionMenu(form);
|
||||
await cpHelpers.toggleMenuItem(form, "Cyberdyne Systems");
|
||||
|
||||
QUnit.test('click on the google drive attachments after switching records', async function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
var currentID;
|
||||
var form = await createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch: '<form string="Partners">' +
|
||||
'<field name="display_name"/>' +
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
viewOptions: {
|
||||
hasSidebar: true,
|
||||
ids: [1, 2],
|
||||
index: 0,
|
||||
},
|
||||
mockRPC: function (route, args) {
|
||||
if (route === '/web/dataset/call_kw/google.drive.config/get_google_drive_config') {
|
||||
assert.deepEqual(args.args, ['partner', 1],
|
||||
'The route to get google drive config should have been called');
|
||||
return Promise.resolve([{id: 27, name: 'Cyberdyne Systems'}]);
|
||||
}
|
||||
if (route === '/web/dataset/call_kw/google.drive.config/search_read'){
|
||||
return Promise.resolve([{google_drive_resource_id: "T1000",
|
||||
google_drive_client_id: "cyberdyne.org",
|
||||
id: 1}]);
|
||||
}
|
||||
if (route === '/web/dataset/call_kw/google.drive.config/get_google_drive_url') {
|
||||
assert.deepEqual(args.args, [27, currentID, 'T1000'],
|
||||
'The route to get the Google url should have been called');
|
||||
// We don't return anything useful, otherwise it will open a new tab
|
||||
return Promise.resolve();
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
currentID = 1;
|
||||
await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
|
||||
await testUtils.dom.click(form.sidebar.$('.oe_share_gdoc'));
|
||||
|
||||
await testUtils.dom.click(form.pager.$('.o_pager_next'));
|
||||
currentID = 2;
|
||||
await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
|
||||
await testUtils.dom.click(form.sidebar.$('.oe_share_gdoc'));
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -38,7 +38,7 @@ QUnit.test('messaging menu does not display the Support channel if not available
|
||||
assert.expect(1);
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
data: this.data,
|
||||
services: this.services,
|
||||
});
|
||||
|
||||
@@ -33,7 +33,7 @@ QUnit.test('messaging menu displays the Support channel', async function (assert
|
||||
assert.expect(1);
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
addMockSupportEnvironment(messagingMenu, {
|
||||
await addMockSupportEnvironment(messagingMenu, {
|
||||
data: this.data,
|
||||
services: this.services,
|
||||
session: this.supportParams,
|
||||
@@ -51,7 +51,7 @@ QUnit.test('clicking on Support channel: channel not available', async function
|
||||
assert.expect(9);
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
addMockSupportEnvironment(messagingMenu, {
|
||||
await addMockSupportEnvironment(messagingMenu, {
|
||||
data: this.data,
|
||||
mockRPC: function (route, args) {
|
||||
if (!_.string.endsWith(route, '.png')) { // ignore images
|
||||
@@ -100,7 +100,7 @@ QUnit.test('clicking on Support channel: channel available', async function (ass
|
||||
assert.expect(9);
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
addMockSupportEnvironment(messagingMenu, {
|
||||
await addMockSupportEnvironment(messagingMenu, {
|
||||
data: this.data,
|
||||
mockRPC: function (route, args) {
|
||||
if (!_.string.endsWith(route, '.png')) { // ignore images
|
||||
@@ -145,7 +145,7 @@ QUnit.test('post messages in Support channel', async function (assert) {
|
||||
assert.expect(8);
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
addMockSupportEnvironment(messagingMenu, {
|
||||
await addMockSupportEnvironment(messagingMenu, {
|
||||
data: this.data,
|
||||
mockRPC: function (route, args) {
|
||||
if (!_.string.endsWith(route, '.png')) { // ignore images
|
||||
@@ -190,7 +190,7 @@ QUnit.test('fold Support channel', async function (assert) {
|
||||
assert.expect(11);
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
addMockSupportEnvironment(messagingMenu, {
|
||||
await addMockSupportEnvironment(messagingMenu, {
|
||||
data: this.data,
|
||||
mockRPC: function (route, args) {
|
||||
if (!_.string.endsWith(route, '.png')) { // ignore images
|
||||
@@ -245,7 +245,7 @@ QUnit.test('restore Support channel if necessary', async function (assert) {
|
||||
assert.expect(5);
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
addMockSupportEnvironment(messagingMenu, {
|
||||
await addMockSupportEnvironment(messagingMenu, {
|
||||
data: this.data,
|
||||
enableSupportPoll: true,
|
||||
mockRPC: function (route, args) {
|
||||
@@ -270,8 +270,8 @@ QUnit.test('restore Support channel if necessary', async function (assert) {
|
||||
"should have open a chat window");
|
||||
|
||||
assert.verifySteps([
|
||||
'cors: /odoo_im_support/get_support_channel',
|
||||
'/mail/init_messaging',
|
||||
'cors: /odoo_im_support/get_support_channel',
|
||||
'cors: /odoo_im_support/fetch_messages',
|
||||
]);
|
||||
|
||||
@@ -284,7 +284,7 @@ QUnit.test('receive messages in the Support channel', async function (assert) {
|
||||
var supportChannelID;
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
addMockSupportEnvironment(messagingMenu, {
|
||||
await addMockSupportEnvironment(messagingMenu, {
|
||||
data: this.data,
|
||||
enableSupportPoll: true,
|
||||
mockRPC: function (route, args) {
|
||||
@@ -330,8 +330,8 @@ QUnit.test('receive messages in the Support channel', async function (assert) {
|
||||
'A message', "message is correct");
|
||||
|
||||
assert.verifySteps([
|
||||
'cors: /odoo_im_support/get_support_channel',
|
||||
'/mail/init_messaging',
|
||||
'cors: /odoo_im_support/get_support_channel',
|
||||
'cors: /odoo_im_support/fetch_messages',
|
||||
]);
|
||||
|
||||
|
||||
@@ -316,7 +316,6 @@ QUnit.test('activity view: activity widget', async function (assert) {
|
||||
},
|
||||
};
|
||||
|
||||
owl.Component.env = testUtils.mock.getMockedOwlEnv(params);
|
||||
var activity = await createView(params);
|
||||
var today = activity.$('table tbody tr:first td:nth-child(2).today');
|
||||
var dropdown = today.find('.dropdown-menu.o_activity');
|
||||
@@ -391,9 +390,9 @@ QUnit.test('activity view: no group_by_menu and no time_range_menu', async funct
|
||||
|
||||
assert.containsN(actionManager, '.o_search_options .o_dropdown button:visible', 2,
|
||||
"only two elements should be available in view search");
|
||||
assert.isVisible(actionManager.$('.o_search_options .o_dropdown button.o_filters_menu_button'),
|
||||
assert.isVisible(actionManager.$('.o_search_options .o_dropdown.o_filter_menu > button'),
|
||||
"filter should be available in view search");
|
||||
assert.isVisible(actionManager.$('.o_search_options .o_dropdown button.o_favorites_menu_button'),
|
||||
assert.isVisible(actionManager.$('.o_search_options .o_dropdown.o_favorite_menu > button'),
|
||||
"favorites should be available in view search");
|
||||
actionManager.destroy();
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ var mailTestUtils = require('mail.testUtils');
|
||||
var testUtils = require('web.test_utils');
|
||||
|
||||
var createDiscuss = mailTestUtils.createDiscuss;
|
||||
const cpHelpers = testUtils.controlPanel;
|
||||
|
||||
QUnit.module('mail', {}, function () {
|
||||
QUnit.module('Discuss', {
|
||||
@@ -139,6 +140,7 @@ QUnit.test('basic rendering', async function (assert) {
|
||||
var $history = $sidebar.find('.o_mail_discuss_item[data-thread-id=mailbox_history]');
|
||||
assert.strictEqual($history.length, 1,
|
||||
"should have the mailbox item 'mailbox_history' in the sidebar");
|
||||
|
||||
discuss.destroy();
|
||||
});
|
||||
|
||||
@@ -305,43 +307,44 @@ QUnit.test('searchview filter messages', async function (assert) {
|
||||
'</search>',
|
||||
},
|
||||
});
|
||||
assert.containsN(discuss, '.o_thread_message', 2,
|
||||
"there should be two messages in the inbox mailbox");
|
||||
assert.strictEqual($('.o_searchview_input').length, 1,
|
||||
"there should be a searchview on discuss");
|
||||
assert.strictEqual($('.o_searchview_input').val(), '',
|
||||
"the searchview should be empty initially");
|
||||
// needed to handle events triggered by the controlPanelModel
|
||||
discuss.on_attach_callback();
|
||||
await testUtils.nextTick();
|
||||
|
||||
// interact with searchview so that there is only once message
|
||||
$('.o_searchview_input').val("ab").trigger('keyup');
|
||||
await testUtils.nextTick();
|
||||
$('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.ENTER }));
|
||||
await testUtils.nextTick();
|
||||
assert.strictEqual($('.o_searchview_facet').length, 1,
|
||||
"the searchview should have a facet");
|
||||
assert.strictEqual($('.o_facet_values').text().trim(), 'ab',
|
||||
"the facet should be a search on 'ab'");
|
||||
assert.containsOnce(discuss, '.o_thread_message',
|
||||
"there should be a single message after filter");
|
||||
assert.containsN(discuss, '.o_thread_message', 2,
|
||||
"there should be two messages in the inbox mailbox");
|
||||
assert.strictEqual($('.o_searchview_input').length, 1,
|
||||
"there should be a searchview on discuss");
|
||||
assert.strictEqual($('.o_searchview_input').val(), '',
|
||||
"the searchview should be empty initially");
|
||||
|
||||
// interact with search view so that there are no matching messages
|
||||
await testUtils.dom.click($('.o_facet_remove'));
|
||||
$('.o_searchview_input').val("abcd").trigger('keyup');
|
||||
await testUtils.nextTick();
|
||||
$('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.ENTER }));
|
||||
await testUtils.nextTick();
|
||||
// interact with searchview so that there is only once message
|
||||
await cpHelpers.editSearch(discuss, "ab");
|
||||
await cpHelpers.validateSearch(discuss);
|
||||
assert.strictEqual($('.o_searchview_facet').length, 1,
|
||||
"the searchview should have a facet");
|
||||
assert.strictEqual($('.o_facet_values').text().trim(), 'ab',
|
||||
"the facet should be a search on 'ab'");
|
||||
assert.containsOnce(discuss, '.o_thread_message',
|
||||
"there should be a single message after filter");
|
||||
|
||||
assert.strictEqual($('.o_searchview_facet').length, 1,
|
||||
"the searchview should have a facet");
|
||||
assert.strictEqual($('.o_facet_values').text().trim(), 'abcd',
|
||||
"the facet should be a search on 'abcd'");
|
||||
assert.containsNone(discuss, '.o_thread_message',
|
||||
"there should be no message after 2nd filter");
|
||||
assert.strictEqual(discuss.$('.o_thread_title').text().trim(),
|
||||
"No matches found",
|
||||
"should display that there are no matching messages");
|
||||
// interact with search view so that there are no matching messages
|
||||
await testUtils.dom.click($('.o_facet_remove'));
|
||||
await cpHelpers.editSearch(discuss, "abcd");
|
||||
await cpHelpers.validateSearch(discuss);
|
||||
|
||||
discuss.destroy();
|
||||
assert.strictEqual($('.o_searchview_facet').length, 1,
|
||||
"the searchview should have a facet");
|
||||
assert.strictEqual($('.o_facet_values').text().trim(), 'abcd',
|
||||
"the facet should be a search on 'abcd'");
|
||||
assert.containsNone(discuss, '.o_thread_message',
|
||||
"there should be no message after 2nd filter");
|
||||
assert.strictEqual(discuss.$('.o_thread_title').text().trim(),
|
||||
"No matches found",
|
||||
"should display that there are no matching messages");
|
||||
|
||||
discuss.on_detach_callback();
|
||||
discuss.destroy();
|
||||
|
||||
});
|
||||
|
||||
@@ -1147,6 +1150,7 @@ QUnit.test('mark all messages as read from Inbox', async function (assert) {
|
||||
|
||||
await testUtils.dom.click($markAllReadButton);
|
||||
|
||||
|
||||
markAllReadDef.then(function () {
|
||||
// immediately jump to end of the fadeout animation on messages
|
||||
$inbox = discuss.$('.o_mail_discuss_item[data-thread-id="mailbox_inbox"]');
|
||||
@@ -1964,33 +1968,38 @@ QUnit.test('save filter discuss', async function (assert) {
|
||||
}
|
||||
return this._super.apply(this,arguments);
|
||||
},
|
||||
intercepts: {
|
||||
create_filter: function (ev) {
|
||||
assert.deepEqual(
|
||||
JSON.parse(ev.data.filter.domain), [
|
||||
"|",
|
||||
["subject", "ilike", "she was born in a hurricane"],
|
||||
["body", "ilike", "she was born in a hurricane"]
|
||||
], 'The filter should have been saved with the right domain');
|
||||
env: {
|
||||
dataManager: {
|
||||
create_filter: async function (filter) {
|
||||
assert.deepEqual(
|
||||
JSON.parse(filter.domain), [
|
||||
"|",
|
||||
["subject", "ilike", "she was born in a hurricane"],
|
||||
["body", "ilike", "she was born in a hurricane"]
|
||||
], 'The filter should have been saved with the right domain');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
// needed to handle events triggered by the controlPanelModel
|
||||
discuss.on_attach_callback();
|
||||
await testUtils.nextTick();
|
||||
|
||||
assert.containsOnce(discuss, '.o_searchview_input_container', 'search view input present');
|
||||
|
||||
$('.o_searchview_input').val("she was born in a hurricane").trigger('keyup');
|
||||
await testUtils.nextTick();
|
||||
await cpHelpers.editSearch(discuss, "she was born in a hurricane");
|
||||
|
||||
messageFetchCount = 1;
|
||||
$('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.ENTER }));
|
||||
await testUtils.nextTick();
|
||||
|
||||
await testUtils.dom.click(discuss.$('.o_favorites_menu_button'));
|
||||
await testUtils.dom.click(discuss.$('.o_add_favorite'));
|
||||
await cpHelpers.validateSearch(discuss);
|
||||
|
||||
await testUtils.fields.editInput(discuss.$('.o_favorite_name input'), 'War');
|
||||
await testUtils.dom.click(discuss.$('.o_save_favorite button'));
|
||||
await cpHelpers.toggleFavoriteMenu(discuss);
|
||||
await cpHelpers.toggleSaveFavorite(discuss);
|
||||
|
||||
await cpHelpers.editFavoriteName(discuss, "War");
|
||||
await cpHelpers.saveFavorite(discuss);
|
||||
|
||||
discuss.on_detach_callback();
|
||||
discuss.destroy();
|
||||
});
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ QUnit.test('open a document thread in a thread window', async function (assert)
|
||||
assert.expect(6);
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
session: this.session,
|
||||
@@ -129,7 +129,7 @@ QUnit.test('expand a document thread window', async function (assert) {
|
||||
assert.expect(4);
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
session: this.session,
|
||||
@@ -177,7 +177,7 @@ QUnit.test('post messages in a document thread window', async function (assert)
|
||||
res_id: 1,
|
||||
};
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
session: this.session,
|
||||
@@ -229,7 +229,7 @@ QUnit.test('post messages in a document thread window', async function (assert)
|
||||
QUnit.test('open, fold, unfold and close a document thread window', async function (assert) {
|
||||
assert.expect(20);
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
session: this.session,
|
||||
@@ -285,7 +285,7 @@ QUnit.test('do not open thread window on fetch message failure', async function
|
||||
assert.expect(4);
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
session: this.session,
|
||||
|
||||
@@ -82,7 +82,7 @@ QUnit.test('preview of mail failure', async function (assert) {
|
||||
}];
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
data: this.data,
|
||||
services: this.services,
|
||||
});
|
||||
@@ -138,7 +138,7 @@ QUnit.test('preview grouped failures by document', async function (assert) {
|
||||
}];
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
data: this.data,
|
||||
services: this.services,
|
||||
});
|
||||
@@ -194,7 +194,7 @@ QUnit.test('preview grouped failures by document model', async function (assert)
|
||||
}];
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
data: this.data,
|
||||
services: this.services,
|
||||
});
|
||||
|
||||
@@ -105,7 +105,7 @@ QUnit.test('messaging menu widget: menu with no records', async function (assert
|
||||
assert.expect(1);
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
mockRPC: function (route, args) {
|
||||
if (args.method === 'message_fetch') {
|
||||
@@ -114,7 +114,7 @@ QUnit.test('messaging menu widget: menu with no records', async function (assert
|
||||
return this._super.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
await testUtils.dom.click(messagingMenu.$('.dropdown-toggle'));
|
||||
assert.hasClass(messagingMenu.$('.o_no_activity'),'o_no_activity', "should not have instance of widget");
|
||||
messagingMenu.destroy();
|
||||
@@ -126,7 +126,7 @@ QUnit.test('messaging menu widget: messaging not ready', async function (assert)
|
||||
const messagingReadyProm = testUtils.makeTestPromise();
|
||||
|
||||
const messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
async mockRPC(route, args) {
|
||||
if (route === '/mail/init_messaging') {
|
||||
@@ -142,7 +142,7 @@ QUnit.test('messaging menu widget: messaging not ready', async function (assert)
|
||||
return this._super(...arguments);
|
||||
},
|
||||
});
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
assert.verifySteps(['/mail/init_messaging:pending']);
|
||||
assert.ok(
|
||||
messagingMenu.el,
|
||||
@@ -170,11 +170,11 @@ QUnit.test('messaging menu widget: messaging not ready', async function (assert)
|
||||
QUnit.test('messaging menu widget: messaging menu with 1 record', async function (assert) {
|
||||
assert.expect(3);
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
});
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
|
||||
await testUtils.dom.click(messagingMenu.$('.dropdown-toggle'));
|
||||
|
||||
@@ -197,14 +197,14 @@ QUnit.test('messaging menu widget: open inbox for needaction not linked to any d
|
||||
assert.expect(4);
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
session: {
|
||||
partner_id: 1,
|
||||
},
|
||||
});
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
|
||||
// Simulate received needaction message without associated document,
|
||||
// so that we have a message in inbox without a model and a resID
|
||||
@@ -272,12 +272,12 @@ QUnit.test("messaging menu widget: mark as read on thread preview", async functi
|
||||
}];
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
});
|
||||
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
await testUtils.dom.click(messagingMenu.$('.dropdown-toggle'));
|
||||
assert.hasClass(messagingMenu.$el,'o_mail_systray_item',
|
||||
'should be the instance of widget');
|
||||
@@ -335,14 +335,14 @@ QUnit.test('needaction messages in channels should appear, in addition to channe
|
||||
this.data['mail.message'].records = [needactionMessage, lastMessage];
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
session: {
|
||||
partner_id: partnerID,
|
||||
},
|
||||
});
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
|
||||
await testUtils.dom.click(messagingMenu.$('.dropdown-toggle'));
|
||||
|
||||
@@ -391,14 +391,15 @@ QUnit.test('preview of message on a document + mark as read', async function (as
|
||||
this.data['mail.message'].records.push(needactionMessage);
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
session: {
|
||||
partner_id: partnerID,
|
||||
},
|
||||
});
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
await testUtils.nextTick();
|
||||
assert.strictEqual(messagingMenu.$('.o_notification_counter').text(), '1',
|
||||
"should display a counter of 1 on the messaging menu icon");
|
||||
|
||||
@@ -427,11 +428,11 @@ QUnit.test('update messaging preview on receiving a new message in channel previ
|
||||
assert.expect(8);
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
});
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
|
||||
await testUtils.dom.click(messagingMenu.$('.dropdown-toggle'));
|
||||
|
||||
@@ -478,11 +479,11 @@ QUnit.test('new message of type "notification" are not considered as unread mess
|
||||
assert.expect(8);
|
||||
|
||||
const messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
data: this.data,
|
||||
services: this.services,
|
||||
});
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
// open messaging menu
|
||||
await testUtils.dom.click(messagingMenu.$('.dropdown-toggle'));
|
||||
assert.containsOnce(
|
||||
@@ -580,7 +581,7 @@ QUnit.test('preview of inbox message not linked to document + mark as read', asy
|
||||
this.data['mail.message'].records.concat(needactionMessages);
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
session: {
|
||||
@@ -593,7 +594,9 @@ QUnit.test('preview of inbox message not linked to document + mark as read', asy
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
await testUtils.nextTick();
|
||||
|
||||
assert.strictEqual(messagingMenu.$('.o_notification_counter').text(), '2',
|
||||
"should display a counter of 2 on the messaging menu icon");
|
||||
|
||||
@@ -673,14 +676,14 @@ QUnit.test('grouped preview for needaction messages linked to same document', as
|
||||
this.data.initMessaging.needaction_inbox_counter = 2;
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
session: {
|
||||
partner_id: 44,
|
||||
},
|
||||
});
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
|
||||
await testUtils.dom.click(messagingMenu.$('.dropdown-toggle'));
|
||||
var $previews = messagingMenu.$('.o_mail_preview');
|
||||
@@ -719,13 +722,13 @@ QUnit.test("messaging menu widget: channel seen notification", async function (a
|
||||
};
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
session: { partner_id: 3 },
|
||||
});
|
||||
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
await testUtils.dom.click(messagingMenu.$('.dropdown-toggle'));
|
||||
|
||||
assert.strictEqual(messagingMenu.$('.o_notification_counter').text(), '1',
|
||||
@@ -767,13 +770,13 @@ QUnit.test("messaging menu widget: no traceback when receiving channel_fetched n
|
||||
};
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
session: { partner_id: 3 },
|
||||
});
|
||||
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
await testUtils.dom.click(messagingMenu.$('.dropdown-toggle'));
|
||||
assert.containsOnce(messagingMenu, '.o_new_message',
|
||||
"should have button to open blank thread window");
|
||||
@@ -806,12 +809,12 @@ QUnit.test("messaging menu widget: preview with no message should be undated", a
|
||||
this.data['mail.message'].records[0].channel_ids = [];
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
});
|
||||
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
await testUtils.dom.click(messagingMenu.$('.dropdown-toggle'));
|
||||
|
||||
assert.strictEqual(messagingMenu.$('.o_mail_preview').length, 1,
|
||||
@@ -836,12 +839,12 @@ QUnit.test("messaging menu widget: sort dated previews before undated previews",
|
||||
this.data.initMessaging.channel_slots.direct_message = [dm];
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
});
|
||||
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
await testUtils.dom.click(messagingMenu.$('.dropdown-toggle'));
|
||||
|
||||
assert.strictEqual(messagingMenu.$('.o_mail_preview').length, 2,
|
||||
@@ -924,16 +927,19 @@ QUnit.test('global counter with channel previews', async function (assert) {
|
||||
this.data['mail.message'].records = messages;
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
session: {
|
||||
partner_id: 3,
|
||||
},
|
||||
});
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
await testUtils.nextTick();
|
||||
|
||||
assert.strictEqual(messagingMenu.$('.o_notification_counter').text(), '2',
|
||||
"should display a counter of 2 on the messaging menu icon");
|
||||
|
||||
await testUtils.dom.click(messagingMenu.$('.dropdown-toggle'));
|
||||
|
||||
assert.strictEqual(messagingMenu.$('.o_mail_preview').length, 3,
|
||||
@@ -965,7 +971,7 @@ QUnit.test('messaging menu widget: do not open chat window twice on preview clic
|
||||
var messageFetchDef = testUtils.makeTestPromise();
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
session: { partner_id: 1 },
|
||||
@@ -991,7 +997,7 @@ QUnit.test('messaging menu widget: do not open chat window twice on preview clic
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
|
||||
// Opening chat window from messaging menu (pending from `messageFetchDef`)
|
||||
await testUtils.dom.click(messagingMenu.$('.dropdown-toggle'));
|
||||
@@ -1023,7 +1029,7 @@ QUnit.test('messaging menu widget: expand on thread preview', async function (as
|
||||
});
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
session: { partner_id: 44 },
|
||||
@@ -1036,7 +1042,7 @@ QUnit.test('messaging menu widget: expand on thread preview', async function (as
|
||||
},
|
||||
},
|
||||
});
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
|
||||
await testUtils.dom.click(messagingMenu.$('.dropdown-toggle'));
|
||||
var $preview = messagingMenu.$('.o_mail_preview');
|
||||
@@ -1062,7 +1068,7 @@ QUnit.test('messaging menu widget: click twice preview on slow message_fetch sho
|
||||
const messageFetchProm = testUtils.makeTestPromise();
|
||||
|
||||
const messagingMenu = new MessagingMenu();
|
||||
testUtils.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
session: { partner_id: 1 },
|
||||
@@ -1086,7 +1092,7 @@ QUnit.test('messaging menu widget: click twice preview on slow message_fetch sho
|
||||
return this._super(...arguments);
|
||||
},
|
||||
});
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
|
||||
// Opening chat window 1st time from messaging menu (pending from `messageFetchDef`)
|
||||
await testUtils.dom.click(messagingMenu.$('.dropdown-toggle'));
|
||||
@@ -1113,11 +1119,11 @@ QUnit.test('no code injection in message body preview', async function (assert)
|
||||
`<p><script>throw new Error('CodeInjectionError');</script></p>`;
|
||||
|
||||
const messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
services: this.services,
|
||||
data: this.data,
|
||||
});
|
||||
await messagingMenu.appendTo($('#qunit-fixture'));
|
||||
await messagingMenu.appendTo(testUtils.prepareTarget());
|
||||
await testUtils.dom.click(messagingMenu.$('.dropdown-toggle'));
|
||||
assert.containsOnce(
|
||||
messagingMenu,
|
||||
|
||||
@@ -70,7 +70,7 @@ QUnit.test('messaging menu widget: rendering with OdooBot has a request', async
|
||||
assert.expect(5);
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
data: this.data,
|
||||
services: this.services,
|
||||
});
|
||||
@@ -99,7 +99,7 @@ QUnit.test('messaging menu widget: rendering without OdooBot has a request (deni
|
||||
window.Notification.permission = 'denied';
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
data: this.data,
|
||||
services: this.services,
|
||||
});
|
||||
@@ -122,7 +122,7 @@ QUnit.test('messaging menu widget: rendering without OdooBot has a request (acce
|
||||
window.Notification.permission = 'granted';
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
data: this.data,
|
||||
services: this.services,
|
||||
});
|
||||
@@ -143,7 +143,7 @@ QUnit.test('messaging menu widget: respond to notification prompt', async functi
|
||||
assert.expect(4);
|
||||
|
||||
var messagingMenu = new MessagingMenu();
|
||||
testUtils.addMockEnvironment(messagingMenu, {
|
||||
await testUtils.mock.addMockEnvironment(messagingMenu, {
|
||||
data: this.data,
|
||||
services: this.services,
|
||||
});
|
||||
|
||||
@@ -16,7 +16,9 @@ var ReportService = require('web.ReportService');
|
||||
var SessionStorageService = require('web.SessionStorageService');
|
||||
var testUtils = require('web.test_utils');
|
||||
var Widget = require('web.Widget');
|
||||
|
||||
var createActionManager = testUtils.createActionManager;
|
||||
const cpHelpers = testUtils.controlPanel;
|
||||
|
||||
QUnit.module('ActionManager', {
|
||||
beforeEach: function () {
|
||||
@@ -198,8 +200,9 @@ QUnit.module('ActionManager', {
|
||||
|
||||
var n = delta;
|
||||
await actionManager.doAction(4);
|
||||
|
||||
// kanban view is loaded, switch to list view
|
||||
await testUtils.dom.click($('.o_control_panel .o_cp_switch_list'));
|
||||
await cpHelpers.switchView(actionManager, 'list');
|
||||
// open a record in form view
|
||||
await testUtils.dom.click(actionManager.$('.o_list_view .o_data_row:first'));
|
||||
// go back to action 7 in breadcrumbs
|
||||
@@ -1336,12 +1339,13 @@ QUnit.module('ActionManager', {
|
||||
},
|
||||
});
|
||||
await actionManager.doAction(4);
|
||||
|
||||
// kanban view is loaded, switch to list view
|
||||
await testUtils.dom.click($('.o_control_panel .o_cp_switch_list'));
|
||||
await cpHelpers.switchView(actionManager, 'list');
|
||||
|
||||
// here, list view is not ready yet, because def is not resolved
|
||||
// switch back to kanban view
|
||||
await testUtils.dom.click($('.o_control_panel .o_cp_switch_kanban'));
|
||||
await cpHelpers.switchView(actionManager, 'kanban');
|
||||
|
||||
// here, we want the kanban view to reload itself, regardless of list view
|
||||
assert.verifySteps([
|
||||
@@ -1607,8 +1611,8 @@ QUnit.module('ActionManager', {
|
||||
'load_views', // action 3
|
||||
'/web/dataset/search_read', // search read of list view of action 3
|
||||
'/web/action/load', // action 4
|
||||
'load_views', // action 4
|
||||
'read', // read the opened record of action 3 (this request is blocked)
|
||||
'load_views', // action 4
|
||||
'/web/dataset/search_read', // search read action 4
|
||||
]);
|
||||
|
||||
@@ -1753,7 +1757,7 @@ QUnit.module('ActionManager', {
|
||||
// reload (the search_read RPC will be blocked)
|
||||
def = testUtils.makeTestPromise();
|
||||
await testUtils.nextTick();
|
||||
await testUtils.dom.click($('.o_control_panel .o_cp_switch_list'));
|
||||
await cpHelpers.switchView(actionManager, 'list');
|
||||
|
||||
assert.containsN(actionManager, '.o_list_view .o_data_row', 5,
|
||||
"list view should still contain 5 records");
|
||||
@@ -1822,11 +1826,11 @@ QUnit.module('ActionManager', {
|
||||
|
||||
var ClientAction = AbstractAction.extend({
|
||||
hasControlPanel: true,
|
||||
start: function () {
|
||||
start: async function () {
|
||||
this.$('.o_content').text('Hello World');
|
||||
this.$el.addClass('o_client_action_test');
|
||||
this._setTitle('Hello');
|
||||
return this._super.apply(this, arguments);
|
||||
this.controlPanelProps.title = 'Hello';
|
||||
await this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
core.action_registry.add('HelloWorldTest', ClientAction);
|
||||
@@ -1885,14 +1889,14 @@ QUnit.module('ActionManager', {
|
||||
hasControlPanel: true,
|
||||
events: {
|
||||
click: function () {
|
||||
this._setTitle('new title');
|
||||
this.updateControlPanel({ title: 'new title' });
|
||||
},
|
||||
},
|
||||
start: function () {
|
||||
this._setTitle('initial title');
|
||||
start: async function () {
|
||||
this.$('.o_content').text('Hello World');
|
||||
this.$el.addClass('o_client_action_test');
|
||||
return this._super.apply(this, arguments);
|
||||
this.controlPanelProps.title = 'initial title';
|
||||
await this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
var actionManager = await createActionManager();
|
||||
@@ -1902,7 +1906,7 @@ QUnit.module('ActionManager', {
|
||||
assert.strictEqual($('ol.breadcrumb').text(), "initial title",
|
||||
"should have initial title as breadcrumb content");
|
||||
|
||||
testUtils.dom.click(actionManager.$('.o_client_action_test'));
|
||||
await testUtils.dom.click(actionManager.$('.o_client_action_test'));
|
||||
assert.strictEqual($('ol.breadcrumb').text(), "new title",
|
||||
"should have updated title as breadcrumb content");
|
||||
|
||||
@@ -2322,7 +2326,7 @@ QUnit.module('ActionManager', {
|
||||
});
|
||||
|
||||
QUnit.test('sidebar is present in list view', async function (assert) {
|
||||
assert.expect(5);
|
||||
assert.expect(4);
|
||||
|
||||
var actionManager = await createActionManager({
|
||||
actions: this.actions,
|
||||
@@ -2345,11 +2349,11 @@ QUnit.module('ActionManager', {
|
||||
});
|
||||
await actionManager.doAction(3);
|
||||
|
||||
assert.isNotVisible(actionManager.$('.o_cp_sidebar button.o_dropdown_toggler_btn:contains("Print")'));
|
||||
assert.isNotVisible(actionManager.$('.o_cp_sidebar button.o_dropdown_toggler_btn:contains("Action")'));
|
||||
assert.containsNone(actionManager, '.o_cp_action_menus');
|
||||
|
||||
await testUtils.dom.clickFirst(actionManager.$('input.custom-control-input'));
|
||||
assert.isVisible(actionManager.$('.o_cp_sidebar button.o_dropdown_toggler_btn:contains("Print")'));
|
||||
assert.isVisible(actionManager.$('.o_cp_sidebar button.o_dropdown_toggler_btn:contains("Action")'));
|
||||
assert.isVisible(actionManager.$('.o_cp_action_menus button.o_dropdown_toggler_btn:contains("Print")'));
|
||||
assert.isVisible(actionManager.$('.o_cp_action_menus button.o_dropdown_toggler_btn:contains("Action")'));
|
||||
|
||||
actionManager.destroy();
|
||||
});
|
||||
@@ -2372,14 +2376,14 @@ QUnit.module('ActionManager', {
|
||||
"should display the list view");
|
||||
|
||||
// switch to kanban view
|
||||
await testUtils.dom.click($('.o_control_panel .o_cp_switch_kanban'));
|
||||
await cpHelpers.switchView(actionManager, 'kanban');
|
||||
assert.containsNone(actionManager, '.o_list_view',
|
||||
"should no longer display the list view");
|
||||
assert.containsOnce(actionManager, '.o_kanban_view',
|
||||
"should display the kanban view");
|
||||
|
||||
// switch back to list view
|
||||
await testUtils.dom.click($('.o_control_panel .o_cp_switch_list'));
|
||||
await cpHelpers.switchView(actionManager, 'list');
|
||||
assert.containsOnce(actionManager, '.o_list_view',
|
||||
"should display the list view");
|
||||
assert.containsNone(actionManager, '.o_kanban_view',
|
||||
@@ -2486,7 +2490,7 @@ QUnit.module('ActionManager', {
|
||||
"breadcrumbs should display the display_name of the action");
|
||||
|
||||
// switch to kanban view
|
||||
await testUtils.dom.click($('.o_control_panel .o_cp_switch_kanban'));
|
||||
await cpHelpers.switchView(actionManager, 'kanban');
|
||||
assert.strictEqual($('.o_control_panel .breadcrumb-item').length, 1,
|
||||
"there should still be one controller in the breadcrumbs");
|
||||
assert.strictEqual($('.o_control_panel .breadcrumb-item').text(), 'Partners',
|
||||
@@ -2508,7 +2512,7 @@ QUnit.module('ActionManager', {
|
||||
"breadcrumbs should display the display_name of the action");
|
||||
|
||||
// switch back to list view
|
||||
await testUtils.dom.click($('.o_control_panel .o_cp_switch_list'));
|
||||
await cpHelpers.switchView(actionManager, 'list');
|
||||
assert.strictEqual($('.o_control_panel .breadcrumb-item').length, 1,
|
||||
"there should still be one controller in the breadcrumbs");
|
||||
assert.strictEqual($('.o_control_panel .breadcrumb-item').text(), 'Partners',
|
||||
@@ -2543,43 +2547,43 @@ QUnit.module('ActionManager', {
|
||||
});
|
||||
await actionManager.doAction(3);
|
||||
|
||||
assert.strictEqual($('.o_control_panel .o_cp_switch_buttons button').length, 2,
|
||||
assert.containsN(actionManager, '.o_control_panel button.o_switch_view', 2,
|
||||
"should have two switch buttons (list and kanban)");
|
||||
assert.strictEqual($('.o_control_panel .o_cp_switch_buttons button.active').length, 1,
|
||||
assert.containsOnce(actionManager, '.o_control_panel button.o_switch_view.active',
|
||||
"should have only one active button");
|
||||
assert.hasClass($('.o_control_panel .o_cp_switch_buttons button:first'),'o_cp_switch_list',
|
||||
assert.hasClass($('.o_control_panel .o_switch_view:first'),'o_list',
|
||||
"list switch button should be the first one");
|
||||
assert.hasClass($('.o_control_panel .o_cp_switch_list'),'active',
|
||||
assert.hasClass($('.o_control_panel .o_switch_view.o_list'), 'active',
|
||||
"list should be the active view");
|
||||
|
||||
// switch to kanban view
|
||||
await testUtils.dom.click($('.o_control_panel .o_cp_switch_kanban'));
|
||||
assert.strictEqual($('.o_control_panel .o_cp_switch_buttons button').length, 2,
|
||||
await cpHelpers.switchView(actionManager, 'kanban');
|
||||
assert.containsN(actionManager, '.o_control_panel .o_switch_view', 2,
|
||||
"should still have two switch buttons (list and kanban)");
|
||||
assert.strictEqual($('.o_control_panel .o_cp_switch_buttons button.active').length, 1,
|
||||
assert.containsOnce(actionManager, '.o_control_panel .o_switch_view.active',
|
||||
"should still have only one active button");
|
||||
assert.hasClass($('.o_control_panel .o_cp_switch_buttons button:first'),'o_cp_switch_list',
|
||||
assert.hasClass($('.o_control_panel .o_switch_view:first'), 'o_list',
|
||||
"list switch button should still be the first one");
|
||||
assert.hasClass($('.o_control_panel .o_cp_switch_kanban'),'active',
|
||||
assert.hasClass($('.o_control_panel .o_switch_view.o_kanban'),'active',
|
||||
"kanban should now be the active view");
|
||||
|
||||
// switch back to list view
|
||||
await testUtils.dom.click($('.o_control_panel .o_cp_switch_list'));
|
||||
assert.strictEqual($('.o_control_panel .o_cp_switch_buttons button').length, 2,
|
||||
await cpHelpers.switchView(actionManager, 'list');
|
||||
assert.containsN(actionManager, '.o_control_panel .o_switch_view', 2,
|
||||
"should still have two switch buttons (list and kanban)");
|
||||
assert.hasClass($('.o_control_panel .o_cp_switch_list'),'active',
|
||||
assert.hasClass($('.o_control_panel .o_switch_view.o_list'),'active',
|
||||
"list should now be the active view");
|
||||
|
||||
// open a record in form view
|
||||
await testUtils.dom.click(actionManager.$('.o_list_view .o_data_row:first'));
|
||||
assert.strictEqual($('.o_control_panel .o_cp_switch_buttons button').length, 0,
|
||||
assert.containsNone(actionManager, '.o_control_panel .o_switch_view',
|
||||
"should not have any switch buttons");
|
||||
|
||||
// go back to list view using the breadcrumbs
|
||||
await testUtils.dom.click($('.o_control_panel .breadcrumb a'));
|
||||
assert.strictEqual($('.o_control_panel .o_cp_switch_buttons button').length, 2,
|
||||
assert.containsN(actionManager, '.o_control_panel .o_switch_view', 2,
|
||||
"should have two switch buttons (list and kanban)");
|
||||
assert.hasClass($('.o_control_panel .o_cp_switch_list'),'active',
|
||||
assert.hasClass($('.o_control_panel .o_switch_view.o_list'),'active',
|
||||
"list should be the active view");
|
||||
|
||||
actionManager.destroy();
|
||||
@@ -2601,7 +2605,7 @@ QUnit.module('ActionManager', {
|
||||
"limit should be correct for kanban");
|
||||
|
||||
// switch to list view
|
||||
await testUtils.dom.click($('.o_control_panel .o_cp_switch_list'));
|
||||
await cpHelpers.switchView(actionManager, 'list');
|
||||
assert.strictEqual($('.o_control_panel .o_pager_value').text(), '1-3',
|
||||
"value should be correct for list");
|
||||
assert.strictEqual($('.o_control_panel .o_pager_limit').text(), '5',
|
||||
@@ -2622,7 +2626,7 @@ QUnit.module('ActionManager', {
|
||||
"limit should be correct for list");
|
||||
|
||||
// switch back to kanban view
|
||||
await testUtils.dom.click($('.o_control_panel .o_cp_switch_kanban'));
|
||||
await cpHelpers.switchView(actionManager, 'kanban');
|
||||
assert.strictEqual($('.o_control_panel .o_pager_value').text(), '1-5',
|
||||
"value should be correct for kanban");
|
||||
assert.strictEqual($('.o_control_panel .o_pager_limit').text(), '5',
|
||||
@@ -2646,12 +2650,12 @@ QUnit.module('ActionManager', {
|
||||
assert.containsN(actionManager, '.o_data_row', 5);
|
||||
|
||||
// activate a domain
|
||||
await testUtils.dom.click(actionManager.$('.o_search_options .o_filters_menu_button'));
|
||||
await testUtils.dom.click(actionManager.$('.o_search_options .o_filters_menu a:contains(Bar)'));
|
||||
await cpHelpers.toggleFilterMenu(actionManager);
|
||||
await cpHelpers.toggleMenuItem(actionManager, "Bar");
|
||||
assert.containsN(actionManager, '.o_data_row', 2);
|
||||
|
||||
// switch to kanban
|
||||
await testUtils.dom.click(actionManager.$('.o_control_panel .o_cp_switch_kanban'));
|
||||
await cpHelpers.switchView(actionManager, 'kanban');
|
||||
assert.containsN(actionManager, '.o_kanban_record:not(.o_kanban_ghost)', 2);
|
||||
|
||||
// remove the domain
|
||||
@@ -2659,7 +2663,7 @@ QUnit.module('ActionManager', {
|
||||
assert.containsN(actionManager, '.o_kanban_record:not(.o_kanban_ghost)', 5);
|
||||
|
||||
// switch back to list
|
||||
await testUtils.dom.click(actionManager.$('.o_control_panel .o_cp_switch_list'));
|
||||
await cpHelpers.switchView(actionManager, 'list');
|
||||
assert.containsN(actionManager, '.o_data_row', 5);
|
||||
|
||||
actionManager.destroy();
|
||||
@@ -2682,7 +2686,7 @@ QUnit.module('ActionManager', {
|
||||
|
||||
// switch to kanban view
|
||||
def = testUtils.makeTestPromise();
|
||||
await testUtils.dom.click($('.o_control_panel .o_cp_switch_kanban'));
|
||||
await cpHelpers.switchView(actionManager, 'kanban');
|
||||
assert.containsOnce(actionManager, '.o_list_view',
|
||||
"should still display the list view");
|
||||
assert.containsNone(actionManager, '.o_kanban_view',
|
||||
@@ -2696,7 +2700,7 @@ QUnit.module('ActionManager', {
|
||||
|
||||
// switch back to list view
|
||||
def = testUtils.makeTestPromise();
|
||||
await testUtils.dom.click($('.o_control_panel .o_cp_switch_list'));
|
||||
await cpHelpers.switchView(actionManager, 'list');
|
||||
assert.containsOnce(actionManager, '.o_kanban_view',
|
||||
"should still display the kanban view");
|
||||
assert.containsNone(actionManager, '.o_list_view',
|
||||
@@ -3044,11 +3048,11 @@ QUnit.module('ActionManager', {
|
||||
"line chart button is now active");
|
||||
|
||||
// switch to kanban and back to graph view
|
||||
await testUtils.dom.click($('.o_control_panel .o_cp_switch_kanban'));
|
||||
await cpHelpers.switchView(actionManager, 'kanban');
|
||||
assert.strictEqual($('.o_control_panel .fa-area-chart').length, 0,
|
||||
"graph buttons are no longer in control panel");
|
||||
|
||||
await testUtils.dom.click($('.o_control_panel .o_cp_switch_graph'));
|
||||
await cpHelpers.switchView(actionManager, 'graph');
|
||||
assert.hasClass($('.o_control_panel .fa-area-chart'),'active',
|
||||
"line chart button is still active");
|
||||
actionManager.destroy();
|
||||
@@ -3069,16 +3073,16 @@ QUnit.module('ActionManager', {
|
||||
});
|
||||
await actionManager.doAction(3);
|
||||
|
||||
assert.hasClass($('.o_control_panel .o_cp_switch_list'),'active',
|
||||
assert.hasClass($('.o_control_panel .o_switch_view.o_list'),'active',
|
||||
"list button in control panel is active");
|
||||
assert.doesNotHaveClass($('.o_control_panel .o_cp_switch_graph'), 'active',
|
||||
assert.doesNotHaveClass($('.o_control_panel .o_switch_view.o_graph'), 'active',
|
||||
"graph button in control panel is not active");
|
||||
|
||||
// switch to graph view
|
||||
await testUtils.dom.click($('.o_control_panel .o_cp_switch_graph'));
|
||||
assert.doesNotHaveClass($('.o_control_panel .o_cp_switch_list'), 'active',
|
||||
await cpHelpers.switchView(actionManager, 'graph');
|
||||
assert.doesNotHaveClass($('.o_control_panel .o_switch_view.o_list'), 'active',
|
||||
"list button in control panel is not active");
|
||||
assert.hasClass($('.o_control_panel .o_cp_switch_graph'),'active',
|
||||
assert.hasClass($('.o_control_panel .o_switch_view.o_graph'),'active',
|
||||
"graph button in control panel is active");
|
||||
actionManager.destroy();
|
||||
});
|
||||
@@ -3222,7 +3226,7 @@ QUnit.module('ActionManager', {
|
||||
"should only display 2 record");
|
||||
|
||||
// switch to kanban view
|
||||
await testUtils.dom.click($('.o_control_panel .o_cp_switch_kanban'));
|
||||
await cpHelpers.switchView(actionManager, 'kanban');
|
||||
|
||||
assert.strictEqual(actionManager.$('.o_kanban_record:not(.o_kanban_ghost)').length, 2,
|
||||
"should only display 2 record");
|
||||
@@ -3412,14 +3416,19 @@ QUnit.module('ActionManager', {
|
||||
actions: this.actions,
|
||||
archs: this.archs,
|
||||
data: this.data,
|
||||
intercepts: {
|
||||
create_filter: function (event) {
|
||||
var filter = event.data.filter;
|
||||
assert.deepEqual(filter.domain, `[("bar", "=", 1)]`,
|
||||
"should save the correct domain");
|
||||
assert.deepEqual(filter.context, {shouldBeInFilterContext: true},
|
||||
"should save the correct context");
|
||||
},
|
||||
env: {
|
||||
dataManager: {
|
||||
create_filter: function (filter) {
|
||||
assert.strictEqual(filter.domain, `[("bar", "=", 1)]`,
|
||||
"should save the correct domain");
|
||||
const expectedContext = {
|
||||
group_by: [], // default groupby is an empty list
|
||||
shouldBeInFilterContext: true,
|
||||
};
|
||||
assert.deepEqual(filter.context, expectedContext,
|
||||
"should save the correct context");
|
||||
},
|
||||
}
|
||||
},
|
||||
});
|
||||
await actionManager.doAction(33);
|
||||
@@ -3428,16 +3437,16 @@ QUnit.module('ActionManager', {
|
||||
"should contain 5 records");
|
||||
|
||||
// filter on bar
|
||||
await testUtils.dom.click($('.o_control_panel .o_search_options .o_dropdown_toggler_btn:contains(Filters)'));
|
||||
await testUtils.dom.click($('.o_control_panel .o_filters_menu a:contains(Bar)'));
|
||||
await cpHelpers.toggleFilterMenu(actionManager);
|
||||
await cpHelpers.toggleMenuItem(actionManager, "Bar");
|
||||
|
||||
assert.containsN(actionManager, '.o_data_row', 2);
|
||||
|
||||
// save filter
|
||||
await testUtils.dom.click($('.o_control_panel .o_search_options .o_dropdown_toggler_btn:contains(Favorites)'));
|
||||
await testUtils.dom.click($('.o_control_panel .o_add_favorite'));
|
||||
$('.o_control_panel .o_favorite_name input[type=text]').val('some name'); // name the filter
|
||||
await testUtils.dom.click($('.o_control_panel .o_save_favorite button'));
|
||||
await cpHelpers.toggleFavoriteMenu(actionManager);
|
||||
await cpHelpers.toggleSaveFavorite(actionManager);
|
||||
await cpHelpers.editFavoriteName(actionManager, "some name");
|
||||
await cpHelpers.saveFavorite(actionManager);
|
||||
|
||||
testUtils.mock.unpatch(ListController);
|
||||
actionManager.destroy();
|
||||
@@ -3460,29 +3469,23 @@ QUnit.module('ActionManager', {
|
||||
actions: this.actions,
|
||||
archs: this.archs,
|
||||
data: this.data,
|
||||
intercepts: {
|
||||
load_filters: function (ev) {
|
||||
ev.data.on_success([
|
||||
{
|
||||
user_id: [2, "Mitchell Admin"],
|
||||
name: 'favorite filter',
|
||||
id: 5,
|
||||
context: {},
|
||||
sort: '[]',
|
||||
domain: '[("bar", "=", 1)]'
|
||||
}
|
||||
]);
|
||||
},
|
||||
},
|
||||
favoriteFilters: [{
|
||||
user_id: [2, "Mitchell Admin"],
|
||||
name: 'favorite filter',
|
||||
id: 5,
|
||||
context: {},
|
||||
sort: '[]',
|
||||
domain: '[("bar", "=", 1)]'
|
||||
}],
|
||||
});
|
||||
|
||||
await actionManager.doAction(12);
|
||||
|
||||
assert.strictEqual(actionManager.$('.o_list_view tr.o_data_row .o_data_cell').text(), 'zoupyopplopgnapblip',
|
||||
'record should be in descending order as default_order applies');
|
||||
|
||||
// apply favorite filter
|
||||
await testUtils.dom.click(actionManager.$('.o_favorites_menu_button'));
|
||||
await testUtils.dom.click(actionManager.$('.o_menu_item a:contains("favorite filter")'));
|
||||
await cpHelpers.toggleFavoriteMenu(actionManager);
|
||||
await cpHelpers.toggleMenuItem(actionManager, "favorite filter");
|
||||
|
||||
assert.strictEqual(actionManager.$('.o_control_panel .o_facet_values').text().trim(),
|
||||
'favorite filter', 'favorite filter should be applied');
|
||||
assert.strictEqual(actionManager.$('.o_list_view tr.o_data_row .o_data_cell').text(), 'gnapblip',
|
||||
@@ -3495,7 +3498,7 @@ QUnit.module('ActionManager', {
|
||||
'order of records should not be changed, while coming back through breadcrumb');
|
||||
|
||||
// remove filter
|
||||
await testUtils.dom.click(actionManager.$('.o_searchview .o_facet_remove'));
|
||||
await cpHelpers.removeFacet(actionManager, 0);
|
||||
assert.strictEqual(actionManager.$('.o_list_view tr.o_data_row .o_data_cell').text(),
|
||||
'zoupyopplopgnapblip', 'order of records should not be changed, after removing current filter');
|
||||
|
||||
@@ -3512,16 +3515,16 @@ QUnit.module('ActionManager', {
|
||||
});
|
||||
|
||||
await actionManager.doAction(1);
|
||||
assert.strictEqual($('.o_search_options .o_dropdown:visible .o_filters_menu').length, 1,
|
||||
assert.isVisible(actionManager.el.querySelector('.o_search_options .o_dropdown.o_filter_menu'),
|
||||
"the search options should be available");
|
||||
|
||||
await actionManager.doAction(3);
|
||||
assert.strictEqual($('.o_search_options .o_dropdown:visible .o_filters_menu').length, 1,
|
||||
assert.isVisible(actionManager.el.querySelector('.o_search_options .o_dropdown.o_filter_menu'),
|
||||
"the search options should be available");
|
||||
|
||||
// go back using the breadcrumbs
|
||||
await testUtils.dom.click($('.o_control_panel .breadcrumb a:first'));
|
||||
assert.strictEqual($('.o_search_options .o_dropdown:visible .o_filters_menu').length, 1,
|
||||
assert.isVisible(actionManager.el.querySelector('.o_search_options .o_dropdown.o_filter_menu'),
|
||||
"the search options should be available");
|
||||
|
||||
actionManager.destroy();
|
||||
@@ -3772,11 +3775,11 @@ QUnit.module('ActionManager', {
|
||||
});
|
||||
await actionManager.doAction(5);
|
||||
|
||||
assert.strictEqual($('.o_technical_modal .modal-body button.infooter').length, 0,
|
||||
assert.containsNone($('.o_technical_modal .modal-body'), 'button.infooter',
|
||||
"the button should not be in the body");
|
||||
assert.strictEqual($('.o_technical_modal .modal-footer button.infooter').length, 1,
|
||||
assert.containsOnce($('.o_technical_modal .modal-footer'), 'button.infooter',
|
||||
"the button should be in the footer");
|
||||
assert.strictEqual($('.o_technical_modal .modal-footer button').length, 1,
|
||||
assert.containsOnce($('.o_technical_modal .modal-footer'), 'button',
|
||||
"the modal footer should only contain one button");
|
||||
|
||||
actionManager.destroy();
|
||||
@@ -4235,7 +4238,7 @@ QUnit.module('ActionManager', {
|
||||
<t t-name="kanban-box">
|
||||
<div class="oe_kanban_global_click">
|
||||
<field name="display_name"/>
|
||||
<button
|
||||
<button
|
||||
name="1"
|
||||
string="Execute action"
|
||||
type="action"
|
||||
@@ -4294,28 +4297,21 @@ QUnit.module('ActionManager', {
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
await actionManager.doAction(3);
|
||||
|
||||
var $searchInput = $('.o_searchview input');
|
||||
$searchInput.val('m'); // the searchbar checks the contents of the input on keypress events
|
||||
await testUtils.fields.triggerKey('press', $searchInput, 'm');
|
||||
await testUtils.fields.triggerKeydown($searchInput, 'enter');
|
||||
await cpHelpers.editSearch(actionManager, "m");
|
||||
await cpHelpers.validateSearch(actionManager);
|
||||
|
||||
assert.verifySteps(["search_read ",
|
||||
"search_read foo,ilike,m"]);
|
||||
assert.verifySteps(["search_read ", "search_read foo,ilike,m"]);
|
||||
|
||||
// Triggering the do_search above will kill the current searchview Input
|
||||
$searchInput = $('.o_searchview input');
|
||||
$searchInput.val('o'); // the searchbar checks the contents of the input on keypress events
|
||||
await testUtils.fields.triggerKey('press', $searchInput, 'o');
|
||||
await cpHelpers.editSearch(actionManager, "o");
|
||||
|
||||
// We have something in the input of the search view. Making the search_read
|
||||
// return at this point will trigger the redraw of the view.
|
||||
// However we want to hold on to what we just typed
|
||||
searchPromise.resolve();
|
||||
await testUtils.nextTick();
|
||||
await testUtils.fields.triggerKeydown($searchInput, 'enter');
|
||||
await cpHelpers.validateSearch(actionManager);
|
||||
|
||||
assert.verifySteps(["search_read |,foo,ilike,m,foo,ilike,o"]);
|
||||
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
odoo.define('web.pager_tests', function (require) {
|
||||
"use strict";
|
||||
|
||||
var Pager = require('web.Pager');
|
||||
var concurrency = require('web.concurrency');
|
||||
var testUtils = require('web.test_utils');
|
||||
|
||||
QUnit.module('chrome', {}, function () {
|
||||
|
||||
QUnit.module('Pager');
|
||||
|
||||
QUnit.test('basic stuff', async function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
var pager = new Pager(null, 10, 1, 4);
|
||||
pager.appendTo($('#qunit-fixture'));
|
||||
await testUtils.nextTick();
|
||||
|
||||
assert.strictEqual(pager.state.current_min, 1,
|
||||
"current_min should be set to 1");
|
||||
|
||||
// click on next
|
||||
await testUtils.dom.click(pager.$('.o_pager_next'));
|
||||
assert.strictEqual(pager.state.current_min, 5,
|
||||
"current_min should now be 5");
|
||||
|
||||
pager.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('edit the pager', async function (assert) {
|
||||
assert.expect(5);
|
||||
|
||||
var pager = new Pager(null, 10, 1, 4);
|
||||
pager.appendTo($('#qunit-fixture'));
|
||||
await testUtils.nextTick();
|
||||
|
||||
// enter edition
|
||||
await testUtils.dom.click(pager.$('.o_pager_value'));
|
||||
assert.containsOnce(pager, 'input',
|
||||
"the pager should contain an input");
|
||||
assert.strictEqual(pager.$('input').val(), '1-4',
|
||||
"the input should have correct value");
|
||||
|
||||
// change the limit
|
||||
await testUtils.fields.editInput(pager.$('input'), '1-6');
|
||||
await testUtils.fields.triggerKeydown(pager.$('input'), 'enter');
|
||||
assert.strictEqual(pager.state.limit, 6,
|
||||
"the limit should have been updated");
|
||||
assert.strictEqual(pager.state.current_min, 1,
|
||||
"the current_min should not have changed");
|
||||
assert.strictEqual(pager.$('.o_pager_value').text(), '1-6',
|
||||
"the input should have correct value");
|
||||
|
||||
pager.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('disabling the pager', async function (assert) {
|
||||
assert.expect(4);
|
||||
|
||||
var pager = new Pager(null, 10, 1, 4);
|
||||
pager.appendTo($('#qunit-fixture'));
|
||||
await testUtils.nextTick();
|
||||
await pager.disable();
|
||||
|
||||
// try to go to the next or previous pages
|
||||
await testUtils.dom.click(pager.$('.o_pager_next'));
|
||||
assert.strictEqual(pager.state.current_min, 1,
|
||||
"current_min should still be 1");
|
||||
await testUtils.dom.click(pager.$('.o_pager_previous'));
|
||||
assert.strictEqual(pager.state.current_min, 1,
|
||||
"current_min should still be 1");
|
||||
|
||||
// try to change the limit
|
||||
await testUtils.dom.click(pager.$('.o_pager_value'));
|
||||
assert.containsNone(pager, 'input',
|
||||
"the pager should not contain an input");
|
||||
|
||||
// a common use is to disable the pager before reloading the data, and
|
||||
// re-enable it once they have been loaded
|
||||
// the following emulates this situation
|
||||
pager.on('pager_changed', null, function () {
|
||||
pager.disable();
|
||||
concurrency.delay(0).then(function () {
|
||||
assert.ok(pager.disabled, "pager should still be disabled");
|
||||
pager.destroy();
|
||||
});
|
||||
});
|
||||
pager.enable();
|
||||
await testUtils.dom.click(pager.$('.o_pager_next'));
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -2,102 +2,89 @@ odoo.define('web.custom_file_input_tests', function (require) {
|
||||
"use strict";
|
||||
|
||||
const CustomFileInput = require('web.CustomFileInput');
|
||||
const makeTestEnvironment = require('web.test_env');
|
||||
const testUtils = require('web.test_utils');
|
||||
|
||||
const { Component, tags, useState } = owl;
|
||||
const { xml } = tags;
|
||||
const { createComponent } = testUtils;
|
||||
|
||||
QUnit.module('Components', {}, function () {
|
||||
|
||||
// This module cannot be tested as thoroughly as we want it to be:
|
||||
// browsers do not let scripts programmatically assign values to inputs
|
||||
// of type file
|
||||
QUnit.module('CustomFileInput', {}, function () {
|
||||
QUnit.test("Rendering of all props", async function (assert) {
|
||||
assert.expect(12);
|
||||
QUnit.module('CustomFileInput');
|
||||
|
||||
class Parent extends Component {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.state = useState({ innerContent: '<a href="#">Trigger</a>' });
|
||||
}
|
||||
// Handlers
|
||||
_onFileUploaded(ev) {
|
||||
assert.strictEqual(ev.detail.files.length, 0,
|
||||
"'files' property should be an empty array");
|
||||
}
|
||||
}
|
||||
Parent.components = { CustomFileInput };
|
||||
Parent.env = makeTestEnvironment({
|
||||
QUnit.test("Upload a file: default props", async function (assert) {
|
||||
assert.expect(6);
|
||||
|
||||
const customFileInput = await createComponent(CustomFileInput, {
|
||||
env: {
|
||||
services: {
|
||||
httpRequest: (route, params) => {
|
||||
if (route === '/web/binary/upload') {
|
||||
assert.deepEqual(params, {
|
||||
csrf_token: odoo.csrf_token,
|
||||
ufile: [],
|
||||
});
|
||||
assert.step(route);
|
||||
return Promise.resolve('[]');
|
||||
} else if (route === '/web/binary/upload_attachment') {
|
||||
assert.deepEqual(params, {
|
||||
id: 5,
|
||||
model: 'res.model',
|
||||
csrf_token: odoo.csrf_token,
|
||||
ufile: [],
|
||||
});
|
||||
assert.step(route);
|
||||
return Promise.resolve('[]');
|
||||
}
|
||||
async httpRequest(route, params) {
|
||||
assert.deepEqual(params, {
|
||||
csrf_token: odoo.csrf_token,
|
||||
ufile: [],
|
||||
});
|
||||
assert.step(route);
|
||||
return '[]';
|
||||
},
|
||||
},
|
||||
});
|
||||
Parent.template = xml`
|
||||
<CustomFileInput
|
||||
accepted_file_extensions="state.accepted_file_extensions"
|
||||
action="state.action"
|
||||
id="state.id"
|
||||
model="state.model"
|
||||
multi_upload="state.multi_upload"
|
||||
t-on-uploaded="_onFileUploaded"
|
||||
>
|
||||
<t t-raw="state.innerContent"/>
|
||||
</CustomFileInput>`;
|
||||
},
|
||||
});
|
||||
const input = customFileInput.el.querySelector('input');
|
||||
|
||||
const parent = new Parent();
|
||||
await parent.mount(testUtils.prepareTarget());
|
||||
const fileInput = parent.el;
|
||||
const input = fileInput.querySelector('input');
|
||||
assert.strictEqual(customFileInput.el.innerText.trim().toUpperCase(), "CHOOSE FILE",
|
||||
"File input total text should match its given inner element's text");
|
||||
assert.strictEqual(input.accept, '*',
|
||||
"Input should accept all files by default");
|
||||
|
||||
// Default props
|
||||
assert.strictEqual(fileInput.innerText.trim(), "Trigger",
|
||||
"File input total text should match its given inner element's text");
|
||||
assert.strictEqual(input.accept, '*',
|
||||
"Input should accept all files by default");
|
||||
await testUtils.dom.triggerEvent(input, 'change');
|
||||
assert.notOk(input.multiple,
|
||||
"'multiple' attribute should not be set");
|
||||
await testUtils.dom.triggerEvent(input, 'change');
|
||||
|
||||
// Change props
|
||||
Object.assign(parent.state, {
|
||||
assert.notOk(input.multiple, "'multiple' attribute should not be set");
|
||||
assert.verifySteps(['/web/binary/upload']);
|
||||
|
||||
customFileInput.destroy();
|
||||
});
|
||||
|
||||
QUnit.test("Upload a file: custom attachment", async function (assert) {
|
||||
assert.expect(6);
|
||||
|
||||
const customFileInput = await createComponent(CustomFileInput, {
|
||||
env: {
|
||||
services: {
|
||||
async httpRequest(route, params) {
|
||||
assert.deepEqual(params, {
|
||||
id: 5,
|
||||
model: 'res.model',
|
||||
csrf_token: odoo.csrf_token,
|
||||
ufile: [],
|
||||
});
|
||||
assert.step(route);
|
||||
return '[]';
|
||||
},
|
||||
},
|
||||
},
|
||||
props: {
|
||||
accepted_file_extensions: '.png',
|
||||
action: '/web/binary/upload_attachment',
|
||||
id: 5,
|
||||
model: 'res.model',
|
||||
multi_upload: true,
|
||||
});
|
||||
await testUtils.nextTick();
|
||||
|
||||
assert.strictEqual(input.accept, '.png',
|
||||
"Input should now only accept pngs");
|
||||
await testUtils.dom.triggerEvent(input, 'change');
|
||||
assert.ok(input.multiple,
|
||||
"'multiple' attribute should be set");
|
||||
|
||||
assert.verifySteps(['/web/binary/upload', '/web/binary/upload_attachment']);
|
||||
|
||||
parent.destroy();
|
||||
},
|
||||
intercepts: {
|
||||
'uploaded': ev => assert.strictEqual(ev.detail.files.length, 0,
|
||||
"'files' property should be an empty array"),
|
||||
},
|
||||
});
|
||||
const input = customFileInput.el.querySelector('input');
|
||||
|
||||
assert.strictEqual(input.accept, '.png', "Input should now only accept pngs");
|
||||
|
||||
await testUtils.dom.triggerEvent(input, 'change');
|
||||
|
||||
assert.ok(input.multiple, "'multiple' attribute should be set");
|
||||
assert.verifySteps(['/web/binary/upload_attachment']);
|
||||
|
||||
customFileInput.destroy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,6 +19,10 @@ var DebouncedField = basicFields.DebouncedField;
|
||||
var JournalDashboardGraph = basicFields.JournalDashboardGraph;
|
||||
var _t = core._t;
|
||||
|
||||
// Base64 images for testing purpose
|
||||
const MY_IMAGE = 'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
|
||||
const PRODUCT_IMAGE = 'R0lGODlhDAAMAKIFAF5LAP/zxAAAANyuAP/gaP///wAAAAAAACH5BAEAAAUALAAAAAAMAAwAAAMlWLPcGjDKFYi9lxKBOaGcF35DhWHamZUW0K4mAbiwWtuf0uxFAgA7';
|
||||
|
||||
QUnit.module('fields', {}, function () {
|
||||
|
||||
QUnit.module('basic_fields', {
|
||||
@@ -2516,7 +2520,7 @@ QUnit.module('basic_fields', {
|
||||
assert.expect(7);
|
||||
|
||||
this.data.partner.records[0].__last_update = '2017-02-08 10:00:00';
|
||||
this.data.partner.records[0].document = 'myimage';
|
||||
this.data.partner.records[0].document = MY_IMAGE;
|
||||
|
||||
var form = await createView({
|
||||
View: FormView,
|
||||
@@ -2526,13 +2530,13 @@ QUnit.module('basic_fields', {
|
||||
'<field name="document" widget="image" options="{\'size\': [90, 90]}"/> ' +
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
mockRPC: function (route, args) {
|
||||
async mockRPC(route, args) {
|
||||
if (route === '/web/dataset/call_kw/partner/read') {
|
||||
assert.deepEqual(args.args[1], ['document', '__last_update', 'display_name'], "The fields document, display_name and __last_update should be present when reading an image");
|
||||
}
|
||||
if (route === 'data:image/png;base64,myimage') {
|
||||
if (route === `data:image/png;base64,${MY_IMAGE}`) {
|
||||
assert.ok(true, "should called the correct route");
|
||||
return Promise.resolve('wow');
|
||||
return 'wow';
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
@@ -2551,6 +2555,59 @@ QUnit.module('basic_fields', {
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('image fields are correctly replaced when given an incorrect value', async function (assert) {
|
||||
assert.expect(7);
|
||||
|
||||
this.data.partner.records[0].__last_update = '2017-02-08 10:00:00';
|
||||
this.data.partner.records[0].document = 'incorrect_base64_value';
|
||||
|
||||
testUtils.mock.patch(basicFields.FieldBinaryImage, {
|
||||
// Delay the _render function: this will ensure that the error triggered
|
||||
// by the incorrect base64 value is dispatched before the src is replaced
|
||||
// (see test_utils_mock.removeSrcAttribute), since that function is called
|
||||
// when the element is inserted into the DOM.
|
||||
async _render() {
|
||||
const result = this._super.apply(this, arguments);
|
||||
await concurrency.delay(100);
|
||||
return result;
|
||||
},
|
||||
});
|
||||
|
||||
const form = await createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch: `
|
||||
<form string="Partners">
|
||||
<field name="document" widget="image" options="{'size': [90, 90]}"/>
|
||||
</form>`,
|
||||
res_id: 1,
|
||||
async mockRPC(route, args) {
|
||||
const _super = this._super;
|
||||
if (route === '/web/static/src/img/placeholder.png') {
|
||||
assert.step('call placeholder route');
|
||||
}
|
||||
return _super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
assert.hasClass(form.$('div[name="document"]'),'o_field_image',
|
||||
"the widget should have the correct class");
|
||||
assert.containsOnce(form, 'div[name="document"] > img',
|
||||
"the widget should contain an image");
|
||||
assert.hasClass(form.$('div[name="document"] > img'), 'img-fluid',
|
||||
"the image should have the correct class");
|
||||
assert.hasAttrValue(form.$('div[name="document"] > img'), 'width', "90",
|
||||
"the image should correctly set its attributes");
|
||||
assert.strictEqual(form.$('div[name="document"] > img').css('max-width'), "90px",
|
||||
"the image should correctly set its attributes");
|
||||
|
||||
assert.verifySteps(['call placeholder route']);
|
||||
|
||||
form.destroy();
|
||||
testUtils.mock.unpatch(basicFields.FieldBinaryImage);
|
||||
});
|
||||
|
||||
QUnit.test('image: option accepted_file_extensions', async function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
@@ -2583,9 +2640,9 @@ QUnit.module('basic_fields', {
|
||||
assert.expect(6);
|
||||
|
||||
this.data.partner.records[0].__last_update = '2017-02-08 10:00:00';
|
||||
this.data.partner.records[0].document = 'myimage';
|
||||
this.data.partner.records[0].document = MY_IMAGE;
|
||||
this.data.partner_type.fields.image = {name: 'image', type: 'binary'};
|
||||
this.data.partner_type.records[0].image = 'product_image';
|
||||
this.data.partner_type.records[0].image = PRODUCT_IMAGE;
|
||||
this.data.partner.records[0].timmy = [12];
|
||||
|
||||
var form = await createView({
|
||||
@@ -2604,14 +2661,14 @@ QUnit.module('basic_fields', {
|
||||
'</field>' +
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
mockRPC: function (route) {
|
||||
if (route === 'data:image/png;base64,myimage') {
|
||||
async mockRPC(route) {
|
||||
if (route === `data:image/png;base64,${MY_IMAGE}`) {
|
||||
assert.step("The view's image should have been fetched");
|
||||
return Promise.resolve('wow');
|
||||
return 'wow';
|
||||
}
|
||||
if (route === 'data:image/png;base64,product_image') {
|
||||
if (route === `data:image/gif;base64,${PRODUCT_IMAGE}`) {
|
||||
assert.step("The dialog's image should have been fetched");
|
||||
return Promise.resolve();
|
||||
return;
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
@@ -2634,7 +2691,7 @@ QUnit.module('basic_fields', {
|
||||
assert.expect(2);
|
||||
|
||||
this.data.partner_type.fields.image = {name: 'image', type: 'binary'};
|
||||
this.data.partner_type.records[0].image = 'product_image';
|
||||
this.data.partner_type.records[0].image = PRODUCT_IMAGE;
|
||||
this.data.partner.records[0].timmy = [12];
|
||||
|
||||
var form = await createView({
|
||||
@@ -2649,10 +2706,10 @@ QUnit.module('basic_fields', {
|
||||
'</field>' +
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
mockRPC: function (route) {
|
||||
if (route === 'data:image/png;base64,product_image') {
|
||||
async mockRPC(route) {
|
||||
if (route === `data:image/gif;base64,${PRODUCT_IMAGE}`) {
|
||||
assert.ok(true, "The list's image should have been fetched");
|
||||
return Promise.resolve();
|
||||
return;
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
@@ -2961,7 +3018,7 @@ QUnit.module('basic_fields', {
|
||||
|
||||
QUnit.module('FieldDateRange');
|
||||
|
||||
QUnit.test('Datetime field', async function (assert) {
|
||||
QUnit.test('Datetime field [REQUIRE FOCUS]', async function (assert) {
|
||||
assert.expect(20);
|
||||
|
||||
this.data.partner.fields.datetime_end = {string: 'Datetime End', type: 'datetime'};
|
||||
@@ -3039,7 +3096,7 @@ QUnit.module('basic_fields', {
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('Date field', async function (assert) {
|
||||
QUnit.test('Date field [REQUIRE FOCUS]', async function (assert) {
|
||||
assert.expect(18);
|
||||
|
||||
this.data.partner.fields.date_end = {string: 'Date End', type: 'date'};
|
||||
|
||||
@@ -3,6 +3,8 @@ odoo.define('web.field_many_to_many_tests', function (require) {
|
||||
|
||||
var FormView = require('web.FormView');
|
||||
var testUtils = require('web.test_utils');
|
||||
|
||||
const cpHelpers = testUtils.controlPanel;
|
||||
var createView = testUtils.createView;
|
||||
|
||||
QUnit.module('fields', {}, function () {
|
||||
@@ -1003,8 +1005,8 @@ QUnit.module('fields', {}, function () {
|
||||
assert.strictEqual($('.modal .o_data_row').length, 1,
|
||||
"should contain only one row (gold)");
|
||||
|
||||
await testUtils.fields.triggerKey('press', $('.modal .o_searchview_input'), 's');
|
||||
await testUtils.fields.triggerKeydown($('.modal .o_searchview_input'), 'enter');
|
||||
await cpHelpers.editSearch('.modal', 's');
|
||||
await cpHelpers.validateSearch('.modal');
|
||||
|
||||
assert.strictEqual($('.modal .o_data_row').length, 0, "should contain no row");
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ var StandaloneFieldManagerMixin = require('web.StandaloneFieldManagerMixin');
|
||||
var testUtils = require('web.test_utils');
|
||||
var Widget = require('web.Widget');
|
||||
|
||||
const cpHelpers = testUtils.controlPanel;
|
||||
var createView = testUtils.createView;
|
||||
|
||||
QUnit.module('fields', {}, function () {
|
||||
@@ -244,11 +245,11 @@ QUnit.module('fields', {}, function () {
|
||||
// save form
|
||||
await testUtils.form.clickSave(form);
|
||||
// click next on pager
|
||||
await testUtils.dom.click(form.pager.$('.o_pager_next'));
|
||||
await testUtils.dom.click(form.el.querySelector('.o_pager .o_pager_next'));
|
||||
|
||||
// this checks that the view did not ask for confirmation that the
|
||||
// record is dirty
|
||||
assert.strictEqual(form.pager.$el.text().trim(), '2 / 2',
|
||||
assert.strictEqual(form.el.querySelector('.o_pager').innerText.trim(), '2 / 2',
|
||||
'pager should be at second page');
|
||||
form.destroy();
|
||||
});
|
||||
@@ -316,11 +317,11 @@ QUnit.module('fields', {}, function () {
|
||||
// save form
|
||||
await testUtils.form.clickSave(form);
|
||||
// click next on pager
|
||||
await testUtils.dom.click(form.pager.$('.o_pager_next'));
|
||||
await testUtils.dom.click(form.el.querySelector('.o_pager .o_pager_next'));
|
||||
|
||||
// this checks that the view did not ask for confirmation that the
|
||||
// record is dirty
|
||||
assert.strictEqual(form.pager.$el.text().trim(), '2 / 2',
|
||||
assert.strictEqual(form.el.querySelector('.o_pager').innerText.trim(), '2 / 2',
|
||||
'pager should be at second page');
|
||||
form.destroy();
|
||||
});
|
||||
@@ -506,11 +507,11 @@ QUnit.module('fields', {}, function () {
|
||||
|
||||
assert.strictEqual($('tr.o_data_row').length, 9, "should display 9 records");
|
||||
|
||||
await testUtils.dom.click($('button:contains(Filters)'));
|
||||
await testUtils.dom.click($('.o_add_custom_filter:visible'));
|
||||
assert.strictEqual($('.o_filter_condition select.o_searchview_extended_prop_field').val(), 'datetime',
|
||||
await cpHelpers.toggleFilterMenu('.modal');
|
||||
await cpHelpers.toggleAddCustomFilter('.modal');
|
||||
assert.strictEqual(document.querySelector('.modal .o_generator_menu_field').value, 'datetime',
|
||||
"datetime field should be selected");
|
||||
await testUtils.dom.click($('.o_apply_filter'));
|
||||
await cpHelpers.applyFilter('.modal');
|
||||
|
||||
assert.strictEqual($('tr.o_data_row').length, 0, "should display 0 records");
|
||||
form.destroy();
|
||||
@@ -592,7 +593,6 @@ QUnit.module('fields', {}, function () {
|
||||
assert.containsNone(document.body, '.modal',
|
||||
"No save should be triggered when removing value");
|
||||
|
||||
await testUtils.fields.many2one.clickOpenDropdown('trululu');
|
||||
await testUtils.fields.many2one.clickHighlightedItem('trululu');
|
||||
|
||||
assert.containsOnce(document.body, '.modal',
|
||||
@@ -741,8 +741,8 @@ QUnit.module('fields', {}, function () {
|
||||
assert.ok(!$('.modal .modal-footer .o_select_button').length,
|
||||
"there should be no 'Select' button in the footer");
|
||||
assert.ok($('.modal tbody tr').length > 10, "list should contain more than 10 records");
|
||||
await testUtils.fields.triggerKey('press', $('.modal .o_searchview_input'), 'P'),
|
||||
await testUtils.fields.triggerKeydown($('.modal .o_searchview_input'), 'enter');
|
||||
await cpHelpers.editSearch('.modal', "P");
|
||||
await cpHelpers.validateSearch('.modal');
|
||||
assert.strictEqual($('.modal tbody tr').length, 10,
|
||||
"list should be restricted to records containing a P (10 records)");
|
||||
// choose a record
|
||||
|
||||
@@ -12,6 +12,7 @@ var relationalFields = require('web.relational_fields');
|
||||
var testUtils = require('web.test_utils');
|
||||
var fieldUtils = require('web.field_utils');
|
||||
|
||||
const cpHelpers = testUtils.controlPanel;
|
||||
var createView = testUtils.createView;
|
||||
|
||||
QUnit.module('fields', {}, function () {
|
||||
@@ -1505,7 +1506,7 @@ QUnit.module('fields', {}, function () {
|
||||
"second dialog should be closed");
|
||||
assert.strictEqual($('.modal .o_data_row').length, 1,
|
||||
"there should be one record in the one2many in the dialog");
|
||||
assert.notOk($('.modal .o_x2m_control_panel .o_cp_pager div').is(':visible'),
|
||||
assert.containsNone($('.modal'), '.o_x2m_control_panel .o_pager',
|
||||
'm2m pager should be hidden');
|
||||
|
||||
// click on 'Save & Close'
|
||||
@@ -1756,16 +1757,14 @@ QUnit.module('fields', {}, function () {
|
||||
// move to record 2, which has 3 related records (and shouldn't contain the
|
||||
// related records of record 1 anymore). Two additional RPCs should have
|
||||
// been done
|
||||
form.pager.next();
|
||||
await testUtils.nextTick();
|
||||
await cpHelpers.pagerNext(form);
|
||||
assert.strictEqual(count, 4, 'two RPCs should have been done');
|
||||
assert.strictEqual(form.$('.o_kanban_record:not(".o_kanban_ghost")').length, 3,
|
||||
'one2many kanban should contain 3 cards for record 2');
|
||||
|
||||
// move back to record 1, which should contain again its first 40 related
|
||||
// records
|
||||
form.pager.previous();
|
||||
await testUtils.nextTick();
|
||||
await cpHelpers.pagerPrevious(form);
|
||||
assert.strictEqual(count, 6, 'two RPCs should have been done');
|
||||
assert.strictEqual(form.$('.o_kanban_record:not(".o_kanban_ghost")').length, 40,
|
||||
'one2many kanban should contain 40 cards for record 1');
|
||||
@@ -1778,16 +1777,14 @@ QUnit.module('fields', {}, function () {
|
||||
'one2many kanban should contain 2 cards for record 1 at page 2');
|
||||
|
||||
// move to record 2 again and check that everything is correctly updated
|
||||
form.pager.next();
|
||||
await testUtils.nextTick();
|
||||
await cpHelpers.pagerNext(form);
|
||||
assert.strictEqual(count, 9, 'two RPCs should have been done');
|
||||
assert.strictEqual(form.$('.o_kanban_record:not(".o_kanban_ghost")').length, 3,
|
||||
'one2many kanban should contain 3 cards for record 2');
|
||||
|
||||
// move back to record 1 and move to page 2 again: all data should have
|
||||
// been correctly reloaded
|
||||
form.pager.previous();
|
||||
await testUtils.nextTick();
|
||||
await cpHelpers.pagerPrevious(form);
|
||||
assert.strictEqual(count, 11, 'two RPCs should have been done');
|
||||
await testUtils.dom.click(form.$('.o_x2m_control_panel .o_pager_next'));
|
||||
assert.strictEqual(count, 12, 'one RPC should have been done');
|
||||
@@ -2565,7 +2562,7 @@ QUnit.module('fields', {}, function () {
|
||||
await testUtils.dom.click(form.$('.o_field_x2many_list_row_add a'));
|
||||
await testUtils.dom.click(form.$el);
|
||||
|
||||
assert.strictEqual(form.$('.o_field_widget[name=turtles] .o_cp_pager').text().trim(), '1-3 / 5',
|
||||
assert.strictEqual(form.$('.o_field_widget[name=turtles] .o_pager').text().trim(), '1-3 / 5',
|
||||
"pager should display the correct total");
|
||||
form.destroy();
|
||||
});
|
||||
@@ -2898,7 +2895,7 @@ QUnit.module('fields', {}, function () {
|
||||
await testUtils.form.clickEdit(form);
|
||||
await testUtils.dom.click(form.$('.o_field_x2many_list_row_add a'));
|
||||
// the record currently being added should not count in the pager
|
||||
assert.isNotVisible(form.$('.o_field_widget[name=turtles] .o_cp_pager'));
|
||||
assert.containsNone(form, '.o_field_widget[name=turtles] .o_pager');
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
@@ -2931,8 +2928,8 @@ QUnit.module('fields', {}, function () {
|
||||
// confirm the discard operation
|
||||
await testUtils.dom.click($('.modal .modal-footer .btn-primary'));
|
||||
|
||||
assert.isVisible(form.$('.o_field_widget[name=turtles] .o_cp_pager'));
|
||||
assert.strictEqual(form.$('.o_field_widget[name=turtles] .o_cp_pager').text().trim(), '1-3 / 4',
|
||||
assert.isVisible(form.$('.o_field_widget[name=turtles] .o_pager'));
|
||||
assert.strictEqual(form.$('.o_field_widget[name=turtles] .o_pager').text().trim(), '1-3 / 4',
|
||||
"pager should display correct values");
|
||||
|
||||
form.destroy();
|
||||
@@ -3001,13 +2998,13 @@ QUnit.module('fields', {}, function () {
|
||||
// see a confirm dialog
|
||||
await testUtils.dom.click(form.$('.o_field_widget[name=turtles] .o_pager_next'));
|
||||
|
||||
assert.strictEqual(form.$('.o_field_widget[name=turtles] .o_cp_pager').text().trim(), '1-3 / 4',
|
||||
assert.strictEqual(form.$('.o_field_widget[name=turtles] .o_pager').text().trim(), '1-3 / 4',
|
||||
"pager should still display the correct total");
|
||||
|
||||
// click on cancel
|
||||
await testUtils.dom.click($('.modal .modal-footer .btn-secondary'));
|
||||
|
||||
assert.strictEqual(form.$('.o_field_widget[name=turtles] .o_cp_pager').text().trim(), '1-3 / 4',
|
||||
assert.strictEqual(form.$('.o_field_widget[name=turtles] .o_pager').text().trim(), '1-3 / 4',
|
||||
"pager should again display the correct total");
|
||||
assert.containsOnce(form, '.o_field_one2many input.o_field_invalid',
|
||||
"there should be an invalid input in the one2many");
|
||||
@@ -3048,7 +3045,7 @@ QUnit.module('fields', {}, function () {
|
||||
await testUtils.dom.click($('.modal .modal-footer .btn-primary'));
|
||||
|
||||
assert.containsOnce(form, 'tr.o_data_row');
|
||||
assert.isNotVisible(form.$('.o_field_widget[name=turtles] .o_cp_pager'));
|
||||
assert.containsNone(form, '.o_field_widget[name=turtles] .o_pager');
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
@@ -3911,14 +3908,14 @@ QUnit.module('fields', {}, function () {
|
||||
'</form>',
|
||||
});
|
||||
|
||||
assert.ok(!form.$('.o_x2m_control_panel .o_cp_pager div').is(':visible'),
|
||||
assert.containsNone(form, '.o_x2m_control_panel .o_pager',
|
||||
'o2m pager should be hidden');
|
||||
|
||||
// click to create a subrecord
|
||||
await testUtils.dom.click(form.$('tbody td.o_field_x2many_list_row_add a'));
|
||||
assert.containsOnce(form, 'tr.o_data_row');
|
||||
|
||||
assert.ok(!form.$('.o_x2m_control_panel .o_cp_pager div').is(':visible'),
|
||||
assert.containsNone(form, '.o_x2m_control_panel .o_pager',
|
||||
'o2m pager should be hidden');
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
@@ -8,6 +8,7 @@ var RamStorage = require('web.RamStorage');
|
||||
var relationalFields = require('web.relational_fields');
|
||||
var testUtils = require('web.test_utils');
|
||||
|
||||
const cpHelpers = testUtils.controlPanel;
|
||||
var createView = testUtils.createView;
|
||||
|
||||
QUnit.module('fields', {}, function () {
|
||||
@@ -153,24 +154,10 @@ QUnit.module('relational_fields', {
|
||||
|
||||
QUnit.test('search more pager is reset when doing a new search', async function (assert) {
|
||||
assert.expect(6);
|
||||
for(var i = 10; i < 180; i++) {
|
||||
this.data.partner.records.push({
|
||||
id: i,
|
||||
display_name: "Partner " + i,
|
||||
});
|
||||
}
|
||||
|
||||
async function stringToEvent ($element, string) {
|
||||
for (var i = 0; i < string.length; i++) {
|
||||
var keyAscii = string.charCodeAt(i);
|
||||
$element.val($element.val()+string[i]);
|
||||
$element.trigger($.Event('keyup', {which: keyAscii, keyCode:keyAscii}));
|
||||
await testUtils.nextTick();
|
||||
}
|
||||
$element.trigger($.Event('keyup', {which: $.ui.keyCode.ENTER, keyCode:$.ui.keyCode.ENTER}));
|
||||
await testUtils.nextTick();
|
||||
}
|
||||
|
||||
this.data.partner.records.push(
|
||||
...new Array(170).fill().map((_, i) => ({ id: i + 10, name: "Partner " + i }))
|
||||
);
|
||||
this.data.partner.fields.datetime.searchable = true;
|
||||
var form = await createView({
|
||||
View: FormView,
|
||||
@@ -192,7 +179,6 @@ QUnit.module('relational_fields', {
|
||||
|
||||
await testUtils.form.clickEdit(form);
|
||||
|
||||
|
||||
await testUtils.fields.many2one.clickOpenDropdown('trululu');
|
||||
await testUtils.fields.many2one.clickItem('trululu','Search');
|
||||
await testUtils.dom.click($('.modal .o_pager_next'));
|
||||
@@ -201,7 +187,8 @@ QUnit.module('relational_fields', {
|
||||
assert.strictEqual($('.o_pager_value').text(), "181-160", "should display the second page");
|
||||
assert.strictEqual($('tr.o_data_row').length, 80, "should display 80 record");
|
||||
|
||||
await stringToEvent($('.modal .o_searchview_input'), 'first');
|
||||
await cpHelpers.editSearch('.modal', "first");
|
||||
await cpHelpers.validateSearch('.modal');
|
||||
|
||||
assert.strictEqual($('.o_pager_limit').text(), "11", "there should be 1 record");
|
||||
assert.strictEqual($('.o_pager_value').text(), "11-1", "should display the first page");
|
||||
@@ -1708,8 +1695,8 @@ QUnit.module('relational_fields', {
|
||||
});
|
||||
await testUtils.fields.many2one.clickOpenDropdown('trululu');
|
||||
await testUtils.fields.many2one.clickItem('trululu', 'Search');
|
||||
await testUtils.dom.click($('.modal .o_search_options .fa-bars'));
|
||||
await testUtils.dom.click($('.modal .o_search_options .o_group_by_menu a:contains(Bar)'));
|
||||
await cpHelpers.toggleGroupByMenu('.modal');
|
||||
await cpHelpers.toggleMenuItem('.modal', "Bar");
|
||||
|
||||
await testUtils.dom.click($('.modal .o_group_header:first'));
|
||||
|
||||
@@ -1977,7 +1964,7 @@ QUnit.module('relational_fields', {
|
||||
|
||||
await testUtils.form.clickSave(form);
|
||||
|
||||
assert.strictEqual(form.el.querySelector('.o_field_many2manytags').innerText, 'new value');
|
||||
assert.strictEqual(form.el.querySelector('.o_field_many2manytags').innerText.trim(), "new value");
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
@@ -305,6 +305,8 @@ QUnit.module('Views', {
|
||||
});
|
||||
|
||||
await actionManager.doAction(1);
|
||||
await testUtils.nextTick();
|
||||
|
||||
// displays month mode by default
|
||||
assert.strictEqual($('.o_control_panel .breadcrumb-item').text(),
|
||||
'Meetings Test (Dec 11 – 17, 2016)', "should display the current week");
|
||||
|
||||
@@ -16,6 +16,7 @@ var widgetRegistry = require('web.widget_registry');
|
||||
var Widget = require('web.Widget');
|
||||
|
||||
var _t = core._t;
|
||||
const cpHelpers = testUtils.controlPanel;
|
||||
var createView = testUtils.createView;
|
||||
var createActionManager = testUtils.createActionManager;
|
||||
|
||||
@@ -213,7 +214,7 @@ QUnit.module('Views', {
|
||||
bar: true,
|
||||
foo: "blip",
|
||||
int_field: 9,
|
||||
})
|
||||
});
|
||||
var form = await createView({
|
||||
View: FormView,
|
||||
viewOptions: { mode: 'edit' },
|
||||
@@ -249,7 +250,7 @@ QUnit.module('Views', {
|
||||
this.data.partner.records.push({
|
||||
id: 6,
|
||||
p: [1],
|
||||
})
|
||||
});
|
||||
var form = await createView({
|
||||
View: FormView,
|
||||
viewOptions: { mode: 'edit' },
|
||||
@@ -1858,7 +1859,7 @@ QUnit.module('Views', {
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('sidebar is hidden when switching to edit mode', async function (assert) {
|
||||
QUnit.test('toolbar is hidden when switching to edit mode', async function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
var form = await createView({
|
||||
@@ -1870,15 +1871,19 @@ QUnit.module('Views', {
|
||||
'<field name="foo"/>' +
|
||||
'</sheet>' +
|
||||
'</form>',
|
||||
viewOptions: {hasSidebar: true},
|
||||
viewOptions: {hasActionMenus: true},
|
||||
res_id: 1,
|
||||
});
|
||||
|
||||
assert.isVisible(form.sidebar);
|
||||
assert.containsOnce(form, '.o_cp_action_menus');
|
||||
|
||||
await testUtils.form.clickEdit(form);
|
||||
assert.isNotVisible(form.sidebar);
|
||||
|
||||
assert.containsNone(form, '.o_cp_action_menus');
|
||||
|
||||
await testUtils.form.clickDiscard(form);
|
||||
assert.isVisible(form.sidebar);
|
||||
|
||||
assert.containsOnce(form, '.o_cp_action_menus');
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
@@ -2013,14 +2018,14 @@ QUnit.module('Views', {
|
||||
'<field name="foo"/>' +
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
viewOptions: {hasSidebar: true},
|
||||
viewOptions: {hasActionMenus: true},
|
||||
});
|
||||
|
||||
assert.strictEqual(form.$('.o_control_panel .breadcrumb').text(), 'first record',
|
||||
"should have the display name of the record as title");
|
||||
|
||||
await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
|
||||
await testUtils.dom.click(form.sidebar.$('a:contains(Duplicate)'));
|
||||
await cpHelpers.toggleActionMenu(form);
|
||||
await cpHelpers.toggleMenuItem(form, "Duplicate");
|
||||
|
||||
assert.strictEqual(form.$('.o_control_panel .breadcrumb').text(), 'first record (copy)',
|
||||
"should have duplicated the record");
|
||||
@@ -2040,7 +2045,7 @@ QUnit.module('Views', {
|
||||
'<field name="foo"/>' +
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
viewOptions: {hasSidebar: true, context: {hey: 'hoy'}},
|
||||
viewOptions: {hasActionMenus: true, context: {hey: 'hoy'}},
|
||||
mockRPC: function (route, args) {
|
||||
if (args.method === 'read') {
|
||||
// should have 2 read, one for initial load, second for
|
||||
@@ -2052,8 +2057,8 @@ QUnit.module('Views', {
|
||||
},
|
||||
});
|
||||
|
||||
await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
|
||||
await testUtils.dom.click(form.sidebar.$('a:contains(Duplicate)'));
|
||||
await cpHelpers.toggleActionMenu(form);
|
||||
await cpHelpers.toggleMenuItem(form, "Duplicate");
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
@@ -2069,12 +2074,12 @@ QUnit.module('Views', {
|
||||
'<field name="foo"/>' +
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
viewOptions: {hasSidebar: true},
|
||||
viewOptions: {hasActionMenus: true},
|
||||
});
|
||||
|
||||
assert.strictEqual(form.$('.o_control_panel .breadcrumb').text(), 'first record',
|
||||
"should have the display name of the record as title");
|
||||
assert.containsNone(form.sidebar, 'a:contains(Duplicate)',
|
||||
assert.containsNone(form, '.o_cp_action_menus a:contains(Duplicate)',
|
||||
"should not contains a 'Duplicate' action");
|
||||
form.destroy();
|
||||
});
|
||||
@@ -2603,14 +2608,14 @@ QUnit.module('Views', {
|
||||
data: this.data,
|
||||
arch: '<form string="Partners"><field name="foo"></field></form>',
|
||||
res_id: 1,
|
||||
viewOptions: {hasSidebar: true},
|
||||
viewOptions: {hasActionMenus: true},
|
||||
});
|
||||
await testUtils.form.clickEdit(form);
|
||||
await testUtils.fields.editInput(form.$('input[name=foo]'), 'tralala');
|
||||
await testUtils.form.clickSave(form);
|
||||
|
||||
await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
|
||||
await testUtils.dom.click(form.sidebar.$('a:contains(Duplicate)'));
|
||||
await cpHelpers.toggleActionMenu(form);
|
||||
await cpHelpers.toggleMenuItem(form, "Duplicate");
|
||||
|
||||
assert.strictEqual(form.$('input[name=foo]').val(), 'tralala', 'input should contain ABC');
|
||||
|
||||
@@ -2643,8 +2648,8 @@ QUnit.module('Views', {
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(form.$('.o_pager_value').text(), '1', "pager value should be 1");
|
||||
assert.strictEqual(form.$('.o_pager_limit').text(), '2', "pager limit should be 2");
|
||||
assert.strictEqual(cpHelpers.getPagerValue(form), '1', "pager value should be 1");
|
||||
assert.strictEqual(cpHelpers.getPagerSize(form), '2', "pager limit should be 2");
|
||||
|
||||
// switch to edit mode
|
||||
await testUtils.form.clickEdit(form);
|
||||
@@ -2655,19 +2660,19 @@ QUnit.module('Views', {
|
||||
assert.strictEqual(form.$('input').val(), 'new value', 'input should contain new value');
|
||||
|
||||
// click on the pager to switch to the next record and cancel the confirm request
|
||||
await testUtils.dom.click('.o_pager_next'); // click on next
|
||||
await cpHelpers.pagerNext(form);
|
||||
assert.containsOnce(document.body, '.modal', "a confirm modal should be displayed");
|
||||
await testUtils.dom.click('.modal-footer .btn-secondary'); // click on cancel
|
||||
assert.strictEqual(form.$('input[name=foo]').val(), 'new value',
|
||||
"input should still contain new value");
|
||||
assert.strictEqual(form.$('.o_pager_value').text(), '1', "pager value should still be 1");
|
||||
assert.strictEqual(cpHelpers.getPagerValue(form), '1', "pager value should still be 1");
|
||||
|
||||
// click on the pager to switch to the next record and confirm
|
||||
await testUtils.dom.click('.o_pager_next'); // click on next
|
||||
await cpHelpers.pagerNext(form);
|
||||
assert.containsOnce(document.body, '.modal', "a confirm modal should be displayed");
|
||||
await testUtils.dom.click('.modal-footer .btn-primary'); // click on confirm
|
||||
assert.strictEqual(form.$('input[name=foo]').val(), 'blip', "input should contain blip");
|
||||
assert.strictEqual(form.$('.o_pager_value').text(), '2', "pager value should be 2");
|
||||
assert.strictEqual(cpHelpers.getPagerValue(form), '2', "pager value should be 2");
|
||||
|
||||
assert.strictEqual(nbWrite, 0, 'no write RPC should have been done');
|
||||
form.destroy();
|
||||
@@ -2690,7 +2695,8 @@ QUnit.module('Views', {
|
||||
},
|
||||
res_id: 1,
|
||||
});
|
||||
assert.strictEqual(form.$('.o_pager_value').text(), '1', "pager value should be 1");
|
||||
|
||||
assert.strictEqual(cpHelpers.getPagerValue(form), '1', "pager value should be 1");
|
||||
|
||||
// switch to edit mode
|
||||
await testUtils.form.clickEdit(form);
|
||||
@@ -2704,10 +2710,10 @@ QUnit.module('Views', {
|
||||
await testUtils.form.clickSave(form);
|
||||
|
||||
// click on the pager to switch to the next record and cancel the confirm request
|
||||
await testUtils.dom.click('.o_pager_next'); // click on next
|
||||
await cpHelpers.pagerNext(form);
|
||||
assert.containsNone(document.body, '.modal:visible',
|
||||
"no confirm modal should be displayed");
|
||||
assert.strictEqual(form.$('.o_pager_value').text(), '2', "pager value should be 2");
|
||||
assert.strictEqual(cpHelpers.getPagerValue(form), '2', "pager value should be 2");
|
||||
|
||||
assert.containsN(form, '.o_priority .fa-star-o', 2,
|
||||
'priority widget should have been rendered with correct value');
|
||||
@@ -2717,10 +2723,10 @@ QUnit.module('Views', {
|
||||
assert.containsOnce(form, '.o_priority .fa-star',
|
||||
'priority widget should have been updated');
|
||||
|
||||
await testUtils.dom.click('.o_pager_next'); // click on next
|
||||
assert.containsNone(document.body, '.modal:visible',
|
||||
await cpHelpers.pagerNext(form);
|
||||
assert.containsNone(document.body, '.modal:visible',
|
||||
"no confirm modal should be displayed");
|
||||
assert.strictEqual(form.$('.o_pager_value').text(), '1', "pager value should be 1");
|
||||
assert.strictEqual(cpHelpers.getPagerValue(form), '1', "pager value should be 1");
|
||||
|
||||
// switch to edit mode
|
||||
await testUtils.form.clickEdit(form);
|
||||
@@ -2733,8 +2739,8 @@ QUnit.module('Views', {
|
||||
await testUtils.form.clickDiscard(form);
|
||||
assert.containsOnce(document.body, '.modal', "a confirm modal should be displayed");
|
||||
await testUtils.dom.click('.modal-footer .btn-primary'); // click on confirm
|
||||
await testUtils.dom.click('.o_pager_next'); // click on next
|
||||
assert.strictEqual(form.$('.o_pager_value').text(), '2', "pager value should be 2");
|
||||
await cpHelpers.pagerNext(form);
|
||||
assert.strictEqual(cpHelpers.getPagerValue(form), '2', "pager value should be 2");
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
@@ -2769,7 +2775,7 @@ QUnit.module('Views', {
|
||||
assert.hasClass(form.$('.o_notebook .nav-link:eq(1)'), 'active');
|
||||
|
||||
// click on the pager to switch to the next record
|
||||
await testUtils.dom.click('.o_pager_next');
|
||||
await cpHelpers.pagerNext(form);
|
||||
|
||||
assert.doesNotHaveClass(form.$('.o_notebook .nav-link:eq(0)'), 'active');
|
||||
assert.hasClass(form.$('.o_notebook .nav-link:eq(1)'), 'active');
|
||||
@@ -2793,20 +2799,22 @@ QUnit.module('Views', {
|
||||
},
|
||||
});
|
||||
|
||||
assert.isVisible(form.pager);
|
||||
assert.strictEqual(form.pager.$('.o_pager_value').text(), "1",
|
||||
assert.containsOnce(form, '.o_pager');
|
||||
assert.strictEqual(cpHelpers.getPagerValue(form), "1",
|
||||
"current pager value should be 1");
|
||||
assert.strictEqual(form.pager.$('.o_pager_limit').text(), "2",
|
||||
assert.strictEqual(cpHelpers.getPagerSize(form), "2",
|
||||
"current pager limit should be 1");
|
||||
|
||||
await testUtils.form.clickCreate(form);
|
||||
assert.isNotVisible(form.pager);
|
||||
|
||||
assert.containsNone(form, '.o_pager');
|
||||
|
||||
await testUtils.form.clickSave(form);
|
||||
assert.isVisible(form.pager);
|
||||
assert.strictEqual(form.pager.$('.o_pager_value').text(), "3",
|
||||
|
||||
assert.containsOnce(form, '.o_pager');
|
||||
assert.strictEqual(cpHelpers.getPagerValue(form), "3",
|
||||
"current pager value should be 3");
|
||||
assert.strictEqual(form.pager.$('.o_pager_limit').text(), "3",
|
||||
assert.strictEqual(cpHelpers.getPagerSize(form), "3",
|
||||
"current pager limit should be 3");
|
||||
|
||||
form.destroy();
|
||||
@@ -2835,10 +2843,11 @@ QUnit.module('Views', {
|
||||
});
|
||||
|
||||
assert.strictEqual(form.mode, 'readonly', 'form view should be in readonly mode');
|
||||
assert.strictEqual(form.pager.$('.o_pager_value').text(), "1", 'pager value should be 1');
|
||||
await testUtils.dom.click(form.pager.$('.o_pager_next'));
|
||||
assert.strictEqual(cpHelpers.getPagerValue(form), "1", 'pager value should be 1');
|
||||
|
||||
assert.strictEqual(form.pager.$('.o_pager_value').text(), "2", 'pager value should be 2');
|
||||
await cpHelpers.pagerNext(form);
|
||||
|
||||
assert.strictEqual(cpHelpers.getPagerValue(form), "2", 'pager value should be 2');
|
||||
assert.strictEqual(form.mode, 'readonly', 'form view should be in readonly mode');
|
||||
|
||||
assert.strictEqual(pushStateCount, 2, "should have triggered 2 push_state");
|
||||
@@ -2935,28 +2944,28 @@ QUnit.module('Views', {
|
||||
viewOptions: {
|
||||
ids: [1, 2, 4],
|
||||
index: 0,
|
||||
hasSidebar: true,
|
||||
hasActionMenus: true,
|
||||
},
|
||||
res_id: 1,
|
||||
});
|
||||
|
||||
assert.strictEqual(form.pager.$('.o_pager_value').text(), "1", 'pager value should be 1');
|
||||
assert.strictEqual(form.pager.$('.o_pager_limit').text(), "3", 'pager limit should be 3');
|
||||
assert.strictEqual(cpHelpers.getPagerValue(form), "1", 'pager value should be 1');
|
||||
assert.strictEqual(cpHelpers.getPagerSize(form), "3", 'pager limit should be 3');
|
||||
assert.strictEqual(form.$('span:contains(yop)').length, 1,
|
||||
'should have a field with foo value for record 1');
|
||||
assert.ok(!$('.modal:visible').length, 'no confirm modal should be displayed');
|
||||
|
||||
// open sidebar and delete
|
||||
await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
|
||||
await testUtils.dom.click(form.sidebar.$('a:contains(Delete)'));
|
||||
// open action menu and delete
|
||||
await cpHelpers.toggleActionMenu(form);
|
||||
await cpHelpers.toggleMenuItem(form, "Delete");
|
||||
|
||||
assert.ok($('.modal').length, 'a confirm modal should be displayed');
|
||||
|
||||
// confirm the delete
|
||||
await testUtils.dom.click($('.modal-footer button.btn-primary'));
|
||||
|
||||
assert.strictEqual(form.pager.$('.o_pager_value').text(), "1", 'pager value should be 1');
|
||||
assert.strictEqual(form.pager.$('.o_pager_limit').text(), "2", 'pager limit should be 2');
|
||||
assert.strictEqual(cpHelpers.getPagerValue(form), "1", 'pager value should be 1');
|
||||
assert.strictEqual(cpHelpers.getPagerSize(form), "2", 'pager limit should be 2');
|
||||
assert.strictEqual(form.$('span:contains(blip)').length, 1,
|
||||
'should have a field with foo value for record 2');
|
||||
form.destroy();
|
||||
@@ -2973,7 +2982,7 @@ QUnit.module('Views', {
|
||||
viewOptions: {
|
||||
ids: [1],
|
||||
index: 0,
|
||||
hasSidebar: true,
|
||||
hasActionMenus: true,
|
||||
},
|
||||
res_id: 1,
|
||||
mockRPC: function (route, args) {
|
||||
@@ -2982,9 +2991,8 @@ QUnit.module('Views', {
|
||||
}
|
||||
});
|
||||
|
||||
// open sidebar, click on delete and confirm
|
||||
await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
|
||||
await testUtils.dom.click(form.sidebar.$('a:contains(Delete)'));
|
||||
await cpHelpers.toggleActionMenu(form);
|
||||
await cpHelpers.toggleMenuItem(form, "Delete");
|
||||
|
||||
await testUtils.mock.intercept(form, 'history_back', function () {
|
||||
assert.step('history_back');
|
||||
@@ -5209,13 +5217,13 @@ QUnit.module('Views', {
|
||||
device: {size_class: size_class},
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var assertFormContainsNButtonsWithSizeClass = async function (size_class, n) {
|
||||
var form = await createFormWithDeviceSizeClass(size_class);
|
||||
assert.containsN(form, statButtonSelector, n, 'The form has the expected amount of buttons');
|
||||
form.destroy();
|
||||
}
|
||||
};
|
||||
|
||||
await assertFormContainsNButtonsWithSizeClass(0, 2);
|
||||
await assertFormContainsNButtonsWithSizeClass(1, 2);
|
||||
@@ -5510,7 +5518,7 @@ QUnit.module('Views', {
|
||||
print: [],
|
||||
},
|
||||
viewOptions: {
|
||||
hasSidebar: true,
|
||||
hasActionMenus: true,
|
||||
},
|
||||
mockRPC: function (route, args) {
|
||||
if (route === '/web/action/load') {
|
||||
@@ -5524,17 +5532,15 @@ QUnit.module('Views', {
|
||||
},
|
||||
});
|
||||
|
||||
var $printMenu = form.$('.o_cp_sidebar .o_dropdown:contains(Print)');
|
||||
assert.isNotVisible($printMenu);
|
||||
var $actionMenu = form.$('.o_cp_sidebar .o_dropdown:contains(Action)');
|
||||
assert.isVisible($actionMenu);
|
||||
assert.containsNone(form, '.o_cp_action_menus .o_dropdown:contains(Print)');
|
||||
assert.containsOnce(form, '.o_cp_action_menus .o_dropdown:contains(Action)');
|
||||
|
||||
testUtils.dom.click($actionMenu.find('button')); // open Action menu
|
||||
assert.strictEqual($actionMenu.find('.dropdown-item').length, 3,
|
||||
'there should be 3 actions');
|
||||
var $customAction = $actionMenu.find('.dropdown-item:last');
|
||||
assert.strictEqual($customAction.text().trim(), 'Action partner',
|
||||
await cpHelpers.toggleActionMenu(form);
|
||||
|
||||
assert.containsN(form, '.o_cp_action_menus .dropdown-item', 3, "there should be 3 actions");
|
||||
assert.strictEqual(form.$('.o_cp_action_menus .dropdown-item:last').text().trim(), 'Action partner',
|
||||
"the custom action should have 'Action partner' as name");
|
||||
|
||||
await testUtils.mock.intercept(form, 'do_action', function (event) {
|
||||
var context = event.data.action.context.__contexts[1];
|
||||
assert.strictEqual(context.active_id, 1,
|
||||
@@ -5542,7 +5548,7 @@ QUnit.module('Views', {
|
||||
assert.deepEqual(context.active_ids, [1],
|
||||
"the active_ids should be an array with 1 inside.");
|
||||
});
|
||||
await testUtils.dom.click($customAction);
|
||||
await cpHelpers.toggleMenuItem(form, "Action partner");
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
@@ -5687,14 +5693,16 @@ QUnit.module('Views', {
|
||||
"first tab should be active");
|
||||
|
||||
// click on the pager to switch to the next record
|
||||
await testUtils.dom.click(form.pager.$('.o_pager_next'));
|
||||
await cpHelpers.pagerNext(form);
|
||||
|
||||
assert.strictEqual(form.$('.o_notebook .nav-item:not(.o_invisible_modifier)').length, 1,
|
||||
"only the second tab should be visible");
|
||||
assert.hasClass(form.$('.o_notebook .nav-item:not(.o_invisible_modifier) .nav-link'),'active',
|
||||
"the visible tab should be active");
|
||||
|
||||
// click on the pager to switch back to the previous record
|
||||
await testUtils.dom.click(form.pager.$('.o_pager_previous'));
|
||||
await cpHelpers.pagerPrevious(form);
|
||||
|
||||
assert.strictEqual(form.$('.o_notebook .nav-item:not(.o_invisible_modifier)').length, 2,
|
||||
"both tabs should be visible again");
|
||||
assert.hasClass(form.$('.o_notebook .nav-link:nth(1)'),'active',
|
||||
@@ -6205,24 +6213,22 @@ QUnit.module('Views', {
|
||||
await testUtils.fields.editInput(form.$('input[name="foo"]'), "test");
|
||||
await testUtils.form.clickSave(form);
|
||||
|
||||
assert.containsOnce(form, '.o_form_view .alert > div',"should have a translation alert");
|
||||
assert.containsOnce(form, '.o_form_view .alert > div', "should have a translation alert");
|
||||
|
||||
// click on the pager to switch to the next record
|
||||
await testUtils.dom.click(form.pager.$('.o_pager_next'));
|
||||
assert.strictEqual(form.$('.o_form_view .alert > div').length, 0,
|
||||
"should not have a translation alert");
|
||||
await cpHelpers.pagerNext(form);
|
||||
assert.containsNone(form, '.o_form_view .alert > div', "should not have a translation alert");
|
||||
|
||||
// click on the pager to switch back to the previous record
|
||||
await testUtils.dom.click(form.pager.$('.o_pager_previous'));
|
||||
assert.containsOnce(form, '.o_form_view .alert > div',"should have a translation alert");
|
||||
await cpHelpers.pagerPrevious(form);
|
||||
assert.containsOnce(form, '.o_form_view .alert > div', "should have a translation alert");
|
||||
|
||||
// remove translation alert by click X and check alert even after form reload
|
||||
await testUtils.dom.click(form.$('.o_form_view .alert > .close'));
|
||||
assert.strictEqual(form.$('.o_form_view > .alert > div').length, 0,
|
||||
"should not have a translation alert");
|
||||
assert.containsNone(form, '.o_form_view .alert > div', "should not have a translation alert");
|
||||
|
||||
await form.reload();
|
||||
assert.strictEqual(form.$('.o_form_view .alert > div').length, 0,
|
||||
"should not have a translation alert after reload");
|
||||
assert.containsNone(form, '.o_form_view .alert > div', "should not have a translation alert after reload");
|
||||
|
||||
form.destroy();
|
||||
_t.database.multi_lang = multi_lang;
|
||||
@@ -7017,7 +7023,7 @@ QUnit.module('Views', {
|
||||
'<field name="display_name"/>' +
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
viewOptions: {hasSidebar: true},
|
||||
viewOptions: {hasActionMenus: true},
|
||||
mockRPC: function (route, args) {
|
||||
var result = this._super.apply(this, arguments);
|
||||
if (args.method === 'copy') {
|
||||
@@ -7035,8 +7041,9 @@ QUnit.module('Views', {
|
||||
});
|
||||
|
||||
// duplicate record 1
|
||||
await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
|
||||
await testUtils.dom.click(form.sidebar.$('a:contains(Duplicate)'));
|
||||
await cpHelpers.toggleActionMenu(form);
|
||||
await cpHelpers.toggleMenuItem(form, "Duplicate");
|
||||
|
||||
assert.containsOnce(form, '.o_form_editable',
|
||||
"form should be in edit mode");
|
||||
assert.strictEqual(form.$('.o_field_widget').val(), 'first record (copy)',
|
||||
@@ -7044,8 +7051,8 @@ QUnit.module('Views', {
|
||||
await testUtils.form.clickSave(form); // save duplicated record
|
||||
|
||||
// delete duplicated record
|
||||
await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
|
||||
await testUtils.dom.click(form.sidebar.$('a:contains(Delete)'));
|
||||
await cpHelpers.toggleActionMenu(form);
|
||||
await cpHelpers.toggleMenuItem(form, "Delete");
|
||||
|
||||
assert.strictEqual($('.modal').length, 1, "should have opened a confirm dialog");
|
||||
await testUtils.dom.click($('.modal-footer .btn-primary'));
|
||||
@@ -7320,7 +7327,7 @@ QUnit.module('Views', {
|
||||
'</form>',
|
||||
});
|
||||
|
||||
var onFileLoadedEventName = form.$('.o_form_binary_form').attr('target')
|
||||
var onFileLoadedEventName = form.$('.o_form_binary_form').attr('target');
|
||||
// trigger _onFileLoaded function
|
||||
$(window).trigger(onFileLoadedEventName, [{id: 5}, {id:2}]);
|
||||
|
||||
@@ -7629,7 +7636,7 @@ QUnit.module('Views', {
|
||||
});
|
||||
|
||||
QUnit.test('do not change pager when discarding current record', async function (assert) {
|
||||
assert.expect(2);
|
||||
assert.expect(4);
|
||||
|
||||
var form = await createView({
|
||||
View: FormView,
|
||||
@@ -7645,14 +7652,18 @@ QUnit.module('Views', {
|
||||
res_id: 2,
|
||||
});
|
||||
|
||||
assert.strictEqual(form.pager.$('.o_pager_counter').text().trim(), '2 / 2',
|
||||
assert.strictEqual(cpHelpers.getPagerValue(form), "2",
|
||||
'pager should indicate that we are on second record');
|
||||
assert.strictEqual(cpHelpers.getPagerSize(form), "2",
|
||||
'pager should indicate that we are on second record');
|
||||
|
||||
await testUtils.form.clickEdit(form);
|
||||
await testUtils.form.clickDiscard(form);
|
||||
|
||||
assert.strictEqual(form.pager.$('.o_pager_counter').text().trim(), '2 / 2',
|
||||
'pager should not have changed');
|
||||
assert.strictEqual(cpHelpers.getPagerValue(form), "2",
|
||||
'pager value should not have changed');
|
||||
assert.strictEqual(cpHelpers.getPagerSize(form), "2",
|
||||
'pager limit should not have changed');
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
@@ -7801,13 +7812,13 @@ QUnit.module('Views', {
|
||||
},
|
||||
res_id: 1,
|
||||
viewOptions: {
|
||||
hasSidebar: true,
|
||||
hasActionMenus: true,
|
||||
},
|
||||
});
|
||||
core.bus.on('clear_cache', form, assert.step.bind(assert, 'clear_cache'));
|
||||
|
||||
await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
|
||||
await testUtils.dom.click(form.sidebar.$('a:contains(Delete)'));
|
||||
await cpHelpers.toggleActionMenu(form);
|
||||
await cpHelpers.toggleMenuItem(form, "Delete");
|
||||
await testUtils.dom.click($('.modal-footer .btn-primary'));
|
||||
|
||||
assert.verifySteps(['unlink', 'clear_cache']);
|
||||
@@ -8166,7 +8177,7 @@ QUnit.module('Views', {
|
||||
await testUtils.fields.many2one.clickOpenDropdown('trululu');
|
||||
|
||||
// switch to another record (should ask to discard changes, and reset the domain)
|
||||
await testUtils.dom.click(form.pager.$('.o_pager_next'));
|
||||
await cpHelpers.pagerNext(form);
|
||||
|
||||
// discard changes by clicking on confirm in the dialog
|
||||
await testUtils.dom.click($('.modal .modal-footer .btn-primary:first'));
|
||||
|
||||
@@ -1,24 +1,26 @@
|
||||
odoo.define('web.graph_view_tests', function (require) {
|
||||
"use strict";
|
||||
|
||||
var concurrency = require('web.concurrency');
|
||||
var controlPanelViewParameters = require('web.controlPanelViewParameters');
|
||||
var searchUtils = require('web.searchUtils');
|
||||
var GraphView = require('web.GraphView');
|
||||
var testUtils = require('web.test_utils');
|
||||
|
||||
const cpHelpers = testUtils.controlPanel;
|
||||
var createActionManager = testUtils.createActionManager;
|
||||
var createView = testUtils.createView;
|
||||
var patchDate = testUtils.mock.patchDate;
|
||||
|
||||
var INTERVAL_OPTIONS = controlPanelViewParameters.INTERVAL_OPTIONS.map(o => o.optionId);
|
||||
var TIME_RANGE_OPTIONS = controlPanelViewParameters.TIME_RANGE_OPTIONS.map(o => o.optionId);
|
||||
var COMPARISON_TIME_RANGE_OPTIONS = controlPanelViewParameters.COMPARISON_TIME_RANGE_OPTIONS.map(o => o.optionId);
|
||||
const { INTERVAL_OPTIONS, TIME_RANGE_OPTIONS, COMPARISON_TIME_RANGE_OPTIONS } = searchUtils;
|
||||
|
||||
var INTERVAL_OPTION_IDS = Object.keys(INTERVAL_OPTIONS);
|
||||
var TIME_RANGE_OPTION_IDS = Object.keys(TIME_RANGE_OPTIONS);
|
||||
var COMPARISON_TIME_RANGE_OPTION_IDS = Object.keys(COMPARISON_TIME_RANGE_OPTIONS);
|
||||
|
||||
var f = (a, b) => [].concat(...a.map(d => b.map(e => [].concat(d, e))));
|
||||
var cartesian = (a, b, ...c) => (b ? cartesian(f(a, b), ...c) : a);
|
||||
|
||||
var COMBINATIONS = cartesian(TIME_RANGE_OPTIONS, COMPARISON_TIME_RANGE_OPTIONS);
|
||||
var COMBINATIONS_WITH_DATE = cartesian(TIME_RANGE_OPTIONS, COMPARISON_TIME_RANGE_OPTIONS, INTERVAL_OPTIONS);
|
||||
var COMBINATIONS = cartesian(TIME_RANGE_OPTION_IDS, COMPARISON_TIME_RANGE_OPTION_IDS);
|
||||
var COMBINATIONS_WITH_DATE = cartesian(TIME_RANGE_OPTION_IDS, COMPARISON_TIME_RANGE_OPTION_IDS, INTERVAL_OPTION_IDS);
|
||||
|
||||
QUnit.assert.checkDatasets = function (graph, keys, expectedDatasets) {
|
||||
keys = keys instanceof Array ? keys : [keys];
|
||||
@@ -192,7 +194,7 @@ QUnit.module('Views', {
|
||||
'groupby should not contain id field');
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
});
|
||||
graph.destroy();
|
||||
});
|
||||
@@ -298,9 +300,9 @@ QUnit.module('Views', {
|
||||
return this._super(route, args);
|
||||
},
|
||||
});
|
||||
await cpHelpers.toggleMenu(graph, "Measures");
|
||||
await cpHelpers.toggleMenuItem(graph, "Foo");
|
||||
|
||||
testUtils.dom.click(graph.$buttons.find('.dropdown-toggle:contains(Measures)'));
|
||||
await testUtils.dom.click(graph.$buttons.find('.dropdown-item[data-field="foo"]'));
|
||||
assert.checkLegend(graph, 'Foo');
|
||||
assert.strictEqual(rpcCount, 2, "should have done 2 rpcs (2 readgroups)");
|
||||
|
||||
@@ -330,7 +332,7 @@ QUnit.module('Views', {
|
||||
|
||||
QUnit.test('no content helper (pie chart)', async function (assert) {
|
||||
assert.expect(2);
|
||||
this.data.foo.records = []
|
||||
this.data.foo.records = [];
|
||||
|
||||
var graph = await createView({
|
||||
View: GraphView,
|
||||
@@ -357,14 +359,11 @@ QUnit.module('Views', {
|
||||
model: "foo",
|
||||
data: this.data,
|
||||
context: {
|
||||
timeRangeMenuData: {
|
||||
//Q3 2018
|
||||
timeRange: ['&', ["date", ">=", "2018-07-01"],["date", "<=", "2018-09-30"]],
|
||||
timeRangeDescription: 'This Quarter',
|
||||
//Q4 2018
|
||||
comparisonTimeRange: ['&', ["date", ">=", "2018-10-01"],["date", "<=", "2018-12-31"]],
|
||||
comparisonTimeRangeDescription: 'Previous Period',
|
||||
},
|
||||
time_ranges: {
|
||||
field: 'date',
|
||||
range: 'this_quarter',
|
||||
comparisonRange: 'previous_period',
|
||||
}
|
||||
},
|
||||
arch: '<graph type="pie">' +
|
||||
'<field name="product_id"/>' +
|
||||
@@ -443,8 +442,9 @@ QUnit.module('Views', {
|
||||
}
|
||||
}, "context should be correct");
|
||||
|
||||
testUtils.dom.click(graph.$buttons.find('.dropdown-toggle:contains(Measures)'));
|
||||
await testUtils.dom.click(graph.$buttons.find('.dropdown-item[data-field="foo"]'));
|
||||
await cpHelpers.toggleMenu(graph, "Measures");
|
||||
await cpHelpers.toggleMenuItem(graph, "Foo");
|
||||
|
||||
assert.deepEqual(graph.getOwnedQueryParams(), {
|
||||
context: {
|
||||
graph_mode: 'bar',
|
||||
@@ -567,7 +567,7 @@ QUnit.module('Views', {
|
||||
assert.hasClass(graph.$buttons.find('button[data-mode="line"]'),'active',
|
||||
'line chart button should be active');
|
||||
// check groupby values ('Undefined' is rejected in line chart) are in labels
|
||||
assert.checkLabels(graph, [['red'], ['black']])
|
||||
assert.checkLabels(graph, [['red'], ['black']]);
|
||||
|
||||
graph.destroy();
|
||||
});
|
||||
@@ -687,10 +687,11 @@ QUnit.module('Views', {
|
||||
additionalMeasures: ['product_id'],
|
||||
},
|
||||
});
|
||||
|
||||
// need to set the measure this way because it cannot be set in the
|
||||
// arch.
|
||||
await testUtils.dom.click(graph.$buttons.find('.dropdown-toggle:contains(Measures)'));
|
||||
await testUtils.dom.click(graph.$buttons.find('.dropdown-item[data-field="product_id"]'));
|
||||
await cpHelpers.toggleMenu(graph, "Measures");
|
||||
await cpHelpers.toggleMenuItem(graph, "Product");
|
||||
|
||||
assert.checkLabels(graph, [['xphone'], ['xpad']]);
|
||||
assert.checkLegend(graph, 'Product');
|
||||
@@ -729,8 +730,10 @@ QUnit.module('Views', {
|
||||
additionalMeasures: ['product_id'],
|
||||
},
|
||||
});
|
||||
assert.ok(graph.measures.product_id,
|
||||
|
||||
assert.ok(graph.measures.find(m => m.fieldName === 'product_id'),
|
||||
"should have product_id as measure");
|
||||
|
||||
graph.destroy();
|
||||
});
|
||||
|
||||
@@ -766,9 +769,10 @@ QUnit.module('Views', {
|
||||
'</graph>',
|
||||
});
|
||||
|
||||
assert.strictEqual(graph.$buttons.find('.o_graph_measures_list .dropdown-item:first').data('field'), 'bouh',
|
||||
await cpHelpers.toggleMenu(graph, "Measures");
|
||||
assert.strictEqual(graph.$buttons.find('.o_graph_measures_list .dropdown-item:first').text(), 'bouh',
|
||||
"Bouh should be the first measure");
|
||||
assert.strictEqual(graph.$buttons.find('.o_graph_measures_list .dropdown-item:last').data('field'), '__count__',
|
||||
assert.strictEqual(graph.$buttons.find('.o_graph_measures_list .dropdown-item:last').text(), 'Count',
|
||||
"Count should be the last measure");
|
||||
|
||||
graph.destroy();
|
||||
@@ -788,7 +792,7 @@ QUnit.module('Views', {
|
||||
});
|
||||
|
||||
function _indexOf (label) {
|
||||
return graph.renderer._indexOf(graph.renderer.chart.data.labels, label)
|
||||
return graph.renderer._indexOf(graph.renderer.chart.data.labels, label);
|
||||
}
|
||||
|
||||
assert.strictEqual(_indexOf(['Undefined']), -1);
|
||||
@@ -816,7 +820,7 @@ QUnit.module('Views', {
|
||||
});
|
||||
|
||||
function _indexOf (label) {
|
||||
return graph.renderer._indexOf(graph.renderer.chart.data.labels, label)
|
||||
return graph.renderer._indexOf(graph.renderer.chart.data.labels, label);
|
||||
}
|
||||
|
||||
assert.strictEqual(_indexOf(['Undefined']), -1);
|
||||
@@ -825,7 +829,7 @@ QUnit.module('Views', {
|
||||
assert.ok(_indexOf(['Undefined']) >= 0);
|
||||
|
||||
await testUtils.dom.click(graph.$buttons.find('.o_graph_button[data-mode=pie]'));
|
||||
var labels = graph.renderer.chart.data.labels
|
||||
var labels = graph.renderer.chart.data.labels;
|
||||
assert.ok(labels.filter(label => /Undefined/.test(label.join(''))).length >= 1);
|
||||
|
||||
// Undefined should not appear after switching back to line chart
|
||||
@@ -908,7 +912,7 @@ QUnit.module('Views', {
|
||||
groupBy: ['product_id', 'color_id'],
|
||||
});
|
||||
|
||||
assert.checkLabels(graph, [['xphone'], ['xpad']])
|
||||
assert.checkLabels(graph, [['xphone'], ['xpad']]);
|
||||
assert.checkLegend(graph, ['Undefined', 'red']);
|
||||
assert.checkDatasets(graph, ['label', 'data'], [
|
||||
{
|
||||
@@ -922,7 +926,7 @@ QUnit.module('Views', {
|
||||
]);
|
||||
|
||||
await testUtils.dom.click(graph.$('.o_graph_button[data-mode=line]'));
|
||||
assert.checkLabels(graph, [['xphone'], ['xpad']])
|
||||
assert.checkLabels(graph, [['xphone'], ['xpad']]);
|
||||
assert.checkLegend(graph, ['Undefined', 'red']);
|
||||
assert.checkDatasets(graph, ['label', 'data'], [
|
||||
{
|
||||
@@ -936,7 +940,7 @@ QUnit.module('Views', {
|
||||
]);
|
||||
|
||||
await testUtils.dom.click(graph.$('.o_graph_button[data-mode=pie]'));
|
||||
assert.checkLabels(graph, [['xphone', 'Undefined'], ['xphone', 'red'], ['xpad', 'Undefined']])
|
||||
assert.checkLabels(graph, [['xphone', 'Undefined'], ['xphone', 'red'], ['xpad', 'Undefined']]);
|
||||
assert.checkLegend(graph, ['xphone/Undefined', 'xphone/red', 'xpad/Undefined']);
|
||||
assert.checkDatasets(graph, ['label', 'data'], {
|
||||
label: '',
|
||||
@@ -1015,7 +1019,7 @@ QUnit.module('Views', {
|
||||
if (exhaustiveTest) {
|
||||
i++;
|
||||
} else {
|
||||
i += Math.floor(1 + Math.random() * 20)
|
||||
i += Math.floor(1 + Math.random() * 20);
|
||||
}
|
||||
yield combination;
|
||||
}
|
||||
@@ -1033,7 +1037,7 @@ QUnit.module('Views', {
|
||||
self.combinationsToCheck[combination].errorMessage
|
||||
);
|
||||
} else {
|
||||
assert.checkLabels(graph, self.combinationsToCheck[combination].labels)
|
||||
assert.checkLabels(graph, self.combinationsToCheck[combination].labels);
|
||||
assert.checkLegend(graph, self.combinationsToCheck[combination].legend);
|
||||
assert.checkDatasets(graph, ['label', 'data'], self.combinationsToCheck[combination].datasets);
|
||||
}
|
||||
@@ -1041,76 +1045,62 @@ QUnit.module('Views', {
|
||||
}
|
||||
};
|
||||
|
||||
const GROUPBY_NAMES = ['Date', 'Bar', 'Product', 'Color'];
|
||||
|
||||
// time range menu is assumed to be closed
|
||||
this.selectTimeRanges = async function (timeRangeOption, comparisonTimeRangeOption) {
|
||||
comparisonTimeRangeOption = comparisonTimeRangeOption || 'previous_period';
|
||||
// open time range menu
|
||||
await testUtils.dom.click($('.o_control_panel .o_time_range_menu_button'));
|
||||
// select range
|
||||
await testUtils.fields.editInput($('.o_control_panel .o_time_range_selector'), timeRangeOption);
|
||||
// check checkbox 'Compare To'
|
||||
if (!$('.o_control_panel .o_time_range_menu .o_comparison_checkbox').prop('checked')) {
|
||||
await testUtils.dom.click($('.o_control_panel .o_time_range_menu .o_comparison_checkbox'));
|
||||
await cpHelpers.toggleTimeRangeMenu(document);
|
||||
await cpHelpers.selectRange(document, timeRangeOption);
|
||||
if (!document.querySelector('div.o_time_range_section input').checked) {
|
||||
await cpHelpers.toggleTimeRangeMenuBox(document);
|
||||
}
|
||||
// select 'Previous period' or 'Previous year' acording to comparisonTimeRangeOption
|
||||
await testUtils.fields.editInput($('.o_control_panel .o_comparison_time_range_selector'), comparisonTimeRangeOption);
|
||||
// Click on 'Apply' button
|
||||
await testUtils.dom.click($('.o_control_panel .o_time_range_menu .o_apply_range'));
|
||||
await cpHelpers.selectComparisonRange(document, comparisonTimeRangeOption);
|
||||
await cpHelpers.applyTimeRange(document);
|
||||
await cpHelpers.toggleTimeRangeMenu(document);
|
||||
};
|
||||
|
||||
// groupby menu is assumed to be closed
|
||||
this.selectDateIntervalOption = async function (intervalOption) {
|
||||
const self = this;
|
||||
intervalOption = intervalOption || 'month';
|
||||
const optionIndex = INTERVAL_OPTION_IDS.indexOf(intervalOption);
|
||||
|
||||
// open group by menu
|
||||
await testUtils.dom.click($('.o_control_panel .o_dropdown span.fa-bars'));
|
||||
|
||||
await cpHelpers.toggleGroupByMenu(document);
|
||||
let wasSelected = false;
|
||||
if (this.keepFirst) {
|
||||
if ($('.o_control_panel .o_group_by_menu .o_menu_item:contains(Product) a').hasClass('selected')) {
|
||||
if (cpHelpers.isItemSelected(document, 2)) {
|
||||
wasSelected = true;
|
||||
await testUtils.dom.click($('.o_control_panel .o_group_by_menu .o_menu_item:contains(Product)'));
|
||||
await cpHelpers.toggleMenuItem(document, 2);
|
||||
}
|
||||
}
|
||||
|
||||
// open option submenu
|
||||
await testUtils.dom.click($('.o_control_panel .o_group_by_menu .o_menu_item:contains("Date")'));
|
||||
// check interval option if not already selected
|
||||
if (!$('.o_control_panel .o_group_by_menu .o_item_option[data-option_id="' + intervalOption + '"] a').hasClass('selected')) {
|
||||
await testUtils.dom.click($('.o_control_panel .o_group_by_menu .o_item_option[data-option_id="' + intervalOption + '"]'));
|
||||
await cpHelpers.toggleMenuItem(document, 0);
|
||||
if (!cpHelpers.isOptionSelected(document, 0, optionIndex)) {
|
||||
await cpHelpers.toggleMenuItemOption(document, 0, optionIndex);
|
||||
}
|
||||
await INTERVAL_OPTIONS.filter(oId => oId !== intervalOption).forEach(async function(oId) {
|
||||
if ($('.o_control_panel .o_group_by_menu .o_item_option[data-option_id="' + oId + '"] a').hasClass('selected')) {
|
||||
await testUtils.dom.click($('.o_control_panel .o_group_by_menu .o_item_option[data-option_id="' + oId + '"]'));
|
||||
for (let i = 0; i < INTERVAL_OPTION_IDS.length; i++) {
|
||||
const oId = INTERVAL_OPTION_IDS[i];
|
||||
if (oId !== intervalOption && cpHelpers.isOptionSelected(document, 0, i)) {
|
||||
await cpHelpers.toggleMenuItemOption(document, 0, i);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (this.keepFirst) {
|
||||
if (wasSelected && !$('.o_control_panel .o_group_by_menu .o_menu_item:contains(Product) a').hasClass('selected')) {
|
||||
await testUtils.dom.click($('.o_control_panel .o_group_by_menu .o_menu_item:contains(Product)'));
|
||||
if (wasSelected && !cpHelpers.isItemSelected(document, 2)) {
|
||||
await cpHelpers.toggleMenuItem(document, 2);
|
||||
}
|
||||
}
|
||||
await cpHelpers.toggleGroupByMenu(document);
|
||||
|
||||
// close group by menu
|
||||
await testUtils.dom.click($('.o_control_panel .o_dropdown span.fa-bars'));
|
||||
};
|
||||
|
||||
// groupby menu is assumed to be closed
|
||||
this.selectGroupBy = async function (groupByName) {
|
||||
// open group by menu
|
||||
await testUtils.dom.click($('.o_control_panel .o_dropdown span.fa-bars'));
|
||||
// check groupBy if not already selected
|
||||
if (!$('.o_control_panel .o_group_by_menu .o_menu_item:contains(' + groupByName + ') a').hasClass('selected')) {
|
||||
await testUtils.dom.click($('.o_control_panel .o_group_by_menu .o_menu_item:contains(' + groupByName + ')'));
|
||||
await cpHelpers.toggleGroupByMenu(document);
|
||||
const index = GROUPBY_NAMES.indexOf(groupByName);
|
||||
if (!cpHelpers.isItemSelected(document, index)) {
|
||||
await cpHelpers.toggleMenuItem(document, index);
|
||||
}
|
||||
// close group by menu
|
||||
await testUtils.dom.click($('.o_control_panel .o_dropdown span.fa-bars'));
|
||||
};
|
||||
// groupby menu is assumed to be closed
|
||||
this.unselectGroupBy = async function (groupByName) {
|
||||
// check groupBy if already selected
|
||||
|
||||
await cpHelpers.toggleGroupByMenu(document);
|
||||
};
|
||||
|
||||
this.setConfig = async function (combination) {
|
||||
@@ -1121,7 +1111,7 @@ QUnit.module('Views', {
|
||||
};
|
||||
|
||||
this.setMode = async function (mode) {
|
||||
await testUtils.dom.click($('.o_control_panel .o_graph_button[data-mode=' + mode + ']'));
|
||||
await testUtils.dom.click($(`.o_control_panel .o_graph_button[data-mode="${mode}"]`));
|
||||
};
|
||||
|
||||
// // create an action manager to test the interactions with the search view
|
||||
@@ -1148,7 +1138,7 @@ QUnit.module('Views', {
|
||||
graph: {
|
||||
additionalMeasures: ['product_id'],
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
afterEach: function () {
|
||||
|
||||
@@ -14,6 +14,7 @@ var widgetRegistry = require('web.widget_registry');
|
||||
|
||||
var makeTestPromise = testUtils.makeTestPromise;
|
||||
var nextTick = testUtils.nextTick;
|
||||
const cpHelpers = testUtils.controlPanel;
|
||||
var createView = testUtils.createView;
|
||||
|
||||
QUnit.module('Views', {
|
||||
@@ -345,10 +346,9 @@ QUnit.module('Views', {
|
||||
'</t></templates></kanban>',
|
||||
groupBy: ['bar'],
|
||||
});
|
||||
await kanban.renderPager();
|
||||
|
||||
assert.isNotVisible(kanban.pager.$el,
|
||||
"pager should be hidden in grouped kanban");
|
||||
assert.containsNone(kanban, '.o_pager');
|
||||
|
||||
kanban.destroy();
|
||||
});
|
||||
|
||||
@@ -369,9 +369,8 @@ QUnit.module('Views', {
|
||||
},
|
||||
});
|
||||
|
||||
assert.isVisible(kanban.pager.$el,
|
||||
"pager should be visible in ungrouped kanban");
|
||||
assert.strictEqual(kanban.pager.state.size, 4, "pager's size should be 4");
|
||||
assert.containsOnce(kanban, '.o_pager');
|
||||
assert.strictEqual(cpHelpers.getPagerSize(kanban), "4", "pager's size should be 4");
|
||||
kanban.destroy();
|
||||
});
|
||||
|
||||
@@ -395,8 +394,8 @@ QUnit.module('Views', {
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(kanban.pager.state.limit, 2, "pager's limit should be 2");
|
||||
assert.strictEqual(kanban.pager.state.size, 4, "pager's size should be 4");
|
||||
assert.strictEqual(cpHelpers.getPagerValue(kanban), "1-2", "pager's limit should be 2");
|
||||
assert.strictEqual(cpHelpers.getPagerSize(kanban), "4", "pager's size should be 4");
|
||||
kanban.destroy();
|
||||
});
|
||||
|
||||
@@ -421,8 +420,8 @@ QUnit.module('Views', {
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(kanban.pager.state.limit, 3, "pager's limit should be 3");
|
||||
assert.strictEqual(kanban.pager.state.size, 4, "pager's size should be 4");
|
||||
assert.strictEqual(cpHelpers.getPagerValue(kanban), "1-3", "pager's limit should be 3");
|
||||
assert.strictEqual(cpHelpers.getPagerSize(kanban), "4", "pager's size should be 4");
|
||||
kanban.destroy();
|
||||
});
|
||||
|
||||
@@ -577,7 +576,7 @@ QUnit.module('Views', {
|
||||
},
|
||||
});
|
||||
|
||||
assert.containsOnce(kanban, '.o_cp_controller', 'should have one control panel');
|
||||
assert.containsOnce(kanban, '.o_control_panel', 'should have one control panel');
|
||||
assert.containsOnce(kanban, '.o_kanban_group:first .o_kanban_record',
|
||||
"first column should contain one record");
|
||||
|
||||
@@ -589,7 +588,7 @@ QUnit.module('Views', {
|
||||
"should have a quick create element in the first column");
|
||||
assert.strictEqual($quickCreate.find('.o_form_view.o_xxs_form_view').length, 1,
|
||||
"should have rendered an XXS form view");
|
||||
assert.containsOnce(kanban, '.o_cp_controller', 'should not have instantiated an extra control panel');
|
||||
assert.containsOnce(kanban, '.o_control_panel', 'should not have instantiated an extra control panel');
|
||||
assert.strictEqual($quickCreate.find('input').length, 2,
|
||||
"should have two inputs");
|
||||
assert.strictEqual($quickCreate.find('.o_field_widget').length, 3,
|
||||
@@ -1160,7 +1159,7 @@ QUnit.module('Views', {
|
||||
assert.step('onchange');
|
||||
if (shouldDelayOnchange) {
|
||||
return Promise.resolve(prom).then(function () {
|
||||
return result
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1255,7 +1254,7 @@ QUnit.module('Views', {
|
||||
assert.step('onchange');
|
||||
if (shouldDelayOnchange) {
|
||||
return Promise.resolve(prom).then(function () {
|
||||
return result
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -4836,7 +4835,7 @@ QUnit.module('Views', {
|
||||
'</t></templates>' +
|
||||
'</kanban>',
|
||||
mockRPC: function (route, args) {
|
||||
assert.step(route)
|
||||
assert.step(route);
|
||||
return this._super(route, args);
|
||||
},
|
||||
});
|
||||
@@ -4971,12 +4970,12 @@ QUnit.module('Views', {
|
||||
mockRPC: function (route, args) {
|
||||
if (route === '/web/dataset/call_kw/partner/action_archive') {
|
||||
var partnerIDS = args.args[0];
|
||||
var records = this.data.partner.records
|
||||
var records = this.data.partner.records;
|
||||
_.each(partnerIDS, function(partnerID) {
|
||||
_.find(records, function (record) {
|
||||
return record.id === partnerID;
|
||||
}).active = false;
|
||||
})
|
||||
});
|
||||
this.data.partner.records[0].active;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@@ -15,11 +15,12 @@ var testUtils = require('web.test_utils');
|
||||
var widgetRegistry = require('web.widget_registry');
|
||||
var Widget = require('web.Widget');
|
||||
|
||||
|
||||
var _t = core._t;
|
||||
const cpHelpers = testUtils.controlPanel;
|
||||
var createActionManager = testUtils.createActionManager;
|
||||
var createView = testUtils.createView;
|
||||
|
||||
|
||||
QUnit.module('Views', {
|
||||
beforeEach: function () {
|
||||
this.data = {
|
||||
@@ -178,20 +179,26 @@ QUnit.module('Views', {
|
||||
QUnit.test('list with delete="0"', async function (assert) {
|
||||
assert.expect(4);
|
||||
|
||||
var list = await createView({
|
||||
const list = await createView({
|
||||
View: ListView,
|
||||
model: 'foo',
|
||||
data: this.data,
|
||||
viewOptions: {hasSidebar: true},
|
||||
viewOptions: {hasActionMenus: true},
|
||||
arch: '<tree delete="0"><field name="foo"/></tree>',
|
||||
});
|
||||
|
||||
assert.isNotVisible(list.sidebar.$el, 'sidebar should be invisible');
|
||||
|
||||
assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus');
|
||||
assert.ok(list.$('tbody td.o_list_record_selector').length, 'should have at least one record');
|
||||
|
||||
await testUtils.dom.click(list.$('tbody td.o_list_record_selector:first input'));
|
||||
assert.isVisible(list.sidebar.$el, 'sidebar should be visible');
|
||||
assert.notOk(list.sidebar.$('a:contains(Delete)').length, 'sidebar should not have Delete button');
|
||||
assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
|
||||
await cpHelpers.toggleActionMenu(list);
|
||||
assert.deepEqual(
|
||||
cpHelpers.getMenuItemTexts(list),
|
||||
['Export'],
|
||||
'action menu should not have Delete button'
|
||||
);
|
||||
|
||||
list.destroy();
|
||||
});
|
||||
@@ -203,7 +210,7 @@ QUnit.module('Views', {
|
||||
View: ListView,
|
||||
model: 'foo',
|
||||
data: this.data,
|
||||
viewOptions: {hasSidebar: true},
|
||||
viewOptions: {hasActionMenus: true},
|
||||
arch: '<tree editable="top" edit="0"><field name="foo"/></tree>',
|
||||
});
|
||||
|
||||
@@ -762,33 +769,31 @@ QUnit.module('Views', {
|
||||
}
|
||||
return this._super.apply(this,arguments);
|
||||
},
|
||||
intercepts: {
|
||||
load_filters: function (event) {
|
||||
return Promise.resolve([
|
||||
{
|
||||
context: "{}",
|
||||
domain: "[]",
|
||||
id: 7,
|
||||
is_default: true,
|
||||
name: "My favorite",
|
||||
sort: "[\"date asc\", \"foo desc\"]",
|
||||
user_id: [2, "Mitchell Admin"],
|
||||
}, {
|
||||
context: "{}",
|
||||
domain: "[]",
|
||||
id: 8,
|
||||
is_default: false,
|
||||
name: "My second favorite",
|
||||
sort: "[\"date desc\", \"foo asc\"]",
|
||||
user_id: [2, "Mitchell Admin"],
|
||||
}
|
||||
]).then(event.data.on_success);
|
||||
},
|
||||
},
|
||||
favoriteFilters : [
|
||||
{
|
||||
context: "{}",
|
||||
domain: "[]",
|
||||
id: 7,
|
||||
is_default: true,
|
||||
name: "My favorite",
|
||||
sort: "[\"date asc\", \"foo desc\"]",
|
||||
user_id: [2, "Mitchell Admin"],
|
||||
}, {
|
||||
context: "{}",
|
||||
domain: "[]",
|
||||
id: 8,
|
||||
is_default: false,
|
||||
name: "My second favorite",
|
||||
sort: "[\"date desc\", \"foo asc\"]",
|
||||
user_id: [2, "Mitchell Admin"],
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
await testUtils.dom.click(list.$('.o_control_panel .o_search_options button.o_favorites_menu_button'));
|
||||
await testUtils.dom.click(list.$('.o_control_panel .o_search_options .o_favorites_menu .o_menu_item').eq(1));
|
||||
|
||||
await cpHelpers.toggleFavoriteMenu(list);
|
||||
await cpHelpers.toggleMenuItem(list, "My second favorite");
|
||||
|
||||
list.destroy();
|
||||
});
|
||||
|
||||
@@ -843,9 +848,10 @@ QUnit.module('Views', {
|
||||
assert.ok("list view should trigger 'open_record' event");
|
||||
});
|
||||
|
||||
testUtils.dom.click(list.$('tr td:not(.o_list_record_selector)').first());
|
||||
await testUtils.dom.click(list.$('tr td:not(.o_list_record_selector)').first());
|
||||
list.update({groupBy: ['foo']});
|
||||
await testUtils.nextTick();
|
||||
|
||||
assert.containsN(list, 'tr.o_group_header', 3, "list should be grouped");
|
||||
await testUtils.dom.click(list.$('th.o_group_name').first());
|
||||
|
||||
@@ -1007,11 +1013,13 @@ QUnit.module('Views', {
|
||||
domain: [['foo', '=', 'yop']],
|
||||
});
|
||||
|
||||
|
||||
assert.containsN(list, 'tbody tr', 4,
|
||||
"list should contain 4 rows");
|
||||
assert.containsOnce(list, '.o_data_row',
|
||||
"list should contain one record (and thus 3 empty rows)");
|
||||
assert.strictEqual(list.pager.$('.o_pager_value').text(), '1-1',
|
||||
|
||||
assert.strictEqual(cpHelpers.getPagerValue(list), '1-1',
|
||||
"pager should be correct");
|
||||
|
||||
await testUtils.dom.click(list.$buttons.find('.o_list_button_add'));
|
||||
@@ -1020,7 +1028,7 @@ QUnit.module('Views', {
|
||||
"list should still contain 4 rows");
|
||||
assert.containsN(list, '.o_data_row', 2,
|
||||
"list should contain two record (and thus 2 empty rows)");
|
||||
assert.strictEqual(list.pager.$('.o_pager_value').text(), '1-2',
|
||||
assert.strictEqual(cpHelpers.getPagerValue(list), '1-2',
|
||||
"pager should be correct");
|
||||
|
||||
await testUtils.dom.click(list.$buttons.find('.o_list_button_discard'));
|
||||
@@ -1029,7 +1037,7 @@ QUnit.module('Views', {
|
||||
"list should still contain 4 rows");
|
||||
assert.containsOnce(list, '.o_data_row',
|
||||
"list should contain one record (and thus 3 empty rows)");
|
||||
assert.strictEqual(list.pager.$('.o_pager_value').text(), '1-1',
|
||||
assert.strictEqual(cpHelpers.getPagerValue(list), '1-1',
|
||||
"pager should be correct");
|
||||
assert.verifySteps(['destroy'],
|
||||
"should have destroyed the widget of the removed line");
|
||||
@@ -1285,32 +1293,32 @@ QUnit.module('Views', {
|
||||
model: 'foo',
|
||||
data: this.data,
|
||||
groupBy: ['foo'],
|
||||
viewOptions: {hasSidebar: true},
|
||||
viewOptions: {hasActionMenus: true},
|
||||
arch: '<tree>' +
|
||||
'<field name="foo"/>' +
|
||||
'<field name="int_field" sum="Sum"/>' +
|
||||
'</tree>',
|
||||
});
|
||||
|
||||
assert.isNotVisible(list.sidebar);
|
||||
assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus');
|
||||
|
||||
// open blip grouping and check all lines
|
||||
await testUtils.dom.click(list.$('.o_group_header:contains("blip (2)")'));
|
||||
await testUtils.dom.click(list.$('.o_data_row:first input'));
|
||||
assert.isVisible(list.sidebar);
|
||||
assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
|
||||
|
||||
// open yop grouping and verify blip are still checked
|
||||
await testUtils.dom.click(list.$('.o_group_header:contains("yop (1)")'));
|
||||
assert.containsOnce(list, '.o_data_row input:checked',
|
||||
"opening a grouping does not uncheck others");
|
||||
assert.isVisible(list.sidebar);
|
||||
assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
|
||||
|
||||
// close and open blip grouping and verify blip are unchecked
|
||||
await testUtils.dom.click(list.$('.o_group_header:contains("blip (2)")'));
|
||||
await testUtils.dom.click(list.$('.o_group_header:contains("blip (2)")'));
|
||||
assert.containsNone(list, '.o_data_row input:checked',
|
||||
"opening and closing a grouping uncheck its elements");
|
||||
assert.isNotVisible(list.sidebar);
|
||||
assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus');
|
||||
|
||||
list.destroy();
|
||||
});
|
||||
@@ -1599,10 +1607,9 @@ QUnit.module('Views', {
|
||||
limit: 2,
|
||||
},
|
||||
});
|
||||
|
||||
var widthPage1 = list.$(`th[data-name=foo]`)[0].offsetWidth;
|
||||
|
||||
await testUtils.dom.click(list.$('.o_pager_next'));
|
||||
await cpHelpers.pagerNext(list);
|
||||
|
||||
var widthPage2 = list.$(`th[data-name=foo]`)[0].offsetWidth;
|
||||
assert.ok(widthPage1 > widthPage2,
|
||||
@@ -2477,19 +2484,20 @@ QUnit.module('Views', {
|
||||
View: ListView,
|
||||
model: 'foo',
|
||||
data: this.data,
|
||||
viewOptions: {hasSidebar: true},
|
||||
viewOptions: {hasActionMenus: true},
|
||||
arch: '<tree><field name="foo"/></tree>',
|
||||
});
|
||||
|
||||
assert.isNotVisible(list.sidebar.$el, 'sidebar should be invisible');
|
||||
|
||||
assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus');
|
||||
assert.containsN(list, 'tbody td.o_list_record_selector', 4, "should have 4 records");
|
||||
|
||||
await testUtils.dom.click(list.$('tbody td.o_list_record_selector:first input'));
|
||||
|
||||
assert.isVisible(list.sidebar.$el, 'sidebar should be visible');
|
||||
assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
|
||||
|
||||
await testUtils.dom.click(list.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
|
||||
await testUtils.dom.click(list.sidebar.$('a:contains(Delete)'));
|
||||
await cpHelpers.toggleActionMenu(list);
|
||||
await cpHelpers.toggleMenuItem(list, "Delete");
|
||||
assert.hasClass($('body'),'modal-open', 'body should have modal-open clsss');
|
||||
|
||||
await testUtils.dom.click($('body .modal button span:contains(Ok)'));
|
||||
@@ -2508,7 +2516,7 @@ QUnit.module('Views', {
|
||||
View: ListView,
|
||||
model: 'foo',
|
||||
data: this.data,
|
||||
viewOptions: {hasSidebar: true},
|
||||
viewOptions: {hasActionMenus: true},
|
||||
arch: '<tree><field name="foo"/></tree>',
|
||||
mockRPC: function (route) {
|
||||
assert.step(route);
|
||||
@@ -2520,22 +2528,23 @@ QUnit.module('Views', {
|
||||
},
|
||||
});
|
||||
|
||||
assert.isNotVisible(list.sidebar.$el, 'sidebar should be invisible');
|
||||
|
||||
assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus');
|
||||
assert.containsN(list, 'tbody td.o_list_record_selector', 4, "should have 4 records");
|
||||
|
||||
await testUtils.dom.click(list.$('tbody td.o_list_record_selector:first input'));
|
||||
|
||||
assert.isVisible(list.sidebar.$el, 'sidebar should be visible');
|
||||
assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
|
||||
|
||||
assert.verifySteps(['/web/dataset/search_read']);
|
||||
await testUtils.dom.click(list.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
|
||||
await testUtils.dom.click(list.sidebar.$('a:contains(Archive)'));
|
||||
await cpHelpers.toggleActionMenu(list);
|
||||
await cpHelpers.toggleMenuItem(list, "Archive");
|
||||
assert.strictEqual($('.modal').length, 1, 'a confirm modal should be displayed');
|
||||
await testUtils.dom.click($('.modal-footer .btn-secondary'));
|
||||
assert.containsN(list, 'tbody td.o_list_record_selector', 4, "still should have 4 records");
|
||||
|
||||
await testUtils.dom.click(list.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
|
||||
await testUtils.dom.click(list.sidebar.$('a:contains(Archive)'));
|
||||
await cpHelpers.toggleActionMenu(list);
|
||||
await cpHelpers.toggleMenuItem(list, "Archive");
|
||||
assert.strictEqual($('.modal').length, 1, 'a confirm modal should be displayed');
|
||||
await testUtils.dom.click($('.modal-footer .btn-primary'));
|
||||
assert.containsN(list, 'tbody td.o_list_record_selector', 3, "should have 3 records");
|
||||
@@ -2559,10 +2568,10 @@ QUnit.module('Views', {
|
||||
},
|
||||
});
|
||||
|
||||
assert.isVisible(list.pager.$el, "pager should be visible");
|
||||
assert.strictEqual(list.pager.state.size, 4, "pager's size should be 4");
|
||||
assert.containsOnce(list.el, 'div.o_control_panel .o_cp_pager');
|
||||
assert.strictEqual(cpHelpers.getPagerSize(list), "4", "pager's size should be 4");
|
||||
await list.update({ groupBy: ['bar']});
|
||||
assert.strictEqual(list.pager.state.size, 2, "pager's size should be 2");
|
||||
assert.strictEqual(cpHelpers.getPagerSize(list), "2", "pager's size should be 2");
|
||||
list.destroy();
|
||||
});
|
||||
|
||||
@@ -2803,8 +2812,7 @@ QUnit.module('Views', {
|
||||
res_id: 1,
|
||||
});
|
||||
|
||||
// Change page
|
||||
await testUtils.dom.click(form.$('.o_field_widget[name=o2m] .o_pager_next'));
|
||||
await cpHelpers.pagerNext('.o_field_widget[name=o2m]');
|
||||
assert.strictEqual(form.$('tbody tr:first').text(), 'Value 44',
|
||||
"record 44 should be first");
|
||||
assert.strictEqual(form.$('tbody tr:eq(4)').text(), 'Value 48',
|
||||
@@ -3819,23 +3827,23 @@ QUnit.module('Views', {
|
||||
limit: 3,
|
||||
},
|
||||
});
|
||||
|
||||
var headerHeight = list.$('.o_group_header').css('height');
|
||||
|
||||
// basic rendering checks
|
||||
await testUtils.dom.click(list.$('.o_group_header'));
|
||||
assert.strictEqual(list.$('.o_group_header').css('height'), headerHeight,
|
||||
"height of group header shouldn't have changed");
|
||||
assert.hasClass(list.$('.o_group_header th:eq(1) > div'), 'o_pager',
|
||||
assert.hasClass(list.$('.o_group_header th:eq(1) > nav'), 'o_pager',
|
||||
"last cell of open group header should have classname 'o_pager'");
|
||||
assert.strictEqual(list.$('.o_group_header .o_pager_value').text(), '1-3',
|
||||
|
||||
assert.strictEqual(cpHelpers.getPagerValue('.o_group_header'), '1-3',
|
||||
"pager's value should be correct");
|
||||
assert.containsN(list, '.o_data_row', 3,
|
||||
"open group should display 3 records");
|
||||
|
||||
// go to next page
|
||||
await testUtils.dom.click(list.$('.o_group_header .o_pager_next'));
|
||||
assert.strictEqual(list.$('.o_group_header .o_pager_value').text(), '4-4',
|
||||
await cpHelpers.pagerNext('.o_group_header');
|
||||
assert.strictEqual(cpHelpers.getPagerValue('.o_group_header'), '4-4',
|
||||
"pager's value should be correct");
|
||||
assert.containsOnce(list, '.o_data_row',
|
||||
"open group should display 1 record");
|
||||
@@ -4109,14 +4117,14 @@ QUnit.module('Views', {
|
||||
"3rd row should be selected");
|
||||
|
||||
// press enter in input
|
||||
await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input'), 'enter');
|
||||
await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input[name="foo"]'), 'enter');
|
||||
assert.hasClass(list.$('tr.o_data_row:eq(3)'),'o_selected_row',
|
||||
"4rd row should be selected");
|
||||
assert.doesNotHaveClass(list.$('tr.o_data_row:eq(2)'), 'o_selected_row',
|
||||
"3rd row should no longer be selected");
|
||||
|
||||
// press enter on last row
|
||||
await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input'), 'enter');
|
||||
await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input[name="foo"]'), 'enter');
|
||||
assert.containsN(list, 'tr.o_data_row', 5, "should have created a 5th row");
|
||||
|
||||
assert.verifySteps(['/web/dataset/search_read', '/web/dataset/call_kw/foo/default_get']);
|
||||
@@ -4220,7 +4228,7 @@ QUnit.module('Views', {
|
||||
});
|
||||
|
||||
QUnit.test('display toolbar', async function (assert) {
|
||||
assert.expect(6);
|
||||
assert.expect(2);
|
||||
|
||||
var list = await createView({
|
||||
View: ListView,
|
||||
@@ -4237,31 +4245,22 @@ QUnit.module('Views', {
|
||||
print: [],
|
||||
},
|
||||
viewOptions: {
|
||||
hasSidebar: true,
|
||||
hasActionMenus: true,
|
||||
},
|
||||
});
|
||||
|
||||
var $printMenu = list.$('.o_cp_sidebar .o_dropdown:contains(Print)');
|
||||
assert.isNotVisible($printMenu);
|
||||
var $actionMenu = list.$('.o_cp_sidebar .o_dropdown:contains(Action)');
|
||||
assert.isNotVisible($actionMenu);
|
||||
|
||||
testUtils.dom.click(list.$('.o_list_record_selector:first input'));
|
||||
assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus');
|
||||
|
||||
assert.isNotVisible($printMenu);
|
||||
assert.isVisible($actionMenu);
|
||||
await testUtils.dom.click(list.$('.o_list_record_selector:first input'));
|
||||
|
||||
testUtils.dom.click($actionMenu.find('button')); // open Action menu
|
||||
assert.strictEqual($actionMenu.find('.dropdown-item').length, 3,
|
||||
"there should be 3 actions");
|
||||
var $customAction = $actionMenu.find('.dropdown-item:last');
|
||||
assert.strictEqual($customAction.text().trim(), 'Action event',
|
||||
"the custom action should have 'Action event' as name");
|
||||
await cpHelpers.toggleActionMenu(list);
|
||||
assert.deepEqual(cpHelpers.getMenuItemTexts(list), ['Export', 'Delete', 'Action event']);
|
||||
|
||||
list.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('execute a sidebar actions with correct params', async function (assert) {
|
||||
QUnit.test('execute ActionMenus actions with correct params', async function (assert) {
|
||||
assert.expect(12);
|
||||
|
||||
const list = await createView({
|
||||
@@ -4285,39 +4284,40 @@ QUnit.module('Views', {
|
||||
return this._super(...arguments);
|
||||
},
|
||||
viewOptions: {
|
||||
hasSidebar: true,
|
||||
hasActionMenus: true,
|
||||
},
|
||||
});
|
||||
|
||||
let $actionMenu = list.$('.o_cp_sidebar .o_dropdown:contains(Action)');
|
||||
assert.isNotVisible($actionMenu);
|
||||
assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus');
|
||||
|
||||
assert.containsN(list, '.o_data_row', 4);
|
||||
|
||||
// select all records
|
||||
await testUtils.dom.click(list.$('thead .o_list_record_selector input'));
|
||||
assert.containsN(list, '.o_list_record_selector input:checked', 5);
|
||||
|
||||
assert.isVisible($actionMenu);
|
||||
assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
|
||||
|
||||
await testUtils.dom.click($actionMenu.find('button')); // open Action menu
|
||||
await testUtils.dom.click($actionMenu.find('.dropdown-item:contains(Custom Action)'));
|
||||
await cpHelpers.toggleActionMenu(list);
|
||||
await cpHelpers.toggleMenuItem(list, "Custom Action");
|
||||
|
||||
// unselect first record (will unselect the thead checkbox as well)
|
||||
await testUtils.dom.click(list.$('tbody .o_list_record_selector:first input'));
|
||||
assert.containsN(list, '.o_list_record_selector input:checked', 3);
|
||||
await testUtils.dom.click($actionMenu.find('button')); // open Action menu
|
||||
await testUtils.dom.click($actionMenu.find('.dropdown-item:contains(Custom Action)'));
|
||||
await cpHelpers.toggleActionMenu(list);
|
||||
await cpHelpers.toggleMenuItem(list, "Custom Action");
|
||||
|
||||
// add a domain and select first two records
|
||||
await list.reload({ domain: [['bar', '=', true]] });
|
||||
assert.containsN(list, '.o_data_row', 3);
|
||||
assert.containsNone(list, '.o_list_record_selector input:checked');
|
||||
$actionMenu = list.$('.o_cp_sidebar .o_dropdown:contains(Action)');
|
||||
|
||||
await testUtils.dom.click(list.$('tbody .o_list_record_selector:nth(0) input'));
|
||||
await testUtils.dom.click(list.$('tbody .o_list_record_selector:nth(1) input'));
|
||||
assert.containsN(list, '.o_list_record_selector input:checked', 2);
|
||||
await testUtils.dom.click($actionMenu.find('button')); // open Action menu
|
||||
await testUtils.dom.click($actionMenu.find('.dropdown-item:contains(Custom Action)'));
|
||||
|
||||
await cpHelpers.toggleActionMenu(list);
|
||||
await cpHelpers.toggleMenuItem(list, "Custom Action");
|
||||
|
||||
assert.verifySteps([
|
||||
'{"action_id":44,"context":{"active_id":1,"active_ids":[1,2,3,4],"active_model":"foo","select_all":true,"active_domain":[]}}',
|
||||
@@ -4374,13 +4374,13 @@ QUnit.module('Views', {
|
||||
assert.hasClass(list.$('.o_data_row:first'), 'o_selected_row');
|
||||
assert.strictEqual(document.activeElement, list.$('.o_data_row:first .o_data_cell:first input')[0]);
|
||||
|
||||
// Press 'Tab' -> should go to next cell (still in first row)
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
// // Press 'Tab' -> should go to next cell (still in first row)
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input[name="foo"]'), 'tab');
|
||||
assert.hasClass(list.$('.o_data_row:first'), 'o_selected_row');
|
||||
assert.strictEqual(document.activeElement, list.$('.o_data_row:first .o_data_cell:last input')[0]);
|
||||
|
||||
// Press 'Tab' -> should go to next line (first cell)
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
// // Press 'Tab' -> should go to next line (first cell)
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input[name="int_field"]'), 'tab');
|
||||
assert.hasClass(list.$('.o_data_row:nth(1)'), 'o_selected_row');
|
||||
assert.strictEqual(document.activeElement, list.$('.o_data_row:nth(1) .o_data_cell:first input')[0]);
|
||||
|
||||
@@ -4507,13 +4507,13 @@ QUnit.module('Views', {
|
||||
// Press 'Tab' -> should go to next line
|
||||
// add a value in the cell because the Tab on an empty first cell would activate the next widget in the view
|
||||
await testUtils.fields.editInput(list.$('.o_selected_row input').eq(1), 11);
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input[name="display_name"]'), 'tab');
|
||||
assert.hasClass(list.$('.o_data_row:nth(3)'),'o_selected_row',
|
||||
"fourth row should be in edition");
|
||||
|
||||
// Press 'Tab' -> should go back to first line as the create action isn't available
|
||||
await testUtils.fields.editInput(list.$('.o_selected_row input').eq(1), 11);
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input[name="display_name"]'), 'tab');
|
||||
assert.hasClass(list.$('.o_data_row:first'),'o_selected_row',
|
||||
"first row should be in edition");
|
||||
|
||||
@@ -6080,7 +6080,7 @@ QUnit.module('Views', {
|
||||
"the second row should be selected");
|
||||
|
||||
// Keyboard navigation only interracts with selected elements
|
||||
await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input.o_field_widget'), 'enter');
|
||||
await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input.o_field_widget[name="int_field"]'), 'enter');
|
||||
assert.hasClass(list.$('.o_data_row:eq(3)'), 'o_selected_row',
|
||||
"the fourth row should be selected");
|
||||
|
||||
@@ -6493,7 +6493,7 @@ QUnit.module('Views', {
|
||||
});
|
||||
|
||||
QUnit.test('use the limit attribute in arch', async function (assert) {
|
||||
assert.expect(3);
|
||||
assert.expect(4);
|
||||
|
||||
var list = await createView({
|
||||
View: ListView,
|
||||
@@ -6507,8 +6507,9 @@ QUnit.module('Views', {
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(list.pager.$el.text().trim(), '1-2 / 4',
|
||||
"pager should be correct");
|
||||
|
||||
assert.strictEqual(cpHelpers.getPagerValue(list), '1-2');
|
||||
assert.strictEqual(cpHelpers.getPagerSize(list), '4');
|
||||
|
||||
assert.containsN(list, '.o_data_row', 2,
|
||||
'should display 2 data rows');
|
||||
@@ -6641,7 +6642,7 @@ QUnit.module('Views', {
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
viewOptions: {
|
||||
hasSidebar: true,
|
||||
hasActionMenus: true,
|
||||
},
|
||||
});
|
||||
core.bus.on('clear_cache', list, assert.step.bind(assert, 'clear_cache'));
|
||||
@@ -6658,8 +6659,8 @@ QUnit.module('Views', {
|
||||
|
||||
// delete a record
|
||||
await testUtils.dom.click(list.$('.o_data_row:first .o_list_record_selector input'));
|
||||
await testUtils.dom.click(list.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
|
||||
await testUtils.dom.click(list.sidebar.$('a:contains(Delete)'));
|
||||
await cpHelpers.toggleActionMenu(list);
|
||||
await cpHelpers.toggleMenuItem(list, "Delete");
|
||||
await testUtils.dom.click($('.modal-footer .btn-primary'));
|
||||
|
||||
assert.verifySteps([
|
||||
@@ -6696,23 +6697,21 @@ QUnit.module('Views', {
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
// switch pages (should ask to scroll)
|
||||
await testUtils.dom.click(list.pager.$('.o_pager_next'));
|
||||
await testUtils.dom.click(list.pager.$('.o_pager_previous'));
|
||||
await cpHelpers.pagerNext(list);
|
||||
await cpHelpers.pagerPrevious(list);
|
||||
assert.verifySteps(['scroll', 'scroll'],
|
||||
"should ask to scroll when switching pages");
|
||||
|
||||
// change the limit (should not ask to scroll)
|
||||
await testUtils.dom.click(list.pager.$('.o_pager_value'));
|
||||
await testUtils.fields.editAndTrigger(list.pager.$('.o_pager_value input'),
|
||||
'1-2', ['blur']);
|
||||
assert.strictEqual(list.pager.$('.o_pager_value').text(), '1-2',
|
||||
"should have changed the limit");
|
||||
|
||||
await cpHelpers.setPagerValue(list, '1-2');
|
||||
await testUtils.nextTick();
|
||||
assert.strictEqual(cpHelpers.getPagerValue(list), '1-2');
|
||||
assert.verifySteps([], "should not ask to scroll when changing the limit");
|
||||
|
||||
// switch pages again (should still ask to scroll)
|
||||
await testUtils.dom.click(list.pager.$('.o_pager_next'));
|
||||
await cpHelpers.pagerNext(list);
|
||||
|
||||
assert.verifySteps(['scroll'], "this is still working after a limit change");
|
||||
|
||||
@@ -6895,9 +6894,9 @@ QUnit.module('Views', {
|
||||
|
||||
assert.containsN(list, '.o_group_header', 3); // page 1
|
||||
assert.containsNone(list, '.o_data_row');
|
||||
assert.containsOnce(list, '.o_pager_counter'); // has a pager
|
||||
assert.containsOnce(list, '.o_pager'); // has a pager
|
||||
|
||||
await testUtils.dom.click(list.$('.o_pager_next')); // switch to page 2
|
||||
await cpHelpers.pagerNext(list); // switch to page 2
|
||||
|
||||
assert.containsN(list, '.o_group_header', 1); // page 2
|
||||
assert.containsNone(list, '.o_data_row');
|
||||
@@ -6986,9 +6985,9 @@ QUnit.module('Views', {
|
||||
|
||||
assert.containsN(list, '.o_group_header', 10); // page 1
|
||||
assert.containsN(list, '.o_data_row', 11); // one group contains two records
|
||||
assert.containsOnce(list, '.o_pager_counter'); // has a pager
|
||||
assert.containsOnce(list, '.o_pager'); // has a pager
|
||||
|
||||
await testUtils.dom.click(list.$('.o_pager_next')); // switch to page 2
|
||||
await cpHelpers.pagerNext(list); // switch to page 2
|
||||
|
||||
assert.containsN(list, '.o_group_header', 7); // page 2
|
||||
assert.containsN(list, '.o_data_row', 7);
|
||||
@@ -7044,8 +7043,8 @@ QUnit.module('Views', {
|
||||
assert.containsN(actionManager, '.o_group_header', 1); // page 2
|
||||
|
||||
// toggle a filter -> there should be only one group left (on page 1)
|
||||
await testUtils.dom.click(actionManager.$('.o_control_panel .o_search_options .o_filters_menu_button'));
|
||||
await testUtils.dom.click(actionManager.$('.o_control_panel .o_search_options .o_filters_menu .o_menu_item:first'));
|
||||
await cpHelpers.toggleFilterMenu(actionManager);
|
||||
await cpHelpers.toggleMenuItem(actionManager, 0);
|
||||
|
||||
assert.strictEqual(actionManager.$('.o_pager_counter').text().trim(), '1-1 / 1');
|
||||
assert.containsN(actionManager, '.o_group_header', 1); // page 1
|
||||
@@ -7314,19 +7313,19 @@ QUnit.module('Views', {
|
||||
assert.hasClass(list.$('.o_data_row:first'), 'o_selected_row');
|
||||
|
||||
// Press 'Tab' -> should go to next line (still in first group)
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
|
||||
assert.hasClass(list.$('.o_data_row:nth(1)'), 'o_selected_row');
|
||||
|
||||
// Press 'Tab' -> should go to next line (still in first group)
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
|
||||
assert.hasClass(list.$('.o_data_row:nth(2)'), 'o_selected_row');
|
||||
|
||||
// Press 'Tab' -> should go to first line of next group
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
|
||||
assert.hasClass(list.$('.o_data_row:nth(3)'), 'o_selected_row');
|
||||
|
||||
// Press 'Tab' -> should go back to first line of first group
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
|
||||
assert.hasClass(list.$('.o_data_row:first'), 'o_selected_row');
|
||||
|
||||
list.destroy();
|
||||
@@ -7354,19 +7353,19 @@ QUnit.module('Views', {
|
||||
assert.hasClass(list.$('.o_data_row:first'), 'o_selected_row');
|
||||
|
||||
// Press 'Tab' -> should go to next line (still in first group)
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
|
||||
assert.hasClass(list.$('.o_data_row:nth(1)'), 'o_selected_row');
|
||||
|
||||
// Press 'Tab' -> should go to next line (still in first group)
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
|
||||
assert.hasClass(list.$('.o_data_row:nth(2)'), 'o_selected_row');
|
||||
|
||||
// Press 'Tab' -> should go to first line of next group
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
|
||||
assert.hasClass(list.$('.o_data_row:nth(3)'), 'o_selected_row');
|
||||
|
||||
// Press 'Tab' -> should go back to first line of first group
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
|
||||
assert.hasClass(list.$('.o_data_row:first'), 'o_selected_row');
|
||||
|
||||
list.destroy();
|
||||
@@ -7394,19 +7393,19 @@ QUnit.module('Views', {
|
||||
assert.hasClass(list.$('.o_data_row:first'), 'o_selected_row');
|
||||
|
||||
// Press 'Tab' -> should go to next line (still in first group)
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
|
||||
assert.hasClass(list.$('.o_data_row:nth(1)'), 'o_selected_row');
|
||||
|
||||
// Press 'Tab' -> should go to next line (still in first group)
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
|
||||
assert.hasClass(list.$('.o_data_row:nth(2)'), 'o_selected_row');
|
||||
|
||||
// Press 'Tab' -> should go to first line of next group
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
|
||||
assert.hasClass(list.$('.o_data_row:nth(3)'), 'o_selected_row');
|
||||
|
||||
// Press 'Tab' -> should go back to first line of first group
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
|
||||
assert.hasClass(list.$('.o_data_row:first'), 'o_selected_row');
|
||||
|
||||
list.destroy();
|
||||
@@ -7550,20 +7549,20 @@ QUnit.module('Views', {
|
||||
await testUtils.fields.editInput(list.$('.o_selected_row input[name="foo"]'), 'new value');
|
||||
|
||||
// Press 'Tab' -> should create a new record as we edited the previous one
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
|
||||
assert.containsN(list, '.o_data_row', 5);
|
||||
assert.hasClass(list.$('.o_data_row:nth(3)'), 'o_selected_row');
|
||||
|
||||
// fill foo field for the new record and press 'tab' -> should create another record
|
||||
await testUtils.fields.editInput(list.$('.o_selected_row input[name="foo"]'), 'new record');
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
|
||||
|
||||
assert.containsN(list, '.o_data_row', 6);
|
||||
assert.hasClass(list.$('.o_data_row:nth(4)'), 'o_selected_row');
|
||||
|
||||
// leave this new row empty and press tab -> should discard the new record and move to the
|
||||
// next group
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
|
||||
await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
|
||||
assert.containsN(list, '.o_data_row', 5);
|
||||
assert.hasClass(list.$('.o_data_row:nth(4)'), 'o_selected_row');
|
||||
|
||||
@@ -7637,13 +7636,13 @@ QUnit.module('Views', {
|
||||
assert.hasClass(list.$('tr.o_data_row:eq(1)'), 'o_selected_row');
|
||||
|
||||
// press enter in input should move to next record
|
||||
await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input'), 'enter');
|
||||
await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row .o_input'), 'enter');
|
||||
|
||||
assert.hasClass(list.$('tr.o_data_row:eq(2)'), 'o_selected_row');
|
||||
assert.doesNotHaveClass(list.$('tr.o_data_row:eq(1)'), 'o_selected_row');
|
||||
|
||||
// press enter on last row should create a new record
|
||||
await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input'), 'enter');
|
||||
await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row .o_input'), 'enter');
|
||||
|
||||
assert.containsN(list, 'tr.o_data_row', 5);
|
||||
assert.hasClass(list.$('tr.o_data_row:eq(3)'), 'o_selected_row');
|
||||
@@ -7680,13 +7679,13 @@ QUnit.module('Views', {
|
||||
assert.hasClass(list.$('tr.o_data_row:eq(1)'), 'o_selected_row');
|
||||
|
||||
// press enter in input should move to next record
|
||||
await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input'), 'enter');
|
||||
await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row .o_input'), 'enter');
|
||||
|
||||
assert.hasClass(list.$('tr.o_data_row:eq(2)'), 'o_selected_row');
|
||||
assert.doesNotHaveClass(list.$('tr.o_data_row:eq(1)'), 'o_selected_row');
|
||||
|
||||
// press enter on last row should move to first record of next group
|
||||
await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input'), 'enter');
|
||||
await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row .o_input'), 'enter');
|
||||
|
||||
assert.hasClass(list.$('tr.o_data_row:eq(3)'), 'o_selected_row');
|
||||
assert.doesNotHaveClass(list.$('tr.o_data_row:eq(2)'), 'o_selected_row');
|
||||
@@ -7722,13 +7721,13 @@ QUnit.module('Views', {
|
||||
assert.hasClass(list.$('tr.o_data_row:eq(1)'), 'o_selected_row');
|
||||
|
||||
// press enter in input should move to next record
|
||||
await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input'), 'enter');
|
||||
await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row .o_input'), 'enter');
|
||||
|
||||
assert.hasClass(list.$('tr.o_data_row:eq(2)'), 'o_selected_row');
|
||||
assert.doesNotHaveClass(list.$('tr.o_data_row:eq(1)'), 'o_selected_row');
|
||||
|
||||
// press enter on last row should move to first record of next group
|
||||
await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input'), 'enter');
|
||||
await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row .o_input'), 'enter');
|
||||
|
||||
assert.hasClass(list.$('tr.o_data_row:eq(3)'), 'o_selected_row');
|
||||
assert.doesNotHaveClass(list.$('tr.o_data_row:eq(2)'), 'o_selected_row');
|
||||
|
||||
@@ -3,11 +3,11 @@ odoo.define('web.pivot_tests', function (require) {
|
||||
|
||||
var core = require('web.core');
|
||||
var PivotView = require('web.PivotView');
|
||||
var PivotRenderer = require('web.PivotRenderer');
|
||||
var testUtils = require('web.test_utils');
|
||||
var testUtilsDom = require('web.test_utils_dom');
|
||||
|
||||
var _t = core._t;
|
||||
const cpHelpers = testUtils.controlPanel;
|
||||
var createActionManager = testUtils.createActionManager;
|
||||
var createView = testUtils.createView;
|
||||
var patchDate = testUtils.mock.patchDate;
|
||||
@@ -388,10 +388,9 @@ QUnit.module('Views', {
|
||||
|
||||
var unpatchDate = patchDate(2016, 11, 20, 1, 0, 0);
|
||||
var context = {
|
||||
timeRangeMenuData: {
|
||||
timeRange: ["&",["date",">=","2016-12-01"],["date","<","2017-01-01"]],
|
||||
timeRangeDescription: 'This Month',
|
||||
comparisonTimeRange: [],
|
||||
time_ranges: {
|
||||
field: 'date',
|
||||
range: 'this_month'
|
||||
}
|
||||
};
|
||||
var pivot = await createView({
|
||||
@@ -411,7 +410,7 @@ QUnit.module('Views', {
|
||||
viewOptions: {
|
||||
context: context,
|
||||
title: 'Partners',
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
assert.hasClass(pivot.$('table'), 'o_enable_linking',
|
||||
@@ -433,11 +432,10 @@ QUnit.module('Views', {
|
||||
this.data.partner.records[3].date = '2016-11-03';
|
||||
|
||||
var context = {
|
||||
timeRangeMenuData: {
|
||||
timeRange: ["&",["date",">=","2016-12-01"],["date","<","2017-01-01"]],
|
||||
timeRangeDescription: 'This Month',
|
||||
comparisonTimeRange: ["&",["date",">=","2016-11-01"],["date","<","2017-12-01"]],
|
||||
comparisonTimeRangeDescription: 'Previous Period'
|
||||
time_ranges: {
|
||||
field: 'date',
|
||||
range: 'this_month',
|
||||
comparisonRange: 'previous_period',
|
||||
}
|
||||
};
|
||||
|
||||
@@ -470,7 +468,7 @@ QUnit.module('Views', {
|
||||
viewOptions: {
|
||||
context: context,
|
||||
title: 'Partners',
|
||||
}
|
||||
},
|
||||
});
|
||||
assert.hasClass(pivot.$('table'), 'o_enable_linking',
|
||||
"root node should have classname 'o_enable_linking'");
|
||||
@@ -1945,7 +1943,7 @@ QUnit.module('Views', {
|
||||
});
|
||||
|
||||
QUnit.test('rendering of pivot view with comparison', async function (assert) {
|
||||
assert.expect(7);
|
||||
assert.expect(8);
|
||||
|
||||
this.data.partner.records[0].date = '2016-12-15';
|
||||
this.data.partner.records[1].date = '2016-12-17';
|
||||
@@ -1966,31 +1964,40 @@ QUnit.module('Views', {
|
||||
viewOptions: {
|
||||
additionalMeasures: ['product_id'],
|
||||
},
|
||||
intercepts: {
|
||||
create_filter: function (ev) {
|
||||
var data = ev.data;
|
||||
assert.deepEqual(data.filter.context.timeRangeMenuData, {
|
||||
timeRange: ["&", ["date", ">=", "2016-12-01"], ["date", "<", "2017-01-01"]],
|
||||
timeRangeDescription: 'This Month',
|
||||
comparisonTimeRange: ["&", ["date", ">=", "2016-11-01"], ["date", "<", "2016-12-01"]],
|
||||
comparisonTimeRangeDescription: 'Previous Period',
|
||||
});
|
||||
mockRPC: function () {
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
env: {
|
||||
dataManager: {
|
||||
create_filter: async function (filter) {
|
||||
assert.deepEqual(filter.context, {
|
||||
pivot_measures: ['__count'],
|
||||
pivot_column_groupby: [],
|
||||
pivot_row_groupby: ['product_id'],
|
||||
group_by: [],
|
||||
time_ranges: {
|
||||
field: 'date',
|
||||
range: 'this_month',
|
||||
comparisonRange: 'previous_period',
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
// with no data
|
||||
await testUtils.dom.click(pivot.$('.o_time_range_menu_button'));
|
||||
await testUtils.dom.click(pivot.$('.o_time_range_menu .o_comparison_checkbox'));
|
||||
pivot.$('.o_time_range_selector').val('today');
|
||||
await testUtils.dom.click(pivot.$('.o_time_range_menu .o_apply_range'));
|
||||
await cpHelpers.toggleTimeRangeMenu(pivot);
|
||||
await cpHelpers.toggleTimeRangeMenuBox(pivot);
|
||||
await cpHelpers.selectRange(pivot, 'today');
|
||||
await cpHelpers.applyTimeRange(pivot);
|
||||
|
||||
assert.strictEqual(pivot.$('.o_pivot p.o_view_nocontent_empty_folder').length, 1);
|
||||
|
||||
// with data, no row groupby
|
||||
await testUtils.dom.click(pivot.$('.o_time_range_menu_button'));
|
||||
pivot.$('.o_time_range_selector').val('this_month');
|
||||
await testUtils.dom.click(pivot.$('.o_time_range_menu .o_apply_range'));
|
||||
await cpHelpers.selectRange(pivot, 'this_month');
|
||||
await cpHelpers.applyTimeRange(pivot);
|
||||
assert.containsN(pivot, '.o_pivot thead tr:last th', 9,
|
||||
"last header row should contains 9 cells (3*[This month, Previous Period, Variation]");
|
||||
var values = [
|
||||
@@ -2035,11 +2042,10 @@ QUnit.module('Views', {
|
||||
];
|
||||
assert.strictEqual(getCurrentValues(pivot), values.join());
|
||||
|
||||
pivot.$('.o_search_options button:contains("Favorites")').click();
|
||||
var $favorites = pivot.$('.dropdown-menu.o_favorites_menu');
|
||||
$favorites.find('a.o_save_search').click();
|
||||
$favorites.find('.o_input').val('Fav').trigger('input');
|
||||
$favorites.find('button').click();
|
||||
await cpHelpers.toggleFavoriteMenu(pivot);
|
||||
await cpHelpers.toggleSaveFavorite(pivot);
|
||||
await cpHelpers.editFavoriteName(pivot, 'Fav');
|
||||
await cpHelpers.saveFavorite(pivot);
|
||||
|
||||
unpatchDate();
|
||||
pivot.destroy();
|
||||
@@ -2093,14 +2099,15 @@ QUnit.module('Views', {
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
// open time range menu
|
||||
await testUtils.dom.click(pivot.$('.o_control_panel .o_time_range_menu_button'));
|
||||
await cpHelpers.toggleTimeRangeMenu(pivot);
|
||||
// select 'Today' as range
|
||||
pivot.$('.o_control_panel .o_time_range_selector').val('today');
|
||||
await cpHelpers.selectRange(pivot, 'today');
|
||||
// check checkbox 'Compare To'
|
||||
await testUtils.dom.click(pivot.$('.o_control_panel .o_time_range_menu .o_comparison_checkbox'));
|
||||
await cpHelpers.toggleTimeRangeMenuBox(pivot);
|
||||
// Click on 'Apply' button
|
||||
await testUtils.dom.click(pivot.$('.o_control_panel .o_time_range_menu .o_apply_range'));
|
||||
await cpHelpers.applyTimeRange(pivot);
|
||||
|
||||
// the time range menu configuration is by now: Date, Today, checkbox checked, Previous Period
|
||||
// With the data above, the time ranges contain no record.
|
||||
@@ -2109,13 +2116,11 @@ QUnit.module('Views', {
|
||||
// are deactivated (exception: the 'Measures' button).
|
||||
assert.ok(pivot.$('.o_control_panel button.o_pivot_download').prop('disabled'));
|
||||
|
||||
// open time range menu
|
||||
await testUtils.dom.click(pivot.$('.o_control_panel .o_time_range_menu_button'));
|
||||
// select 'This Month' as date range
|
||||
pivot.$('.o_control_panel .o_time_range_selector').val('this_month');
|
||||
await cpHelpers.selectRange(pivot, 'this_month');
|
||||
|
||||
// Click on 'Apply' button
|
||||
await testUtils.dom.click(pivot.$('.o_control_panel .o_time_range_menu .o_apply_range'));
|
||||
await cpHelpers.applyTimeRange(pivot);
|
||||
// the time range menu configuration is by now: Date, This Month, checkbox checked, Previous Period
|
||||
// With the data above, the time ranges contain some records.
|
||||
// export data. Should execute 'get_file'
|
||||
@@ -2177,11 +2182,12 @@ QUnit.module('Views', {
|
||||
|
||||
mockMock = true;
|
||||
|
||||
|
||||
// activate 'This Month' and 'Previous Period' in time range menu
|
||||
await testUtils.dom.click(pivot.$('.o_control_panel .o_time_range_menu_button'));
|
||||
pivot.$('.o_control_panel .o_time_range_selector').val('this_month');
|
||||
await testUtils.dom.click(pivot.$('.o_control_panel .o_time_range_menu .o_comparison_checkbox'));
|
||||
await testUtils.dom.click(pivot.$('.o_control_panel .o_time_range_menu .o_apply_range'));
|
||||
await cpHelpers.toggleTimeRangeMenu(pivot);
|
||||
await cpHelpers.selectRange(pivot, 'this_month');
|
||||
await cpHelpers.toggleTimeRangeMenuBox(pivot);
|
||||
await cpHelpers.applyTimeRange(pivot);
|
||||
|
||||
var values = [
|
||||
"4", "0", "100%",
|
||||
@@ -2219,16 +2225,12 @@ QUnit.module('Views', {
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
// enable comparison mode
|
||||
var $cp = pivot.$('.o_control_panel');
|
||||
// open time range menu
|
||||
await testUtils.dom.click($cp.find('.o_time_range_menu_button'));
|
||||
// select 'This month' as range
|
||||
await testUtils.fields.editInput($cp.find('.o_time_range_selector'), 'this_month');
|
||||
// check checkbox 'Compare To'
|
||||
await testUtils.dom.click($cp.find('.o_time_range_menu .o_comparison_checkbox'));
|
||||
// click on 'Apply' button
|
||||
await testUtils.dom.click($cp.find('.o_time_range_menu .o_apply_range'));
|
||||
await cpHelpers.toggleTimeRangeMenu(pivot);
|
||||
await cpHelpers.selectRange(pivot, 'this_month');
|
||||
await cpHelpers.toggleTimeRangeMenuBox(pivot);
|
||||
await cpHelpers.applyTimeRange(pivot);
|
||||
|
||||
// initial sanity check
|
||||
var values = [
|
||||
@@ -2303,6 +2305,7 @@ QUnit.module('Views', {
|
||||
assert.expect(16);
|
||||
// create an action manager to test the interactions with the search view
|
||||
var readGroupCount = 0;
|
||||
|
||||
var actionManager = await createActionManager({
|
||||
data: this.data,
|
||||
archs: {
|
||||
@@ -2322,9 +2325,9 @@ QUnit.module('Views', {
|
||||
mockRPC: function (route, args) {
|
||||
if (args.method === 'read_group') {
|
||||
assert.step('read_group');
|
||||
var domain = args.kwargs.domain;
|
||||
const domain = args.kwargs.domain;
|
||||
if ([0,1].indexOf(readGroupCount) !== -1) {
|
||||
assert.deepEqual(domain, [], 'initial domain empty');
|
||||
assert.deepEqual(domain, [], 'domain empty');
|
||||
} else if ([2,3,4,5].indexOf(readGroupCount) !== -1) {
|
||||
assert.deepEqual(domain, [['foo', '=', 12]],
|
||||
'domain conserved when back with breadcrumbs');
|
||||
@@ -2333,12 +2336,12 @@ QUnit.module('Views', {
|
||||
}
|
||||
if (route === '/web/dataset/search_read') {
|
||||
assert.step('search_read');
|
||||
var domain = args.domain;
|
||||
const domain = args.domain;
|
||||
assert.deepEqual(domain, [['customer', '=', 1], ['foo', '=', 12]],
|
||||
'list domain is correct');
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
await actionManager.doAction({
|
||||
@@ -2347,20 +2350,23 @@ QUnit.module('Views', {
|
||||
views: [[false, 'pivot']],
|
||||
});
|
||||
|
||||
await testUtilsDom.click(actionManager.$('.o_filters_menu_button'));
|
||||
await testUtilsDom.click(actionManager.$('.o_menu_item:contains("Bayou")'));
|
||||
|
||||
await testUtilsDom.click(actionManager.$('.o_pivot_cell_value:nth(1)'))
|
||||
await cpHelpers.toggleFilterMenu(actionManager);
|
||||
await cpHelpers.toggleMenuItem(actionManager, 0);
|
||||
await testUtils.nextTick();
|
||||
|
||||
await testUtilsDom.click(actionManager.$('.o_pivot_cell_value:nth(1)'));
|
||||
await testUtils.nextTick();
|
||||
|
||||
assert.containsOnce(actionManager, '.o_list_view');
|
||||
|
||||
await testUtilsDom.click(actionManager.$('.o_control_panel .breadcrumb-item:first() a'));
|
||||
await testUtilsDom.click(actionManager.$('.o_control_panel ol.breadcrumb li.breadcrumb-item').eq(0));
|
||||
|
||||
assert.verifySteps([
|
||||
'read_group', 'read_group',
|
||||
'read_group', 'read_group',
|
||||
'search_read',
|
||||
'read_group', 'read_group'])
|
||||
'read_group', 'read_group']);
|
||||
actionManager.destroy();
|
||||
});
|
||||
|
||||
@@ -2387,16 +2393,12 @@ QUnit.module('Views', {
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
// enable comparison mode
|
||||
var $cp = pivot.$('.o_control_panel');
|
||||
// open time range menu
|
||||
await testUtils.dom.click($cp.find('.o_time_range_menu_button'));
|
||||
// select 'This month' as range
|
||||
await testUtils.fields.editInput($cp.find('.o_time_range_selector'), 'this_month');
|
||||
// check checkbox 'Compare To'
|
||||
await testUtils.dom.click($cp.find('.o_time_range_menu .o_comparison_checkbox'));
|
||||
// click on 'Apply' button
|
||||
await testUtils.dom.click($cp.find('.o_time_range_menu .o_apply_range'));
|
||||
await cpHelpers.toggleTimeRangeMenu(pivot);
|
||||
await cpHelpers.selectRange(pivot, 'this_month');
|
||||
await cpHelpers.toggleTimeRangeMenuBox(pivot);
|
||||
await cpHelpers.applyTimeRange(pivot);
|
||||
|
||||
// initial sanity check
|
||||
var values = [
|
||||
@@ -2474,8 +2476,7 @@ QUnit.module('Views', {
|
||||
[
|
||||
'', 'Total', '',
|
||||
'2016-12-15', '2016-12-17', '2016-11-22', '2016-11-03',
|
||||
].join('')
|
||||
,
|
||||
].join(''),
|
||||
"The col headers should be as expected"
|
||||
);
|
||||
assert.strictEqual(
|
||||
@@ -2489,24 +2490,19 @@ QUnit.module('Views', {
|
||||
"The row headers should be as expected"
|
||||
);
|
||||
|
||||
|
||||
// enable comparison mode
|
||||
var $cp = pivot.$('.o_control_panel');
|
||||
// open time range menu
|
||||
await testUtils.dom.click($cp.find('.o_time_range_menu_button'));
|
||||
// select 'This month' as range
|
||||
await testUtils.fields.editInput($cp.find('.o_time_range_selector'), 'this_month');
|
||||
// check checkbox 'Compare To'
|
||||
await testUtils.dom.click($cp.find('.o_time_range_menu .o_comparison_checkbox'));
|
||||
// click on 'Apply' button
|
||||
await testUtils.dom.click($cp.find('.o_time_range_menu .o_apply_range'));
|
||||
await cpHelpers.toggleTimeRangeMenu(pivot);
|
||||
await cpHelpers.selectRange(pivot, 'this_month');
|
||||
await cpHelpers.toggleTimeRangeMenuBox(pivot);
|
||||
await cpHelpers.applyTimeRange(pivot);
|
||||
|
||||
assert.strictEqual(
|
||||
pivot.$('th').slice(0, 7).text(),
|
||||
[
|
||||
'', 'Total', '',
|
||||
'2016-12-15', '2016-12-17', '2016-11-22', '2016-11-03',
|
||||
].join('')
|
||||
,
|
||||
].join(''),
|
||||
"The col headers should be as expected"
|
||||
);
|
||||
assert.strictEqual(
|
||||
@@ -2551,10 +2547,10 @@ QUnit.module('Views', {
|
||||
QUnit.test('Does not identify "false" with false as keys when creating group trees', async function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
this.data.partner.fields['favorite_animal'] = {string: "Favorite animal", type: "char", store: true}
|
||||
this.data.partner.records[0]['favorite_animal'] = 'Dog'
|
||||
this.data.partner.records[1]['favorite_animal'] = 'false'
|
||||
this.data.partner.records[2]['favorite_animal'] = 'Undefined'
|
||||
this.data.partner.fields.favorite_animal = {string: "Favorite animal", type: "char", store: true};
|
||||
this.data.partner.records[0].favorite_animal = 'Dog';
|
||||
this.data.partner.records[1].favorite_animal = 'false';
|
||||
this.data.partner.records[2].favorite_animal = 'Undefined';
|
||||
|
||||
var unpatchDate = patchDate(2016, 11, 20, 1, 0, 0);
|
||||
var pivot = await createView({
|
||||
@@ -2571,8 +2567,7 @@ QUnit.module('Views', {
|
||||
pivot.$('th').slice(0, 2).text(),
|
||||
[
|
||||
'', 'Total', '',
|
||||
].join('')
|
||||
,
|
||||
].join(''),
|
||||
"The col headers should be as expected"
|
||||
);
|
||||
assert.strictEqual(
|
||||
@@ -2595,7 +2590,7 @@ QUnit.module('Views', {
|
||||
QUnit.test('group bys added via control panel and expand Header do not stack', async function (assert) {
|
||||
assert.expect(8);
|
||||
|
||||
delete this.data.partner.fields['date'];
|
||||
delete this.data.partner.fields.date;
|
||||
|
||||
var pivot = await createView({
|
||||
View: PivotView,
|
||||
@@ -2624,11 +2619,11 @@ QUnit.module('Views', {
|
||||
"The row headers should be as expected"
|
||||
);
|
||||
|
||||
var $cp = pivot.$('.o_control_panel');
|
||||
|
||||
// open group by menu and add new groupby
|
||||
await testUtils.dom.click($cp.find('button span.fa-bars'));
|
||||
await testUtils.dom.click($cp.find('button.o_add_custom_group'));
|
||||
await testUtils.dom.click($cp.find('button.o_apply_group'));
|
||||
await cpHelpers.toggleGroupByMenu(pivot);
|
||||
await cpHelpers.toggleAddCustomGroup(pivot);
|
||||
await cpHelpers.applyGroup(pivot);
|
||||
|
||||
assert.strictEqual(
|
||||
pivot.$('th').slice(0, 2).text(),
|
||||
@@ -2670,10 +2665,11 @@ QUnit.module('Views', {
|
||||
"The row headers should be as expected"
|
||||
);
|
||||
|
||||
// open group by menu and add new groupby
|
||||
await testUtils.dom.click($cp.find('button span.fa-bars'));
|
||||
await testUtils.dom.click($cp.find('button.o_add_custom_group'));
|
||||
await testUtils.dom.click($cp.find('button.o_apply_group'));
|
||||
// open groupby menu generator and add a new groupby
|
||||
await cpHelpers.toggleGroupByMenu(pivot);
|
||||
await cpHelpers.toggleAddCustomGroup(pivot);
|
||||
await cpHelpers.selectGroup(pivot, 'bar');
|
||||
await cpHelpers.applyGroup(pivot);
|
||||
|
||||
assert.strictEqual(
|
||||
pivot.$('th').slice(0, 2).text(),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
odoo.define('web.qweb_view_tests', function (require) {
|
||||
"use strict";
|
||||
|
||||
var qweb = require('web.qweb');
|
||||
var utils = require('web.test_utils');
|
||||
|
||||
QUnit.module("Views", {
|
||||
|
||||
@@ -1,206 +0,0 @@
|
||||
odoo.define('web.search_filters_menu_tests', function (require) {
|
||||
"use strict";
|
||||
|
||||
var Domain = require('web.Domain');
|
||||
var FilterMenu = require('web.FilterMenu');
|
||||
var pyUtils = require('web.py_utils');
|
||||
var testUtils = require('web.test_utils');
|
||||
|
||||
function createFilterMenu(filters, fields, params) {
|
||||
params = params || {};
|
||||
var target = params.debug ? document.body : $('#qunit-fixture');
|
||||
var menu = new FilterMenu(null, filters, fields);
|
||||
testUtils.mock.addMockEnvironment(menu, params);
|
||||
return menu.appendTo(target).then(function() {
|
||||
return menu;
|
||||
});
|
||||
}
|
||||
|
||||
QUnit.module('FilterMenu', {
|
||||
beforeEach: function () {
|
||||
this.filters = [
|
||||
{
|
||||
isActive: false,
|
||||
description: 'some filter',
|
||||
domain: '',
|
||||
groupNumber: 1,
|
||||
},
|
||||
];
|
||||
this.fields = {
|
||||
boolean_field: {string: "Boolean Field", type: "boolean", default: true, searchable: true},
|
||||
date_field: {string: "A date", type: "date", searchable: true},
|
||||
char_field: {string: "Char Field", type: "char", default: "foo", searchable: true, trim: true},
|
||||
};
|
||||
},
|
||||
}, function () {
|
||||
|
||||
QUnit.test('simple rendering with no filter', async function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
var filterMenu = await createFilterMenu([], this.fields);
|
||||
await testUtils.dom.click(filterMenu.$('span.fa-filter'));
|
||||
assert.containsNone(filterMenu, '.dropdown-divider');
|
||||
assert.containsNone(filterMenu, '.o_add_filter_menu');
|
||||
assert.containsOnce(filterMenu, '.o_add_custom_filter',
|
||||
'should have one element: a add custom filter item');
|
||||
filterMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('simple rendering with a filter', async function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
var filterMenu = await createFilterMenu(this.filters, this.fields);
|
||||
assert.containsN(filterMenu, '.dropdown-divider, .dropdown-item, .o_add_custom_filter', 4,
|
||||
'should have 4 elements: a hidden separator, a filter, a separator, a add custom filter item');
|
||||
assert.containsOnce(filterMenu, '.o_add_custom_filter');
|
||||
filterMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('click on add custom filter opens the submenu', async function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
var filterMenu = await createFilterMenu([], this.fields);
|
||||
// open menu dropdown
|
||||
await testUtils.dom.click(filterMenu.$('span.fa-filter'));
|
||||
// open add custom filter submenu
|
||||
await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
|
||||
assert.containsNone(filterMenu, '.dropdown-divider');
|
||||
assert.isVisible(filterMenu.$('.o_add_filter_menu'));
|
||||
assert.containsN(filterMenu, '.dropdown-item, .dropdown-item-text', 3,
|
||||
'should have 3 elements: a add custom filter item, a proposition, a apply button + add condition button');
|
||||
|
||||
filterMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('removing last prop disable the apply button', async function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
var filterMenu = await createFilterMenu([], this.fields);
|
||||
// open menu dropdown and custom filter submenu
|
||||
await testUtils.dom.click(filterMenu.$('span.fa-filter'));
|
||||
await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
|
||||
|
||||
// remove the current unique proposition
|
||||
await testUtils.dom.click(filterMenu.$('.o_searchview_extended_delete_prop'));
|
||||
|
||||
assert.containsNone(filterMenu, '.dropdown-divider');
|
||||
assert.containsN(filterMenu, '.dropdown-item, .dropdown-item-text', 2,
|
||||
'should have 2 elements: a add custom filter item, a apply button + add condition button');
|
||||
|
||||
filterMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('readding a proposition reenable apply button', async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
var filterMenu = await createFilterMenu([], this.fields);
|
||||
// open menu dropdown and custom filter submenu, remove existing prop
|
||||
await testUtils.dom.click(filterMenu.$('span.fa-filter'));
|
||||
await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
|
||||
await testUtils.dom.click(filterMenu.$('.o_searchview_extended_delete_prop'));
|
||||
// read a proposition
|
||||
await testUtils.dom.click(filterMenu.$('.o_add_condition'));
|
||||
assert.ok(!filterMenu.$('.o_apply_filter').attr('disabled'));
|
||||
|
||||
filterMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('adding a simple filter works', async function (assert) {
|
||||
assert.expect(6);
|
||||
|
||||
delete this.fields.date_field;
|
||||
var filterMenu = await createFilterMenu([], this.fields, {
|
||||
intercepts: {
|
||||
new_filters: function (ev) {
|
||||
var filter = ev.data.filters[0];
|
||||
assert.strictEqual(filter.type, 'filter');
|
||||
assert.strictEqual(filter.description, 'Boolean Field is true');
|
||||
assert.strictEqual(filter.domain, '[[\"boolean_field\",\"=\",True]]');
|
||||
filterMenu.update([{
|
||||
isActive: true,
|
||||
description: '?',
|
||||
domain: '?',
|
||||
groupNumber: 1,
|
||||
}]);
|
||||
},
|
||||
},
|
||||
});
|
||||
// open menu dropdown and custom filter submenu, remove existing prop
|
||||
await testUtils.dom.click(filterMenu.$('span.fa-filter'));
|
||||
await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
|
||||
// click on apply to activate filter
|
||||
await testUtils.dom.click(filterMenu.$('.o_apply_filter'));
|
||||
assert.containsNone(filterMenu, '.o_filter_condition');
|
||||
assert.containsN(filterMenu, '.dropdown-divider', 2);
|
||||
assert.isNotVisible(filterMenu.$('.dropdown-divider').eq(0));
|
||||
filterMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('commit search with an extended proposition with field char does not cause a crash', async function (assert) {
|
||||
assert.expect(6);
|
||||
|
||||
this.fields = {many2one_field: {string: "Trululu", type: "many2one", relation: 'partner', selectable: true, searchable: true}};
|
||||
|
||||
var expectedDomains = [
|
||||
[['many2one_field','ilike', `a`]],
|
||||
[['many2one_field','ilike', `"a"`]],
|
||||
[['many2one_field','ilike', `'a'`]],
|
||||
[['many2one_field','ilike', `'`]],
|
||||
[['many2one_field','ilike', `"`]],
|
||||
[['many2one_field','ilike', `\\`]],
|
||||
];
|
||||
|
||||
var filterMenu = await createFilterMenu([], this.fields, {
|
||||
intercepts: {
|
||||
new_filters: function (ev) {
|
||||
var filter = ev.data.filters[0];
|
||||
// this step combine a tokenization/parsing followed by a string formatting
|
||||
var domain = pyUtils.assembleDomains([filter.domain]);
|
||||
domain = Domain.prototype.stringToArray(domain);
|
||||
assert.deepEqual(domain, expectedDomains.shift());
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
// open menu dropdown and custom filter submenu, select trululu field and enter string `a`, then click apply
|
||||
await testUtils.dom.click(filterMenu.$('span.fa-filter'));
|
||||
await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
|
||||
await testUtils.fields.editSelect(filterMenu.$('.o_filter_condition select.o_input.o_searchview_extended_prop_field'), 'many2one_field');
|
||||
await testUtils.fields.editInput(filterMenu.$('.o_filter_condition .o_searchview_extended_prop_value input'), `a`);
|
||||
await testUtils.dom.click(filterMenu.$('.o_apply_filter'));
|
||||
|
||||
|
||||
// open custom filter submenu, select trululu field and enter string `"a"`, then click apply
|
||||
await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
|
||||
await testUtils.fields.editSelect(filterMenu.$('.o_filter_condition select.o_input.o_searchview_extended_prop_field'), 'many2one_field');
|
||||
await testUtils.fields.editInput(filterMenu.$('.o_filter_condition .o_searchview_extended_prop_value input'), `"a"`);
|
||||
await testUtils.dom.click(filterMenu.$('.o_apply_filter'));
|
||||
|
||||
// open custom filter submenu, select trululu field and enter string `'a'`, then click apply
|
||||
await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
|
||||
await testUtils.fields.editSelect(filterMenu.$('.o_filter_condition select.o_input.o_searchview_extended_prop_field'), 'many2one_field');
|
||||
await testUtils.fields.editInput(filterMenu.$('.o_filter_condition .o_searchview_extended_prop_value input'), `'a'`);
|
||||
await testUtils.dom.click(filterMenu.$('.o_apply_filter'));
|
||||
|
||||
// open custom filter submenu, select trululu field and enter string `'`, then click apply
|
||||
await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
|
||||
await testUtils.fields.editSelect(filterMenu.$('.o_filter_condition select.o_input.o_searchview_extended_prop_field'), 'many2one_field');
|
||||
await testUtils.fields.editInput(filterMenu.$('.o_filter_condition .o_searchview_extended_prop_value input'), `'`);
|
||||
await testUtils.dom.click(filterMenu.$('.o_apply_filter'));
|
||||
|
||||
// open custom filter submenu, select trululu field and enter string `"`, then click apply
|
||||
await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
|
||||
await testUtils.fields.editSelect(filterMenu.$('.o_filter_condition select.o_input.o_searchview_extended_prop_field'), 'many2one_field');
|
||||
await testUtils.fields.editInput(filterMenu.$('.o_filter_condition .o_searchview_extended_prop_value input'), `"`);
|
||||
await testUtils.dom.click(filterMenu.$('.o_apply_filter'));
|
||||
|
||||
// open custom filter submenu, select trululu field and enter string `\`, then click apply
|
||||
await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
|
||||
await testUtils.fields.editSelect(filterMenu.$('.o_filter_condition select.o_input.o_searchview_extended_prop_field'), 'many2one_field');
|
||||
await testUtils.fields.editInput(filterMenu.$('.o_filter_condition .o_searchview_extended_prop_value input'), `\\`);
|
||||
await testUtils.dom.click(filterMenu.$('.o_apply_filter'));
|
||||
|
||||
filterMenu.destroy();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,200 +0,0 @@
|
||||
odoo.define('web.search_groupby_menu_tests', function (require) {
|
||||
"use strict";
|
||||
|
||||
var GroupByMenu = require('web.GroupByMenu');
|
||||
var testUtils = require('web.test_utils');
|
||||
var controlPanelViewParameters = require('web.controlPanelViewParameters');
|
||||
var INTERVAL_OPTIONS = controlPanelViewParameters.INTERVAL_OPTIONS;
|
||||
|
||||
function createGroupByMenu(groupBys, fields, params) {
|
||||
params = params || {};
|
||||
var target = params.debug ? document.body : $('#qunit-fixture');
|
||||
var menu = new GroupByMenu(null, groupBys, fields);
|
||||
testUtils.mock.addMockEnvironment(menu, params);
|
||||
return menu.appendTo(target).then(function() {
|
||||
return menu;
|
||||
});
|
||||
}
|
||||
|
||||
QUnit.module('GroupByMenu', {
|
||||
beforeEach: function () {
|
||||
this.groupBys = [
|
||||
{
|
||||
description: 'some group by',
|
||||
groupNumber: 1,
|
||||
isActive: false,
|
||||
},
|
||||
];
|
||||
this.fields = {
|
||||
fieldName: {sortable: true, string: 'Super Date', type: 'date'}
|
||||
};
|
||||
},
|
||||
}, function () {
|
||||
|
||||
QUnit.test('simple rendering with no filter and no field', async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
var groupByMenu = await createGroupByMenu([], {});
|
||||
// open groupBy menu
|
||||
testUtils.dom.click(groupByMenu.$('button:first'));
|
||||
assert.containsNone(groupByMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text',
|
||||
'should have 0 element');
|
||||
|
||||
groupByMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('simple rendering', async function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
var groupByMenu = await createGroupByMenu(this.groupBys, this.fields);
|
||||
// open groupBy menu
|
||||
await testUtils.dom.click(groupByMenu.$('button:first'));
|
||||
assert.containsN(groupByMenu, '.dropdown-divider, .dropdown-item', 4);
|
||||
assert.strictEqual(groupByMenu.$('.o_menu_item').text().trim(), 'some group by',
|
||||
'should have proper filter name');
|
||||
|
||||
groupByMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('simple rendering with no filter but fields', async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
var groupByMenu = await createGroupByMenu(
|
||||
[],
|
||||
{fieldName: {sortable: true, string: 'Super Date', type: 'date'}}
|
||||
);
|
||||
await testUtils.nextTick();
|
||||
await testUtils.dom.click(groupByMenu.$('button:first'));
|
||||
assert.containsOnce(groupByMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text', 'should have 1 element');
|
||||
|
||||
groupByMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('click on add custom group toggle group selector', async function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
var groupByMenu = await createGroupByMenu([],
|
||||
{fieldName: {sortable: true, string: 'Super Date', type: 'date'}}
|
||||
);
|
||||
await testUtils.dom.click(groupByMenu.$('button:first'));
|
||||
var selector = groupByMenu.$('select.o_group_selector');
|
||||
assert.ok(!selector.is(":visible"), 'should be invisible');
|
||||
await testUtils.dom.click(groupByMenu.$('.o_add_custom_group'));
|
||||
selector = groupByMenu.$('select.o_group_selector');
|
||||
assert.ok(selector.is(":visible"), 'should be visible');
|
||||
|
||||
groupByMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('select a groupBy of no date type in Add Custom Group menu add properly that groupBy to menu', async function (assert) {
|
||||
assert.expect(6);
|
||||
|
||||
var groupByMenu = await createGroupByMenu(
|
||||
[],
|
||||
{
|
||||
fieldName: {sortable: true, name: 'candlelight', string: 'Candlelight', type: 'boolean'},
|
||||
},
|
||||
{
|
||||
intercepts: {
|
||||
new_groupBy: function (ev) {
|
||||
assert.strictEqual(ev.data.description, 'Candlelight');
|
||||
assert.strictEqual(ev.data.fieldName, 'fieldName');
|
||||
assert.strictEqual(ev.data.fieldType, 'boolean');
|
||||
assert.strictEqual(ev.data.type, 'groupBy');
|
||||
groupByMenu.update([{
|
||||
description: 'Candlelight',
|
||||
groupNumber: 1,
|
||||
isActive: true,
|
||||
}]);
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
await testUtils.nextTick();
|
||||
await testUtils.dom.click(groupByMenu.$('button:first'));
|
||||
await testUtils.dom.click(groupByMenu.$('.o_add_custom_group'));
|
||||
assert.strictEqual(groupByMenu.$('select').val(), 'fieldName',
|
||||
'the select value should be "fieldName"');
|
||||
await testUtils.dom.click(groupByMenu.$('button.o_apply_group'));
|
||||
assert.containsOnce(groupByMenu, '.o_menu_item > .dropdown-item.selected', 'there should be a groupby selected');
|
||||
groupByMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('select a groupBy of date type in Add Custom Group menu add properly that groupBy to menu', async function (assert) {
|
||||
assert.expect(13);
|
||||
|
||||
INTERVAL_OPTIONS = INTERVAL_OPTIONS.map(function (option) {
|
||||
return _.extend(option, {description: option.description.toString()});
|
||||
});
|
||||
|
||||
var groupByMenu = await createGroupByMenu(
|
||||
[],
|
||||
this.fields,
|
||||
{
|
||||
intercepts: {
|
||||
new_groupBy: function (ev) {
|
||||
assert.strictEqual(ev.data.description, 'Super Date');
|
||||
assert.strictEqual(ev.data.fieldName, 'fieldName');
|
||||
assert.strictEqual(ev.data.fieldType, 'date');
|
||||
assert.strictEqual(ev.data.type, 'groupBy');
|
||||
assert.strictEqual(ev.data.hasOptions, true);
|
||||
assert.deepEqual(ev.data.options, controlPanelViewParameters.INTERVAL_OPTIONS);
|
||||
assert.strictEqual(ev.data.defaultOptionId, controlPanelViewParameters.DEFAULT_INTERVAL);
|
||||
assert.strictEqual(ev.data.currentOptionIds.size, 0);
|
||||
groupByMenu.update([{
|
||||
description: 'Super Date',
|
||||
fieldName: 'fieldName',
|
||||
groupNumber: 1,
|
||||
isActive: true,
|
||||
hasOptions: true,
|
||||
options: controlPanelViewParameters.INTERVAL_OPTIONS,
|
||||
currentOptionIds: new Set([controlPanelViewParameters.DEFAULT_INTERVAL]),
|
||||
}]);
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
// open groupBy menu
|
||||
await testUtils.dom.click(groupByMenu.$('button:first'));
|
||||
// open Add Custom Group submenu
|
||||
await testUtils.dom.click(groupByMenu.$('.o_add_custom_group'));
|
||||
// select fieldName
|
||||
assert.strictEqual(groupByMenu.$('select').val(), 'fieldName',
|
||||
'the select value should be "fieldName"');
|
||||
// create new groupBy of type date
|
||||
await testUtils.dom.click(groupByMenu.$('button.o_apply_group'));
|
||||
assert.strictEqual(groupByMenu.$('.o_menu_item > .dropdown-item.selected').length, 1,
|
||||
'there should be a groupby selected');
|
||||
assert.strictEqual(groupByMenu.$('.o_menu_item .o_submenu_switcher').length, 1,
|
||||
'there should be options available');
|
||||
// open options submenu
|
||||
await testUtils.dom.click(groupByMenu.$('.o_menu_item .o_submenu_switcher'));
|
||||
assert.strictEqual(groupByMenu.$('.o_item_option').length, 5,
|
||||
'there should be five options available');
|
||||
assert.strictEqual(groupByMenu.$('.o_add_custom_group').length, 0,
|
||||
'there should be no more a Add Custome Group submenu');
|
||||
|
||||
groupByMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('custom group by dropdown should not have ID field', async function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
this.fields.id = {sortable: true, string: 'ID', type: 'integer'};
|
||||
|
||||
var groupByMenu = await createGroupByMenu([], this.fields);
|
||||
// open groupBy menu
|
||||
await testUtils.dom.click(groupByMenu.$('button:first'));
|
||||
// open Add Custom Group submenu
|
||||
await testUtils.dom.click(groupByMenu.$('.o_add_custom_group'))
|
||||
|
||||
assert.containsOnce(groupByMenu, '.o_group_selector option',
|
||||
'groupby menu should have only one option');
|
||||
// custom group by should not have 'ID' field
|
||||
assert.containsNone(groupByMenu, '.o_group_selector option[value="id"]',
|
||||
'id field should not be in custom group by');
|
||||
|
||||
groupByMenu.destroy();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -7,6 +7,7 @@ var KanbanView = require('web.KanbanView');
|
||||
var RamStorage = require('web.RamStorage');
|
||||
var testUtils = require('web.test_utils');
|
||||
|
||||
const cpHelpers = testUtils.controlPanel;
|
||||
var createActionManager = testUtils.createActionManager;
|
||||
var createView = testUtils.createView;
|
||||
|
||||
@@ -1396,7 +1397,7 @@ QUnit.module('Views', {
|
||||
]);
|
||||
|
||||
// go to page 2 (the domain doesn't change, so the filters should not be reloaded)
|
||||
await testUtils.dom.click(kanban.$('.o_pager_next'));
|
||||
await cpHelpers.pagerNext(kanban);
|
||||
|
||||
assert.verifySteps([
|
||||
'/web/dataset/search_read',
|
||||
@@ -1935,16 +1936,17 @@ QUnit.module('Views', {
|
||||
archs: this.archs,
|
||||
data: this.data,
|
||||
});
|
||||
|
||||
await actionManager.doAction(1);
|
||||
|
||||
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_kanban_view');
|
||||
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_search_panel');
|
||||
|
||||
await testUtils.dom.click(actionManager.$('.o_cp_switch_pivot'));
|
||||
await cpHelpers.switchView(actionManager, 'pivot');
|
||||
await testUtils.nextTick();
|
||||
assert.containsOnce(actionManager, '.o_content .o_pivot');
|
||||
assert.containsNone(actionManager, '.o_content .o_search_panel');
|
||||
|
||||
await testUtils.dom.click(actionManager.$('.o_cp_switch_list'));
|
||||
await cpHelpers.switchView(actionManager, 'list');
|
||||
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_list_view');
|
||||
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_search_panel');
|
||||
|
||||
@@ -1972,16 +1974,16 @@ QUnit.module('Views', {
|
||||
archs: this.archs,
|
||||
data: this.data,
|
||||
});
|
||||
|
||||
await actionManager.doAction(1);
|
||||
|
||||
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_kanban_view');
|
||||
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_search_panel');
|
||||
|
||||
await testUtils.dom.click(actionManager.$('.o_cp_switch_list'));
|
||||
await cpHelpers.switchView(actionManager, 'list');
|
||||
assert.containsOnce(actionManager, '.o_content .o_list_view');
|
||||
assert.containsNone(actionManager, '.o_content .o_search_panel');
|
||||
|
||||
await testUtils.dom.click(actionManager.$('.o_cp_switch_pivot'));
|
||||
await cpHelpers.switchView(actionManager, 'pivot');
|
||||
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_pivot');
|
||||
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_search_panel');
|
||||
|
||||
@@ -2003,8 +2005,8 @@ QUnit.module('Views', {
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
await actionManager.doAction(1);
|
||||
|
||||
assert.hasClass(actionManager.$('.o_search_panel_category_value:first header'), 'active');
|
||||
assert.containsN(actionManager, '.o_kanban_record:not(.o_kanban_ghost)', 4);
|
||||
|
||||
@@ -2013,7 +2015,7 @@ QUnit.module('Views', {
|
||||
assert.hasClass(actionManager.$('.o_search_panel_category_value:nth(1) header'), 'active');
|
||||
assert.containsN(actionManager, '.o_kanban_record:not(.o_kanban_ghost)', 2);
|
||||
|
||||
await testUtils.dom.click(actionManager.$('.o_cp_switch_list'));
|
||||
await cpHelpers.switchView(actionManager, 'list');
|
||||
assert.hasClass(actionManager.$('.o_search_panel_category_value:nth(1) header'), 'active');
|
||||
assert.containsN(actionManager, '.o_data_row', 2);
|
||||
|
||||
@@ -2022,7 +2024,7 @@ QUnit.module('Views', {
|
||||
assert.hasClass(actionManager.$('.o_search_panel_category_value:nth(2) header'), 'active');
|
||||
assert.containsN(actionManager, '.o_data_row', 2);
|
||||
|
||||
await testUtils.dom.click(actionManager.$('.o_cp_switch_kanban'));
|
||||
await cpHelpers.switchView(actionManager, 'kanban');
|
||||
assert.hasClass(actionManager.$('.o_search_panel_category_value:nth(2) header'), 'active');
|
||||
assert.containsN(actionManager, '.o_kanban_record:not(.o_kanban_ghost)', 2);
|
||||
|
||||
@@ -2052,8 +2054,8 @@ QUnit.module('Views', {
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
await actionManager.doAction(1);
|
||||
|
||||
assert.containsNone(actionManager, '.o_search_panel_filter_value input:checked');
|
||||
assert.containsN(actionManager, '.o_kanban_record:not(.o_kanban_ghost)', 4);
|
||||
|
||||
@@ -2062,7 +2064,7 @@ QUnit.module('Views', {
|
||||
assert.containsOnce(actionManager, '.o_search_panel_filter_value input:checked');
|
||||
assert.containsN(actionManager, '.o_kanban_record:not(.o_kanban_ghost)', 1);
|
||||
|
||||
await testUtils.dom.click(actionManager.$('.o_cp_switch_list'));
|
||||
await cpHelpers.switchView(actionManager, 'list');
|
||||
assert.containsOnce(actionManager, '.o_search_panel_filter_value input:checked');
|
||||
assert.containsN(actionManager, '.o_data_row', 1);
|
||||
|
||||
@@ -2071,7 +2073,7 @@ QUnit.module('Views', {
|
||||
assert.containsN(actionManager, '.o_search_panel_filter_value input:checked', 2);
|
||||
assert.containsN(actionManager, '.o_data_row', 4);
|
||||
|
||||
await testUtils.dom.click(actionManager.$('.o_cp_switch_kanban'));
|
||||
await cpHelpers.switchView(actionManager, 'kanban');
|
||||
assert.containsN(actionManager, '.o_search_panel_filter_value input:checked', 2);
|
||||
assert.containsN(actionManager, '.o_kanban_record:not(.o_kanban_ghost)', 4);
|
||||
|
||||
@@ -2094,8 +2096,8 @@ QUnit.module('Views', {
|
||||
archs: this.archs,
|
||||
data: this.data,
|
||||
});
|
||||
|
||||
await actionManager.doAction(1);
|
||||
|
||||
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_kanban_view');
|
||||
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_search_panel');
|
||||
assert.containsNone(actionManager, '.o_search_panel_filter_value input:checked');
|
||||
@@ -2107,13 +2109,13 @@ QUnit.module('Views', {
|
||||
assert.containsN(actionManager, '.o_kanban_record:not(.o_kanban_ghost)', 1);
|
||||
|
||||
// switch to pivot
|
||||
await testUtils.dom.click(actionManager.$('.o_cp_switch_pivot'));
|
||||
await cpHelpers.switchView(actionManager, 'pivot');
|
||||
assert.containsOnce(actionManager, '.o_content .o_pivot');
|
||||
assert.containsNone(actionManager, '.o_content .o_search_panel');
|
||||
assert.strictEqual(actionManager.$('.o_pivot_cell_value').text(), '15');
|
||||
|
||||
// switch to list
|
||||
await testUtils.dom.click(actionManager.$('.o_cp_switch_list'));
|
||||
await cpHelpers.switchView(actionManager, 'list');
|
||||
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_list_view');
|
||||
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_search_panel');
|
||||
assert.containsOnce(actionManager, '.o_search_panel_filter_value input:checked');
|
||||
@@ -2192,10 +2194,10 @@ QUnit.module('Views', {
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
await actionManager.doAction(1);
|
||||
await testUtils.dom.click(actionManager.$('.o_cp_switch_list'));
|
||||
await testUtils.dom.click(actionManager.$('.o_cp_switch_kanban'));
|
||||
|
||||
await cpHelpers.switchView(actionManager, 'list');
|
||||
await cpHelpers.switchView(actionManager, 'kanban');
|
||||
|
||||
assert.verifySteps([
|
||||
'/web/action/load',
|
||||
@@ -2226,18 +2228,19 @@ QUnit.module('Views', {
|
||||
actionManager.$el.css('max-height', 300);
|
||||
|
||||
await actionManager.doAction(1);
|
||||
|
||||
assert.containsOnce(actionManager, '.o_content .o_kanban_view');
|
||||
assert.strictEqual(actionManager.$('.o_search_panel').scrollTop(), 0);
|
||||
|
||||
// simulate a scroll in the search panel and switch into list
|
||||
actionManager.$('.o_search_panel').scrollTop(50);
|
||||
await testUtils.dom.click(actionManager.$('.o_cp_switch_list'));
|
||||
await cpHelpers.switchView(actionManager, 'list');
|
||||
assert.containsOnce(actionManager, '.o_content .o_list_view');
|
||||
assert.strictEqual(actionManager.$('.o_search_panel').scrollTop(), 50);
|
||||
|
||||
// simulate another scroll and switch back to kanban
|
||||
actionManager.$('.o_search_panel').scrollTop(30);
|
||||
await testUtils.dom.click(actionManager.$('.o_cp_switch_kanban'));
|
||||
await cpHelpers.switchView(actionManager, 'kanban');
|
||||
assert.containsOnce(actionManager, '.o_content .o_kanban_view');
|
||||
assert.strictEqual(actionManager.$('.o_search_panel').scrollTop(), 30);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,8 +7,16 @@ var testUtils = require('web.test_utils');
|
||||
var Widget = require('web.Widget');
|
||||
var FormView = require('web.FormView');
|
||||
|
||||
const cpHelpers = testUtils.controlPanel;
|
||||
var createView = testUtils.createView;
|
||||
|
||||
async function createParent(params) {
|
||||
var widget = new Widget();
|
||||
params.server = await testUtils.mock.addMockEnvironment(widget, params);
|
||||
owl.Component.env = testUtils.mock.getMockedOwlEnv(params);
|
||||
return widget;
|
||||
}
|
||||
|
||||
QUnit.module('Views', {
|
||||
beforeEach: function () {
|
||||
this.data = {
|
||||
@@ -56,17 +64,10 @@ QUnit.module('Views', {
|
||||
|
||||
QUnit.module('view_dialogs');
|
||||
|
||||
function createParent(params) {
|
||||
var widget = new Widget();
|
||||
|
||||
testUtils.mock.addMockEnvironment(widget, params);
|
||||
return widget;
|
||||
}
|
||||
|
||||
QUnit.test('formviewdialog buttons in footer are positioned properly', async function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
var parent = createParent({
|
||||
var parent = await createParent({
|
||||
data: this.data,
|
||||
archs: {
|
||||
'partner,false,form':
|
||||
@@ -97,7 +98,7 @@ QUnit.module('Views', {
|
||||
this.data.partner.fields.poney_ids = {string: "Poneys", type: "one2many", relation: 'partner'};
|
||||
this.data.partner.records[0].poney_ids = [];
|
||||
|
||||
var parent = createParent({
|
||||
var parent = await createParent({
|
||||
data: this.data,
|
||||
archs: {
|
||||
'partner,false,form':
|
||||
@@ -129,7 +130,7 @@ QUnit.module('Views', {
|
||||
assert.expect(3);
|
||||
|
||||
var search = 0;
|
||||
var parent = createParent({
|
||||
var parent = await createParent({
|
||||
data: this.data,
|
||||
archs: {
|
||||
'partner,false,list':
|
||||
@@ -196,9 +197,8 @@ QUnit.module('Views', {
|
||||
dialog = result;
|
||||
});
|
||||
await testUtils.nextTick();
|
||||
|
||||
await testUtils.dom.click(dialog.$('.o_searchview_facet:contains(groupby_bar) .o_facet_remove'));
|
||||
await testUtils.dom.click(dialog.$('.o_searchview_facet .o_facet_remove'));
|
||||
await cpHelpers.removeFacet('.modal', "Bar");
|
||||
await cpHelpers.removeFacet('.modal');
|
||||
|
||||
parent.destroy();
|
||||
});
|
||||
@@ -206,7 +206,7 @@ QUnit.module('Views', {
|
||||
QUnit.test('SelectCreateDialog correctly evaluates domains', async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
var parent = createParent({
|
||||
var parent = await createParent({
|
||||
data: this.data,
|
||||
archs: {
|
||||
'partner,false,list':
|
||||
@@ -245,7 +245,7 @@ QUnit.module('Views', {
|
||||
QUnit.test('SelectCreateDialog list view in readonly', async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
var parent = createParent({
|
||||
var parent = await createParent({
|
||||
data: this.data,
|
||||
archs: {
|
||||
'partner,false,list':
|
||||
@@ -437,7 +437,7 @@ QUnit.module('Views', {
|
||||
},
|
||||
});
|
||||
|
||||
var parent = createParent({
|
||||
var parent = await createParent({
|
||||
data: this.data,
|
||||
archs: {
|
||||
'partner,false,list':
|
||||
@@ -450,14 +450,19 @@ QUnit.module('Views', {
|
||||
'</search>',
|
||||
|
||||
},
|
||||
intercepts: {
|
||||
create_filter: function (event) {
|
||||
var filter = event.data.filter;
|
||||
assert.deepEqual(filter.domain, `[("bar", "=", True)]`,
|
||||
"should save the correct domain");
|
||||
assert.deepEqual(filter.context, {shouldBeInFilterContext: true},
|
||||
"should save the correct context");
|
||||
},
|
||||
env: {
|
||||
dataManager: {
|
||||
create_filter: function (filter) {
|
||||
assert.strictEqual(filter.domain, `[("bar", "=", True)]`,
|
||||
"should save the correct domain");
|
||||
const expectedContext = {
|
||||
group_by: [], // default groupby is an empty list
|
||||
shouldBeInFilterContext: true,
|
||||
};
|
||||
assert.deepEqual(filter.context, expectedContext,
|
||||
"should save the correct context");
|
||||
},
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -470,19 +475,20 @@ QUnit.module('Views', {
|
||||
});
|
||||
await testUtils.nextTick();
|
||||
|
||||
|
||||
assert.containsN(dialog, '.o_data_row', 3, "should contain 3 records");
|
||||
|
||||
// filter on bar
|
||||
await testUtils.dom.click(dialog.$('.o_dropdown_toggler_btn:contains(Filters)'));
|
||||
await testUtils.dom.click(dialog.$('.o_filters_menu a:contains(Bar)'));
|
||||
await cpHelpers.toggleFilterMenu('.modal');
|
||||
await cpHelpers.toggleMenuItem('.modal', "Bar");
|
||||
|
||||
assert.containsN(dialog, '.o_data_row', 2, "should contain 2 records");
|
||||
|
||||
// save filter
|
||||
await testUtils.dom.click(dialog.$('.o_dropdown_toggler_btn:contains(Favorites)'));
|
||||
await testUtils.dom.click(dialog.$('.o_add_favorite'));
|
||||
await testUtils.fields.editInput(dialog.$('.o_favorite_name input[type=text]'), 'some name'); // name the filter
|
||||
await testUtils.dom.click(dialog.$('.o_save_favorite button'));
|
||||
await cpHelpers.toggleFavoriteMenu('.modal');
|
||||
await cpHelpers.toggleSaveFavorite('.modal');
|
||||
await cpHelpers.editFavoriteName('.modal', "some name");
|
||||
await cpHelpers.saveFavorite('.modal');
|
||||
|
||||
testUtils.mock.unpatch(ListController);
|
||||
parent.destroy();
|
||||
@@ -555,7 +561,7 @@ QUnit.module('Views', {
|
||||
this.data.partner.records[0].poney_ids = [];
|
||||
var reject = true;
|
||||
|
||||
var parent = createParent({
|
||||
var parent = await createParent({
|
||||
data: this.data,
|
||||
archs: {
|
||||
'partner,false,form':
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
odoo.define('web.data_export_tests', function (require) {
|
||||
"use strict";
|
||||
|
||||
var framework = require('web.framework');
|
||||
var ListView = require('web.ListView');
|
||||
var testUtils = require('web.test_utils');
|
||||
var data = require('web.data');
|
||||
const framework = require('web.framework');
|
||||
const ListView = require('web.ListView');
|
||||
const testUtils = require('web.test_utils');
|
||||
const data = require('web.data');
|
||||
|
||||
var createView = testUtils.createView;
|
||||
const cpHelpers = testUtils.controlPanel;
|
||||
const createView = testUtils.createView;
|
||||
|
||||
QUnit.module('widgets', {
|
||||
beforeEach: function () {
|
||||
@@ -63,7 +64,7 @@ QUnit.module('widgets', {
|
||||
data: this.data,
|
||||
arch: '<tree><field name="foo"/></tree>',
|
||||
viewOptions: {
|
||||
hasSidebar: true,
|
||||
hasActionMenus: true,
|
||||
},
|
||||
mockRPC: function (route) {
|
||||
if (route === '/web/export/formats') {
|
||||
@@ -104,9 +105,11 @@ QUnit.module('widgets', {
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
await testUtils.dom.click(list.$('thead th.o_list_record_selector input'));
|
||||
await testUtils.dom.click(list.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
|
||||
await testUtils.dom.click(list.sidebar.$('a:contains(Export)'));
|
||||
|
||||
await cpHelpers.toggleActionMenu(list);
|
||||
await cpHelpers.toggleMenuItem(list, 'Export');
|
||||
|
||||
assert.strictEqual($('.modal').length, 1, "a modal dialog should be open");
|
||||
assert.strictEqual($('div.o_tree_column:contains(Activities)').length, 1,
|
||||
@@ -144,7 +147,7 @@ QUnit.module('widgets', {
|
||||
data: this.data,
|
||||
arch: '<tree><field name="foo"/></tree>',
|
||||
viewOptions: {
|
||||
hasSidebar: true,
|
||||
hasActionMenus: true,
|
||||
},
|
||||
mockRPC: function (route) {
|
||||
if (route === '/web/export/formats') {
|
||||
@@ -179,10 +182,12 @@ QUnit.module('widgets', {
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
// Open the export modal
|
||||
await testUtils.dom.click(list.$('thead th.o_list_record_selector input'));
|
||||
await testUtils.dom.click(list.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
|
||||
await testUtils.dom.click(list.sidebar.$('a:contains(Export)'));
|
||||
await cpHelpers.toggleActionMenu(list);
|
||||
await cpHelpers.toggleMenuItem(list, 'Export');
|
||||
|
||||
assert.strictEqual($('.modal').length, 1,
|
||||
"a modal dialog should be open");
|
||||
|
||||
@@ -214,7 +219,7 @@ QUnit.module('widgets', {
|
||||
data: this.data,
|
||||
arch: '<tree><field name="foo"/></tree>',
|
||||
viewOptions: {
|
||||
hasSidebar: true,
|
||||
hasActionMenus: true,
|
||||
},
|
||||
mockRPC: function (route) {
|
||||
if (route === '/web/export/formats') {
|
||||
@@ -248,10 +253,12 @@ QUnit.module('widgets', {
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
// Open the export modal
|
||||
await testUtils.dom.click(list.$('thead .o_list_record_selector input'));
|
||||
await testUtils.dom.click(list.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
|
||||
await testUtils.dom.click(list.sidebar.$('a:contains(Export)'));
|
||||
await testUtils.dom.click(list.$('thead th.o_list_record_selector input'));
|
||||
await cpHelpers.toggleActionMenu(list);
|
||||
await cpHelpers.toggleMenuItem(list, 'Export');
|
||||
|
||||
assert.strictEqual($('.modal .o_export_tree_item:visible').length, 2, "There should be only two items visible");
|
||||
await testUtils.dom.click($('.modal .o_export_search_input'));
|
||||
@@ -333,7 +340,6 @@ QUnit.module('widgets', {
|
||||
View: ListView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
debug: true,
|
||||
arch: `
|
||||
<tree>
|
||||
<field name="foo"/>
|
||||
|
||||
@@ -1,203 +0,0 @@
|
||||
odoo.define('web.dropdown_menu_tests', function (require) {
|
||||
"use strict";
|
||||
|
||||
var DropdownMenu = require('web.DropdownMenu');
|
||||
var testUtils = require('web.test_utils');
|
||||
|
||||
function createDropdownMenu(items, params) {
|
||||
params = params || {};
|
||||
var target = params.debug ? document.body : $('#qunit-fixture');
|
||||
var menu = new DropdownMenu(null, items);
|
||||
testUtils.mock.addMockEnvironment(menu, params);
|
||||
return menu.appendTo(target).then(function() {
|
||||
return menu;
|
||||
});
|
||||
}
|
||||
|
||||
QUnit.module('Web', {
|
||||
beforeEach: function () {
|
||||
this.items = [
|
||||
{
|
||||
isActive: false,
|
||||
description: 'Some Item',
|
||||
id: 1,
|
||||
groupId: 1,
|
||||
groupNumber: 1,
|
||||
},
|
||||
{
|
||||
isActive: true,
|
||||
description: 'Some other Item',
|
||||
id: 2,
|
||||
groupId: 2,
|
||||
groupNumber: 2,
|
||||
},
|
||||
];
|
||||
},
|
||||
}, function () {
|
||||
QUnit.module('DropdownMenu');
|
||||
|
||||
QUnit.test('simple rendering', async function (assert) {
|
||||
assert.expect(4);
|
||||
|
||||
var dropdownMenu = await createDropdownMenu(this.items);
|
||||
assert.containsN(dropdownMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text', 4,
|
||||
'should have 4 elements counting the dividers');
|
||||
assert.strictEqual(dropdownMenu.$('.o_menu_item').first().text().trim(), 'Some Item',
|
||||
'first element should have "Some Item" description');
|
||||
assert.ok(!dropdownMenu.$('.o_menu_item > .dropdown-item').eq(0).hasClass('selected'),
|
||||
'first element should not be selected');
|
||||
assert.ok(dropdownMenu.$('.o_menu_item > .dropdown-item').eq(1).hasClass('selected'),
|
||||
'second element should be selected');
|
||||
|
||||
dropdownMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('click on an item without options should toggle it', async function (assert) {
|
||||
assert.expect(7);
|
||||
|
||||
var self = this;
|
||||
var dropdownMenu = await createDropdownMenu(this.items, {
|
||||
intercepts: {
|
||||
menu_item_clicked: function (ev) {
|
||||
assert.strictEqual(ev.data.id, 1);
|
||||
self.items[0].isActive = !self.items[0].isActive;
|
||||
dropdownMenu.update(self.items);
|
||||
},
|
||||
},
|
||||
});
|
||||
await testUtils.dom.click(dropdownMenu.$('button:first'));
|
||||
assert.doesNotHaveClass(dropdownMenu.$('.o_menu_item:first > .dropdown-item').first(), 'selected');
|
||||
await testUtils.dom.click(dropdownMenu.$('.o_menu_item a').first());
|
||||
assert.hasClass(dropdownMenu.$('.o_menu_item:first > .dropdown-item'), 'selected');
|
||||
assert.ok(dropdownMenu.$('.o_menu_item:first').is(':visible'),
|
||||
'item should still be visible');
|
||||
await testUtils.dom.click(dropdownMenu.$('.o_menu_item a').first());
|
||||
assert.doesNotHaveClass(dropdownMenu.$('.o_menu_item:first > .dropdown-item').first(), 'selected');
|
||||
assert.ok(dropdownMenu.$('.o_menu_item:first').is(':visible'),
|
||||
'item should still be visible');
|
||||
dropdownMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('click on an item should not change url', async function (assert) {
|
||||
assert.expect(0);
|
||||
|
||||
var dropdownMenu = await createDropdownMenu(this.items);
|
||||
await testUtils.dom.click(dropdownMenu.$('.o_dropdown_toggler_btn'));
|
||||
dropdownMenu.$el.click(function () {
|
||||
// we do not want a click to get out and change the url, for example
|
||||
throw new Error('No click should get out of the dropdown menu');
|
||||
});
|
||||
await testUtils.dom.click(dropdownMenu.$('.o_menu_item a').first());
|
||||
|
||||
dropdownMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('options rendering', async function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
this.items[0].hasOptions = true;
|
||||
this.items[0].options = [
|
||||
{optionId: 1, description: "First Option", groupId: 1},
|
||||
{optionId: 2, description: "Second Option", groupId: 1}
|
||||
];
|
||||
this.items[0].currentOptionIds = new Set();
|
||||
var dropdownMenu = await createDropdownMenu(this.items);
|
||||
testUtils.dom.click(dropdownMenu.$('button:first'));
|
||||
assert.containsN(dropdownMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text', 4);
|
||||
// open options menu
|
||||
await testUtils.dom.click(dropdownMenu.$('span.fa-caret-right'));
|
||||
assert.containsN(dropdownMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text', 7);
|
||||
// close options menu
|
||||
await testUtils.dom.click(dropdownMenu.$('span.fa-caret-down'));
|
||||
assert.containsN(dropdownMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text', 4);
|
||||
|
||||
dropdownMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('close menu closes also submenus', async function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
this.items[0].hasOptions = true;
|
||||
this.items[0].options = [
|
||||
{optionId: 1, description: "First Option"},
|
||||
{optionId: 2, description: "Second Option"}
|
||||
];
|
||||
this.items[0].currentOptionIds = new Set();
|
||||
var dropdownMenu = await createDropdownMenu(this.items);
|
||||
// open dropdown menu
|
||||
testUtils.dom.click(dropdownMenu.$('button:first'));
|
||||
// open options menu
|
||||
await testUtils.dom.click(dropdownMenu.$('span.fa-caret-right'));
|
||||
assert.containsN(dropdownMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text', 7);
|
||||
await testUtils.dom.click(dropdownMenu.$('button:first'));
|
||||
await testUtils.dom.click(dropdownMenu.$('button:first'));
|
||||
assert.containsN(dropdownMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text', 4);
|
||||
|
||||
dropdownMenu.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('click on an option should trigger the event "item_option_clicked" with appropriate data', async function (assert) {
|
||||
assert.expect(18);
|
||||
|
||||
var self = this;
|
||||
var eventNumber = 0;
|
||||
this.items[0].hasOptions = true;
|
||||
this.items[0].options = [
|
||||
{optionId: 1, description: "First Option"},
|
||||
{optionId: 2, description: "Second Option"}
|
||||
];
|
||||
this.items[0].currentOptionIds = new Set();
|
||||
var dropdownMenu = await createDropdownMenu(this.items, {
|
||||
intercepts: {
|
||||
item_option_clicked: function (ev) {
|
||||
eventNumber++;
|
||||
assert.strictEqual(ev.data.id, 1);
|
||||
if (eventNumber === 1) {
|
||||
assert.strictEqual(ev.data.optionId, 1);
|
||||
self.items[0].isActive = true;
|
||||
self.items[0].currentOptionIds.add(1);
|
||||
}
|
||||
if (eventNumber === 2) {
|
||||
assert.strictEqual(ev.data.optionId, 2);
|
||||
self.items[0].currentOptionIds = new Set([1,2]);
|
||||
}
|
||||
if (eventNumber === 3) {
|
||||
assert.strictEqual(ev.data.optionId, 1);
|
||||
self.items[0].currentOptionIds = new Set([2]);
|
||||
}
|
||||
if (eventNumber === 4) {
|
||||
assert.strictEqual(ev.data.optionId, 2);
|
||||
self.items[0].isActive = false;
|
||||
self.items[0].currentOptionIds.clear();
|
||||
}
|
||||
dropdownMenu.update(self.items);
|
||||
},
|
||||
},
|
||||
});
|
||||
await testUtils.nextTick();
|
||||
// open dropdown menu
|
||||
await testUtils.dom.click(dropdownMenu.$('button:first'));
|
||||
assert.containsN(dropdownMenu, '.dropdown-divider, .o_menu_item', 4);
|
||||
await testUtils.dom.clickFirst(dropdownMenu.$('.o_menu_item'));
|
||||
// click on first option
|
||||
await testUtils.dom.click(dropdownMenu.$('.o_item_option > .dropdown-item').eq(0));
|
||||
assert.hasClass(dropdownMenu.$('.o_menu_item > .dropdown-item').first(), 'selected');
|
||||
assert.hasClass(dropdownMenu.$('.o_item_option> .dropdown-item').eq(0),'selected');
|
||||
assert.doesNotHaveClass(dropdownMenu.$('.o_item_option > .dropdown-item').eq(1), 'selected');
|
||||
// click on second option
|
||||
await testUtils.dom.click($('.o_item_option > .dropdown-item').eq(1));
|
||||
assert.hasClass(dropdownMenu.$('.o_menu_item > .dropdown-item').first(), 'selected');
|
||||
assert.hasClass(dropdownMenu.$('.o_item_option > .dropdown-item').eq(0), 'selected');
|
||||
assert.hasClass(dropdownMenu.$('.o_item_option > .dropdown-item').eq(1), 'selected');
|
||||
// click again on first option
|
||||
await testUtils.dom.click(dropdownMenu.$('.o_item_option > .dropdown-item').eq(0));
|
||||
// click again on second option
|
||||
await testUtils.dom.click($('.o_item_option > .dropdown-item').eq(1));
|
||||
assert.doesNotHaveClass(dropdownMenu.$('.o_menu_item > .dropdown-item').first(), 'selected');
|
||||
assert.doesNotHaveClass(dropdownMenu.$('.o_item_option > .dropdown-item').eq(0), 'selected');
|
||||
assert.doesNotHaveClass(dropdownMenu.$('.o_item_option > .dropdown-item').eq(1), 'selected');
|
||||
|
||||
dropdownMenu.destroy();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -46,7 +46,7 @@ tour.register('shop_cart_recovery', {
|
||||
},
|
||||
{
|
||||
content: "click action",
|
||||
trigger: '.btn:containsExact("Action")',
|
||||
trigger: '.o_dropdown_toggler_btn:contains("Action")',
|
||||
},
|
||||
{
|
||||
content: "click Send a Cart Recovery Email",
|
||||
|
||||
@@ -77,6 +77,11 @@ odoo.define('web.test.x2many', function (require) {
|
||||
}, { // add message a
|
||||
content: "Select First Tab",
|
||||
trigger: 'a[role=tab]:first',
|
||||
// We check the "Save" button is in the DOM to ensure that the form renderer
|
||||
// is fully loaded and is on the right pane (right now the renderer dispatches
|
||||
// a click on its last active pane header. We can remove this assert once the
|
||||
// form renderer behaves properly).
|
||||
extra_trigger: 'button.o_form_button_save',
|
||||
}, {
|
||||
content: "create new message a",
|
||||
trigger: '.o_form_sheet .tab-pane:eq(0) .o_field_x2many_list_row_add a'
|
||||
|
||||
Reference in New Issue
Block a user