diff --git a/addons/test_mail/static/tests/activity_tests.js b/addons/test_mail/static/tests/activity_tests.js
index ee59cd8475c..02fb895f1f2 100644
--- a/addons/test_mail/static/tests/activity_tests.js
+++ b/addons/test_mail/static/tests/activity_tests.js
@@ -2,120 +2,81 @@
import ActivityRenderer from '@mail/js/views/activity/activity_renderer';
import ActivityView from '@mail/js/views/activity/activity_view';
+import { start, startServer } from '@mail/../tests/helpers/test_utils';
+
import testUtils from 'web.test_utils';
import domUtils from 'web.dom';
import { getFixture, legacyExtraNextTick, patchWithCleanup, click } from "@web/../tests/helpers/utils";
-import { createWebClient, doAction } from "@web/../tests/webclient/helpers";
+import { doAction } from "@web/../tests/webclient/helpers";
import { session } from '@web/session';
let serverData;
+let pyEnv;
let target;
-var createView = testUtils.createView;
-
-QUnit.module('mail', {}, function () {
+QUnit.module('test_mail', {}, function () {
QUnit.module('activity view', {
- beforeEach: function () {
- this.data = {
- task: {
- fields: {
- id: {string: 'ID', type: 'integer'},
- foo: {string: "Foo", type: "char"},
- activity_ids: {
- string: 'Activities',
- type: 'one2many',
- relation: 'mail.activity',
- relation_field: 'res_id',
- },
- },
- records: [
- {id: 13, foo: 'Meeting Room Furnitures', activity_ids: [1]},
- {id: 30, foo: 'Office planning', activity_ids: [2, 3]},
- ],
+ async beforeEach() {
+ pyEnv = await startServer();
+ const mailTemplateIds = pyEnv['mail.template'].create([{ name: "Template1" }, { name: "Template2" }]);
+ // reset incompatible setup
+ pyEnv['mail.activity.type'].unlink(pyEnv['mail.activity.type'].search([]));
+ const mailActivityTypeIds = pyEnv['mail.activity.type'].create([
+ { name: "Email", mail_template_ids: mailTemplateIds },
+ { name: "Call" },
+ { name: "Call for Demo" },
+ { name: "To Do" },
+ ]);
+ const resUsersId1 = pyEnv['res.users'].create({ display_name: 'first user' });
+ const mailActivityIds = pyEnv['mail.activity'].create([
+ {
+ display_name: "An activity",
+ date_deadline: moment().add(3, "days").format("YYYY-MM-DD"), // now
+ can_write: true,
+ state: "planned",
+ activity_type_id: mailActivityTypeIds[0],
+ mail_template_ids: mailTemplateIds,
+ user_id: resUsersId1,
},
- partner: {
- fields: {
- display_name: { string: "Displayed name", type: "char" },
- },
- records: [{
- id: 2,
- display_name: "first partner",
- }]
+ {
+ display_name: "An activity",
+ date_deadline: moment().format("YYYY-MM-DD"), // now
+ can_write: true,
+ state: "today",
+ activity_type_id: mailActivityTypeIds[0],
+ mail_template_ids: mailTemplateIds,
+ user_id: resUsersId1,
},
- 'mail.activity': {
- fields: {
- res_id: { string: 'Related document id', type: 'integer' },
- activity_type_id: { string: "Activity type", type: "many2one", relation: "mail.activity.type" },
- display_name: { string: "Display name", type: "char" },
- date_deadline: { string: "Due Date", type: "date" },
- can_write: { string: "Can write", type: "boolean" },
- state: {
- string: 'State',
- type: 'selection',
- selection: [['overdue', 'Overdue'], ['today', 'Today'], ['planned', 'Planned']],
- },
- mail_template_ids: { string: "Mail templates", type: "many2many", relation: "mail.template" },
- user_id: { string: "Assigned to", type: "many2one", relation: 'partner' },
- },
- records:[
- {
- id: 1,
- res_id: 13,
- display_name: "An activity",
- date_deadline: moment().add(3, "days").format("YYYY-MM-DD"), // now
- can_write: true,
-
- state: "planned",
- activity_type_id: 1,
- mail_template_ids: [8, 9],
- user_id:2,
- },{
- id: 2,
- res_id: 30,
- display_name: "An activity",
- date_deadline: moment().format("YYYY-MM-DD"), // now
- can_write: true,
- state: "today",
- activity_type_id: 1,
- mail_template_ids: [8, 9],
- user_id:2,
- },{
- id: 3,
- res_id: 30,
- display_name: "An activity",
- date_deadline: moment().subtract(2, "days").format("YYYY-MM-DD"), // now
- can_write: true,
- state: "overdue",
- activity_type_id: 2,
- mail_template_ids: [],
- user_id:2,
- }
- ],
+ {
+ res_model: 'mail.test.activity',
+ display_name: "An activity",
+ date_deadline: moment().subtract(2, "days").format("YYYY-MM-DD"), // now
+ can_write: true,
+ state: "overdue",
+ activity_type_id: mailActivityTypeIds[1],
+ user_id: resUsersId1,
},
- 'mail.template': {
- fields: {
- name: { string: "Name", type: "char" },
- },
- records: [
- { id: 8, name: "Template1" },
- { id: 9, name: "Template2" },
- ],
- },
- 'mail.activity.type': {
- fields: {
- mail_template_ids: { string: "Mail templates", type: "many2many", relation: "mail.template" },
- name: { string: "Name", type: "char" },
- },
- records: [
- { id: 1, name: "Email", mail_template_ids: [8, 9]},
- { id: 2, name: "Call" },
- { id: 3, name: "Call for Demo" },
- { id: 4, name: "To Do" },
- ],
+ ]);
+ pyEnv['mail.test.activity'].create([
+ { name: 'Meeting Room Furnitures', activity_ids: [mailActivityIds[0]] },
+ { name: 'Office planning', activity_ids: [mailActivityIds[1], mailActivityIds[2]] },
+ ]);
+ serverData = {
+ views : {
+ 'mail.test.activity,false,activity':
+ '' +
+ '' +
+ '' +
+ '' +
+ '
' +
+ '' +
+ '',
+ 'mail.activity,false,form': '
',
+ 'mail.test.activity,false,form': '',
+ 'mail.test.activity,false,search': '',
},
};
- serverData = { models: this.data };
target = getFixture();
}
});
@@ -126,14 +87,16 @@ var activityDateFormat = function (date) {
QUnit.test('activity view: simple activity rendering', async function (assert) {
assert.expect(14);
- var activity = await createView({
+ const mailTestActivityIds = pyEnv['mail.test.activity'].search([]);
+ const mailActivityTypeIds = pyEnv['mail.activity.type'].search([]);
+ var { widget: activity } = await start({
View: ActivityView,
- model: 'task',
- data: this.data,
+ hasView: true,
+ model: 'mail.test.activity',
arch: '' +
'' +
'' +
- '' +
+ '' +
'
' +
'' +
'',
@@ -141,9 +104,9 @@ QUnit.test('activity view: simple activity rendering', async function (assert) {
do_action: function (event) {
assert.deepEqual(event.data.action, {
context: {
- default_res_id: 30,
- default_res_model: "task",
- default_activity_type_id: 3,
+ default_res_id: mailTestActivityIds[1],
+ default_res_model: "mail.test.activity",
+ default_activity_type_id: mailActivityTypeIds[2],
},
res_id: false,
res_model: "mail.activity",
@@ -190,28 +153,22 @@ QUnit.test('activity view: simple activity rendering', async function (assert) {
await testUtils.fields.editAndTrigger(activity.$(td + ':first'), null, ['mouseenter', 'click']);
assert.containsOnce(activity, 'table tfoot tr .o_record_selector',
'should contain search more selector to choose the record to schedule an activity for it');
-
- activity.destroy();
});
QUnit.test('activity view: no content rendering', async function (assert) {
assert.expect(2);
// reset incompatible setup
- this.data['mail.activity'].records = [];
- this.data.task.records.forEach(function (task) {
- task.activity_ids = false;
- });
- this.data['mail.activity.type'].records = [];
+ pyEnv['mail.activity.type'].unlink(pyEnv['mail.activity.type'].search([]));
- var activity = await createView({
+ var { widget: activity } = await start({
+ hasView: true,
View: ActivityView,
- model: 'task',
- data: this.data,
+ model: 'mail.test.activity',
arch: '' +
'' +
'' +
- '' +
+ '' +
'
' +
'' +
'',
@@ -222,20 +179,21 @@ QUnit.test('activity view: no content rendering', async function (assert) {
assert.strictEqual(activity.$('.o_view_nocontent .o_view_nocontent_empty_folder').text().trim(),
"No data to display",
"should display the no content helper text");
-
- activity.destroy();
});
QUnit.test('activity view: batch send mail on activity', async function (assert) {
assert.expect(6);
- var activity = await createView({
+
+ const mailTestActivityIds = pyEnv['mail.test.activity'].search([]);
+ const mailTemplateIds = pyEnv['mail.template'].search([]);
+ var { widget: activity } = await start({
+ hasView: true,
View: ActivityView,
- model: 'task',
- data: this.data,
+ model: 'mail.test.activity',
arch: '' +
'' +
'' +
- '' +
+ '' +
'
' +
'' +
'',
@@ -261,30 +219,31 @@ QUnit.test('activity view: batch send mail on activity', async function (assert)
testUtils.dom.click(activity.$('table thead tr:first th:nth-child(2) span:nth-child(2) i.fa-ellipsis-v'));
testUtils.dom.click(activity.$('table thead tr:first th:nth-child(2) span:nth-child(2) .dropdown-menu.show .o_send_mail_template:contains(Template1)'));
assert.verifySteps([
- '[[13,30],9]', // send mail template 9 on tasks 13 and 30
- '[[13,30],8]', // send mail template 8 on tasks 13 and 30
+ `[[${mailTestActivityIds[0]},${mailTestActivityIds[1]}],${mailTemplateIds[1]}]`, // send mail template 1 on mail.test.activity 1 and 2
+ `[[${mailTestActivityIds[0]},${mailTestActivityIds[1]}],${mailTemplateIds[0]}]`, // send mail template 2 on mail.test.activity 1 and 2
]);
-
- activity.destroy();
});
QUnit.test('activity view: activity widget', async function (assert) {
assert.expect(16);
+ const mailActivityTypeIds = pyEnv['mail.activity.type'].search([]);
+ const [mailTestActivityId2] = pyEnv['mail.test.activity'].search([['name', '=', 'Office planning']]);
+ const [mailTemplateId1] = pyEnv['mail.template'].search([['name', '=', 'Template1']]);
const params = {
+ hasView: true,
View: ActivityView,
- model: 'task',
- data: this.data,
+ model: 'mail.test.activity',
arch: '' +
'' +
'' +
- '' +
+ '' +
'
' +
''+
'',
mockRPC: function(route, args) {
if (args.method === 'activity_send_mail'){
- assert.deepEqual([[30],8],args.args, "Should send template 8 on record 30");
+ assert.deepEqual([[mailTestActivityId2],mailTemplateId1],args.args, "Should send template 8 on record 30");
assert.step('activity_send_mail');
return Promise.resolve();
}
@@ -303,18 +262,18 @@ QUnit.test('activity view: activity widget', async function (assert) {
assert.step('serverGeneratedAction');
} else if (action.res_model === 'mail.compose.message') {
assert.deepEqual({
- default_model: "task",
- default_res_id: 30,
- default_template_id: 8,
+ default_model: 'mail.test.activity',
+ default_res_id: mailTestActivityId2,
+ default_template_id: mailTemplateId1,
default_use_template: true,
force_email: true
}, action.context);
assert.step("do_action_compose");
} else if (action.res_model === 'mail.activity') {
assert.deepEqual({
- "default_activity_type_id": 2,
- "default_res_id": 30,
- "default_res_model": "task"
+ "default_activity_type_id": mailActivityTypeIds[1],
+ "default_res_id": mailTestActivityId2,
+ "default_res_model": 'mail.test.activity',
}, action.context);
assert.step("do_action_activity");
} else {
@@ -324,7 +283,7 @@ QUnit.test('activity view: activity widget', async function (assert) {
},
};
- var activity = await createView(params);
+ var { widget: activity } = await start(params);
var today = activity.$('table tbody tr:first td:nth-child(2).today');
var dropdown = today.find('.dropdown-menu.o_activity');
@@ -367,25 +326,13 @@ QUnit.test("activity view: no group_by_menu and no comparison_menu", async funct
serverData.actions = {
1: {
id: 1,
- name: "Task Action",
- res_model: "task",
+ name: "MailTestActivity Action",
+ res_model: "mail.test.activity",
type: "ir.actions.act_window",
views: [[false, "activity"]],
},
};
- serverData.views = {
- "task,false,activity":
- '' +
- "" +
- '' +
- '' +
- "
" +
- "" +
- "",
- "task,false,search": "",
- };
-
const mockRPC = (route, args) => {
if (args.method === "get_activity_data") {
assert.strictEqual(
@@ -398,7 +345,7 @@ QUnit.test("activity view: no group_by_menu and no comparison_menu", async funct
patchWithCleanup(session.user_context, { lang: "zz_ZZ" });
- const webClient = await createWebClient({ serverData, mockRPC , legacyParams: {withLegacyMockServer: true}});
+ const { widget: webClient } = await start({ hasWebClient: true, serverData, mockRPC, legacyParams: {withLegacyMockServer: true}});
await doAction(webClient, 1);
@@ -420,24 +367,24 @@ QUnit.test("activity view: no group_by_menu and no comparison_menu", async funct
QUnit.test('activity view: search more to schedule an activity for a record of a respecting model', async function (assert) {
assert.expect(5);
- _.extend(this.data.task.fields, {
- name: { string: "Name", type: "char" },
+ const mailTestActivityId1 = pyEnv['mail.test.activity'].create({ name: 'MailTestActivity 3' });
+ Object.assign(serverData.views, {
+ 'mail.test.activity,false,list': '',
});
- this.data.task.records[2] = { id: 31, name: "Task 3" };
- var activity = await createView({
+ var { widget: activity } = await start({
+ hasView: true,
View: ActivityView,
- model: 'task',
- data: this.data,
+ model: 'mail.test.activity',
arch: '' +
'' +
'' +
- '' +
+ '' +
'
' +
'' +
'',
archs: {
- "task,false,list": '',
- "task,false,search": '',
+ "mail.test.activity,false,list": '',
+ "mail.test.activity,false,search": '',
},
mockRPC: function(route, args) {
if (args.method === 'name_search') {
@@ -450,8 +397,8 @@ QUnit.test('activity view: search more to schedule an activity for a record of a
assert.step('doAction');
var expectedAction = {
context: {
- default_res_id: { id: 31, display_name: undefined },
- default_res_model: "task",
+ default_res_id: { id: mailTestActivityId1, display_name: undefined },
+ default_res_model: "mail.test.activity",
},
name: "Schedule Activity",
res_id: false,
@@ -487,31 +434,22 @@ QUnit.test("Activity view: discard an activity creation dialog", async function
serverData.actions = {
1: {
id: 1,
- name: "Task Action",
- res_model: "task",
+ name: "MailTestActivity Action",
+ res_model: "mail.test.activity",
type: "ir.actions.act_window",
views: [[false, "activity"]],
},
};
- serverData.views = {
- "task,false,activity": `
-
-
-
-
-
-
- `,
- "task,false,search": "",
- "mail.activity,false,form": `
- `,
- };
+ Object.assign(serverData.views, {
+ 'mail.activity,false,form':
+ ``,
+ });
const mockRPC = (route, args) => {
if (args.method === "check_access_rights") {
@@ -519,7 +457,7 @@ QUnit.test("Activity view: discard an activity creation dialog", async function
}
};
- const webClient = await createWebClient({ serverData, mockRPC, legacyParams: {withLegacyMockServer: true} });
+ const { widget: webClient } = await start({ hasWebClient: true, serverData, mockRPC, legacyParams: {withLegacyMockServer: true} });
await doAction(webClient, 1);
await testUtils.dom.click(
@@ -536,51 +474,39 @@ QUnit.test("Activity view: discard an activity creation dialog", async function
QUnit.test('Activity view: many2one_avatar_user widget in activity view', async function (assert) {
assert.expect(3);
- const taskModel = serverData.models.task;
-
- serverData.models['res.users'] = {
- fields: {
- display_name: { string: "Displayed name", type: "char" },
- avatar_128: { string: "Image 128", type: 'image' },
- },
- records: [{
- id: 1,
- display_name: "first user",
- avatar_128: "Atmaram Bhide",
- }],
- };
- taskModel.fields.user_id = { string: "Related User", type: "many2one", relation: 'res.users' };
- taskModel.records[0].user_id = 1;
-
+ const [mailTestActivityId1] = pyEnv['mail.test.activity'].search([['name', '=', 'Meeting Room Furnitures']]);
+ const resUsersId1 = pyEnv['res.users'].create({
+ display_name: "first user",
+ avatar_128: "Atmaram Bhide",
+ });
+ pyEnv['mail.test.activity'].write([mailTestActivityId1], { activity_user_id: resUsersId1 });
+ Object.assign(serverData.views, {
+ 'mail.test.activity,false,activity':
+ `
+
+
+
+
+
+
+ `,
+ });
serverData.actions = {
1: {
id: 1,
- name: 'Task Action',
- res_model: 'task',
+ name: 'MailTestActivity Action',
+ res_model: 'mail.test.activity',
type: 'ir.actions.act_window',
views: [[false, 'activity']],
}
};
- serverData.views = {
- 'task,false,activity': `
-
-
-
-
-
-
-
- `,
- 'task,false,search': ''
- };
-
- const webClient = await createWebClient({ serverData, legacyParams: { withLegacyMockServer: true } });
+ const { widget: webClient } = await start({ hasWebClient: true, serverData, legacyParams: { withLegacyMockServer: true } });
await doAction(webClient, 1);
await legacyExtraNextTick();
assert.containsN(target, '.o_m2o_avatar', 2);
- assert.containsOnce(target, 'tr[data-res-id=13] .o_m2o_avatar > img[data-src="/web/image/res.users/1/avatar_128"]',
+ assert.containsOnce(target, `tr[data-res-id=${mailTestActivityId1}] .o_m2o_avatar > img[data-src="/web/image/res.users/${resUsersId1}/avatar_128"]`,
"should have m2o avatar image");
assert.containsNone(target, '.o_m2o_avatar > span',
"should not have text on many2one_avatar_user if onlyImage node option is passed");
@@ -590,13 +516,14 @@ QUnit.test("Activity view: on_destroy_callback doesn't crash", async function (a
assert.expect(3);
const params = {
+ hasView: true,
View: ActivityView,
- model: 'task',
+ model: 'mail.test.activity',
data: this.data,
arch: `
-
+
`,
@@ -614,7 +541,7 @@ QUnit.test("Activity view: on_destroy_callback doesn't crash", async function (a
}
});
- const activity = await createView(params);
+ const { widget: activity } = await start(params);
domUtils.detach([{ widget: activity }]);
assert.verifySteps([
@@ -627,21 +554,12 @@ QUnit.test("Activity view: on_destroy_callback doesn't crash", async function (a
QUnit.test("Schedule activity dialog uses the same search view as activity view", async function (assert) {
assert.expect(8);
- serverData.models.task.records = [];
- serverData.views = {
- "task,false,activity": `
-
-
-
-
-
-
-
- `,
- "task,false,list": `
`,
- "task,false,search": ``,
- 'task,1,search': ``,
- };
+ pyEnv['mail.test.activity'].unlink(pyEnv['mail.test.activity'].search([]));
+ Object.assign(serverData.views, {
+ "mail.test.activity,false,list": `
`,
+ "mail.test.activity,false,search": ``,
+ 'mail.test.activity,1,search': ``,
+ });
function mockRPC(route, args) {
if (args.method === "load_views") {
@@ -649,12 +567,12 @@ QUnit.test("Schedule activity dialog uses the same search view as activity view"
}
}
- const webClient = await createWebClient({ serverData, mockRPC, legacyParams: {withLegacyMockServer: true} });
+ const { widget: webClient } = await start({ hasWebClient: true, serverData, mockRPC, legacyParams: {withLegacyMockServer: true} });
// open an activity view (with default search arch)
await doAction(webClient, {
name: 'Dashboard',
- res_model: 'task',
+ res_model: 'mail.test.activity',
type: 'ir.actions.act_window',
views: [[false, 'activity']],
});
@@ -673,7 +591,7 @@ QUnit.test("Schedule activity dialog uses the same search view as activity view"
// open an activity view (with search arch 1)
await doAction(webClient, {
name: 'Dashboard',
- res_model: 'task',
+ res_model: 'mail.test.activity',
type: 'ir.actions.act_window',
views: [[false, 'activity']],
search_view_id: [1,"search"],
@@ -697,25 +615,14 @@ QUnit.test('Activity view: apply progressbar filter', async function (assert) {
serverData.actions = {
1: {
id: 1,
- name: 'Task Action',
- res_model: 'task',
+ name: 'MailTestActivity Action',
+ res_model: 'mail.test.activity',
type: 'ir.actions.act_window',
views: [[false, 'activity']],
}
};
- serverData.views = {
- 'task,false,activity':
- `
-
-
-
-
-
- `,
- 'task,false,search': '',
- };
- const webClient = await createWebClient({ serverData, legacyParams: { withLegacyMockServer: true } });
+ const { widget: webClient } = await start({ hasWebClient:true, serverData, legacyParams: { withLegacyMockServer: true } });
await doAction(webClient, 1);