[IMP] mail: add/modify activity client tests
We add a test that checks the rendering of the activity view and the activity popover with activities done. We also add a test that marks as done an activity and verify that the activity view is updated accordingly. And we do a correction in the test "activity menu widget: activity menu with 2 models" (assert.ok(selectContaining... was always true as an array is always returned and [] is true in javascript). Task-3558929 Part-of: odoo/odoo#139373
This commit is contained in:
committed by
Thibault Delavallée
parent
949039135d
commit
d2f44211b9
@@ -4,7 +4,7 @@ import { Domain } from "@web/core/domain";
|
||||
import { groupBy, sortBy, unique } from "@web/core/utils/arrays";
|
||||
import { patch } from "@web/core/utils/patch";
|
||||
import { MockServer } from "@web/../tests/helpers/mock_server";
|
||||
import { deserializeDate } from "@web/core/l10n/dates";
|
||||
import { deserializeDate, serializeDate, today } from "@web/core/l10n/dates";
|
||||
|
||||
const { DateTime} = luxon;
|
||||
|
||||
@@ -84,8 +84,7 @@ patch(MockServer.prototype, {
|
||||
* @returns {Object}
|
||||
*/
|
||||
_mockMailActivityActionDone(ids) {
|
||||
const activities = this.getRecords("mail.activity", [["id", "in", ids]]);
|
||||
this.mockUnlink("mail.activity", [activities.map((activity) => activity.id)]);
|
||||
this._mockMailActivityActionFeedback(ids);
|
||||
},
|
||||
/**
|
||||
* Simulates `action_feedback` on `mail.activity`.
|
||||
@@ -96,7 +95,24 @@ patch(MockServer.prototype, {
|
||||
* @returns {Object}
|
||||
*/
|
||||
_mockMailActivityActionFeedback(ids, attachment_ids= null) {
|
||||
this._mockMailActivityActionDone(ids);
|
||||
const activities = this.getRecords("mail.activity", [["id", "in", ids]]);
|
||||
const activityTypes = this.getRecords("mail.activity.type", [
|
||||
["id", "in", unique(activities.map((a) => a.activity_type_id))],
|
||||
]);
|
||||
const activityTypeById = Object.fromEntries(
|
||||
activityTypes.map((actType) => [actType.id, actType])
|
||||
);
|
||||
this.mockWrite("mail.activity", [
|
||||
activities
|
||||
.filter((act) => activityTypeById[act.activity_type_id].keep_done)
|
||||
.map((act) => act.id),
|
||||
{ active: false, date_done: serializeDate(today()), state: "done" },
|
||||
]);
|
||||
this.mockUnlink("mail.activity", [
|
||||
activities
|
||||
.filter((act) => !activityTypeById[act.activity_type_id].keep_done)
|
||||
.map((act) => act.id),
|
||||
]);
|
||||
},
|
||||
/**
|
||||
* Simulates `action_feedback_schedule_next` on `mail.activity`.
|
||||
|
||||
@@ -241,6 +241,162 @@ QUnit.module("test_mail", {}, function () {
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test("activity view: Activity rendering with done activities", async function (assert) {
|
||||
function containsN(domElement, selector, containings) {
|
||||
return Array.from(domElement.querySelectorAll(selector)).filter((sel) =>
|
||||
containings.every((containing) => sel.textContent.includes(containing))
|
||||
);
|
||||
}
|
||||
|
||||
const activityTypeUpload = pyEnv["mail.activity.type"].create({
|
||||
category: "upload_file",
|
||||
name: "Test Upload document",
|
||||
keep_done: true,
|
||||
});
|
||||
pyEnv["mail.activity"].create(
|
||||
Object.entries(["done", "done", "done", "done", "planned", "planned", "planned"]).map(
|
||||
([idx, state]) => ({
|
||||
active: state !== "done",
|
||||
activity_type_id: activityTypeUpload,
|
||||
attachment_ids:
|
||||
state === "done"
|
||||
? [
|
||||
pyEnv["ir.attachment"].create({
|
||||
name: `attachment ${idx}`,
|
||||
create_date: serializeDate(
|
||||
DateTime.now().minus({ days: idx })
|
||||
),
|
||||
create_uid: pyEnv.currentUserId,
|
||||
}),
|
||||
]
|
||||
: [],
|
||||
can_write: true,
|
||||
date_deadline: serializeDate(DateTime.now().plus({ days: idx })),
|
||||
date_done:
|
||||
state === "done"
|
||||
? serializeDate(DateTime.now().minus({ days: idx }))
|
||||
: false,
|
||||
display_name: `Upload folders ${idx}`,
|
||||
state: state,
|
||||
user_id: pyEnv["res.users"].create({ display_name: `user${idx}` }),
|
||||
})
|
||||
)
|
||||
);
|
||||
const [meetingRecord, officeRecord] = pyEnv["mail.test.activity"].search([]);
|
||||
const uploadDoneActs = pyEnv["mail.activity"].searchRead([
|
||||
["activity_type_id", "=", activityTypeUpload],
|
||||
["active", "=", false],
|
||||
]);
|
||||
const uploadPlannedActs = pyEnv["mail.activity"].searchRead([
|
||||
["activity_type_id", "=", activityTypeUpload],
|
||||
]);
|
||||
pyEnv["mail.test.activity"].write([meetingRecord], {
|
||||
activity_ids: [
|
||||
uploadPlannedActs[0].id,
|
||||
uploadPlannedActs[1].id,
|
||||
uploadPlannedActs[2].id,
|
||||
uploadDoneActs[0].id,
|
||||
],
|
||||
});
|
||||
pyEnv["mail.test.activity"].write([officeRecord], {
|
||||
activity_ids: [uploadDoneActs[1].id, uploadDoneActs[2].id, uploadDoneActs[3].id],
|
||||
});
|
||||
const { openView } = await start({
|
||||
serverData,
|
||||
});
|
||||
await openView({
|
||||
res_model: "mail.test.activity",
|
||||
views: [[false, "activity"]],
|
||||
});
|
||||
const domActivity = document.querySelector(".o_activity_view");
|
||||
const domHeaderUpload = domActivity.querySelector(
|
||||
"table thead tr:first-child th:nth-child(6)"
|
||||
);
|
||||
const selRowMeetingCellUpload = "table tbody tr:first-child td:nth-child(6)";
|
||||
const domRowMeetingCellUpload = domActivity.querySelector(selRowMeetingCellUpload);
|
||||
const selRowOfficeCellUpload = "table tbody tr:nth-child(2) td:nth-child(6)";
|
||||
const domRowOfficeCellUpload = domActivity.querySelector(selRowOfficeCellUpload);
|
||||
|
||||
// Headers
|
||||
await contains(".o_column_progress .progress-bar:first-child[data-tooltip='3 Planned']", {
|
||||
target: domHeaderUpload,
|
||||
});
|
||||
await contains(".o_animated_number", {
|
||||
target: domHeaderUpload,
|
||||
text: "3",
|
||||
});
|
||||
await contains(".o_column_progress_aggregated_on", {
|
||||
target: domHeaderUpload,
|
||||
text: "7",
|
||||
});
|
||||
// Cells avatars
|
||||
await contains(
|
||||
`.o-mail-Avatar img[data-src='/web/image/res.users/${uploadPlannedActs[0].user_id[0]}/avatar_128'`,
|
||||
{ target: domRowMeetingCellUpload }
|
||||
);
|
||||
await contains(
|
||||
`.o-mail-Avatar img[data-src='/web/image/res.users/${uploadPlannedActs[1].user_id[0]}/avatar_128'`,
|
||||
{ target: domRowMeetingCellUpload }
|
||||
);
|
||||
await contains(
|
||||
`.o-mail-Avatar img[data-src='/web/image/res.users/${uploadPlannedActs[2].user_id[0]}/avatar_128'`,
|
||||
{ target: domRowMeetingCellUpload, count: 0 }
|
||||
);
|
||||
await contains(`.o-mail-Avatar`, { target: domRowOfficeCellUpload, count: 0 }); // all activity are done
|
||||
// Cells counters
|
||||
assert.ok(
|
||||
containsN(domRowMeetingCellUpload, ".o-mail-ActivityCell-counter", ["3", "/", "4"])
|
||||
);
|
||||
await contains(".o-mail-ActivityCell-counter", {
|
||||
text: "3",
|
||||
target: domRowOfficeCellUpload,
|
||||
});
|
||||
// Cells dates
|
||||
await contains(".o-mail-ActivityCell-deadline", {
|
||||
text: luxon.DateTime.fromISO(uploadPlannedActs[0].date_deadline).toLocaleString(
|
||||
luxon.DateTime.DATE_SHORT
|
||||
),
|
||||
target: domRowMeetingCellUpload,
|
||||
});
|
||||
await contains(".o-mail-ActivityCell-deadline", {
|
||||
text: luxon.DateTime.fromISO(uploadDoneActs[1].date_done).toLocaleString(
|
||||
luxon.DateTime.DATE_SHORT
|
||||
),
|
||||
target: domRowOfficeCellUpload,
|
||||
});
|
||||
// Activity list popovers content
|
||||
await click(domActivity, `${selRowMeetingCellUpload} > div`);
|
||||
await contains(".o-mail-ActivityListPopover .badge.text-bg-success", { text: "3" }); // 3 planned
|
||||
for (const actIdx of [0, 1, 2]) {
|
||||
await contains(".o-mail-ActivityListPopoverItem", {
|
||||
text: uploadPlannedActs[actIdx].user_id[1],
|
||||
});
|
||||
}
|
||||
await contains(".o-mail-ActivityListPopoverItem", { text: "Due in 4 days" });
|
||||
await contains(".o-mail-ActivityListPopoverItem", { text: "Due in 5 days" });
|
||||
await contains(".o-mail-ActivityListPopoverItem", { text: "Due in 6 days" });
|
||||
await contains(".o-mail-ActivityListPopover .badge.text-bg-secondary", { text: "1" }); // 1 done
|
||||
await contains(".o-mail-ActivityListPopoverItem", { text: uploadDoneActs[0].user_id[1] });
|
||||
await contains(".o-mail-ActivityListPopoverItem", {
|
||||
text: luxon.DateTime.fromISO(uploadDoneActs[0].date_done).toLocaleString(
|
||||
luxon.DateTime.DATE_SHORT
|
||||
),
|
||||
});
|
||||
|
||||
await click(domActivity, `${selRowOfficeCellUpload} > div`);
|
||||
await contains(".o-mail-ActivityListPopover .badge.text-bg-secondary", { text: "3" }); // 3 done
|
||||
for (const actIdx of [1, 2, 3]) {
|
||||
await contains(".o-mail-ActivityListPopoverItem", {
|
||||
text: luxon.DateTime.fromISO(uploadDoneActs[actIdx].date_done).toLocaleString(
|
||||
luxon.DateTime.DATE_SHORT
|
||||
),
|
||||
});
|
||||
await contains(".o-mail-ActivityListPopoverItem", {
|
||||
text: uploadDoneActs[actIdx].user_id[1],
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
"activity view: a pager can be used when there are more than the limit of 100 activities to display",
|
||||
async function (assert) {
|
||||
@@ -538,6 +694,49 @@ QUnit.module("test_mail", {}, function () {
|
||||
]);
|
||||
});
|
||||
|
||||
QUnit.test("activity view: Mark as done with keep done enabled", async function (assert) {
|
||||
const emailActType = pyEnv["mail.activity.type"].search([["name", "=", "Email"]])[0];
|
||||
pyEnv["mail.activity.type"].write([emailActType], {
|
||||
keep_done: true,
|
||||
});
|
||||
const { openView } = await start({
|
||||
serverData,
|
||||
});
|
||||
await openView({
|
||||
res_model: "mail.test.activity",
|
||||
views: [[false, "activity"]],
|
||||
context: { active_test: false },
|
||||
});
|
||||
const domActivity = document.querySelector(".o_activity_view");
|
||||
const domHeaderEmail = domActivity.querySelector(
|
||||
"table thead tr:first-child th:nth-child(2)"
|
||||
);
|
||||
const selRowOfficeCellEmail = "table tbody tr:nth-child(2) td:nth-child(2)";
|
||||
|
||||
await contains(".o_animated_number", {
|
||||
target: domHeaderEmail,
|
||||
text: "2",
|
||||
});
|
||||
await contains(".o_column_progress_aggregated_on", {
|
||||
target: domHeaderEmail,
|
||||
text: "2",
|
||||
});
|
||||
await click(domActivity, `${selRowOfficeCellEmail} > div`);
|
||||
await click(
|
||||
document,
|
||||
".o-mail-ActivityListPopoverItem .o-mail-ActivityListPopoverItem-markAsDone"
|
||||
);
|
||||
await click(document, ".o-mail-ActivityMarkAsDone button[aria-label='Done']");
|
||||
await contains(".o_animated_number", {
|
||||
target: domHeaderEmail,
|
||||
text: "1",
|
||||
});
|
||||
await contains(".o_column_progress_aggregated_on", {
|
||||
target: domHeaderEmail,
|
||||
text: "2",
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test("activity view: no group_by_menu and no comparison_menu", async function (assert) {
|
||||
assert.expect(4);
|
||||
|
||||
|
||||
@@ -45,10 +45,10 @@ QUnit.test("do not show empty text when at least some future activities", async
|
||||
});
|
||||
|
||||
QUnit.test("activity menu widget: activity menu with 2 models", async (assert) => {
|
||||
function selectContaining(domElement, selector, containings) {
|
||||
function containsN(domElement, selector, containings) {
|
||||
return Array.from(domElement.querySelectorAll(selector)).filter((sel) =>
|
||||
containings.every((containing) => sel.textContent.includes(containing))
|
||||
);
|
||||
).length;
|
||||
}
|
||||
|
||||
const tomorrow = today().plus({ days: 1 });
|
||||
@@ -95,22 +95,22 @@ QUnit.test("activity menu widget: activity menu with 2 models", async (assert) =
|
||||
await contains(".o-mail-ActivityMenu");
|
||||
await contains(".o-mail-ActivityMenu .o-mail-ActivityGroup", { count: 2 });
|
||||
assert.ok(
|
||||
selectContaining(document, ".o-mail-ActivityMenu .o-mail-ActivityGroup", ["res.partner", "0 Late"])
|
||||
containsN(document, ".o-mail-ActivityMenu .o-mail-ActivityGroup", ["res.partner", "0 Late"])
|
||||
);
|
||||
assert.ok(
|
||||
selectContaining(document, ".o-mail-ActivityMenu .o-mail-ActivityGroup", ["res.partner", "1 Today"])
|
||||
containsN(document, ".o-mail-ActivityMenu .o-mail-ActivityGroup", ["res.partner", "1 Today"])
|
||||
);
|
||||
assert.ok(
|
||||
selectContaining(document, ".o-mail-ActivityMenu .o-mail-ActivityGroup", ["res.partner", "0 Future"])
|
||||
containsN(document, ".o-mail-ActivityMenu .o-mail-ActivityGroup", ["res.partner", "0 Future"])
|
||||
);
|
||||
assert.ok(
|
||||
selectContaining(document, ".o-mail-ActivityMenu .o-mail-ActivityGroup", ["mail.test.activity", "1 Late"])
|
||||
containsN(document, ".o-mail-ActivityMenu .o-mail-ActivityGroup", ["mail.test.activity", "1 Late"])
|
||||
);
|
||||
assert.ok(
|
||||
selectContaining(document, ".o-mail-ActivityMenu .o-mail-ActivityGroup", ["mail.test.activity", "1 Today"])
|
||||
containsN(document, ".o-mail-ActivityMenu .o-mail-ActivityGroup", ["mail.test.activity", "1 Today"])
|
||||
);
|
||||
assert.ok(
|
||||
selectContaining(document, ".o-mail-ActivityMenu .o-mail-ActivityGroup", ["mail.test.activity", "2 Future"])
|
||||
containsN(document, ".o-mail-ActivityMenu .o-mail-ActivityGroup", ["mail.test.activity", "2 Future"])
|
||||
);
|
||||
actionChecks.res_model = "res.partner";
|
||||
await click(".o-mail-ActivityMenu .o-mail-ActivityGroup", { text: "res.partner" });
|
||||
|
||||
Reference in New Issue
Block a user