File: test_chatbot_ui.py

package info (click to toggle)
odoo 18.0.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 878,716 kB
  • sloc: javascript: 927,937; python: 685,670; xml: 388,524; sh: 1,033; sql: 415; makefile: 26
file content (204 lines) | stat: -rw-r--r-- 9,716 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import Command, tests
from odoo.addons.im_livechat.tests.chatbot_common import ChatbotCase
from odoo.addons.website_livechat.tests.common import TestLivechatCommon


@tests.tagged('post_install', '-at_install')
class TestLivechatChatbotUI(TestLivechatCommon, ChatbotCase):
    def setUp(self):
        super().setUp()
        self.env['im_livechat.channel'].search([
            ('id', '!=', self.livechat_channel.id)
        ]).unlink()  # delete other channels to avoid them messing with the URL rules

        self.livechat_channel.write({
            'is_published': True,
            'rule_ids': [(5, 0), (0, 0, {
                'action': 'auto_popup',
                'regex_url': '/',
                'chatbot_script_id': self.chatbot_script.id,
            })]
        })

        self.env.ref('website.default_website').channel_id = self.livechat_channel.id

    def _check_complete_chatbot_flow_result(self):
        operator = self.chatbot_script.operator_partner_id
        livechat_discuss_channel = self.env['discuss.channel'].search([
            ('livechat_channel_id', '=', self.livechat_channel.id),
            ('livechat_operator_id', '=', operator.id),
            ('message_ids', '!=', False),
        ])

        self.assertTrue(bool(livechat_discuss_channel))
        self.assertEqual(len(livechat_discuss_channel), 1)

        conversation_messages = livechat_discuss_channel.message_ids.sorted('id')

        expected_messages = [
            ("Hello! I'm a bot!", operator, False),
            ("I help lost visitors find their way.", operator, False),
            # next message would normally have 'self.step_dispatch_buy_software' as answer
            # but it's wiped when restarting the script
            ("How can I help you?", operator, False),
            ("I want to buy the software", False, False),
            ("Can you give us your email please?", operator, False),
            ("No, you won't get my email!", False, False),
            ("'No, you won't get my email!' does not look like a valid email. Can you please try again?", operator, False),
            ("okfine@fakeemail.com", False, False),
            ("Your email is validated, thank you!", operator, False),
            ("Would you mind providing your website address?", operator, False),
            ("https://www.fakeaddress.com", False, False),
            ("Great, do you want to leave any feedback for us to improve?", operator, False),
            ("Yes, actually, I'm glad you asked!", False, False),
            ("I think it's outrageous that you ask for all my personal information!", False, False),
            ("I will be sure to take this to your manager!", False, False),
            ("Ok bye!", operator, False),
            ("Restarting conversation...", operator, False),
            ("Hello! I'm a bot!", operator, False),
            ("I help lost visitors find their way.", operator, False),
            ("How can I help you?", operator, False),
            ("Pricing Question", False, False),
            ("For any pricing question, feel free ton contact us at pricing@mycompany.com", operator, False),
            ("We will reach back to you as soon as we can!", operator, False),
            ("Would you mind providing your website address?", operator, False),
            ("no", False, False),
            ("Great, do you want to leave any feedback for us to improve?", operator, False),
            ("no, nothing so say", False, False),
            ("Ok bye!", operator, False),
            ("Restarting conversation...", operator, False),
            ("Hello! I'm a bot!", operator, False),
            ("I help lost visitors find their way.", operator, False),
            ("How can I help you?", operator, self.step_dispatch_operator),
            ("I want to speak with an operator", False, False),
            ("I will transfer you to a human", operator, False),
            (f"{self.operator.livechat_username} has joined", operator, False),
        ]

        self.assertEqual(len(conversation_messages), len(expected_messages))

        # check that the whole conversation is correctly saved
        # including welcome steps: see chatbot.script#_post_welcome_steps
        for conversation_message, expected_message in zip(conversation_messages, expected_messages):
            [body, operator, user_script_answer_id] = expected_message

            self.assertIn(body, conversation_message.body)

            if operator:
                self.assertEqual(conversation_message.author_id, operator)
            else:
                self.assertNotEqual(conversation_message.author_id, operator)

            if user_script_answer_id:
                self.assertEqual(
                    user_script_answer_id,
                    self.env['chatbot.message'].search([
                        ('mail_message_id', '=', conversation_message.id)
                    ], limit=1).user_script_answer_id
                )

    def test_complete_chatbot_flow_ui(self):
        tests.new_test_user(self.env, login="portal_user", groups="base.group_portal")
        operator = self.chatbot_script.operator_partner_id
        self.start_tour('/', 'website_livechat_chatbot_flow_tour', step_delay=100)
        self._check_complete_chatbot_flow_result()
        self.env['discuss.channel'].search([
            ('livechat_channel_id', '=', self.livechat_channel.id),
            ('livechat_operator_id', '=', operator.id),
        ]).unlink()
        self.start_tour('/', 'website_livechat_chatbot_flow_tour', step_delay=100, login="portal_user")
        self._check_complete_chatbot_flow_result()

    def test_chatbot_available_after_reload(self):
        self.start_tour("/", "website_livechat_chatbot_after_reload_tour", step_delay=100)

    def test_chatbot_test_page_tour(self):
        bob_operator = tests.new_test_user(self.env, login="bob_user", groups="im_livechat.im_livechat_group_user,base.group_user")
        self.livechat_channel.user_ids += bob_operator
        test_page_url = f"/chatbot/{'-'.join(self.chatbot_script.title.split(' '))}-{self.chatbot_script.id}/test"
        self.start_tour(test_page_url, "website_livechat_chatbot_test_page_tour", login="bob_user")

    def test_chatbot_redirect(self):
        chatbot_redirect_script = self.env["chatbot.script"].create(
            {"title": "Redirection Bot"}
        )
        question_step, _ = tuple(
            self.env["chatbot.script.step"].create([
                {
                    "chatbot_script_id": chatbot_redirect_script.id,
                    "message": "Hello, were do you want to go?",
                    "step_type": "question_selection",
                },
                {
                    "chatbot_script_id": chatbot_redirect_script.id,
                    "message": "Tadam, we are on the page you asked for!",
                    "step_type": "text",
                }
            ])
        )
        self.env["chatbot.script.answer"].create([
            {
                "name": "Go to the #chatbot-redirect anchor",
                "redirect_link": "#chatbot-redirect",
                "script_step_id": question_step.id,
            },
            {
                "name": "Go to the /chatbot-redirect page",
                "redirect_link": "/chatbot-redirect",
                "script_step_id": question_step.id,
            },
        ])
        livechat_channel = self.env["im_livechat.channel"].create({
            'name': 'Redirection Channel',
            'rule_ids': [Command.create({
                'regex_url': '/contactus',
                'chatbot_script_id': chatbot_redirect_script.id,
            })]
        })
        default_website = self.env.ref("website.default_website")
        default_website.channel_id = livechat_channel.id
        self.env.ref("website.default_website").channel_id = livechat_channel.id
        self.start_tour("/contactus", "website_livechat.chatbot_redirect")

    def test_chatbot_trigger_selection(self):
        chatbot_trigger_selection = self.env["chatbot.script"].create(
            {"title": "Trigger question selection bot"}
        )
        question_1, question_2 = tuple(
            self.env["chatbot.script.step"].create([
                {
                    "chatbot_script_id": chatbot_trigger_selection.id,
                    "message": "Hello, here is a first question?",
                    "step_type": "question_selection",
                },
                {
                    "chatbot_script_id": chatbot_trigger_selection.id,
                    "message": "Hello, here is a second question?",
                    "step_type": "question_selection",
                },
            ])
        )
        self.env["chatbot.script.answer"].create([
            {
                "name": "Yes to first question",
                "script_step_id": question_1.id,
            },
            {
                "name": "No to second question",
                "script_step_id": question_2.id,
            },
        ])
        livechat_channel = self.env["im_livechat.channel"].create({
            'name': 'Redirection Channel',
            'rule_ids': [Command.create({
                'regex_url': '/contactus',
                'chatbot_script_id': chatbot_trigger_selection.id,
            })]
        })
        default_website = self.env.ref("website.default_website")
        default_website.channel_id = livechat_channel.id
        self.env.ref("website.default_website").channel_id = livechat_channel.id
        self.start_tour("/contactus", "website_livechat.chatbot_trigger_selection")