Files
enterprise-addons/project_enterprise/static/tests/task_gantt.test.js
T

855 lines
29 KiB
JavaScript

import { mailModels } from "@mail/../tests/mail_test_helpers";
import { beforeEach, describe, destroy, expect, test } from "@odoo/hoot";
import { hover, keyDown, queryAll, queryAllTexts, queryOne } from "@odoo/hoot-dom";
import { animationFrame, mockDate } from "@odoo/hoot-mock";
import {
clickModalButton,
contains,
defineModels,
fields,
mockService,
models,
onRpc,
} from "@web/../tests/web_test_helpers";
import {
clickCell,
dragPill,
getGridContent,
hoverGridCell,
mountGanttView,
SELECTORS,
} from "@web_gantt/../tests/web_gantt_test_helpers";
import {
defineProjectModels,
projectModels,
ProjectProject,
} from "@project/../tests/project_models";
describe.current.tags("desktop");
const ganttViewParams = {
arch: '<gantt js_class="task_gantt" date_start="planned_date_begin" date_stop="date_deadline"/>',
resModel: "project.task",
groupBy: ["user_ids"],
};
beforeEach(() => {
mockDate("2021-06-22 08:00:00");
mailModels.ResUsers._records.push({ id: 100, name: "Jane Doe" }, { id: 101, name: "John Doe" });
ProjectProject._records = [
{ id: 1, name: "My Project", date_start: "2021-01-01", date: "2021-06-24" },
];
});
class Task extends projectModels.ProjectTask {
stuff_id = fields.Many2one({ string: "Stuff", relation: "stuff" });
_records = [
{
id: 1,
name: "Blop",
planned_date_begin: "2021-06-14 08:00:00",
date_deadline: "2021-06-24 08:00:00",
user_ids: [100],
project_id: 1,
milestone_id: 3,
},
{
id: 2,
name: "Yop",
planned_date_begin: "2021-06-02 08:00:00",
date_deadline: "2021-06-12 08:00:00",
user_ids: [101],
stuff_id: 1,
project_id: 1,
},
];
_views = {
list: '<list><field name="name"/></list>',
form: '<form><field name="name"/></form>',
};
}
class Stuff extends models.Model {
name = fields.Char();
_records = [{ id: 1, name: "Bruce Willis" }];
}
projectModels.ProjectTask = Task;
defineModels([Stuff]);
defineProjectModels();
test("not user_ids grouped: empty groups are displayed first and user avatar is not displayed", async () => {
await mountGanttView({ ...ganttViewParams, groupBy: ["stuff_id"] });
expect(queryAllTexts(".o_gantt_row_headers .o_gantt_row_title")).toEqual([
"Undefined Stuff",
"Bruce Willis",
]);
expect(".o_gantt_row_headers .o-mail-Avatar").toHaveCount(0);
});
test("Unschedule button is displayed", async () => {
onRpc(({ method, model }) => {
if (model === "project.task" && method == "action_unschedule_task") {
expect.step("unschedule task");
return false;
}
});
await mountGanttView({
arch: `
<gantt date_start="planned_date_begin" date_stop="date_deadline">
<templates>
<t t-name="gantt-popover">
<footer>
<button name="action_unschedule_task" type="object" string="Unschedule"
class="btn btn-sm btn-secondary"/>
</footer>
</t>
</templates>
</gantt>
`,
resModel: "project.task",
});
await contains(".o_gantt_pill").click();
expect(".btn.btn-sm.btn-secondary").toHaveCount(1);
expect(".btn.btn-sm.btn-secondary").toHaveText("Unschedule");
await contains(".btn.btn-sm.btn-secondary").click();
expect.verifySteps(["unschedule task"]);
});
test("not user_ids grouped: no empty group if no records", async () => {
// delete the record having no stuff_id
Task._records.splice(0, 1);
await mountGanttView({ ...ganttViewParams, groupBy: ["stuff_id"] });
expect(queryAllTexts(".o_gantt_row_headers .o_gantt_row_title")).toEqual(["Bruce Willis"]);
});
test("user_ids grouped: specific empty group added, even if no records", async () => {
await mountGanttView(ganttViewParams);
expect(queryAllTexts(".o_gantt_row_headers .o_gantt_row_title")).toEqual(
["👤 Unassigned", "Jane Doe", "John Doe"],
{
message:
"'👤 Unassigned' should be the first group, even if no record exist without user_ids",
}
);
expect(".o_gantt_row_headers .o-mail-Avatar").toHaveCount(2);
});
test("[user_ids, ...] grouped", async () => {
// add an unassigned task (no user_ids) that has a linked stuff
Task._records.push({
id: 3,
name: "Gnop",
planned_date_begin: "2021-06-02 08:00:00",
date_deadline: "2021-06-12 08:00:00",
stuff_id: 1,
});
await mountGanttView({ ...ganttViewParams, groupBy: ["user_ids", "stuff_id"] });
expect(queryAllTexts(".o_gantt_row_headers .o_gantt_row_title")).toEqual([
"👤 Unassigned",
"Undefined Stuff",
"Bruce Willis",
"Jane Doe",
"Undefined Stuff",
"John Doe",
"Bruce Willis",
]);
});
test("[..., user_ids(, ...)] grouped", async () => {
await mountGanttView({ ...ganttViewParams, groupBy: ["stuff_id", "user_ids"] });
expect(queryAllTexts(".o_gantt_row_headers .o_gantt_row_title")).toEqual([
"Undefined Stuff",
"👤 Unassigned",
"Jane Doe",
"Bruce Willis",
"👤 Unassigned",
"John Doe",
]);
});
test('Empty groupby "Assigned To" and "Project" can be rendered', async function (assert) {
Task._records = [];
await mountGanttView({ ...ganttViewParams, groupBy: ["user_ids", "project_id"] });
expect(queryAllTexts(".o_gantt_row_headers .o_gantt_row_title")).toEqual([
"👤 Unassigned",
"🔒 Private",
]);
});
test("progress bar has the correct unit", async () => {
onRpc("get_gantt_data", ({ kwargs, parent }) => {
const result = parent();
expect(kwargs.progress_bar_fields).toEqual(["user_ids"]);
result.progress_bars.user_ids = {
100: { value: 100, max_value: 100 },
};
return result;
});
await mountGanttView({
arch: '<gantt js_class="task_gantt" date_start="planned_date_begin" date_stop="date_deadline" progress_bar="user_ids"/>',
resModel: "project.task",
type: "gantt",
groupBy: ["user_ids"],
});
expect(SELECTORS.progressBar).toHaveCount(1);
expect(SELECTORS.progressBarBackground).toHaveCount(1);
expect(queryOne(SELECTORS.progressBarBackground).style.width).toBe("100%");
expect(SELECTORS.progressBarForeground).toHaveCount(0);
await hoverGridCell("10", "June 2021", "Jane Doe");
expect(SELECTORS.progressBarForeground).toHaveCount(1);
expect(SELECTORS.progressBarForeground).toHaveText("100h / 100h");
});
test("open a dialog to schedule task", async () => {
Task._records.push({
id: 51,
name: "Task 51",
project_id: 1,
user_ids: [100],
});
onRpc("schedule_tasks", () => {
expect.step("schedule_tasks");
return {};
});
await mountGanttView({
arch: '<gantt date_start="planned_date_begin" date_stop="date_deadline" js_class="task_gantt" />',
resModel: "project.task",
type: "gantt",
});
await clickCell("10", "June 2021");
await contains(".modal .o_list_view tbody tr:nth-child(1) input").click();
await animationFrame();
expect(".modal .o_list_view .o_data_row").toHaveClass("o_data_row_selected");
await contains(".modal footer .o_auto_plan_button").click();
expect.verifySteps(["schedule_tasks"]);
});
test("Lines are displayed in alphabetic order, except for the first one", async () => {
for (const user of [
{ id: 102, name: "Omega" },
{ id: 103, name: "Theta" },
{ id: 104, name: "Rho" },
{ id: 105, name: "Zeta" },
{ id: 106, name: "Kappa" },
]) {
mailModels.ResUsers._records.push(user);
Task._records.push({
id: user.id,
name: "Citron en Suédois",
planned_date_begin: "2021-06-02 08:00:00",
date_deadline: "2021-06-12 08:00:00",
project_id: 1,
user_ids: [user.id],
});
}
await mountGanttView(ganttViewParams);
expect(queryAllTexts(".o_gantt_row_headers .o_gantt_row_title")).toEqual(
["👤 Unassigned", "Jane Doe", "John Doe", "Kappa", "Omega", "Rho", "Theta", "Zeta"],
{
message:
"The lines should be sorted by alphabetical order ('👤 Unassigned' is always first)",
}
);
});
test("Display milestones deadline in project.task gantt view", async () => {
onRpc("get_all_deadlines", function () {
const [milestone1, milestone2] = this.env["project.milestone"].browse([1, 2]);
return {
milestone_id: [
{
...milestone1,
project_id: [1, "My Project"],
},
{
...milestone2,
project_id: [1, "My Project"],
},
],
project_id: [],
};
});
await mountGanttView({
...ganttViewParams,
});
expect(".o_project_milestone_diamond").toHaveCount(2);
expect(".o_project_milestone_diamond .o_milestones_reached").toHaveCount(1);
expect(".o_project_milestone_diamond.o_unreached_milestones").toHaveCount(1);
await hover(".o_project_milestone_diamond");
await animationFrame();
expect(".o_popover").toHaveCount(1);
expect(".o_popover u").toHaveCount(1);
expect(".o_popover u").toHaveText("My Project");
expect(".o_popover .o_milestones_reached").toHaveCount(1);
expect(".o_popover strong").toHaveText("Milestone 1");
await hover(".o_project_milestone_diamond.o_unreached_milestones");
await animationFrame();
expect(".o_popover").toHaveCount(1);
expect(".o_popover u").toHaveCount(1);
expect(".o_popover u").toHaveText("My Project");
expect(".o_popover .o_unreached_milestones").toHaveCount(1);
expect(".o_popover strong").toHaveText("Milestone 2");
});
test("Display milestones deadline in gantt view of tasks in a project", async () => {
onRpc("get_all_deadlines", function () {
const [milestone1, milestone2] = this.env["project.milestone"].browse([1, 2]);
return {
milestone_id: [
{
...milestone1,
project_id: [1, "My Project"],
},
{
...milestone2,
project_id: [1, "My Project"],
},
],
project_id: [],
};
});
await mountGanttView({
...ganttViewParams,
context: {
default_project_id: 1,
},
});
expect(".o_project_milestone_diamond").toHaveCount(2);
expect(".o_project_milestone_diamond .o_milestones_reached").toHaveCount(1);
expect(".o_project_milestone_diamond.o_unreached_milestones").toHaveCount(1);
await hover(".o_project_milestone_diamond");
await animationFrame();
expect(".o_popover").toHaveCount(1);
expect(".o_popover u").toHaveCount(0);
expect(".o_popover .o_milestones_reached").toHaveCount(1);
expect(".o_popover strong").toHaveText("Milestone 1");
await hover(".o_project_milestone_diamond.o_unreached_milestones");
await animationFrame();
expect(".o_popover").toHaveCount(1);
expect(".o_popover u").toHaveCount(0);
expect(".o_popover .o_unreached_milestones").toHaveCount(1);
expect(".o_popover strong").toHaveText("Milestone 2");
});
test("Display project deadline in the gantt view of task", async () => {
ProjectProject._records.push({
id: 2,
name: "Other Project",
date_start: "2021-06-12",
date: "2021-06-28",
});
await mountGanttView(ganttViewParams);
expect(".o_gantt_header_cell .o_project_startdate_circle").toHaveCount(1);
expect(".o_gantt_header_cell .o_project_deadline_circle").toHaveCount(2);
expect(".o_popover").toHaveCount(0);
await hover(".o_gantt_header_cell .o_project_startdate_circle");
await animationFrame();
expect(".o_popover").toHaveCount(1);
expect(".o_popover u").toHaveCount(1);
expect(".o_popover .popover-body u").toHaveText("Other Project");
expect(".o_popover .popover-body em").toHaveText("Project start");
const [myProjectDeadlineCircleEl, otherProjectDeadlineCircleEl] = queryAll(
".o_gantt_header_cell .o_project_deadline_circle"
);
await hover(myProjectDeadlineCircleEl);
await animationFrame();
expect(".o_popover").toHaveCount(1);
expect(".o_popover u").toHaveCount(1);
expect(".o_popover u").toHaveText("My Project");
expect(".o_popover .popover-body em").toHaveText("Project due");
await hover(otherProjectDeadlineCircleEl);
await animationFrame();
expect(".o_popover").toHaveCount(1);
expect(".o_popover u").toHaveCount(1);
expect(".o_popover u").toHaveText("Other Project");
expect(".o_popover .popover-body em").toHaveText("Project due");
});
test("Display project and milestones deadline in the gantt view of task", async () => {
ProjectProject._records.push({
id: 2,
name: "Other Project",
date_start: "2021-06-12",
date: "2021-06-28",
});
onRpc("get_all_deadlines", function () {
const [milestone1, milestone2] = this.env["project.milestone"].browse([1, 2]);
return {
milestone_id: [
{
...milestone1,
project_id: [1, "My Project"],
},
{
...milestone2,
project_id: [1, "My Project"],
},
],
project_id: this.env["project.project"].search_read(),
};
});
await mountGanttView(ganttViewParams);
expect(".o_project_milestone_diamond").toHaveCount(2);
expect(".o_project_milestone_diamond .o_milestones_reached").toHaveCount(1);
expect(".o_project_milestone_diamond.o_unreached_milestones").toHaveCount(1);
await hover(".o_project_milestone_diamond");
await animationFrame();
expect(".o_popover").toHaveCount(1);
expect(".o_popover u").toHaveCount(1);
expect(".o_popover u").toHaveText("My Project");
expect(".o_popover .o_milestones_reached").toHaveCount(1);
expect(".o_popover strong").toHaveText("Milestone 1");
await hover(".o_project_milestone_diamond.o_unreached_milestones");
await animationFrame();
expect(".o_popover").toHaveCount(1);
expect(".o_popover u").toHaveCount(1);
expect(".o_popover u").toHaveText("My Project");
expect(".o_popover .o_unreached_milestones").toHaveCount(1);
expect(".o_popover strong").toHaveText("Milestone 2");
expect(".o_gantt_header_cell .o_project_startdate_circle").toHaveCount(1);
expect(".o_gantt_header_cell .o_project_deadline_circle").toHaveCount(2);
await hover(".o_gantt_header_cell .o_project_startdate_circle");
await animationFrame();
expect(".o_popover").toHaveCount(1);
expect(".o_popover u").toHaveCount(1);
expect(".o_popover .popover-body u").toHaveText("Other Project");
expect(".o_popover .popover-body em").toHaveText("Project start");
const [myProjectDeadlineCircleEl, otherProjectDeadlineCircleEl] = queryAll(
".o_gantt_header_cell .o_project_deadline_circle"
);
await hover(myProjectDeadlineCircleEl);
await animationFrame();
expect(".o_popover").toHaveCount(1);
expect(".o_popover u").toHaveCount(1);
expect(".o_popover u").toHaveText("My Project");
expect(".o_popover .popover-body em").toHaveText("Project due");
await hover(otherProjectDeadlineCircleEl);
await animationFrame();
expect(".o_popover").toHaveCount(1);
expect(".o_popover u").toHaveCount(1);
expect(".o_popover u").toHaveText("Other Project");
expect(".o_popover .popover-body em").toHaveText("Project due");
});
test("Display project deadline and milestone date in the same date", async () => {
onRpc("get_all_deadlines", function () {
const [milestone3] = this.env["project.milestone"].browse(3);
return {
milestone_id: [
{
...milestone3,
project_id: [1, "My Project"],
},
],
project_id: this.env["project.project"].search_read(),
};
});
await mountGanttView(ganttViewParams);
expect(
".o_gantt_header_cell .o_project_milestone_diamond.o_project_deadline_milestone"
).toHaveCount(1);
await hover(".o_gantt_header_cell .o_project_milestone_diamond.o_project_deadline_milestone");
await animationFrame();
expect(".o_popover").toHaveCount(1);
expect(".o_popover u").toHaveCount(1);
expect(".o_popover u").toHaveText("My Project");
expect(".o_popover .popover-body").toHaveCount(1);
expect(".o_popover .popover-body em").toHaveText("Project due");
expect(".o_popover .popover-body strong").toHaveText("Milestone 3");
});
test("Display 2 milestones in different project at the same date", async () => {
ProjectProject._records.push({
id: 2,
name: "Other Project",
});
projectModels.ProjectMilestone._records.push({
id: 4,
name: "Milestone 4",
deadline: "2021-06-24",
project_id: 2,
});
onRpc("get_all_deadlines", function () {
const [milestone3, milestone4] = this.env["project.milestone"].browse([3, 4]);
return {
milestone_id: [
{
...milestone3,
project_id: [1, "My Project"],
},
{
...milestone4,
project_id: [2, "Other Project"],
},
],
project_id: [],
};
});
await mountGanttView(ganttViewParams);
expect(".o_project_milestone_diamond").toHaveCount(1);
await hover(".o_project_milestone_diamond");
await animationFrame();
expect(".o_popover").toHaveCount(1);
expect(".o_popover u").toHaveCount(2);
expect(queryAllTexts(".o_popover u")).toEqual(["My Project", "Other Project"]);
expect(".o_popover .popover-body i.fa-square-o").toHaveCount(2);
expect(".o_popover .popover-body strong").toHaveCount(2);
expect(queryAllTexts(".o_popover .popover-body strong")).toEqual([
"Milestone 3",
"Milestone 4",
]);
expect(queryAllTexts(".o_popover .popover-body")).toEqual([
"My Project\nMilestone 3\nOther Project\nMilestone 4",
]);
});
test("Display project deadline of 2 projects with the same deadline", async () => {
ProjectProject._records.push({
id: 2,
name: "Other Project",
date_start: "2021-05-12",
date: "2021-06-24",
});
await mountGanttView(ganttViewParams);
expect(".o_gantt_header_cell .o_project_deadline_circle").toHaveCount(1);
await hover(".o_gantt_header_cell .o_project_deadline_circle");
await animationFrame();
expect(".o_popover").toHaveCount(1);
expect(".o_popover u").toHaveCount(2);
expect(queryAllTexts(".o_popover u")).toEqual(["My Project", "Other Project"]);
expect(".o_popover .popover-body em").toHaveCount(2);
expect(queryAllTexts(".o_popover .popover-body em")).toEqual(["Project due", "Project due"]);
expect(queryAllTexts(".o_popover .popover-body")).toEqual([
"My Project\nProject due\nOther Project\nProject due",
]);
});
test("Display project deadline one day before the start date of the other project", async () => {
ProjectProject._records.push({
id: 2,
name: "Other Project",
date_start: "2021-06-25",
date: "2021-10-01",
});
await mountGanttView(ganttViewParams);
expect(".o_gantt_header_cell .o_project_deadline_circle").toHaveCount(1);
await hover(".o_gantt_header_cell .o_project_deadline_circle");
await animationFrame();
expect(".o_popover").toHaveCount(1);
expect(".o_popover u").toHaveCount(2);
expect(queryAllTexts(".o_popover u")).toEqual(["My Project", "Other Project"]);
expect(".o_popover .popover-body em").toHaveCount(2);
expect(queryAllTexts(".o_popover .popover-body em")).toEqual(["Project due", "Project start"]);
expect(queryAllTexts(".o_popover .popover-body")).toEqual([
"My Project\nProject due\nOther Project\nProject start",
]);
});
test("Copy pill in another row", async () => {
await mountGanttView(ganttViewParams);
expect(getGridContent().rows).toEqual([
{
title: "👤 Unassigned",
},
{
title: "Jane Doe",
pills: [{ title: "Blop", level: 0, colSpan: "14 June 2021 -> 24 (1/2) June 2021" }],
},
{
title: "John Doe",
pills: [{ title: "Yop", level: 0, colSpan: "02 June 2021 -> 12 (1/2) June 2021" }],
},
]);
await keyDown("Control");
// move blop to John Doe
const { drop, moveTo } = await dragPill("Blop");
await moveTo({ columnHeader: "14", groupHeader: "June 2021", row: "John Doe" });
expect(SELECTORS.renderer).toHaveClass("o_copying");
await drop({ columnHeader: "14", groupHeader: "June 2021", row: "John Doe" });
expect(getGridContent().rows).toEqual([
{
title: "👤 Unassigned",
},
{
title: "Jane Doe",
pills: [{ title: "Blop", level: 0, colSpan: "14 June 2021 -> 24 (1/2) June 2021" }],
},
{
title: "John Doe",
pills: [
{ title: "Yop", level: 0, colSpan: "Out of bounds (3) -> 12 (1/2) June 2021" },
{ title: "Blop (copy)", level: 0, colSpan: "14 June 2021 -> 24 (1/2) June 2021" },
],
},
]);
});
test("Smart scheduling", async () => {
Task._records.push({
id: 3,
name: "Gnop",
user_ids: [100],
});
onRpc("schedule_tasks", function (request) {
expect.step("schedule_tasks");
return this.env["project.task"].write(...request.args);
});
await mountGanttView(ganttViewParams);
expect(getGridContent().rows).toEqual([
{
title: "👤 Unassigned",
},
{
title: "Jane Doe",
pills: [{ title: "Blop", level: 0, colSpan: "14 June 2021 -> 24 (1/2) June 2021" }],
},
{
title: "John Doe",
pills: [{ title: "Yop", level: 0, colSpan: "02 June 2021 -> 12 (1/2) June 2021" }],
},
]);
await clickCell("10", "June 2021", "Jane Doe");
expect(".o_dialog").toHaveCount(1);
await contains(".o_dialog .o_data_row .o-checkbox").click();
await contains(".o_dialog .o_auto_plan_button:enabled").click();
expect(getGridContent().rows).toEqual([
{
title: "👤 Unassigned",
},
{
title: "Jane Doe",
pills: [
{ title: "Gnop", level: 0, colSpan: "10 June 2021 -> 10 June 2021" },
{ title: "Blop", level: 0, colSpan: "14 June 2021 -> 24 (1/2) June 2021" },
],
},
{
title: "John Doe",
pills: [{ title: "Yop", level: 0, colSpan: "02 June 2021 -> 12 (1/2) June 2021" }],
},
]);
expect.verifySteps(["schedule_tasks"]);
});
test("Smart scheduling: display warnings", async () => {
Task._records.push({
id: 3,
name: "Gnop",
user_ids: [100],
});
onRpc("schedule_tasks", () => {
expect.step("schedule_tasks");
return [
{},
{
3: {
planned_date_begin: false,
date_deadline: false,
},
},
];
});
let notifications = [];
mockService("notification", {
add: (message, options) => {
expect.step("notification added");
expect(options["type"]).toBe("success");
expect(options["buttons"].length).toBe(1);
expect(options["buttons"][0].icon).toBe("fa-undo");
expect(options["buttons"][0].name).toBe("Undo");
notifications.push({ message, options });
return () => {
notifications = notifications.filter(
(n) => n.message !== message || n.options !== options
);
};
},
});
const ganttView = await mountGanttView(ganttViewParams);
await clickCell("10", "June 2021", "Jane Doe");
expect(".o_dialog").toHaveCount(1);
await contains(".o_dialog .o_data_row .o-checkbox").click();
await contains(".o_dialog .o_auto_plan_button:enabled").click();
expect.verifySteps(["schedule_tasks", "notification added"]);
expect(notifications).toHaveLength(1);
destroy(ganttView);
expect(notifications).toHaveLength(0);
});
test("Schedule a task and verify its display in the gantt view", async () => {
Task._records.push({
id: 3,
name: "Gnop",
user_ids: [100],
});
onRpc("web_gantt_write", ({ args }) => {
expect.step("web_gantt_write");
expect(args[0]).toEqual([3], { message: "should write on the correct record" });
expect(args[1]).toEqual(
{
planned_date_begin: "2021-06-09 23:00:00",
date_deadline: "2021-06-10 23:00:00",
user_ids: [100],
},
{ message: "should write these changes" }
);
});
await mountGanttView(ganttViewParams);
expect(getGridContent().rows).toEqual([
{
title: "👤 Unassigned",
},
{
title: "Jane Doe",
pills: [{ title: "Blop", level: 0, colSpan: "14 June 2021 -> 24 (1/2) June 2021" }],
},
{
title: "John Doe",
pills: [{ title: "Yop", level: 0, colSpan: "02 June 2021 -> 12 (1/2) June 2021" }],
},
]);
await clickCell("10", "June 2021", "Jane Doe");
expect(".o_dialog").toHaveCount(1);
await contains(".o_dialog .o_data_row .o-checkbox input").check();
await clickModalButton({ text: "Select" });
expect(getGridContent().rows).toEqual([
{
title: "👤 Unassigned",
},
{
title: "Jane Doe",
pills: [
{ title: "Gnop", level: 0, colSpan: "10 June 2021 -> 10 June 2021" },
{ title: "Blop", level: 0, colSpan: "14 June 2021 -> 24 (1/2) June 2021" },
],
},
{
title: "John Doe",
pills: [{ title: "Yop", level: 0, colSpan: "02 June 2021 -> 12 (1/2) June 2021" }],
},
]);
expect.verifySteps(["web_gantt_write"]);
});
test("Should open the list dialog with 'Open Tasks' filter on Gantt cell click", async () => {
Task._records.push({ id: 4, name: "Task 4", is_closed: true }, { id: 5, name: "Task 5" });
await mountGanttView({
...ganttViewParams,
searchViewArch: `
<search>
<filter string="Open Tasks" name="open_tasks" domain="[('is_closed', '=', False)]"/>
</search>`,
});
await clickCell("10", "June 2021", "Jane Doe");
expect(".o_dialog").toHaveCount(1);
expect(".o_searchview_facet").toHaveCount(1, { message: "Open Tasks filter applied" });
expect(".o_data_row").toHaveCount(1, { message: "Only open task should appear" });
});
test("template dropdown in gantt view of a project with no template", async () => {
await mountGanttView({
...ganttViewParams,
context: {
default_project_id: 1,
},
});
expect(".o_gantt_button_add").toHaveCount(1, {
message: "The “New” button should be displayed",
});
expect(".o_gantt_button_add").not.toHaveClass("dropdown-toggle", {
message: "The “New” button should not be a dropdown since there is no template",
});
// Test that we can create a new record without errors
await contains(".o_gantt_button_add").click();
});
test("template dropdown in gantt view of a project with one template", async () => {
Task._records.push(
{
id: 3,
name: "Template Task 1",
project_id: 1,
is_template: true,
planned_date_begin: "2021-06-02 08:00:00",
date_deadline: "2021-06-12 08:00:00",
},
{
id: 4,
name: "Template Task 2",
project_id: 1,
is_template: true,
planned_date_begin: "2021-06-02 08:00:00",
date_deadline: "2021-06-12 08:00:00",
}
);
await mountGanttView({
...ganttViewParams,
context: {
default_project_id: 1,
},
});
expect(".o_gantt_button_add").toHaveCount(1, {
message: "The “New” button should be displayed",
});
expect(".o_gantt_button_add").toHaveClass("dropdown-toggle", {
message: "The “New” button should be a dropdown since there is a template",
});
await contains(".o_gantt_button_add").click();
expect("button.dropdown-item:contains('New Task')").toHaveCount(1, {
message: "The “New Task” button should be in the dropdown",
});
expect("button.dropdown-item:contains('Template Task 1')").toHaveCount(1, {
message: "There should be a button named after the task template",
});
});
test("Closed tasks in gantt view have lower opacity than open tasks", async () => {
Task._records = [{ ...Task._records[0], is_closed: true }];
await mountGanttView({
...ganttViewParams,
groupBy: ["user_ids"],
});
expect(".o_gantt_pill").toHaveClass("opacity-50");
});