From 7ab24685e299d8e4902d0b1abb2b831f2cd55ec4 Mon Sep 17 00:00:00 2001 From: tsm-odoo Date: Tue, 25 Jul 2023 13:43:44 +0000 Subject: [PATCH] [FIX] im_livechat: reset livechat when session cannot be persisted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this PR, failing to persist a livechat thread would stuck the livechat session in an incoherent state, preventing the user to open a livechat. This PR ensures the thread service does not write anything if there is no session. closes odoo/odoo#129699 X-original-commit: d4e8b62fa8f008cd4ab7d69e413115cb35a6ac33 Signed-off-by: Alexandre Kühn (aku) Signed-off-by: Matthieu Stockbauer (tsm) --- .../src/embed/core/thread_service_patch.js | 6 ++-- .../src/embed/core_ui/livechat_button.js | 5 +++- .../tests/embed/livechat_session_tests.js | 29 +++++++++++++++++-- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/addons/im_livechat/static/src/embed/core/thread_service_patch.js b/addons/im_livechat/static/src/embed/core/thread_service_patch.js index 1efea50a877..803bad01c4a 100644 --- a/addons/im_livechat/static/src/embed/core/thread_service_patch.js +++ b/addons/im_livechat/static/src/embed/core/thread_service_patch.js @@ -134,17 +134,17 @@ patch(ThreadService.prototype, "im_livechat", { }); } onChange(thread, "state", () => { - if (this.livechatService.state !== SESSION_STATE.CLOSED) { + if ([SESSION_STATE.CLOSED, SESSION_STATE.NONE].includes(thread.state)) { this.livechatService.updateSession({ state: thread.state }); } }); onChange(thread, "seen_message_id", () => { - if (this.livechatService.state !== SESSION_STATE.CLOSED) { + if ([SESSION_STATE.CLOSED, SESSION_STATE.NONE].includes(thread.state)) { this.livechatService.updateSession({ seen_message_id: thread.seen_message_id }); } }); onChange(thread, "message_unread_counter", () => { - if (this.livechatService.state !== SESSION_STATE.CLOSED) { + if ([SESSION_STATE.CLOSED, SESSION_STATE.NONE].includes(thread.state)) { this.livechatService.updateSession({ channel: thread.channel }); } }); diff --git a/addons/im_livechat/static/src/embed/core_ui/livechat_button.js b/addons/im_livechat/static/src/embed/core_ui/livechat_button.js index 0c9727838d6..a6019f8a827 100644 --- a/addons/im_livechat/static/src/embed/core_ui/livechat_button.js +++ b/addons/im_livechat/static/src/embed/core_ui/livechat_button.js @@ -11,6 +11,7 @@ import { debounce } from "@web/core/utils/timing"; export class LivechatButton extends Component { static template = "im_livechat.LivechatButton"; + static DEBOUNCE_DELAY = 500; setup() { this.store = useStore(); @@ -20,7 +21,9 @@ export class LivechatButton extends Component { this.livechatService = useState(useService("im_livechat.livechat")); /** @type {import('@mail/core/common/thread_service').ThreadService} */ this.threadService = useService("mail.thread"); - this.onClick = debounce(this.onClick.bind(this), 500, { leading: true }); + this.onClick = debounce(this.onClick.bind(this), LivechatButton.DEBOUNCE_DELAY, { + leading: true, + }); } onClick() { diff --git a/addons/im_livechat/static/tests/embed/livechat_session_tests.js b/addons/im_livechat/static/tests/embed/livechat_session_tests.js index f97e197574e..af4246fad6b 100644 --- a/addons/im_livechat/static/tests/embed/livechat_session_tests.js +++ b/addons/im_livechat/static/tests/embed/livechat_session_tests.js @@ -3,11 +3,12 @@ import { startServer } from "@bus/../tests/helpers/mock_python_environment"; import { loadDefaultConfig, setCookie, start } from "@im_livechat/../tests/embed/helper/test_utils"; +import { LivechatButton } from "@im_livechat/embed/core_ui/livechat_button"; import { Command } from "@mail/../tests/helpers/command"; -import { afterNextRender, insertText } from "@mail/../tests/helpers/test_utils"; +import { afterNextRender, click, insertText } from "@mail/../tests/helpers/test_utils"; -import { triggerHotkey } from "@web/../tests/helpers/utils"; +import { mockTimeout, triggerHotkey } from "@web/../tests/helpers/utils"; QUnit.module("livechat session"); @@ -37,3 +38,27 @@ QUnit.test("Unsuccessful message post shows session expired", async (assert) => assert.containsOnce($, ".o_notification:contains(Session expired)"); assert.containsNone($, ".o-mail-ChatWindow"); }); + +QUnit.test("Session is reset after failing to persist the channel", async (assert) => { + await startServer(); + await loadDefaultConfig(); + const { advanceTime } = mockTimeout(); + await start({ + mockRPC(route, args) { + if (route === "/im_livechat/get_session" && args.persisted) { + return false; + } + }, + }); + await click(".o-livechat-LivechatButton"); + await insertText(".o-mail-Composer-input", "Hello World!"); + await afterNextRender(() => triggerHotkey("Enter")); + assert.containsOnce( + $, + ".o_notification:contains(No available collaborator, please try again later.)" + ); + assert.containsOnce($, ".o-livechat-LivechatButton"); + await advanceTime(LivechatButton.DEBOUNCE_DELAY + 10); + await click(".o-livechat-LivechatButton"); + assert.containsOnce($, ".o-mail-ChatWindow"); +});