346 lines
13 KiB
JavaScript
346 lines
13 KiB
JavaScript
/** @odoo-module **/
|
|
|
|
import "@crm/../tests/mock_server";
|
|
import { makeView, setupViewRegistries } from "@web/../tests/views/helpers";
|
|
import {
|
|
click,
|
|
dragAndDrop,
|
|
getFixture,
|
|
selectDropdownItem,
|
|
} from '@web/../tests/helpers/utils';
|
|
import testUtils from 'web.test_utils';
|
|
import { addModelNamesToFetch } from '@bus/../tests/helpers/model_definitions_helpers';
|
|
import { startServer } from '@bus/../tests/helpers/mock_python_environment';
|
|
import { start } from "@mail/../tests/helpers/test_utils";
|
|
|
|
addModelNamesToFetch(["crm.stage", "crm.lead"]);
|
|
|
|
const find = testUtils.dom.find;
|
|
|
|
let target;
|
|
|
|
function getMockRpc(assert) {
|
|
return async (route, args, performRpc) => {
|
|
const result = await performRpc(route, args);
|
|
if (args.model === 'crm.lead' && args.method === 'get_rainbowman_message') {
|
|
assert.step(result || "no rainbowman");
|
|
}
|
|
return result;
|
|
};
|
|
}
|
|
|
|
QUnit.module('Crm Rainbowman Triggers', {
|
|
beforeEach: function () {
|
|
const format = "YYYY-MM-DD HH:mm:ss";
|
|
const serverData = {
|
|
models: {
|
|
'res.users': {
|
|
fields: {
|
|
display_name: { string: 'Name', type: 'char' },
|
|
},
|
|
records: [
|
|
{ id: 1, name: 'Mario' },
|
|
{ id: 2, name: 'Luigi' },
|
|
{ id: 3, name: 'Link' },
|
|
{ id: 4, name: 'Zelda' },
|
|
],
|
|
},
|
|
'crm.team': {
|
|
fields: {
|
|
display_name: { string: 'Name', type: 'char' },
|
|
member_ids: { string: 'Members', type: 'many2many', relation: 'res.users' },
|
|
},
|
|
records: [
|
|
{ id: 1, name: 'Mushroom Kingdom', member_ids: [1, 2] },
|
|
{ id: 2, name: 'Hyrule', member_ids: [3, 4] },
|
|
],
|
|
},
|
|
'crm.stage': {
|
|
fields: {
|
|
display_name: { string: 'Name', type: 'char' },
|
|
is_won: { string: 'Is won', type: 'boolean' },
|
|
},
|
|
records: [
|
|
{ id: 1, name: 'Start' },
|
|
{ id: 2, name: 'Middle' },
|
|
{ id: 3, name: 'Won', is_won: true},
|
|
],
|
|
},
|
|
'crm.lead': {
|
|
fields: {
|
|
display_name: { string: 'Name', type: 'char' },
|
|
planned_revenue: { string: 'Revenue', type: 'float' },
|
|
stage_id: { string: 'Stage', type: 'many2one', relation: 'crm.stage' },
|
|
team_id: { string: 'Sales Team', type: 'many2one', relation: 'crm.team' },
|
|
user_id: { string: 'Salesperson', type: 'many2one', relation: 'res.users' },
|
|
date_closed: { string: 'Date closed', type: 'datetime' },
|
|
},
|
|
records : [
|
|
{ id: 1, name: 'Lead 1', planned_revenue: 5.0, stage_id: 1, team_id: 1, user_id: 1 },
|
|
{ id: 2, name: 'Lead 2', planned_revenue: 5.0, stage_id: 2, team_id: 2, user_id: 4 },
|
|
{ id: 3, name: 'Lead 3', planned_revenue: 3.0, stage_id: 3, team_id: 1, user_id: 1, date_closed: moment().subtract(5, 'days').format(format) },
|
|
{ id: 4, name: 'Lead 4', planned_revenue: 4.0, stage_id: 3, team_id: 2, user_id: 4, date_closed: moment().subtract(23, 'days').format(format) },
|
|
{ id: 5, name: 'Lead 5', planned_revenue: 7.0, stage_id: 3, team_id: 1, user_id: 1, date_closed: moment().subtract(20, 'days').format(format) },
|
|
{ id: 6, name: 'Lead 6', planned_revenue: 4.0, stage_id: 2, team_id: 1, user_id: 2 },
|
|
{ id: 7, name: 'Lead 7', planned_revenue: 1.8, stage_id: 3, team_id: 2, user_id: 3, date_closed: moment().subtract(23, 'days').format(format) },
|
|
{ id: 8, name: 'Lead 8', planned_revenue: 1.9, stage_id: 1, team_id: 2, user_id: 3 },
|
|
{ id: 9, name: 'Lead 9', planned_revenue: 1.5, stage_id: 3, team_id: 2, user_id: 3, date_closed: moment().subtract(5, 'days').format(format) },
|
|
{ id: 10, name: 'Lead 10', planned_revenue: 1.7, stage_id: 2, team_id: 2, user_id: 3 },
|
|
{ id: 11, name: 'Lead 11', planned_revenue: 2.0, stage_id: 3, team_id: 2, user_id: 4, date_closed: moment().subtract(5, 'days').format(format) },
|
|
],
|
|
},
|
|
},
|
|
views: {},
|
|
};
|
|
this.testFormView = {
|
|
arch: `
|
|
<form js_class="crm_form">
|
|
<header><field name="stage_id" widget="statusbar" options="{'clickable': '1'}"/></header>
|
|
<field name="name"/>
|
|
<field name="planned_revenue"/>
|
|
<field name="team_id"/>
|
|
<field name="user_id"/>
|
|
</form>`,
|
|
serverData,
|
|
type: "form",
|
|
resModel: 'crm.lead',
|
|
};
|
|
this.testKanbanView = {
|
|
arch: `
|
|
<kanban js_class="crm_kanban">
|
|
<templates>
|
|
<t t-name="kanban-box">
|
|
<div><field name="name"/></div>
|
|
</t>
|
|
</templates>
|
|
</kanban>`,
|
|
serverData,
|
|
resModel: 'crm.lead',
|
|
type: "kanban",
|
|
groupBy: ['stage_id'],
|
|
};
|
|
target = getFixture();
|
|
setupViewRegistries();
|
|
},
|
|
}, function () {
|
|
QUnit.test("first lead won, click on statusbar", async function (assert) {
|
|
assert.expect(2);
|
|
|
|
await makeView({
|
|
...this.testFormView,
|
|
resId: 6,
|
|
mockRPC: getMockRpc(assert),
|
|
mode: "readonly",
|
|
});
|
|
|
|
await click(target.querySelector(".o_statusbar_status button[data-value='3']"));
|
|
assert.verifySteps(['Go, go, go! Congrats for your first deal.']);
|
|
});
|
|
|
|
QUnit.test("first lead won, click on statusbar in edit mode", async function (assert) {
|
|
assert.expect(2);
|
|
|
|
await makeView({
|
|
...this.testFormView,
|
|
resId: 6,
|
|
mockRPC: getMockRpc(assert),
|
|
});
|
|
|
|
await click(target.querySelector(".o_statusbar_status button[data-value='3']"));
|
|
assert.verifySteps(['Go, go, go! Congrats for your first deal.']);
|
|
});
|
|
|
|
QUnit.test("team record 30 days, click on statusbar", async function (assert) {
|
|
assert.expect(2);
|
|
|
|
await makeView({
|
|
...this.testFormView,
|
|
resId: 2,
|
|
mockRPC: getMockRpc(assert),
|
|
mode: "readonly",
|
|
});
|
|
|
|
await click(target.querySelector(".o_statusbar_status button[data-value='3']"));
|
|
assert.verifySteps(['Boom! Team record for the past 30 days.']);
|
|
});
|
|
|
|
QUnit.test("team record 7 days, click on statusbar", async function (assert) {
|
|
assert.expect(2);
|
|
|
|
await makeView({
|
|
...this.testFormView,
|
|
resId: 1,
|
|
mockRPC: getMockRpc(assert),
|
|
mode: "readonly",
|
|
});
|
|
|
|
await click(target.querySelector(".o_statusbar_status button[data-value='3']"));
|
|
assert.verifySteps(['Yeah! Deal of the last 7 days for the team.']);
|
|
});
|
|
|
|
QUnit.test("user record 30 days, click on statusbar", async function (assert) {
|
|
assert.expect(2);
|
|
|
|
await makeView({
|
|
...this.testFormView,
|
|
resId: 8,
|
|
mockRPC: getMockRpc(assert),
|
|
mode: "readonly",
|
|
});
|
|
|
|
await click(target.querySelector(".o_statusbar_status button[data-value='3']"));
|
|
assert.verifySteps(['You just beat your personal record for the past 30 days.']);
|
|
});
|
|
|
|
QUnit.test("user record 7 days, click on statusbar", async function (assert) {
|
|
assert.expect(2);
|
|
|
|
await makeView({
|
|
...this.testFormView,
|
|
resId: 10,
|
|
mockRPC: getMockRpc(assert),
|
|
mode: "readonly",
|
|
});
|
|
|
|
await click(target.querySelector(".o_statusbar_status button[data-value='3']"));
|
|
assert.verifySteps(['You just beat your personal record for the past 7 days.']);
|
|
});
|
|
|
|
QUnit.test("click on stage (not won) on statusbar", async function (assert) {
|
|
assert.expect(2);
|
|
|
|
await makeView({
|
|
...this.testFormView,
|
|
resId: 1,
|
|
mockRPC: getMockRpc(assert),
|
|
mode: "readonly",
|
|
});
|
|
|
|
await click(target.querySelector(".o_statusbar_status button[data-value='2']"));
|
|
assert.verifySteps(['no rainbowman']);
|
|
});
|
|
|
|
QUnit.test("first lead won, drag & drop kanban", async function (assert) {
|
|
assert.expect(2);
|
|
|
|
await makeView({
|
|
...this.testKanbanView,
|
|
mockRPC: getMockRpc(assert),
|
|
});
|
|
|
|
await dragAndDrop(find(target, ".o_kanban_record", "Lead 6"), target.querySelector('.o_kanban_group:nth-of-type(3)'));
|
|
assert.verifySteps(['Go, go, go! Congrats for your first deal.']);
|
|
});
|
|
|
|
QUnit.test("team record 30 days, drag & drop kanban", async function (assert) {
|
|
assert.expect(2);
|
|
|
|
await makeView({
|
|
...this.testKanbanView,
|
|
mockRPC: getMockRpc(assert),
|
|
});
|
|
|
|
await dragAndDrop(find(target, ".o_kanban_record", "Lead 2"), target.querySelector('.o_kanban_group:nth-of-type(3)'));
|
|
assert.verifySteps(['Boom! Team record for the past 30 days.']);
|
|
});
|
|
|
|
QUnit.test("team record 7 days, drag & drop kanban", async function (assert) {
|
|
assert.expect(2);
|
|
|
|
await makeView({
|
|
...this.testKanbanView,
|
|
mockRPC: getMockRpc(assert),
|
|
});
|
|
|
|
await dragAndDrop(find(target, ".o_kanban_record", "Lead 1"), target.querySelector('.o_kanban_group:nth-of-type(3)'));
|
|
assert.verifySteps(['Yeah! Deal of the last 7 days for the team.']);
|
|
});
|
|
|
|
QUnit.test("user record 30 days, drag & drop kanban", async function (assert) {
|
|
assert.expect(2);
|
|
|
|
await makeView({
|
|
...this.testKanbanView,
|
|
mockRPC: getMockRpc(assert),
|
|
});
|
|
|
|
await dragAndDrop(find(target, ".o_kanban_record", "Lead 8"), target.querySelector('.o_kanban_group:nth-of-type(3)'));
|
|
assert.verifySteps(['You just beat your personal record for the past 30 days.']);
|
|
});
|
|
|
|
QUnit.test("user record 7 days, drag & drop kanban", async function (assert) {
|
|
assert.expect(2);
|
|
|
|
await makeView({
|
|
...this.testKanbanView,
|
|
mockRPC: getMockRpc(assert),
|
|
});
|
|
|
|
await dragAndDrop(find(target, ".o_kanban_record", "Lead 10"), target.querySelector('.o_kanban_group:nth-of-type(3)'));
|
|
assert.verifySteps(['You just beat your personal record for the past 7 days.']);
|
|
});
|
|
|
|
QUnit.test("drag & drop record kanban in stage not won", async function (assert) {
|
|
assert.expect(2);
|
|
|
|
await makeView({
|
|
...this.testKanbanView,
|
|
mockRPC: getMockRpc(assert),
|
|
});
|
|
|
|
await dragAndDrop(find(target, ".o_kanban_record", "Lead 8"), target.querySelector('.o_kanban_group:nth-of-type(2)'));
|
|
assert.verifySteps(["no rainbowman"]);
|
|
});
|
|
|
|
QUnit.test("drag & drop record in kanban not grouped by stage_id", async function (assert) {
|
|
assert.expect(1);
|
|
|
|
await makeView({
|
|
...this.testKanbanView,
|
|
groupBy: ["user_id"],
|
|
mockRPC: getMockRpc(assert),
|
|
});
|
|
|
|
await dragAndDrop(target.querySelector('.o_kanban_group:nth-of-type(1)'), target.querySelector('.o_kanban_group:nth-of-type(2)'));
|
|
assert.verifySteps([]); // Should never pass by the rpc
|
|
});
|
|
|
|
QUnit.test("send a message on a new record after changing the stage", async function (assert) {
|
|
assert.expect(1);
|
|
|
|
const pyEnv = await startServer();
|
|
pyEnv["crm.stage"].create({ name : "Dummy Stage", is_won: true });
|
|
const views = {
|
|
"crm.lead,false,form": `
|
|
<form js_class="crm_form">
|
|
<sheet>
|
|
<field name="stage_id"/>
|
|
</sheet>
|
|
<div class="oe_chatter">
|
|
<field name="message_ids" options="{'open_attachments': True}"/>
|
|
</div>
|
|
</form>`,
|
|
};
|
|
|
|
const messageBody = "some message";
|
|
const { insertText, openView } = await start({
|
|
serverData: { views },
|
|
mockRPC: function (route, args) {
|
|
if (route === "/mail/message/post") {
|
|
assert.deepEqual(args.post_data.body, messageBody);
|
|
}
|
|
}
|
|
});
|
|
|
|
await openView({
|
|
res_model: "crm.lead",
|
|
views: [[false, "form"]],
|
|
});
|
|
|
|
await selectDropdownItem(target, "stage_id", "Dummy Stage");
|
|
await click(target, ".o_ChatterTopbar_buttonSendMessage");
|
|
await insertText(".o_ComposerTextInput_textarea", messageBody);
|
|
await click(target, ".o_Composer_buttonSend");
|
|
});
|
|
});
|