diff --git a/addons/calendar/static/tests/systray_activity_menu_tests.js b/addons/calendar/static/tests/systray_activity_menu_tests.js
index a8b0d24956c..3a0bcdd50f8 100644
--- a/addons/calendar/static/tests/systray_activity_menu_tests.js
+++ b/addons/calendar/static/tests/systray_activity_menu_tests.js
@@ -3,8 +3,10 @@
import { start, startServer } from '@mail/../tests/helpers/test_utils';
import ActivityMenu from '@mail/js/systray/systray_activity_menu';
+import { Items as legacySystrayItems } from 'web.SystrayMenu';
import testUtils from 'web.test_utils';
-import { patchDate } from "@web/../tests/helpers/utils";
+import { registerCleanup } from '@web/../tests/helpers/cleanup';
+import { patchDate, patchWithCleanup } from "@web/../tests/helpers/utils";
QUnit.module('calendar', {}, function () {
QUnit.module('ActivityMenu');
@@ -29,23 +31,25 @@ QUnit.test('activity menu widget:today meetings', async function (assert) {
attendee_ids: [calendarAttendeeId1],
},
]);
- const { widget } = await start();
-
- const activityMenu = new ActivityMenu(widget);
- await activityMenu.appendTo($('#qunit-fixture'));
-
- assert.hasClass(activityMenu.$el, 'o_mail_systray_item', 'should be the instance of widget');
-
- await testUtils.dom.click(activityMenu.$('.dropdown-toggle'));
-
- testUtils.mock.intercept(activityMenu, 'do_action', function (event) {
- assert.strictEqual(event.data.action, "calendar.action_calendar_event", 'should open meeting calendar view in day mode');
+ legacySystrayItems.push(ActivityMenu);
+ registerCleanup(() => legacySystrayItems.pop());
+ const { wowlEnv: env } = await start({
+ hasWebClient: true,
});
- await testUtils.dom.click(activityMenu.$('.o_mail_preview'));
+ assert.containsOnce(document.body, '.o_mail_systray_item', 'should contain an instance of widget');
- assert.ok(activityMenu.$('.o_meeting_filter'), "should be a meeting");
- assert.containsN(activityMenu, '.o_meeting_filter', 2, 'there should be 2 meetings');
- assert.hasClass(activityMenu.$('.o_meeting_filter').eq(0), 'o_meeting_bold', 'this meeting is yet to start');
- assert.doesNotHaveClass(activityMenu.$('.o_meeting_filter').eq(1), 'o_meeting_bold', 'this meeting has been started');
+ await testUtils.dom.click(document.querySelector('.dropdown-toggle[title="Activities"]'));
+
+ patchWithCleanup(env.services.action, {
+ doAction(action) {
+ assert.strictEqual(action, "calendar.action_calendar_event", 'should open meeting calendar view in day mode');
+ },
+ });
+ await testUtils.dom.click(document.querySelector('.o_mail_preview'));
+
+ assert.ok(document.querySelector('.o_meeting_filter'), "should be a meeting");
+ assert.containsN(document.body, '.o_meeting_filter', 2, 'there should be 2 meetings');
+ assert.hasClass(document.querySelector('.o_meeting_filter'), 'o_meeting_bold', 'this meeting is yet to start');
+ assert.doesNotHaveClass(document.querySelectorAll('.o_meeting_filter')[1], 'o_meeting_bold', 'this meeting has been started');
});
});
diff --git a/addons/mail/static/tests/helpers/test_utils.js b/addons/mail/static/tests/helpers/test_utils.js
index 54e2d49da94..ed965ffaf03 100644
--- a/addons/mail/static/tests/helpers/test_utils.js
+++ b/addons/mail/static/tests/helpers/test_utils.js
@@ -189,6 +189,13 @@ async function getModelDefinitions() {
}
let pyEnv;
+const VIEW_TYPE_TO_ARCH = {
+ activity: '',
+ form: '
',
+ list: '',
+ search: '',
+ kanban: '',
+};
/**
* Creates an environment that can be used to setup test data as well as
* creating data after test start.
@@ -198,6 +205,7 @@ let pyEnv;
*/
export async function startServer() {
const data = { ...TEST_USER_IDS };
+ const views = {};
const modelDefinitions = await modelDefinitionsPromise;
const recordsToInsertRegistry = registry.category('mail.model.definitions').category('recordsToInsert');
for (const [modelName, fields] of modelDefinitions) {
@@ -207,12 +215,20 @@ let pyEnv;
records.push(...JSON.parse(JSON.stringify(recordsToInsertRegistry.get(modelName))));
}
data[modelName] = { fields: { ...fields }, records };
+
+ // generate default views for this model.
+ for (const [viewType, viewArch] of Object.entries(VIEW_TYPE_TO_ARCH)) {
+ views[`${modelName},false,${viewType}`] = viewArch;
+ }
}
pyEnv = new Proxy(
{
...TEST_USER_IDS,
get currentPartner() {
return this.mockServer.currentPartner;
+ },
+ getViews() {
+ return views;
}
},
{
@@ -761,6 +777,7 @@ async function start(param0 = {}) {
if (hasWebClient) {
param0.serverData = param0.serverData || getActionManagerServerData();
param0.serverData.models = data;
+ param0.serverData.views = { ...pyEnv.getViews(), ...param0.serverData.views };
} else {
param0.data = data;
}
@@ -871,6 +888,7 @@ async function start(param0 = {}) {
mockServer,
pyEnv,
widget,
+ wowlEnv: hasWebClient ? widget.env : undefined,
};
if (hasTimeControl) {
result['advanceTime'] = env.testUtils.advanceTime;
@@ -898,7 +916,7 @@ async function start(param0 = {}) {
result['discussWidget'] = discussWidget;
}
await waitUntilEventPromise;
- const target = widget.el;
+ const target = hasWebClient ? webclientTarget : widget.el;
return {
...result,
afterNextRender,
diff --git a/addons/note/static/tests/systray_activity_menu_tests.js b/addons/note/static/tests/systray_activity_menu_tests.js
index 32dbdd9e85c..26c9567ef38 100644
--- a/addons/note/static/tests/systray_activity_menu_tests.js
+++ b/addons/note/static/tests/systray_activity_menu_tests.js
@@ -3,7 +3,9 @@
import ActivityMenu from '@mail/js/systray/systray_activity_menu';
import { start } from '@mail/../tests/helpers/test_utils';
+import { Items as legacySystrayItems } from 'web.SystrayMenu';
import testUtils from 'web.test_utils';
+import { registerCleanup } from '@web/../tests/helpers/cleanup';
QUnit.module('note', {}, function () {
QUnit.module("ActivityMenu");
@@ -11,56 +13,56 @@ QUnit.module("ActivityMenu");
QUnit.test('note activity menu widget: create note from activity menu', async function (assert) {
assert.expect(15);
- const { widget } = await start();
+ legacySystrayItems.push(ActivityMenu);
+ registerCleanup(() => legacySystrayItems.pop());
- const activityMenu = new ActivityMenu(widget);
- await activityMenu.appendTo($('#qunit-fixture'));
- assert.hasClass(activityMenu.$el, 'o_mail_systray_item',
- 'should be the instance of widget');
+ await start({ hasWebClient: true });
+ assert.containsOnce(document.body, '.o_mail_systray_item',
+ 'should contain an instance of widget');
await testUtils.nextTick();
- assert.strictEqual(activityMenu.$('.o_notification_counter').text(), '0',
+ assert.strictEqual(document.querySelector('.o_notification_counter').innerText, '0',
"should not have any activity notification initially");
// toggle quick create for note
- await testUtils.dom.click(activityMenu.$('.dropdown-toggle'));
- assert.containsOnce(activityMenu, '.o_no_activity',
+ await testUtils.dom.click(document.querySelector('.dropdown-toggle[title="Activities"]'));
+ assert.containsOnce(document.body, '.o_no_activity',
"should not have any activity preview");
- assert.doesNotHaveClass(activityMenu.$('.o_note_show'), 'd-none',
+ assert.doesNotHaveClass(document.querySelector('.o_note_show'), 'd-none',
'ActivityMenu should have Add new note CTA');
- await testUtils.dom.click(activityMenu.$('.o_note_show'));
- assert.hasClass(activityMenu.$('.o_note_show'), 'd-none',
+ await testUtils.dom.click(document.querySelector('.o_note_show'));
+ assert.hasClass(document.querySelector('.o_note_show'), 'd-none',
'ActivityMenu should hide CTA when entering a new note');
- assert.doesNotHaveClass(activityMenu.$('.o_note'), 'd-none',
+ assert.doesNotHaveClass(document.querySelector('.o_note'), 'd-none',
'ActivityMenu should display input for new note');
// creating quick note without date
- await testUtils.fields.editInput(activityMenu.$("input.o_note_input"), "New Note");
- await testUtils.dom.click(activityMenu.$(".o_note_save"));
- assert.strictEqual(activityMenu.$('.o_notification_counter').text(), '1',
+ await testUtils.fields.editInput(document.querySelector("input.o_note_input"), "New Note");
+ await testUtils.dom.click(document.querySelector(".o_note_save"));
+ assert.strictEqual(document.querySelector('.o_notification_counter').innerText, '1',
"should increment activity notification counter after creating a note");
- assert.containsOnce(activityMenu, '.o_mail_preview[data-res_model="note.note"]',
+ assert.containsOnce(document.body, '.o_mail_preview[data-res_model="note.note"]',
"should have an activity preview that is a note");
- assert.strictEqual(activityMenu.$('.o_activity_filter_button[data-filter="today"]').text().trim(),
+ assert.strictEqual(document.querySelector('.o_activity_filter_button[data-filter="today"]').innerText.trim(),
"1 Today",
"should display one note for today");
- assert.doesNotHaveClass(activityMenu.$('.o_note_show'), 'd-none',
+ assert.doesNotHaveClass(document.querySelector('.o_note_show'), 'd-none',
'ActivityMenu add note button should be displayed');
- assert.hasClass(activityMenu.$('.o_note'), 'd-none',
+ assert.hasClass(document.querySelector('.o_note'), 'd-none',
'ActivityMenu add note input should be hidden');
// creating quick note with date
- await testUtils.dom.click(activityMenu.$('.o_note_show'));
- activityMenu.$('input.o_note_input').val("New Note");
- await testUtils.dom.click(activityMenu.$(".o_note_save"));
- assert.strictEqual(activityMenu.$('.o_notification_counter').text(), '2',
+ await testUtils.dom.click(document.querySelector('.o_note_show'));
+ document.querySelector('input.o_note_input').value = "New Note";
+ await testUtils.dom.click(document.querySelector(".o_note_save"));
+ assert.strictEqual(document.querySelector('.o_notification_counter').innerText, '2',
"should increment activity notification counter after creating a second note");
- assert.strictEqual(activityMenu.$('.o_activity_filter_button[data-filter="today"]').text().trim(),
+ assert.strictEqual(document.querySelector('.o_activity_filter_button[data-filter="today"]').innerText.trim(),
"2 Today",
"should display 2 notes for today");
- assert.doesNotHaveClass(activityMenu.$('.o_note_show'), 'd-none',
+ assert.doesNotHaveClass(document.querySelector('.o_note_show'), 'd-none',
'ActivityMenu add note button should be displayed');
- assert.hasClass(activityMenu.$('.o_note'), 'd-none',
+ assert.hasClass(document.querySelector('.o_note'), 'd-none',
'ActivityMenu add note input should be hidden');
});
});
diff --git a/addons/test_mail/static/tests/systray_activity_menu_tests.js b/addons/test_mail/static/tests/systray_activity_menu_tests.js
index 322e502df43..00690df9cd6 100644
--- a/addons/test_mail/static/tests/systray_activity_menu_tests.js
+++ b/addons/test_mail/static/tests/systray_activity_menu_tests.js
@@ -6,8 +6,13 @@ import {
startServer,
} from '@mail/../tests/helpers/test_utils';
+import session from 'web.session';
+import { Items as legacySystrayItems } from 'web.SystrayMenu';
import testUtils from 'web.test_utils';
import { date_to_str } from 'web.time';
+import { registerCleanup } from '@web/../tests/helpers/cleanup';
+import { patchWithCleanup } from '@web/../tests/helpers/utils';
+
QUnit.module('test_mail', {}, function () {
QUnit.module('systray_activity_menu_tests.js', {
@@ -26,125 +31,130 @@ QUnit.module('systray_activity_menu_tests.js', {
{ date_deadline: date_to_str(tomorrow), res_id: mailTestActivityIds[2], res_model: 'mail.test.activity' },
{ date_deadline: date_to_str(yesterday), res_id: mailTestActivityIds[3], res_model: 'mail.test.activity' },
]);
- this.session = {
- uid: 10,
- };
},
});
QUnit.test('activity menu widget: menu with no records', async function (assert) {
assert.expect(1);
- const { widget } = await start({
+ legacySystrayItems.push(ActivityMenu);
+ registerCleanup(() => legacySystrayItems.pop());
+ await start({
+ hasWebClient: true,
mockRPC: function (route, args) {
if (args.method === 'systray_get_activities') {
return Promise.resolve([]);
}
- return this._super(route, args);
},
});
- const activityMenu = new ActivityMenu(widget);
- await activityMenu.appendTo($('#qunit-fixture'));
await testUtils.nextTick();
- assert.containsOnce(activityMenu, '.o_no_activity');
+ assert.containsOnce(document.body, '.o_no_activity');
});
QUnit.test('activity menu widget: activity menu with 2 models', async function (assert) {
assert.expect(10);
- const { widget } = await start();
- var activityMenu = new ActivityMenu(widget);
- await activityMenu.appendTo($('#qunit-fixture'));
+ legacySystrayItems.push(ActivityMenu);
+ registerCleanup(() => legacySystrayItems.pop());
+ const { wowlEnv: env } = await start({
+ hasWebClient: true,
+ });
+
await testUtils.nextTick();
- assert.hasClass(activityMenu.$el, 'o_mail_systray_item', 'should be the instance of widget');
+ assert.containsOnce(document.body, '.o_mail_systray_item', 'should contain an instance of widget');
// the assertion below has not been replace because there are includes of ActivityMenu that modify the length.
- assert.ok(activityMenu.$('.o_mail_preview').length);
- assert.containsOnce(activityMenu.$el, '.o_notification_counter', "widget should have notification counter");
- assert.strictEqual(parseInt(activityMenu.el.innerText), 5, "widget should have 5 notification counter");
+ assert.ok(document.querySelectorAll('.o_mail_preview').length);
+ assert.containsOnce(document.body, '.o_notification_counter', "widget should have notification counter");
+ assert.strictEqual(parseInt(document.querySelector('.o_notification_counter').innerText), 5, "widget should have 5 notification counter");
var context = {};
- testUtils.mock.intercept(activityMenu, 'do_action', function (event) {
- assert.deepEqual(event.data.action.context, context, "wrong context value");
- }, true);
+ patchWithCleanup(env.services.action, {
+ doAction(action) {
+ assert.deepEqual(action.context, context, "wrong context value");
+ },
+ });
// case 1: click on "late"
context = {
force_search_count: 1,
search_default_activities_overdue: 1,
};
- await testUtils.dom.click(activityMenu.$('.dropdown-toggle'));
- assert.hasClass(activityMenu.$el, 'show', 'ActivityMenu should be open');
- await testUtils.dom.click(activityMenu.$(".o_activity_filter_button[data-model_name='mail.test.activity'][data-filter='overdue']"));
- assert.doesNotHaveClass(activityMenu.$el, 'show', 'ActivityMenu should be closed');
+ await testUtils.dom.click(document.querySelector('.dropdown-toggle[title="Activities"]'));
+ assert.containsOnce(document.body, '.o_mail_systray_dropdown.show', 'ActivityMenu should be open');
+ await testUtils.dom.click(document.querySelector(".o_activity_filter_button[data-model_name='mail.test.activity'][data-filter='overdue']"));
+ assert.containsNone(document.body, '.show', 'ActivityMenu should be closed');
// case 2: click on "today"
context = {
force_search_count: 1,
search_default_activities_today: 1,
};
- await testUtils.dom.click(activityMenu.$('.dropdown-toggle'));
- await testUtils.dom.click(activityMenu.$(".o_activity_filter_button[data-model_name='mail.test.activity'][data-filter='today']"));
+ await testUtils.dom.click(document.querySelector('.dropdown-toggle[title="Activities"]'));
+ await testUtils.dom.click(document.querySelector(".o_activity_filter_button[data-model_name='mail.test.activity'][data-filter='today']"));
// case 3: click on "future"
context = {
force_search_count: 1,
search_default_activities_upcoming_all: 1,
};
- await testUtils.dom.click(activityMenu.$('.dropdown-toggle'));
- await testUtils.dom.click(activityMenu.$(".o_activity_filter_button[data-model_name='mail.test.activity'][data-filter='upcoming_all']"));
+ await testUtils.dom.click(document.querySelector('.dropdown-toggle[title="Activities"]'));
+ await testUtils.dom.click(document.querySelector(".o_activity_filter_button[data-model_name='mail.test.activity'][data-filter='upcoming_all']"));
// case 4: click anywere else
context = {
force_search_count: 1,
search_default_activities_overdue: 1,
search_default_activities_today: 1,
};
- await testUtils.dom.click(activityMenu.$('.dropdown-toggle'));
- await testUtils.dom.click(activityMenu.$(".o_mail_systray_dropdown_items > div[data-model_name='mail.test.activity']"));
+ await testUtils.dom.click(document.querySelector('.dropdown-toggle[title="Activities"]'));
+ await testUtils.dom.click(document.querySelector(".o_mail_systray_dropdown_items > div[data-model_name='mail.test.activity']"));
});
QUnit.test('activity menu widget: activity view icon', async function (assert) {
assert.expect(14);
- const { widget } = await start({
- session: this.session,
+ patchWithCleanup(session, { uid: 10 });
+ legacySystrayItems.push(ActivityMenu);
+ registerCleanup(() => legacySystrayItems.pop());
+ const { wowlEnv: env } = await start({
+ hasWebClient: true,
});
- var activityMenu = new ActivityMenu(widget);
- await activityMenu.appendTo($('#qunit-fixture'));
await testUtils.nextTick();
- assert.containsN(activityMenu, '.o_mail_activity_action', 2,
+ assert.containsN(document.body, '.o_mail_activity_action', 2,
"widget should have 2 activity view icons");
- var $first = activityMenu.$('.o_mail_activity_action').eq(0);
- var $second = activityMenu.$('.o_mail_activity_action').eq(1);
- assert.strictEqual($first.data('model_name'), "res.partner",
+ var first = document.querySelector('.o_mail_activity_action');
+ var second = document.querySelectorAll('.o_mail_activity_action')[1];
+ assert.strictEqual(first.getAttribute('data-model_name'), "res.partner",
"first activity action should link to 'res.partner'");
- assert.hasClass($first, 'fa-clock-o', "should display the activity action icon");
+ assert.hasClass(first, 'fa-clock-o', "should display the activity action icon");
- assert.strictEqual($second.data('model_name'), "mail.test.activity",
+ assert.strictEqual(second.getAttribute('data-model_name'), "mail.test.activity",
"Second activity action should link to 'mail.test.activity'");
- assert.hasClass($second, 'fa-clock-o', "should display the activity action icon");
+ assert.hasClass(second, 'fa-clock-o', "should display the activity action icon");
- testUtils.mock.intercept(activityMenu, 'do_action', function (ev) {
- if (ev.data.action.name) {
- assert.ok(ev.data.action.domain, "should define a domain on the action");
- assert.deepEqual(ev.data.action.domain, [["activity_ids.user_id", "=", 10]],
- "should set domain to user's activity only");
- assert.step('do_action:' + ev.data.action.name);
- } else {
- assert.step('do_action:' + ev.data.action);
- }
- }, true);
+ patchWithCleanup(env.services.action, {
+ doAction(action) {
+ if (action.name) {
+ assert.ok(action.domain, "should define a domain on the action");
+ assert.deepEqual(action.domain, [["activity_ids.user_id", "=", 10]],
+ "should set domain to user's activity only");
+ assert.step('do_action:' + action.name);
+ } else {
+ assert.step('do_action:' + action);
+ }
+ },
+ });
// click on the "mail.test.activity" activity icon
- await testUtils.dom.click(activityMenu.$('.dropdown-toggle'));
- assert.hasClass(activityMenu.$('.dropdown-menu'), 'show',
+ await testUtils.dom.click(document.querySelector('.dropdown-toggle[title="Activities"]'));
+ assert.hasClass(document.querySelector('.dropdown-menu'), 'show',
"dropdown should be expanded");
- await testUtils.dom.click(activityMenu.$(".o_mail_activity_action[data-model_name='mail.test.activity']"));
- assert.doesNotHaveClass(activityMenu.$('.dropdown-menu'), 'show',
+ await testUtils.dom.click(document.querySelector(".o_mail_activity_action[data-model_name='mail.test.activity']"));
+ assert.doesNotHaveClass(document.querySelector('.dropdown-menu'), 'show',
"dropdown should be collapsed");
// click on the "res.partner" activity icon
- await testUtils.dom.click(activityMenu.$('.dropdown-toggle'));
- await testUtils.dom.click(activityMenu.$(".o_mail_activity_action[data-model_name='res.partner']"));
+ await testUtils.dom.click(document.querySelector('.dropdown-toggle[title="Activities"]'));
+ await testUtils.dom.click(document.querySelector(".o_mail_activity_action[data-model_name='res.partner']"));
assert.verifySteps([
'do_action:mail.test.activity',
@@ -155,22 +165,24 @@ QUnit.test('activity menu widget: activity view icon', async function (assert) {
QUnit.test('activity menu widget: close on messaging menu click', async function (assert) {
assert.expect(2);
- const { click, createMessagingMenuComponent, widget } = await start();
+ legacySystrayItems.push(ActivityMenu);
+ registerCleanup(() => legacySystrayItems.pop());
+ const { click, createMessagingMenuComponent } = await start({
+ hasWebClient: true,
+ });
await createMessagingMenuComponent();
- const activityMenu = new ActivityMenu(widget);
- await activityMenu.appendTo($('#qunit-fixture'));
await testUtils.nextTick();
- await testUtils.dom.click(activityMenu.$('.dropdown-toggle'));
+ await testUtils.dom.click(document.querySelector('.dropdown-toggle[title="Activities"]'));
assert.hasClass(
- activityMenu.el.querySelector('.o_mail_systray_dropdown'),
+ document.querySelector('.o_mail_systray_dropdown'),
'show',
"activity menu should be shown after click on itself"
);
await click(`.o_MessagingMenu_toggler`);
assert.doesNotHaveClass(
- activityMenu.el.querySelector('.o_mail_systray_dropdown'),
+ document.querySelector('.o_mail_systray_dropdown'),
'show',
"activity menu should be hidden after click on messaging menu"
);