325 lines
12 KiB
JavaScript
325 lines
12 KiB
JavaScript
import { describe, expect, test } from "@odoo/hoot";
|
|
import { animationFrame, click } from "@odoo/hoot-dom";
|
|
|
|
import { mockDate } from "@odoo/hoot-mock";
|
|
import { asyncStep, contains, onRpc, selectGroup, waitForSteps } from "@web/../tests/web_test_helpers";
|
|
|
|
import {
|
|
dragPill,
|
|
getGridContent,
|
|
getPill,
|
|
mountGanttView,
|
|
SELECTORS,
|
|
} from "@web_gantt/../tests/web_gantt_test_helpers";
|
|
import { CalendarEvent, defineAppointmentModels } from "./appointment_tests_common";
|
|
|
|
describe.current.tags("desktop");
|
|
|
|
defineAppointmentModels();
|
|
|
|
/**
|
|
* @param {string} status
|
|
*/
|
|
async function mountGanttViewWithStatus(status) {
|
|
mockDate("2022-01-12 11:10:00", 0);
|
|
|
|
Object.assign(CalendarEvent._records[0], {
|
|
appointment_status: status,
|
|
appointment_type_id: 1,
|
|
start: "2022-01-12 10:00:00", // Late
|
|
stop: "2022-01-12 10:30:00",
|
|
});
|
|
Object.assign(CalendarEvent._records[1], {
|
|
appointment_status: status,
|
|
appointment_type_id: 1,
|
|
start: "2022-01-12 11:00:00", // Current
|
|
stop: "2022-01-12 11:30:00",
|
|
});
|
|
Object.assign(CalendarEvent._records[2], {
|
|
appointment_status: status,
|
|
appointment_type_id: 1,
|
|
start: "2022-01-12 12:00:00", // Future
|
|
stop: "2022-01-12 12:30:00",
|
|
partner_ids: [100, 214],
|
|
});
|
|
|
|
await mountGanttView({
|
|
resModel: "calendar.event",
|
|
});
|
|
}
|
|
|
|
function testGroupPillColorsCheckColors() {
|
|
const almostPastEventPill = getPill("Event 1", { nth: 1 });
|
|
const pastEventPill = getPill("Event 2", { nth: 1 });
|
|
const futureEventPill = getPill("Event 3", { nth: 3 });
|
|
|
|
const otherPartnerEventPills = [
|
|
getPill("Event 1", { nth: 2 }),
|
|
getPill("Event 2", { nth: 2 }),
|
|
getPill("Event 3", { nth: 1 }),
|
|
getPill("Event 3", { nth: 2 }),
|
|
getPill("Event 3", { nth: 4 }),
|
|
];
|
|
for (const pill of otherPartnerEventPills) {
|
|
expect(pill).toHaveClass("o_appointment_booking_gantt_color_grey");
|
|
}
|
|
expect(almostPastEventPill).toHaveClass("o_gantt_color_4");
|
|
expect(futureEventPill).toHaveClass("o_gantt_color_4");
|
|
expect(pastEventPill).toHaveClass("o_gantt_color_2");
|
|
}
|
|
|
|
const STATUS_CLASSNAMES = {
|
|
red: "o_gantt_color_1",
|
|
orange: "o_gantt_color_2",
|
|
lightBlue: "o_gantt_color_4",
|
|
blue: "o_gantt_color_8",
|
|
green: "o_gantt_color_10",
|
|
};
|
|
|
|
// minimalist version of the appointment gantt view
|
|
CalendarEvent._views.gantt = /* xml */ `
|
|
<gantt
|
|
js_class="appointment_booking_gantt"
|
|
date_start="start"
|
|
date_stop="stop"
|
|
default_group_by="partner_ids"
|
|
default_range="day"
|
|
default_scale="day"
|
|
>
|
|
<field name="active"/>
|
|
<field name="appointment_status"/>
|
|
<field name="appointment_type_id"/>
|
|
<field name="partner_id"/>
|
|
<field name="partner_ids"/>
|
|
<field name="resource_ids"/>
|
|
<field name="user_id"/>
|
|
<templates>
|
|
<div t-name="gantt-popover">
|
|
<ul>
|
|
<li>Name: <t t-out="gantt_pill_contact_name"/></li>
|
|
<li>Phone: <t t-out="gantt_pill_contact_phone"/></li>
|
|
<li>Email: <t t-out="gantt_pill_contact_email"/></li>
|
|
</ul>
|
|
</div>
|
|
</templates>
|
|
</gantt>`;
|
|
|
|
test("empty default group gantt rendering", async () => {
|
|
expect.assertions(18);
|
|
mockDate("2022-01-03 08:00:00");
|
|
CalendarEvent._records[0].appointment_type_id = 1;
|
|
CalendarEvent._records[1].appointment_type_id = 1;
|
|
CalendarEvent._records[2].appointment_type_id = 1;
|
|
CalendarEvent._views.gantt = CalendarEvent._views.gantt
|
|
.replace(`default_range="day"`, "")
|
|
.replace(`default_scale="day"`, "");
|
|
|
|
const partners = ["Partner 1", "Partner 214", "Partner 216"];
|
|
const partnerEvents = [
|
|
["Event 3", "Event 1"],
|
|
["Event 2", "Event 3", "Event 1"],
|
|
["Event 2", "Event 3"],
|
|
];
|
|
onRpc((args) => {
|
|
if (
|
|
args.model === "calendar.event" &&
|
|
args.method === "write" &&
|
|
args.args[0][0] === 2 &&
|
|
"partner_ids" in args.args[1]
|
|
) {
|
|
const methodArgs = args.args[1];
|
|
expect(methodArgs.start).toBe("2022-01-21 22:00:00");
|
|
expect(methodArgs.stop).toBe("2022-01-21 23:00:00");
|
|
const [unlinkCommand, linkCommand] = methodArgs.partner_ids;
|
|
expect(unlinkCommand[0]).toBe(3);
|
|
expect(unlinkCommand[1]).toBe(214);
|
|
expect(linkCommand[0]).toBe(4);
|
|
expect(linkCommand[1]).toBe(100);
|
|
|
|
asyncStep("write partners and date");
|
|
} else if (
|
|
args.model === "calendar.event" &&
|
|
args.method === "write" &&
|
|
args.args[0][0] === 2 &&
|
|
"user_id" in args.args[1]
|
|
) {
|
|
expect(args.args[1].user_id).toBe(100);
|
|
|
|
asyncStep("write user id");
|
|
} else if (args.model === "calendar.event" && args.method === "get_gantt_data") {
|
|
asyncStep("get_gantt_data");
|
|
}
|
|
});
|
|
await mountGanttView({ resModel: "calendar.event" });
|
|
const { rows } = getGridContent();
|
|
for (let pid = 0; pid < partners.length; pid++) {
|
|
expect(rows[pid].title).toBe(partners[pid]);
|
|
for (let eid = 0; eid < partnerEvents[pid].length; eid++) {
|
|
expect(rows[pid].pills[eid].title).toBe(partnerEvents[pid][eid]);
|
|
}
|
|
}
|
|
const { drop } = await dragPill("Event 2", { nth: 1 });
|
|
await drop({ row: "Partner 1", columnHeader: "21", groupHeader: "January 2022", part: 2 });
|
|
await waitForSteps([
|
|
"get_gantt_data",
|
|
"write partners and date",
|
|
"write user id",
|
|
"get_gantt_data",
|
|
]);
|
|
});
|
|
|
|
test("'Add Closing Days' button rendering - 1", async () => {
|
|
onRpc("has_group", ({ args }) => {
|
|
if (args[1] === "appointment.group_appointment_manager") {
|
|
return true;
|
|
}
|
|
});
|
|
await mountGanttView({
|
|
resModel: "calendar.event",
|
|
groupBy: ["resource_ids"],
|
|
});
|
|
expect(".o_appointment_booking_gantt_button_add_leaves").toHaveCount(1, {
|
|
message: "the button should have been rendered",
|
|
});
|
|
});
|
|
|
|
test("'Add Closing Days' button rendering - 2", async () => {
|
|
onRpc("has_group", ({ args }) => {
|
|
if (args[1] === "appointment.group_appointment_manager") {
|
|
return false;
|
|
}
|
|
});
|
|
await mountGanttView({
|
|
resModel: "calendar.event",
|
|
groupBy: ["resource_ids"],
|
|
});
|
|
expect(".o_appointment_booking_gantt_button_add_leaves").toHaveCount(0, {
|
|
message: "the button should not have been rendered: the user is not an appointment manager",
|
|
});
|
|
});
|
|
|
|
test("'Add Closing Days' button rendering - 3", async () => {
|
|
onRpc("has_group", ({ args }) => {
|
|
if (args[1] === "appointment.group_appointment_manager") {
|
|
return true;
|
|
}
|
|
});
|
|
await mountGanttView({
|
|
resModel: "calendar.event",
|
|
groupBy: ["partner_ids"],
|
|
});
|
|
expect(".o_appointment_booking_gantt_button_add_leaves").toHaveCount(0, {
|
|
message: "the button should not have been rendered: not grouped by 'resource_ids'",
|
|
});
|
|
});
|
|
|
|
test("group pill colors", async () => {
|
|
mockDate("2022-01-12 11:00:00", 0);
|
|
Object.assign(CalendarEvent._records[0], {
|
|
appointment_type_id: 1,
|
|
start: "2022-01-12 11:16:00",
|
|
stop: "2022-01-12 12:00:00",
|
|
});
|
|
Object.assign(CalendarEvent._records[1], {
|
|
appointment_type_id: 1,
|
|
start: "2022-01-12 10:30:00",
|
|
stop: "2022-01-12 12:00:00",
|
|
});
|
|
Object.assign(CalendarEvent._records[2], {
|
|
appointment_type_id: 1,
|
|
start: "2022-01-12 12:00:00",
|
|
stop: "2022-01-12 13:00:00",
|
|
});
|
|
await mountGanttView({
|
|
resModel: "calendar.event",
|
|
});
|
|
testGroupPillColorsCheckColors();
|
|
await click(SELECTORS.sparse);
|
|
await animationFrame();
|
|
testGroupPillColorsCheckColors();
|
|
await selectGroup("appointment_type_id");
|
|
// when not grouping by attendees we show "lateness" every time
|
|
expect(document.querySelectorAll(".o_appointment_booking_gantt_color_grey")).toBeEmpty();
|
|
await selectGroup("partner_ids");
|
|
testGroupPillColorsCheckColors();
|
|
await click(SELECTORS.dense);
|
|
await animationFrame();
|
|
testGroupPillColorsCheckColors();
|
|
});
|
|
|
|
test("appointment status pill colors: request", async () => {
|
|
await mountGanttViewWithStatus("request");
|
|
|
|
expect(getPill("Event 1", { nth: 1 })).toHaveClass(STATUS_CLASSNAMES.orange);
|
|
expect(getPill("Event 2", { nth: 1 })).toHaveClass(STATUS_CLASSNAMES.orange);
|
|
expect(getPill("Event 3", { nth: 1 })).toHaveClass(STATUS_CLASSNAMES.blue);
|
|
|
|
expect(getPill("Event 1", { nth: 2 })).toHaveClass("o_appointment_booking_gantt_color_grey");
|
|
expect(getPill("Event 2", { nth: 2 })).toHaveClass("o_appointment_booking_gantt_color_grey");
|
|
expect(getPill("Event 3", { nth: 2 })).toHaveClass("o_appointment_booking_gantt_color_grey");
|
|
});
|
|
|
|
test("appointment status pill colors: booked", async () => {
|
|
await mountGanttViewWithStatus("booked");
|
|
|
|
expect(getPill("Event 1", { nth: 1 })).toHaveClass(STATUS_CLASSNAMES.orange);
|
|
expect(getPill("Event 2", { nth: 1 })).toHaveClass(STATUS_CLASSNAMES.lightBlue);
|
|
expect(getPill("Event 3", { nth: 1 })).toHaveClass(STATUS_CLASSNAMES.lightBlue);
|
|
|
|
expect(getPill("Event 1", { nth: 2 })).toHaveClass("o_appointment_booking_gantt_color_grey");
|
|
expect(getPill("Event 2", { nth: 2 })).toHaveClass("o_appointment_booking_gantt_color_grey");
|
|
expect(getPill("Event 3", { nth: 2 })).toHaveClass("o_appointment_booking_gantt_color_grey");
|
|
});
|
|
|
|
test("appointment status pill colors: attended", async () => {
|
|
await mountGanttViewWithStatus("attended");
|
|
|
|
expect(getPill("Event 1", { nth: 1 })).toHaveClass(STATUS_CLASSNAMES.green);
|
|
expect(getPill("Event 2", { nth: 1 })).toHaveClass(STATUS_CLASSNAMES.green);
|
|
expect(getPill("Event 3", { nth: 1 })).toHaveClass(STATUS_CLASSNAMES.green);
|
|
|
|
expect(getPill("Event 1", { nth: 2 })).toHaveClass("o_appointment_booking_gantt_color_grey");
|
|
expect(getPill("Event 2", { nth: 2 })).toHaveClass("o_appointment_booking_gantt_color_grey");
|
|
expect(getPill("Event 3", { nth: 2 })).toHaveClass("o_appointment_booking_gantt_color_grey");
|
|
});
|
|
|
|
test("appointment status pill colors: no_show", async () => {
|
|
await mountGanttViewWithStatus("no_show");
|
|
|
|
expect(getPill("Event 1", { nth: 1 })).toHaveClass(STATUS_CLASSNAMES.red);
|
|
expect(getPill("Event 2", { nth: 1 })).toHaveClass(STATUS_CLASSNAMES.red);
|
|
expect(getPill("Event 3", { nth: 1 })).toHaveClass(STATUS_CLASSNAMES.red);
|
|
|
|
expect(getPill("Event 1", { nth: 2 })).toHaveClass("o_appointment_booking_gantt_color_grey");
|
|
expect(getPill("Event 2", { nth: 2 })).toHaveClass("o_appointment_booking_gantt_color_grey");
|
|
expect(getPill("Event 3", { nth: 2 })).toHaveClass("o_appointment_booking_gantt_color_grey");
|
|
});
|
|
|
|
test("undo action: move and undo a pill", async () => {
|
|
expect.assertions(4);
|
|
mockDate("2022-01-03 08:00:00")
|
|
CalendarEvent._views.gantt = CalendarEvent._views.gantt
|
|
.replace(`default_range="day"`, "")
|
|
.replace(`default_scale="day"`, "");
|
|
|
|
onRpc("gantt_undo_drag_drop", function ({ model, args }) {
|
|
expect(args[0]).toEqual(2);
|
|
expect(args[1]).toEqual("reschedule");
|
|
expect(args[2]).toEqual({
|
|
partner_ids: [ 214 ],
|
|
start: "2022-01-05 10:00:00",
|
|
stop: "2022-01-05 11:00:00",
|
|
},
|
|
);
|
|
return this.env[model].write([args[0]], args[2]);
|
|
});
|
|
|
|
await mountGanttView({ resModel: "calendar.event" });
|
|
|
|
const { drop } = await dragPill("Event 2", { nth: 1 });
|
|
await drop({ row: "Partner 1", columnHeader: "21", groupHeader: "January 2022", part: 2 });
|
|
|
|
await contains(".o_notification_buttons button i[title='Undo']").click();
|
|
expect(".o_notification_content").toHaveText("Record reschedule undone");
|
|
});
|