diff --git a/addons/mail/static/src/core/thread_service.js b/addons/mail/static/src/core/thread_service.js index 813f494f324..2a8d4184383 100644 --- a/addons/mail/static/src/core/thread_service.js +++ b/addons/mail/static/src/core/thread_service.js @@ -681,6 +681,7 @@ export class ThreadService { const tmpId = lastMessageId + 0.01; const params = { context: { + mail_post_autofollow: !isNote && thread.hasWriteAccess, temporary_id: tmpId, }, post_data: { diff --git a/addons/mail/static/tests/composer/suggested_recipients_test.js b/addons/mail/static/tests/composer/suggested_recipients_test.js index 28b58aedab4..73721df62c8 100644 --- a/addons/mail/static/tests/composer/suggested_recipients_test.js +++ b/addons/mail/static/tests/composer/suggested_recipients_test.js @@ -206,6 +206,26 @@ QUnit.test( } ); +QUnit.test( + "suggested recipients should be added as follower when posting a message", + async (assert) => { + const pyEnv = await startServer(); + const partnerId = pyEnv["res.partner"].create({ + display_name: "John Jane", + email: "john@jane.be", + }); + const fakeId = pyEnv["res.fake"].create({ partner_ids: [partnerId] }); + const { openFormView } = await start({ + serverData: { views }, + }); + await openFormView("res.fake", fakeId); + await click("button:contains(Send message)"); + await insertText(".o-mail-Composer-input", "Dummy Message"); + await click(".o-mail-Composer-send"); + assert.strictEqual($(".o-mail-Followers-counter").text(), "1"); + } +); + QUnit.test( "suggested recipient without partner are unchecked when closing the dialog without creating partner", async (assert) => { diff --git a/addons/mail/static/tests/helpers/mock_server/controllers/discuss.js b/addons/mail/static/tests/helpers/mock_server/controllers/discuss.js index f3e5d27c484..4387dd8a545 100644 --- a/addons/mail/static/tests/helpers/mock_server/controllers/discuss.js +++ b/addons/mail/static/tests/helpers/mock_server/controllers/discuss.js @@ -448,7 +448,7 @@ patch(MockServer.prototype, "mail/controllers/discuss", { res["hasReadAccess"] = false; return res; } - res['canPostOnReadonly'] = thread_model === 'mail.channel'; // model that have attr _mail_post_access='read' + res["canPostOnReadonly"] = thread_model === "mail.channel"; // model that have attr _mail_post_access='read' if (request_list.includes("activities")) { const activities = this.pyEnv["mail.activity"].searchRead([ ["id", "in", thread.activity_ids || []], diff --git a/addons/mail/static/tests/helpers/mock_server/models/mail_thread.js b/addons/mail/static/tests/helpers/mock_server/models/mail_thread.js index ba22e2c5946..abc8d11a868 100644 --- a/addons/mail/static/tests/helpers/mock_server/models/mail_thread.js +++ b/addons/mail/static/tests/helpers/mock_server/models/mail_thread.js @@ -154,6 +154,9 @@ patch(MockServer.prototype, "mail/models/mail_thread", { */ _mockMailThreadMessagePost(model, ids, kwargs, context) { const id = ids[0]; // ensure_one + if (context?.["mail_post_autofollow"] && kwargs["partner_ids"].length > 0) { + this._mockMailThreadMessageSubscribe(model, ids, kwargs["partner_ids"]); + } if (kwargs.attachment_ids) { const attachments = this.getRecords("ir.attachment", [ ["id", "in", kwargs.attachment_ids], @@ -197,7 +200,7 @@ patch(MockServer.prototype, "mail/models/mail_thread", { * @param {string} model not in server method but necessary for thread mock * @param {integer[]} ids * @param {integer[]} partner_ids - * @param {integer[]} subtype_ids + * @param {integer[]} [subtype_ids] * @returns {boolean} */ _mockMailThreadMessageSubscribe(model, ids, partner_ids, subtype_ids) { @@ -207,6 +210,14 @@ patch(MockServer.prototype, "mail/models/mail_thread", { ["partner_id", "=", partner_id], ])[0]; if (!followerId) { + if (!subtype_ids || subtype_ids.length === 0) { + subtype_ids = this.pyEnv["mail.message.subtype"].search([ + ["default", "=", true], + "|", + ["res_model", "=", model], + ["res_model", "=", false], + ]); + } followerId = this.pyEnv["mail.followers"].create({ is_active: true, partner_id, @@ -215,6 +226,9 @@ patch(MockServer.prototype, "mail/models/mail_thread", { subtype_ids: subtype_ids, }); } + this.pyEnv[model].write(ids, { + message_follower_ids: [followerId], + }); this.pyEnv["res.partner"].write([partner_id], { message_follower_ids: [followerId], }); diff --git a/addons/mail/static/tests/helpers/model_definitions_setup.js b/addons/mail/static/tests/helpers/model_definitions_setup.js index ffa14f68168..4cfe51defc1 100644 --- a/addons/mail/static/tests/helpers/model_definitions_setup.js +++ b/addons/mail/static/tests/helpers/model_definitions_setup.js @@ -95,6 +95,7 @@ insertModelFields("mail.message", { res_model_name: { string: "Res Model Name", type: "char" }, }); insertModelFields("mail.message.subtype", { + default: { default: true }, subtype_xmlid: { type: "char" }, }); insertModelFields("mail.tracking.value", {