# Part of Odoo. See LICENSE file for full copyright and licensing details.

from datetime import datetime
from dateutil.relativedelta import relativedelta
from freezegun import freeze_time
from unittest.mock import patch, PropertyMock

from odoo import Command, fields
from odoo.fields import Domain
from odoo.addons.mail.tests.common import MailCommon
from odoo.addons.mail.tools.discuss import Store
from odoo.tests.common import users, tagged, HttpCase, warmup


@tagged("is_query_count")
class TestDiscussFullPerformance(HttpCase, MailCommon):
    # Queries for _query_count_init_store (in order):
    #   1: search res_partner (odooot ref exists)
    #   1: search res_groups (internalUserGroupId ref exists)
    #   6: settings:
    #       - search res_users_settings (_find_or_create_for_user)
    #       - search res_users_settings_embedded_action (_format_settings)
    #       - fetch res_users_settings (_format_settings)
    #       - search res_users_settings_volumes (_format_settings)
    #       - search res_lang_res_users_settings_rel (_format_settings)
    #       - search im_livechat_expertise_res_users_settings_rel (_format_settings)
    #   2: hasCannedResponses
    #       - fetch res_groups_users_rel
    #       - search mail_canned_response
    #   2: show_livechat_category
    #       - search discuss_channel_member (is_self for ACL check)
    #       - search_count discuss_channel_member
    #   10: store add odoobot:
    #       - fetch res_partner
    #       - search res_users
    #       - search presence (_compute_im_status)
    #       - fetch presence (_compute_im_status)
    #       - search employee
    #       - search employee (company specific)
    #       - fetch res_users
    #       - search hr_employee_location
    #       - fetch employee
    #       - search hr_leave
    _query_count_init_store = 22
    # Queries for _query_count_init_messaging (in order):
    #   1: insert res_device_log
    #   3: _search_is_member (for current user, first occurence _search_is_member for chathub given channel ids)
    #       - fetch res_users
    #       - search discuss_channel_member
    #       - fetch discuss_channel
    #   1: search bus_bus (_bus_last_id)
    #   1. search discuss_channel (chathub given channel ids)
    #   1: channels_as_member
    #   2: _init_messaging_global_fields (discuss)
    #       - fetch discuss_channel_member (is_self)
    #       - _compute_message_unread
    #   4: _init_messaging (mail)
    #       - search bus_bus (_bus_last_id)
    #       - _get_needaction_count (inbox counter)
    #       - search mail_message (bookmark counter)
    #           - _check_access
    #   23: _process_request_for_all (discuss):
    #       - search discuss_channel (channels_domain)
    #       22: store add channel:
    #           - read group member (prefetch _compute_self_member_id from _compute_is_member)
    #           - read group member (_compute_invited_member_ids)
    #           - search discuss_channel_rtc_session
    #           - fetch discuss_channel_rtc_session
    #           - search member (channel_member_ids)
    #           - fetch discuss_channel_member (manual prefetch)
    #           10: member:
    #               10: partner:
    #                   - fetch res_partner (partner)
    #                   - fetch res_users (_compute_im_status)
    #                   - search mail_presence (_compute_im_status)
    #                   - fetch mail_presence (_compute_im_status)
    #                   - _get_on_leave_ids (_compute_im_status override)
    #                   - search hr_employee (_compute_im_status override)
    #                   - fetch hr_employee (_compute_im_status override)
    #                   - search hr_employee (user override)
    #                   - search hr_leave (leave_date_to)
    #                   - fetch res_users (_compute_main_user_id)
    #           - search bus_bus (_bus_last_id)
    #           - count discuss_channel_member (member_count)
    #           - _compute_message_needaction
    #           - search discuss_channel_res_groups_rel (group_ids)
    #           - search_fetch ir_attachment (_compute_avatar_cache_key -> _compute_avatar_128)
    #           - fetch res_groups (group_public_id)
    _query_count_init_messaging = 36
    # Queries for _query_count_discuss_channels (in order):
    #   1: insert res_device_log
    #   3: _search_is_member (for current user, first occurence channels_as_member)
    #       - fetch res_users
    #       - search discuss_channel_member
    #       - fetch discuss_channel
    #   2: _get_channels_as_member
    #       - search discuss_channel (member_domain)
    #       - search discuss_channel (pinned_member_domain)
    #   34: channel _to_store_defaults:
    #       - read mail.message model for get_annotatable models and check access
    #       - read group member (prefetch _compute_self_member_id from _compute_is_member)
    #       - read group member (_compute_invited_member_ids)
    #       - search discuss_channel_rtc_session
    #       - fetch discuss_channel_rtc_session
    #       - search member (channel_member_ids)
    #       - search member (channel_name_member_ids)
    #       - fetch discuss_channel_member (manual prefetch)
    #       17: member:
    #           - search im_livechat_channel_member_history (livechat member type)
    #           - fetch im_livechat_channel_member_history (livechat member type)
    #           13: partner:
    #               - fetch res_partner (partner)
    #               - fetch res_users (_compute_im_status)
    #               - search mail_presence (_compute_im_status)
    #               - fetch mail_presence (_compute_im_status)
    #               - _get_on_leave_ids (_compute_im_status override)
    #               - search hr_employee (_compute_im_status override)
    #               - fetch hr_employee (_compute_im_status override)
    #               - search hr_employee (user override)
    #               - search hr_leave (leave_date_to)
    #               - search res_users_settings (livechat username)
    #               - fetch res_users_settings (livechat username)
    #               - fetch res_users (_compute_main_user_id)
    #               - fetch res_country (livechat override)
    #           2: guest:
    #               - fetch mail_presence (_compute_im_status)
    #               - fetch mail_guest
    #       - search bus_bus (_bus_last_id)
    #       - count discuss_channel_member (member_count)
    #       - _compute_message_needaction
    #       - search ir_attachment (_compute_avatar_128)
    #       - search discuss_channel_res_groups_rel (group_ids)
    #       - fetch im_livechat_channel_member_history (requested_by_operator)
    #       - fetch livechat_expertise_ids
    #       - fetch res_groups (group_ids)
    #       - _compute_message_unread
    #       - fetch im_livechat_channel
    #   1: _get_last_messages
    #   22: store add message:
    #       - fetch mail_message
    #       - search mail_message_schedule
    #       - search mail_message_res_partner_bookmarked_rel
    #       - search message_attachment_rel
    #       - search mail_message_res_partner_rel
    #       - search mail_message_reaction
    #       - search mail_poll (_compute_has_poll start_message_id)
    #       - search mail_poll (_compute_has_poll end_message_id)
    #       - search mail_message_link_preview
    #       - search mail_notification
    #       - search mail_tracking_value
    #       - search rating_rating
    #       - fetch mail_notification
    #       - search mail_message_subtype
    #       - search discuss_call_history
    #       - fetch mail_message_reaction
    #       - read_group (_compute_rating_stats)
    #       - fetch mail_message_subtype
    #       - fetch partner (author)
    #       - search user (author)
    #       - fetch user (author)
    #       - fetch discuss_call_history
    # TODO use assertQueries
    _query_count_discuss_channels = 64

    def setUp(self):
        super().setUp()
        self.maxDiff = None
        self.group_user = self.env.ref('base.group_user')
        self.livechat_user = self.env.ref("im_livechat.im_livechat_group_user")
        self.password = 'Pl1bhD@2!kXZ'
        self.users = self.env['res.users'].create([
            {
                'email': 'e.e@example.com',
                'group_ids': [Command.link(self.group_user.id), Command.link(self.livechat_user.id)],
                'login': 'emp',
                'name': 'Ernest Employee',
                'notification_type': 'inbox',
                'odoobot_state': 'disabled',
                'password': self.password,
                'signature': '--\nErnest',
                'tz': 'Europe/Brussels',
            },
            {'name': 'test1', 'login': 'test1', 'password': self.password, 'email': 'test1@example.com', 'country_id': self.env.ref('base.in').id},
            {'name': 'test2', 'login': 'test2', 'email': 'test2@example.com'},
            {'name': 'test3', 'login': 'test3'},
            {'name': 'test4', 'login': 'test4'},
            {'name': 'test5', 'login': 'test5'},
            {'name': 'test6', 'login': 'test6'},
            {'name': 'test7', 'login': 'test7'},
            {'name': 'test8', 'login': 'test8'},
            {'name': 'test9', 'login': 'test9'},
            {'name': 'test10', 'login': 'test10'},
            {'name': 'test11', 'login': 'test11'},
            {'name': 'test12', 'login': 'test12'},
            {'name': 'test13', 'login': 'test13'},
            {'name': 'test14', 'login': 'test14'},
            {'name': 'test15', 'login': 'test15'},
        ])
        self.env.ref("base.partner_root").tz = "Europe/Brussels"
        self.employees = self.env['hr.employee'].create([{
            'user_id': user.id,
        } for user in self.users])
        self.work_entry_type = self.env['hr.work.entry.type'].create({
            'requires_allocation': False,
            'name': 'Legal Leaves',
            'code': 'Legal Leaves',
            'count_as': 'absence',
            'request_unit': 'day',
            'unit_of_measure': 'day',
        })
        self.leaves = self.env['hr.leave'].create([{
            'request_date_from': fields.Datetime.today() + relativedelta(days=-2),
            'request_date_to': fields.Datetime.today() + relativedelta(days=2),
            'employee_id': employee.id,
            'work_entry_type_id': self.work_entry_type.id,
        } for employee in self.employees])
        self.authenticate(self.users[0].login, self.password)
        Channel = self.env["discuss.channel"].with_user(self.users[0])
        self.channel_general = self.env.ref('mail.channel_all_employees')  # Unfortunately #general cannot be deleted. Assertions below assume data from a fresh db with demo.
        self.channel_general.message_ids.unlink() # Remove messages to avoid depending on demo data.
        self.channel_general.last_interest_dt = False  # Reset state
        self.channel_general.channel_member_ids.sudo().last_interest_dt = False  # Reset state
        self.env['discuss.channel'].sudo().search([('id', '!=', self.channel_general.id)]).unlink()
        self.user_root = self.env.ref('base.user_root')
        # create public channels
        self.channel_channel_public_1 = Channel._create_channel(
            name="public channel 1", group_id=None
        )
        self.channel_channel_public_1._add_members(users=self.users[0] | self.users[2] | self.users[3] | self.users[4] | self.users[8])
        self.channel_channel_public_2 = Channel._create_channel(
            name="public channel 2", group_id=None
        )
        self.channel_channel_public_2._add_members(users=self.users[0] | self.users[2] | self.users[4] | self.users[7] | self.users[9])
        # create group-restricted channels
        self.channel_channel_group_1 = Channel._create_channel(
            name="group restricted channel 1", group_id=self.env.ref("base.group_user").id
        )
        self.channel_channel_group_1._add_members(users=self.users[0] | self.users[2] | self.users[3] | self.users[6] | self.users[12])
        self.channel_channel_group_2 = Channel._create_channel(
            name="group restricted channel 2", group_id=self.env.ref("base.group_user").id
        )
        self.channel_channel_group_2._add_members(users=self.users[0] | self.users[2] | self.users[6] | self.users[7] | self.users[13])
        self.channel_channel_group_3 = Channel._create_channel(
            name="group restricted channel 3 (archived)", group_id=self.env.ref("base.group_user").id
        )
        self.channel_channel_group_3._add_members(users=self.users[0] | self.users[2])
        self.channel_channel_group_4 = Channel._create_channel(
            name="group restricted channel 4 (muted)", group_id=self.env.ref("base.group_user").id
        )
        self.channel_channel_group_4._add_members(users=self.users[0] | self.users[2])
        # create chats
        self.channel_chat_1 = Channel._get_or_create_chat((self.users[0] + self.users[14]).partner_id.ids)
        self.channel_chat_2 = Channel._get_or_create_chat((self.users[0] + self.users[15]).partner_id.ids)
        self.channel_chat_3 = Channel._get_or_create_chat((self.users[0] + self.users[2]).partner_id.ids)
        self.channel_chat_4 = Channel._get_or_create_chat((self.users[0] + self.users[3]).partner_id.ids)
        # create groups
        self.channel_group_1 = Channel._create_group((self.users[0] + self.users[12]).partner_id.ids)
        # create livechats
        self.im_livechat_channel = self.env['im_livechat.channel'].sudo().create({'name': 'support', 'user_ids': [Command.link(self.users[0].id)]})
        self.env['mail.presence']._update_presence(self.users[0])
        self.authenticate('test1', self.password)
        self.channel_livechat_1 = Channel.browse(
            self.make_jsonrpc_request(
                "/im_livechat/get_session",
                {
                    "channel_id": self.im_livechat_channel.id,
                    "previous_operator_id": self.users[0].partner_id.id,
                },
            )["channel_id"]
        )
        self.channel_livechat_1.with_user(self.users[1]).message_post(body="test", message_type="comment")
        self.authenticate(None, None)
        with patch(
            "odoo.http.geoip.GeoIP.country_code",
            new_callable=PropertyMock(return_value=self.env.ref("base.be").code),
        ):
            self.channel_livechat_2 = Channel.browse(
                self.make_jsonrpc_request(
                    "/im_livechat/get_session",
                    {
                        "channel_id": self.im_livechat_channel.id,
                        "previous_operator_id": self.users[0].partner_id.id,
                    },
                )["channel_id"]
            )
        self.guest = self.channel_livechat_2.channel_member_ids.guest_id.sudo()
        self.make_jsonrpc_request("/mail/message/post", {
            "post_data": {
                "body": "test",
                "message_type": "comment",
            },
            "thread_id": self.channel_livechat_2.id,
            "thread_model": "discuss.channel",
        }, cookies={
            self.guest._cookie_name: self.guest._format_auth_cookie(),
        })
        # add needaction messages
        self.users[0].notification_type = 'inbox'
        message_0 = self.channel_channel_public_1.message_post(
            body="test",
            message_type="comment",
            author_id=self.users[2].partner_id.id,
            partner_ids=self.users[0].partner_id.ids,
        )
        members = self.channel_channel_public_1.channel_member_ids
        member = members.filtered(lambda m: m.partner_id == self.users[0].partner_id).with_user(self.users[0])
        member._mark_as_read(message_0.id)
        # add bookmark
        message_0.bookmarked_partner_ids = [Command.link(self.users[0].partner_id.id)]
        self.env.company.sudo().name = 'YourCompany'
        # add unread messages
        self.channel_channel_group_3.with_user(self.users[2]).message_post(
            body="archived_channel's message",
            message_type="comment",
            author_id=self.users[2].partner_id.id,
        )
        self.channel_channel_group_4.with_user(self.users[2]).message_post(
            body="muted_channel's message",
            message_type="comment",
            author_id=self.users[2].partner_id.id,
        )
        # add folded channel
        members = self.channel_chat_1.channel_member_ids
        member = members.with_user(self.users[0]).filtered(lambda m: m.is_self)
        # add call invitation
        members = self.channel_channel_group_1.channel_member_ids
        member_0 = members.with_user(self.users[0]).filtered(lambda m: m.is_self)
        member_2 = members.with_user(self.users[2]).filtered(lambda m: m.is_self)
        self.channel_channel_group_1_invited_member = member_0
        # sudo: discuss.channel.rtc.session - creating a session in a test file
        data = {"channel_id": self.channel_channel_group_1.id, "channel_member_id": member_2.id}
        session = self.env["discuss.channel.rtc.session"].sudo().create(data)
        member_0.rtc_inviting_session_id = session
        # add some reactions with different users on different messages
        message_1 = self.channel_general.message_post(
            body="test", message_type="comment", author_id=self.users[0].partner_id.id
        )
        self.authenticate(self.users[0].login, self.password)
        self._add_reactions(message_0, ["😊", "😏"])
        self._add_reactions(message_1, ["😊"])
        self.authenticate(self.users[1].login, self.password)
        self._add_reactions(message_0, ["😊", "😏"])
        self._add_reactions(message_1, ["😊", "😁"])
        self.authenticate(self.users[2].login, self.password)
        self._add_reactions(message_0, ["😊", "😁"])
        self._add_reactions(message_1, ["😊", "😁", "👍"])
        # add archive / muted on channels
        self.channel_channel_group_3.active = False
        channel_group_4_member = self.channel_channel_group_4.channel_member_ids.filtered(lambda m: m.partner_id == self.users[0].partner_id)
        channel_group_4_member.mute_until_dt = datetime.max
        self.env.cr.precommit.run()  # trigger the creation of bus.bus records

    def _add_reactions(self, message, reactions):
        for reaction in reactions:
            self.make_jsonrpc_request(
                "/mail/message/reaction",
                {
                    "action": "add",
                    "content": reaction,
                    "message_id": message.id,
                },
            )

    def _run_test(self, /, *, fn, count, results):
        self.authenticate(self.users[0].login, self.password)
        self.env["res.lang"]._get_data(code="en_US")  # cache language for validation
        with self.assertQueryCount(emp=count):
            if self.warm:
                with self.env.cr._enable_logging():
                    res = fn()
            else:
                res = fn()
        self.assertEqual(res, results)

    @freeze_time("2025-04-22 21:18:33")
    @users('emp')
    @warmup
    def test_10_init_store_data(self):
        """Test performance of `_store_init_global_fields`."""

        def test_fn():
            field_list = self.users[0].with_user(self.users[0])._store_init_global_fields
            return Store().add_global_values(field_list).get_result()

        self._run_test(
            fn=test_fn,
            count=self._query_count_init_store,
            results=self._get_init_store_data_result(),
        )

    @freeze_time("2025-04-22 21:18:33")
    @users('emp')
    @warmup
    def test_20_init_messaging(self):
        """Test performance of `init_messaging`."""
        self._run_test(
            fn=lambda: self.make_jsonrpc_request(
                "/mail/data",
                {"fetch_params": [["discuss.channel", [self.channel_chat_1.id]], "init_messaging"]},
            ),
            count=self._query_count_init_messaging,
            results=self._get_init_messaging_result(),
        )

    @freeze_time("2025-04-22 21:18:33")
    @users("emp")
    @warmup
    def test_30_discuss_channels(self):
        """Test performance of `/mail/data` with `channels_as_member`."""
        self._run_test(
            fn=lambda: self.make_jsonrpc_request(
                "/mail/data", {"fetch_params": ["channels_as_member"]}
            ),
            count=self._query_count_discuss_channels,
            results=self._get_discuss_channels_result(),
        )

    def _get_init_store_data_result(self):
        """Returns the result of a call to init_messaging.
        The point of having a separate getter is to allow it to be overriden.
        """
        xmlid_to_res_id = self.env["ir.model.data"]._xmlid_to_res_id
        user_0 = self.users[0]
        partner_0 = user_0.partner_id
        return {
            "hr.employee": [
                self._res_for_employee(self.employees[0]),
            ],
            "res.partner": self._filter_partners_fields(
                {
                    "active": False,
                    "avatar_128_access_token": self.partner_root._get_avatar_128_access_token(),
                    "email": "odoobot@example.com",
                    "id": self.partner_root.id,
                    "im_status": "bot",
                    "im_status_access_token": self.partner_root._get_im_status_access_token(),
                    "is_company": False,
                    "main_user_id": self.user_root.id,
                    "name": "OdooBot",
                    "tz": "Europe/Brussels",
                    "write_date": fields.Datetime.to_string(self.partner_root.write_date),
                },
                {
                    "active": True,
                    "avatar_128_access_token": partner_0._get_avatar_128_access_token(),
                    "id": partner_0.id,
                    "im_status": "online",
                    "im_status_access_token": partner_0._get_im_status_access_token(),
                    "main_user_id": self.users[0].id,
                    "name": "Ernest Employee",
                    "tz": "Europe/Brussels",
                    "write_date": fields.Datetime.to_string(partner_0.write_date),
                },
            ),
            "res.users": self._filter_users_fields(
                {
                    "all_employee_ids": [],
                    "employee_ids": [],
                    "id": self.user_root.id,
                    "partner_id": self.partner_root.id,
                    "share": False,
                    "active": False,
                },
                {
                    "all_employee_ids": [self.employees[0].id],
                    "id": user_0.id,
                    "employee_ids": [self.employees[0].id],
                    "is_admin": False,
                    "is_livechat_manager": False,
                    "notification_type": "inbox",
                    "partner_id": partner_0.id,
                    "share": False,
                    "signature": ["markup", str(user_0.signature)],
                },
            ),
            "Store": {
                "channel_types_with_seen_infos": sorted(["chat", "group", "livechat"]),
                "action_discuss_id": xmlid_to_res_id("mail.action_discuss"),
                "hasCannedResponses": True,
                "hasGifPickerFeature": False,
                "hasLinkPreviewFeature": True,
                "has_access_livechat": True,
                "hasMessageTranslationFeature": False,
                "has_access_create_lead": False,
                "internalUserGroupId": self.env.ref("base.group_user").id,
                "mt_comment": self.env.ref("mail.mt_comment").id,
                "mt_note": self.env.ref("mail.mt_note").id,
                "odoobot": self.user_root.partner_id.id,
                "self_user": self.users[0].id,
                "show_livechat_category": True,
                "settings": {
                    "channel_notifications": False,
                    "id": self.env["res.users.settings"]._find_or_create_for_user(self.users[0]).id,
                    "livechat_expertise_ids": [],
                    "livechat_lang_ids": [],
                    "livechat_username": False,
                    "push_to_talk_key": False,
                    "use_push_to_talk": False,
                    "user_id": {"id": self.users[0].id},
                    "voice_active_duration": 200,
                    "embedded_actions_config_ids": {},
                },
            },
        }

    def _get_init_messaging_result(self):
        """Returns the result of a call to init_messaging.
        The point of having a separate getter is to allow it to be overriden.
        """
        # sudo: bus.bus: reading non-sensitive last id
        bus_last_id = self.env["bus.bus"].sudo()._bus_last_id()
        return {
            "discuss.channel": self._filter_channels_fields(
                self._expected_result_for_channel(self.channel_chat_1),
                self._expected_result_for_channel(self.channel_channel_group_1),
            ),
            "discuss.channel.member": [
                self._res_for_member(self.channel_chat_1, self.users[0].partner_id),
                self._res_for_member(self.channel_chat_1, self.users[14].partner_id),
                self._res_for_member(self.channel_channel_group_1, self.users[0].partner_id),
                self._res_for_member(self.channel_channel_group_1, self.users[2].partner_id),
            ],
            "discuss.channel.rtc.session": [
                self._expected_result_for_rtc_session(self.channel_channel_group_1, self.users[2]),
            ],
            "res.groups": [{'full_name': 'Role / User', 'id': self.env.ref("base.group_user").id}],
            "res.partner": self._filter_partners_fields(
                self._expected_result_for_persona(self.users[0]),
                self._expected_result_for_persona(self.users[14]),
                self._expected_result_for_persona(self.users[2], only_inviting=True),
            ),
            "res.users": self._filter_users_fields(
                self._res_for_user(self.users[0]),
                self._res_for_user(self.users[14]),
                self._res_for_user(self.users[2], only_inviting=True),
            ),
            "hr.employee": [
                self._res_for_employee(self.users[0].employee_ids[0]),
                self._res_for_employee(self.users[14].employee_ids[0]),
                self._res_for_employee(self.users[2].employee_ids[0]),
            ],
            "Store": {
                "inbox": {
                    "counter": 1,
                    "counter_bus_id": bus_last_id,
                    "id": "inbox",
                    "model": "mail.box",
                },
                "bookmarkBox": {
                    "counter": 1,
                    "counter_bus_id": bus_last_id,
                    "id": "bookmark",
                    "model": "mail.box",
                },
                "initChannelsUnreadCounter": 4,
            },
        }

    def _get_discuss_channels_result(self):
        """Returns the result of a call to `/mail/data` with `channels_as_member`.
        The point of having a separate getter is to allow it to be overriden.
        """
        return {
            "discuss.call.history": [
                {
                    "duration_hour": self.channel_channel_group_1.call_history_ids.duration_hour,
                    "end_dt": False,
                    "id": self.channel_channel_group_1.call_history_ids.id,
                },
            ],
            "discuss.channel": self._filter_channels_fields(
                self._expected_result_for_channel(self.channel_general),
                self._expected_result_for_channel(self.channel_channel_public_1),
                self._expected_result_for_channel(self.channel_channel_public_2),
                self._expected_result_for_channel(self.channel_channel_group_1),
                self._expected_result_for_channel(self.channel_channel_group_2),
                self._expected_result_for_channel(self.channel_channel_group_4),
                self._expected_result_for_channel(self.channel_chat_1),
                self._expected_result_for_channel(self.channel_chat_2),
                self._expected_result_for_channel(self.channel_chat_3),
                self._expected_result_for_channel(self.channel_chat_4),
                self._expected_result_for_channel(self.channel_group_1),
                self._expected_result_for_channel(self.channel_livechat_1),
                self._expected_result_for_channel(self.channel_livechat_2),
            ),
            "discuss.channel.member": [
                self._res_for_member(self.channel_general, self.users[0].partner_id),
                self._res_for_member(self.channel_channel_public_1, self.users[0].partner_id),
                self._res_for_member(self.channel_channel_public_2, self.users[0].partner_id),
                self._res_for_member(self.channel_channel_group_1, self.users[0].partner_id),
                self._res_for_member(self.channel_channel_group_1, self.users[2].partner_id),
                self._res_for_member(self.channel_channel_group_2, self.users[0].partner_id),
                self._res_for_member(self.channel_channel_group_4, self.users[0].partner_id),
                self._res_for_member(self.channel_chat_1, self.users[0].partner_id),
                self._res_for_member(self.channel_chat_1, self.users[14].partner_id),
                self._res_for_member(self.channel_chat_2, self.users[0].partner_id),
                self._res_for_member(self.channel_chat_2, self.users[15].partner_id),
                self._res_for_member(self.channel_chat_3, self.users[0].partner_id),
                self._res_for_member(self.channel_chat_3, self.users[2].partner_id),
                self._res_for_member(self.channel_chat_4, self.users[0].partner_id),
                self._res_for_member(self.channel_chat_4, self.users[3].partner_id),
                self._res_for_member(self.channel_group_1, self.users[0].partner_id),
                self._res_for_member(self.channel_group_1, self.users[12].partner_id),
                self._res_for_member(self.channel_livechat_1, self.users[0].partner_id),
                self._res_for_member(self.channel_livechat_1, self.users[1].partner_id),
                self._res_for_member(self.channel_livechat_2, self.users[0].partner_id),
                self._res_for_member(self.channel_livechat_2, guest=True),
            ],
            "discuss.channel.rtc.session": [
                self._expected_result_for_rtc_session(self.channel_channel_group_1, self.users[2]),
            ],
            "im_livechat.channel": [
                self._expected_result_for_livechat_channel(),
            ],
            "im_livechat.channel.member.history": [
                *self._expected_result_for_livechat_member_history(self.channel_livechat_1),
                *self._expected_result_for_livechat_member_history(self.channel_livechat_2),
            ],
            "mail.guest": [
                self._expected_result_for_persona(guest=True),
            ],
            "mail.message": self._filter_messages_fields(
                self._expected_result_for_message(self.channel_general),
                self._expected_result_for_message(self.channel_channel_public_1),
                self._expected_result_for_message(self.channel_channel_public_2),
                self._expected_result_for_message(self.channel_channel_group_1),
                self._expected_result_for_message(self.channel_channel_group_2),
                self._expected_result_for_message(self.channel_channel_group_4),
                self._expected_result_for_message(self.channel_livechat_1),
                self._expected_result_for_message(self.channel_livechat_2),
            ),
            "mail.notification": [
                self._expected_result_for_notification(self.channel_channel_public_1),
            ],
            "mail.message.subtype": [
                {"description": False, "id": self.env.ref("mail.mt_note").id},
                {"description": False, "id": self.env.ref("mail.mt_comment").id},
            ],
            "mail.thread": self._filter_threads_fields(
                self._expected_result_for_thread(self.channel_general),
                self._expected_result_for_thread(self.channel_channel_public_1),
                self._expected_result_for_thread(self.channel_channel_public_2),
                self._expected_result_for_thread(self.channel_channel_group_1),
                self._expected_result_for_thread(self.channel_channel_group_2),
                self._expected_result_for_thread(self.channel_channel_group_4),
                self._expected_result_for_thread(self.channel_livechat_1),
                self._expected_result_for_thread(self.channel_livechat_2),
            ),
            "MessageReactions": [
                *self._expected_result_for_message_reactions(self.channel_general),
                *self._expected_result_for_message_reactions(self.channel_channel_public_1),
            ],
            "res.country": [
                {"code": "IN", "id": self.env.ref("base.in").id, "name": "India"},
                {"code": "BE", "id": self.env.ref("base.be").id, "name": "Belgium"},
            ],
            "res.groups": [{"full_name": "Role / User", "id": self.env.ref("base.group_user").id}],
            "res.partner": self._filter_partners_fields(
                self._expected_result_for_persona(
                    self.users[0],
                    also_livechat=True,
                    also_notification=True,
                ),
                self._expected_result_for_persona(self.users[2]),
                self._expected_result_for_persona(self.users[14]),
                self._expected_result_for_persona(self.users[15]),
                self._expected_result_for_persona(self.users[3]),
                self._expected_result_for_persona(self.users[12]),
                self._expected_result_for_persona(self.users[1], also_livechat=True),
                self._expected_result_for_persona(self.user_root),
            ),
            "res.users": self._filter_users_fields(
                self._res_for_user(self.users[0]),
                self._res_for_user(self.users[2]),
                self._res_for_user(self.users[14]),
                self._res_for_user(self.users[15]),
                self._res_for_user(self.users[3]),
                self._res_for_user(self.users[12]),
                self._res_for_user(self.users[1]),
                self._res_for_user(self.user_root),
            ),
            "Store": {"has_unpinned_channels": False},
            "hr.employee": [
                self._res_for_employee(self.users[0].employee_ids[0]),
                self._res_for_employee(self.users[2].employee_ids[0]),
                self._res_for_employee(self.users[14].employee_ids[0]),
                self._res_for_employee(self.users[15].employee_ids[0]),
                self._res_for_employee(self.users[3].employee_ids[0]),
                self._res_for_employee(self.users[12].employee_ids[0]),
                self._res_for_employee(self.users[1].employee_ids[0]),
            ],
        }

    def _expected_result_for_channel(self, channel):
        # sudo: bus.bus: reading non-sensitive last id
        bus_last_id = self.env["bus.bus"].sudo()._bus_last_id()
        members = channel.channel_member_ids
        member_0 = members.filtered(lambda m: m.partner_id == self.users[0].partner_id)
        member_2 = members.filtered(lambda m: m.partner_id == self.users[2].partner_id)
        member_12 = members.filtered(lambda m: m.partner_id == self.users[12].partner_id)
        last_interest_dt = fields.Datetime.to_string(channel.last_interest_dt)
        if channel == self.channel_general:
            return {
                "avatar_cache_key": channel.avatar_cache_key,
                "channel_type": "channel",
                "create_uid": self.user_root.id,
                "default_display_mode": False,
                "description": "General announcements for all employees.",
                "discuss_category_id": False,
                "fetchChannelInfoState": "fetched",
                "from_message_id": False,
                "group_ids": channel.group_ids.ids,
                "group_public_id": self.env.ref("base.group_user").id,
                "id": channel.id,
                "is_editable": True,
                "is_readonly": False,
                "last_interest_dt": last_interest_dt,
                "member_count": len(self.group_user.all_user_ids),
                "message_needaction_counter_bus_id": bus_last_id,
                "message_needaction_counter": 0,
                "name": "general",
                "parent_channel_id": False,
                "uuid": channel.uuid,
            }
        if channel == self.channel_channel_public_1:
            return {
                "avatar_cache_key": channel.avatar_cache_key,
                "channel_type": "channel",
                "create_uid": self.env.user.id,
                "default_display_mode": False,
                "description": False,
                "discuss_category_id": False,
                "fetchChannelInfoState": "fetched",
                "from_message_id": False,
                "group_ids": [],
                "group_public_id": False,
                "id": channel.id,
                "is_editable": True,
                "is_readonly": False,
                "last_interest_dt": last_interest_dt,
                "member_count": 5,
                "message_needaction_counter_bus_id": bus_last_id,
                "message_needaction_counter": 1,
                "name": "public channel 1",
                "parent_channel_id": False,
                "uuid": channel.uuid,
            }
        if channel == self.channel_channel_public_2:
            return {
                "avatar_cache_key": channel.avatar_cache_key,
                "channel_type": "channel",
                "create_uid": self.env.user.id,
                "default_display_mode": False,
                "description": False,
                "discuss_category_id": False,
                "fetchChannelInfoState": "fetched",
                "from_message_id": False,
                "group_ids": [],
                "group_public_id": False,
                "id": channel.id,
                "is_editable": True,
                "is_readonly": False,
                "last_interest_dt": last_interest_dt,
                "member_count": 5,
                "message_needaction_counter_bus_id": bus_last_id,
                "message_needaction_counter": 0,
                "name": "public channel 2",
                "parent_channel_id": False,
                "uuid": channel.uuid,
            }
        if channel == self.channel_channel_group_1:
            return {
                "avatar_cache_key": channel.avatar_cache_key,
                "channel_type": "channel",
                "create_uid": self.env.user.id,
                "default_display_mode": False,
                "description": False,
                "discuss_category_id": False,
                "fetchChannelInfoState": "fetched",
                "from_message_id": False,
                "group_ids": [],
                "group_public_id": self.env.ref("base.group_user").id,
                "id": channel.id,
                "invited_member_ids": [["ADD", [member_0.id]]],
                "is_editable": True,
                "is_readonly": False,
                "last_interest_dt": last_interest_dt,
                "member_count": 5,
                "message_needaction_counter_bus_id": bus_last_id,
                "message_needaction_counter": 0,
                "name": "group restricted channel 1",
                "parent_channel_id": False,
                # sudo: discuss.channel.rtc.session - reading a session in a test file
                "rtc_session_ids": [["ADD", [member_2.sudo().rtc_session_ids.id]]],
                "uuid": channel.uuid,
            }
        if channel == self.channel_channel_group_2:
            return {
                "avatar_cache_key": channel.avatar_cache_key,
                "channel_type": "channel",
                "create_uid": self.env.user.id,
                "default_display_mode": False,
                "description": False,
                "discuss_category_id": False,
                "fetchChannelInfoState": "fetched",
                "from_message_id": False,
                "group_ids": [],
                "group_public_id": self.env.ref("base.group_user").id,
                "id": channel.id,
                "is_editable": True,
                "is_readonly": False,
                "last_interest_dt": last_interest_dt,
                "member_count": 5,
                "message_needaction_counter_bus_id": bus_last_id,
                "message_needaction_counter": 0,
                "name": "group restricted channel 2",
                "parent_channel_id": False,
                "uuid": channel.uuid,
            }
        if channel == self.channel_channel_group_4:
            return {
                "avatar_cache_key": channel.avatar_cache_key,
                "channel_type": "channel",
                "create_uid": self.env.user.id,
                "default_display_mode": False,
                "description": False,
                "discuss_category_id": False,
                "fetchChannelInfoState": "fetched",
                "from_message_id": False,
                "group_ids": [],
                "group_public_id": self.env.ref("base.group_user").id,
                "id": channel.id,
                "is_editable": True,
                "is_readonly": False,
                "last_interest_dt": last_interest_dt,
                "member_count": 2,
                "message_needaction_counter_bus_id": bus_last_id,
                "message_needaction_counter": 0,
                "name": "group restricted channel 4 (muted)",
                "parent_channel_id": False,
                "uuid": channel.uuid,
            }
        if channel == self.channel_group_1:
            return {
                "avatar_cache_key": channel.avatar_cache_key,
                "channel_name_member_ids": [member_0.id, member_12.id],
                "channel_type": "group",
                "create_uid": self.env.user.id,
                "default_display_mode": False,
                "description": False,
                "discuss_category_id": False,
                "fetchChannelInfoState": "fetched",
                "from_message_id": False,
                "id": channel.id,
                "is_editable": True,
                "last_interest_dt": last_interest_dt,
                "member_count": 2,
                "message_needaction_counter_bus_id": bus_last_id,
                "message_needaction_counter": 0,
                "name": "",
                "parent_channel_id": False,
                "uuid": channel.uuid,
            }
        if channel == self.channel_chat_1:
            return {
                "channel_type": "chat",
                "create_uid": self.env.user.id,
                "default_display_mode": False,
                "discuss_category_id": False,
                "fetchChannelInfoState": "fetched",
                "id": channel.id,
                "is_editable": True,
                "last_interest_dt": last_interest_dt,
                "member_count": 2,
                "message_needaction_counter_bus_id": bus_last_id,
                "message_needaction_counter": 0,
                "name": "Ernest Employee, test14",
                "uuid": channel.uuid,
            }
        if channel == self.channel_chat_2:
            return {
                "channel_type": "chat",
                "create_uid": self.env.user.id,
                "default_display_mode": False,
                "discuss_category_id": False,
                "fetchChannelInfoState": "fetched",
                "id": channel.id,
                "is_editable": True,
                "last_interest_dt": last_interest_dt,
                "member_count": 2,
                "message_needaction_counter_bus_id": bus_last_id,
                "message_needaction_counter": 0,
                "name": "Ernest Employee, test15",
                "uuid": channel.uuid,
            }
        if channel == self.channel_chat_3:
            return {
                "channel_type": "chat",
                "create_uid": self.env.user.id,
                "default_display_mode": False,
                "discuss_category_id": False,
                "fetchChannelInfoState": "fetched",
                "id": channel.id,
                "is_editable": True,
                "last_interest_dt": last_interest_dt,
                "member_count": 2,
                "message_needaction_counter_bus_id": bus_last_id,
                "message_needaction_counter": 0,
                "name": "Ernest Employee, test2",
                "uuid": channel.uuid,
            }
        if channel == self.channel_chat_4:
            return {
                "channel_type": "chat",
                "create_uid": self.env.user.id,
                "default_display_mode": False,
                "discuss_category_id": False,
                "fetchChannelInfoState": "fetched",
                "id": channel.id,
                "is_editable": True,
                "last_interest_dt": last_interest_dt,
                "member_count": 2,
                "message_needaction_counter_bus_id": bus_last_id,
                "message_needaction_counter": 0,
                "name": "Ernest Employee, test3",
                "uuid": channel.uuid,
            }
        if channel == self.channel_livechat_1:
            return {
                "ai_agent_id": False,
                "channel_type": "livechat",
                "country_id": self.env.ref("base.in").id,
                "create_uid": self.users[1].id,
                "default_display_mode": False,
                "description": False,
                "discuss_category_id": False,
                "fetchChannelInfoState": "fetched",
                "id": channel.id,
                "is_editable": True,
                "last_interest_dt": last_interest_dt,
                "livechat_end_dt": False,
                "livechat_lang_id": self.channel_livechat_1.livechat_lang_id.id,
                "livechat_channel_id": self.im_livechat_channel.id,
                "livechat_channel_member_history_ids": self.channel_livechat_1.livechat_channel_member_history_ids.ids,
                "livechat_note": False,
                "livechat_outcome": "no_answer",
                "livechat_status": "in_progress",
                "livechat_visitor_id": False,
                "livechat_expertise_ids": [],
                "livechat_looking_for_help_since_dt": False,
                "member_count": 2,
                "message_needaction_counter_bus_id": bus_last_id,
                "message_needaction_counter": 0,
                "name": "test1 Ernest Employee",
                "requested_by_operator": False,
                "uuid": channel.uuid,
            }
        if channel == self.channel_livechat_2:
            return {
                "ai_agent_id": False,
                "channel_type": "livechat",
                "country_id": self.env.ref("base.be").id,
                "create_uid": self.env.ref("base.public_user").id,
                "default_display_mode": False,
                "description": False,
                "discuss_category_id": False,
                "fetchChannelInfoState": "fetched",
                "id": channel.id,
                "is_editable": True,
                "last_interest_dt": last_interest_dt,
                "livechat_end_dt": False,
                "livechat_lang_id": self.channel_livechat_2.livechat_lang_id.id,
                "livechat_channel_id": self.im_livechat_channel.id,
                "livechat_channel_member_history_ids": self.channel_livechat_2.livechat_channel_member_history_ids.ids,
                "livechat_note": False,
                "livechat_outcome": "no_answer",
                "livechat_status": "in_progress",
                "livechat_visitor_id": False,
                "livechat_expertise_ids": [],
                "livechat_looking_for_help_since_dt": False,
                "member_count": 2,
                "message_needaction_counter_bus_id": bus_last_id,
                "message_needaction_counter": 0,
                "name": "Visitor Ernest Employee",
                "requested_by_operator": False,
                "uuid": channel.uuid,
            }
        return {}

    def _res_for_member(self, channel, partner=None, guest=None):
        members = channel.channel_member_ids
        member_0 = members.filtered(lambda m: m.partner_id == self.users[0].partner_id)
        member_0_last_interest_dt = fields.Datetime.to_string(member_0.last_interest_dt)
        member_0_last_seen_dt = fields.Datetime.to_string(member_0.last_seen_dt)
        member_0_create_date = fields.Datetime.to_string(member_0.create_date)
        member_1 = members.filtered(lambda m: m.partner_id == self.users[1].partner_id)
        member_2 = members.filtered(lambda m: m.partner_id == self.users[2].partner_id)
        member_3 = members.filtered(lambda m: m.partner_id == self.users[3].partner_id)
        member_12 = members.filtered(lambda m: m.partner_id == self.users[12].partner_id)
        member_14 = members.filtered(lambda m: m.partner_id == self.users[14].partner_id)
        member_15 = members.filtered(lambda m: m.partner_id == self.users[15].partner_id)
        first_message = channel.message_ids.sorted(lambda message: message.id)[:1]
        last_message = channel._get_last_messages()
        last_message_of_partner_0 = self.env["mail.message"].search(
            Domain("author_id", "=", member_0.partner_id.id)
            & Domain("model", "=", "discuss.channel")
            & Domain("res_id", "=", channel.id),
            order="id desc",
            limit=1,
        )
        member_g = members.filtered(lambda m: m.guest_id)
        guest = member_g.guest_id
        # sudo: bus.bus: reading non-sensitive last id
        bus_last_id = self.env["bus.bus"].sudo()._bus_last_id()
        if channel == self.channel_general and partner == self.users[0].partner_id:
            return {
                "channel_role": False,
                "create_date": member_0_create_date,
                "custom_notifications": False,
                "id": member_0.id,
                "is_favorite": False,
                "last_interest_dt": member_0_last_interest_dt,
                "message_unread_counter": 1,
                "message_unread_counter_bus_id": bus_last_id,
                "mute_until_dt": False,
                "last_seen_dt": member_0_last_seen_dt,
                "new_message_separator": 0,
                "partner_id": self.users[0].partner_id.id,
                "rtc_inviting_session_id": False,
                "seen_message_id": False,
                "unpin_dt": False,
                "channel_id": channel.id,
            }
        if channel == self.channel_channel_public_1 and partner == self.users[0].partner_id:
            return {
                "channel_role": "owner",
                "create_date": member_0_create_date,
                "custom_notifications": False,
                "id": member_0.id,
                "is_favorite": False,
                "last_interest_dt": member_0_last_interest_dt,
                "message_unread_counter": 0,
                "message_unread_counter_bus_id": bus_last_id,
                "mute_until_dt": False,
                "last_seen_dt": member_0_last_seen_dt,
                "new_message_separator": last_message.id + 1,
                "partner_id": self.users[0].partner_id.id,
                "rtc_inviting_session_id": False,
                "seen_message_id": last_message.id,
                "unpin_dt": False,
                "channel_id": channel.id,
            }
        if channel == self.channel_channel_public_2 and partner == self.users[0].partner_id:
            return {
                "channel_role": "owner",
                "create_date": member_0_create_date,
                "custom_notifications": False,
                "id": member_0.id,
                "is_favorite": False,
                "last_interest_dt": member_0_last_interest_dt,
                "message_unread_counter": 0,
                "message_unread_counter_bus_id": bus_last_id,
                "mute_until_dt": False,
                "last_seen_dt": member_0_last_seen_dt,
                "new_message_separator": last_message.id + 1,
                "partner_id": self.users[0].partner_id.id,
                "rtc_inviting_session_id": False,
                "seen_message_id": last_message.id,
                "unpin_dt": False,
                "channel_id": channel.id,
            }
        if channel == self.channel_channel_group_1 and partner == self.users[0].partner_id:
            return {
                "channel_role": "owner",
                "create_date": member_0_create_date,
                "custom_notifications": False,
                "id": member_0.id,
                "is_favorite": False,
                "last_interest_dt": member_0_last_interest_dt,
                "message_unread_counter": 0,
                "message_unread_counter_bus_id": bus_last_id,
                "mute_until_dt": False,
                "last_seen_dt": member_0_last_seen_dt,
                "new_message_separator": last_message_of_partner_0.id + 1,
                "partner_id": self.users[0].partner_id.id,
                "rtc_inviting_session_id": member_0.rtc_inviting_session_id.id,
                "seen_message_id": last_message_of_partner_0.id,
                "unpin_dt": False,
                "channel_id": channel.id,
            }
        if channel == self.channel_channel_group_1 and partner == self.users[2].partner_id:
            return {
                "id": member_2.id,
                "partner_id": self.users[2].partner_id.id,
                "channel_id": channel.id,
            }
        if channel == self.channel_channel_group_2 and partner == self.users[0].partner_id:
            return {
                "channel_role": "owner",
                "create_date": member_0_create_date,
                "custom_notifications": False,
                "id": member_0.id,
                "is_favorite": False,
                "last_interest_dt": member_0_last_interest_dt,
                "message_unread_counter": 0,
                "message_unread_counter_bus_id": bus_last_id,
                "mute_until_dt": False,
                "last_seen_dt": member_0_last_seen_dt,
                "new_message_separator": last_message.id + 1,
                "partner_id": self.users[0].partner_id.id,
                "rtc_inviting_session_id": False,
                "seen_message_id": last_message.id,
                "unpin_dt": False,
                "channel_id": channel.id,
            }
        if channel == self.channel_channel_group_4 and partner == self.users[0].partner_id:
            return {
                "channel_role": "owner",
                "create_date": member_0_create_date,
                "custom_notifications": False,
                "id": member_0.id,
                "is_favorite": False,
                "last_interest_dt": member_0_last_interest_dt,
                "message_unread_counter": 1,
                "message_unread_counter_bus_id": bus_last_id,
                "mute_until_dt": "9999-12-31 23:59:59",
                "last_seen_dt": member_0_last_seen_dt,
                "new_message_separator": first_message.id + 1,
                "partner_id": self.users[0].partner_id.id,
                "rtc_inviting_session_id": False,
                "seen_message_id": first_message.id,
                "unpin_dt": False,
                "channel_id": channel.id,
            }
        if channel == self.channel_channel_group_4 and partner == self.users[2].partner_id:
            return {
                "channel_role": False,
                "create_date": member_0_create_date,
                "custom_channel_name": False,
                "custom_notifications": False,
                "fetched_message_id": first_message.id,
                "id": member_2.id,
                "is_favorite": False,
                "last_interest_dt": member_0_last_interest_dt,
                "message_unread_counter": 1,
                "message_unread_counter_bus_id": bus_last_id,
                "mute_until_dt": "9999-12-31 23:59:59",
                "last_seen_dt": member_0_last_seen_dt,
                "new_message_separator": first_message.id + 1,
                "partner_id": self.users[0].partner_id.id,
                "rtc_inviting_session_id": False,
                "seen_message_id": first_message.id,
                "unpin_dt": False,
                "channel_id": channel.id,
            }
        if channel == self.channel_group_1 and partner == self.users[0].partner_id:
            return {
                "channel_role": "owner",
                "create_date": member_0_create_date,
                "custom_notifications": False,
                "id": member_0.id,
                "is_favorite": False,
                "last_interest_dt": member_0_last_interest_dt,
                "message_unread_counter": 0,
                "message_unread_counter_bus_id": bus_last_id,
                "mute_until_dt": False,
                "last_seen_dt": member_0_last_seen_dt,
                "new_message_separator": 0,
                "partner_id": self.users[0].partner_id.id,
                "rtc_inviting_session_id": False,
                "seen_message_id": False,
                "unpin_dt": False,
                "channel_id": channel.id,
            }
        if channel == self.channel_group_1 and partner == self.users[12].partner_id:
            return {
                "channel_role": False,
                "create_date": fields.Datetime.to_string(member_12.create_date),
                "last_seen_dt": False,
                "id": member_12.id,
                "partner_id": self.users[12].partner_id.id,
                "seen_message_id": False,
                "channel_id": channel.id,
            }
        if channel == self.channel_chat_1 and partner == self.users[0].partner_id:
            return {
                "channel_role": False,
                "create_date": member_0_create_date,
                "custom_notifications": False,
                "id": member_0.id,
                "is_favorite": False,
                "last_interest_dt": member_0_last_interest_dt,
                "message_unread_counter": 0,
                "message_unread_counter_bus_id": bus_last_id,
                "mute_until_dt": False,
                "last_seen_dt": member_0_last_seen_dt,
                "new_message_separator": 0,
                "partner_id": self.users[0].partner_id.id,
                "rtc_inviting_session_id": False,
                "seen_message_id": False,
                "unpin_dt": False,
                "channel_id": channel.id,
            }
        if channel == self.channel_chat_1 and partner == self.users[14].partner_id:
            return {
                "channel_role": False,
                "create_date": fields.Datetime.to_string(member_14.create_date),
                "last_seen_dt": False,
                "id": member_14.id,
                "partner_id": self.users[14].partner_id.id,
                "seen_message_id": False,
                "channel_id": channel.id,
            }
        if channel == self.channel_chat_2 and partner == self.users[0].partner_id:
            return {
                "channel_role": False,
                "create_date": member_0_create_date,
                "custom_notifications": False,
                "id": member_0.id,
                "is_favorite": False,
                "last_interest_dt": member_0_last_interest_dt,
                "message_unread_counter": 0,
                "message_unread_counter_bus_id": bus_last_id,
                "mute_until_dt": False,
                "last_seen_dt": member_0_last_seen_dt,
                "new_message_separator": 0,
                "partner_id": self.users[0].partner_id.id,
                "rtc_inviting_session_id": False,
                "seen_message_id": False,
                "unpin_dt": False,
                "channel_id": channel.id,
            }
        if channel == self.channel_chat_2 and partner == self.users[15].partner_id:
            return {
                "channel_role": False,
                "create_date": fields.Datetime.to_string(member_15.create_date),
                "last_seen_dt": False,
                "id": member_15.id,
                "partner_id": self.users[15].partner_id.id,
                "seen_message_id": False,
                "channel_id": channel.id,
            }
        if channel == self.channel_chat_3 and partner == self.users[0].partner_id:
            return {
                "channel_role": False,
                "create_date": member_0_create_date,
                "custom_notifications": False,
                "id": member_0.id,
                "is_favorite": False,
                "last_interest_dt": member_0_last_interest_dt,
                "message_unread_counter": 0,
                "message_unread_counter_bus_id": bus_last_id,
                "mute_until_dt": False,
                "last_seen_dt": member_0_last_seen_dt,
                "new_message_separator": 0,
                "partner_id": self.users[0].partner_id.id,
                "rtc_inviting_session_id": False,
                "seen_message_id": False,
                "unpin_dt": False,
                "channel_id": channel.id,
            }
        if channel == self.channel_chat_3 and partner == self.users[2].partner_id:
            return {
                "channel_role": False,
                "create_date": fields.Datetime.to_string(member_2.create_date),
                "last_seen_dt": False,
                "id": member_2.id,
                "partner_id": self.users[2].partner_id.id,
                "seen_message_id": False,
                "channel_id": channel.id,
            }
        if channel == self.channel_chat_4 and partner == self.users[0].partner_id:
            return {
                "channel_role": False,
                "create_date": member_0_create_date,
                "custom_notifications": False,
                "id": member_0.id,
                "is_favorite": False,
                "last_interest_dt": member_0_last_interest_dt,
                "message_unread_counter": 0,
                "message_unread_counter_bus_id": bus_last_id,
                "mute_until_dt": False,
                "last_seen_dt": member_0_last_seen_dt,
                "new_message_separator": 0,
                "partner_id": self.users[0].partner_id.id,
                "rtc_inviting_session_id": False,
                "seen_message_id": False,
                "unpin_dt": False,
                "channel_id": channel.id,
            }
        if channel == self.channel_chat_4 and partner == self.users[3].partner_id:
            return {
                "channel_role": False,
                "create_date": fields.Datetime.to_string(member_3.create_date),
                "last_seen_dt": False,
                "id": member_3.id,
                "partner_id": self.users[3].partner_id.id,
                "seen_message_id": False,
                "channel_id": channel.id,
            }
        if channel == self.channel_livechat_1 and partner == self.users[0].partner_id:
            return {
                "channel_role": False,
                "create_date": member_0_create_date,
                "custom_notifications": False,
                "id": member_0.id,
                "is_favorite": False,
                "livechat_member_type": "agent",
                "last_interest_dt": member_0_last_interest_dt,
                "message_unread_counter": 1,
                "message_unread_counter_bus_id": bus_last_id,
                "mute_until_dt": False,
                "last_seen_dt": member_0_last_seen_dt,
                "new_message_separator": 0,
                "partner_id": self.users[0].partner_id.id,
                "rtc_inviting_session_id": False,
                "seen_message_id": False,
                "unpin_dt": fields.Datetime.to_string(member_0.unpin_dt),
                "channel_id": channel.id,
            }
        if channel == self.channel_livechat_1 and partner == self.users[1].partner_id:
            return {
                "channel_role": False,
                "create_date": fields.Datetime.to_string(member_1.create_date),
                "last_seen_dt": fields.Datetime.to_string(member_1.last_seen_dt),
                "id": member_1.id,
                "livechat_member_type": "visitor",
                "partner_id": self.users[1].partner_id.id,
                "seen_message_id": last_message.id,
                "channel_id": channel.id,
            }
        if channel == self.channel_livechat_2 and partner == self.users[0].partner_id:
            return {
                "channel_role": False,
                "create_date": member_0_create_date,
                "custom_notifications": False,
                "id": member_0.id,
                "is_favorite": False,
                "livechat_member_type": "agent",
                "last_interest_dt": member_0_last_interest_dt,
                "message_unread_counter": 1,
                "message_unread_counter_bus_id": bus_last_id,
                "mute_until_dt": False,
                "last_seen_dt": member_0_last_seen_dt,
                "new_message_separator": 0,
                "partner_id": self.users[0].partner_id.id,
                "rtc_inviting_session_id": False,
                "seen_message_id": False,
                "unpin_dt": fields.Datetime.to_string(member_0.unpin_dt),
                "channel_id": channel.id,
            }
        if channel == self.channel_livechat_2 and guest:
            return {
                "channel_role": False,
                "create_date": fields.Datetime.to_string(member_g.create_date),
                "last_seen_dt": fields.Datetime.to_string(member_g.last_seen_dt),
                "id": member_g.id,
                "livechat_member_type": "visitor",
                "guest_id": guest.id,
                "seen_message_id": last_message.id,
                "channel_id": channel.id,
            }
        return {}

    def _expected_result_for_livechat_channel(self):
        return {"id": self.im_livechat_channel.id, "name": "support"}

    def _expected_result_for_livechat_member_history(self, channel):
        histories = channel.livechat_channel_member_history_ids
        if channel == self.channel_livechat_1:
            return [
                {
                    "channel_id": channel.id,
                    "id": histories.filtered(lambda h: h.livechat_member_type == "agent").id,
                    "livechat_member_type": "agent",
                    "partner_id": self.users[0].partner_id.id,
                    "member_id": channel.channel_member_ids.filtered(
                        lambda m: m.partner_id == self.users[0].partner_id
                    ).id,
                },
                {
                    "channel_id": channel.id,
                    "id": histories.filtered(lambda h: h.livechat_member_type == "visitor").id,
                    "livechat_member_type": "visitor",
                    "partner_id": self.users[1].partner_id.id,
                    "member_id": channel.channel_member_ids.filtered(
                        lambda m: m.partner_id == self.users[1].partner_id
                    ).id,
                },
            ]
        if channel == self.channel_livechat_2:
            return [
                {
                    "channel_id": channel.id,
                    "id": histories.filtered(lambda h: h.livechat_member_type == "agent").id,
                    "livechat_member_type": "agent",
                    "partner_id": self.users[0].partner_id.id,
                    "member_id": channel.channel_member_ids.filtered(
                        lambda m: m.partner_id == self.users[0].partner_id
                    ).id,
                },
                {
                    "channel_id": channel.id,
                    "guest_id": self.guest.id,
                    "id": histories.filtered(lambda h: h.livechat_member_type == "visitor").id,
                    "livechat_member_type": "visitor",
                    "member_id": channel.channel_member_ids.filtered(
                        lambda m: m.guest_id == self.guest
                    ).id,
                },
            ]
        return []

    def _expected_result_for_message(self, channel):
        last_message = channel._get_last_messages()
        create_date = fields.Datetime.to_string(last_message.create_date)
        date = fields.Datetime.to_string(last_message.date)
        write_date = fields.Datetime.to_string(last_message.write_date)
        user_0 = self.users[0]
        user_1 = self.users[1]
        user_2 = self.users[2]
        members = channel.channel_member_ids
        member_g = members.filtered(lambda m: m.guest_id)
        guest = member_g.guest_id
        if channel == self.channel_general:
            return {
                "attachment_ids": [],
                "author_guest_id": False,
                "author_id": user_0.partner_id.id,
                "body": ["markup", "<p>test</p>"],
                "create_date": create_date,
                "date": date,
                "default_subject": "general",
                "email_from": '"Ernest Employee" <e.e@example.com>',
                "id": last_message.id,
                "incoming_email_cc": False,
                "incoming_email_to": False,
                "message_link_preview_ids": [],
                "message_type": "comment",
                "model": "discuss.channel",
                "needaction": False,
                "notification_ids": [],
                "parent_id": False,
                "partner_ids": [],
                "pinned_at": False,
                "rating_id": False,
                "reactions": [
                    {"content": "👍", "message": last_message.id},
                    {"content": "😁", "message": last_message.id},
                    {"content": "😊", "message": last_message.id},
                ],
                "record_name": "general",
                "reply_to": '"Ernest Employee" <catchall.test@test.mycompany.com>',
                "res_id": 1,
                "scheduledDatetime": False,
                "is_bookmarked": False,
                "subject": False,
                "subtype_id": self.env.ref("mail.mt_note").id,
                "thread": {"id": channel.id, "model": "discuss.channel"},
                "trackingValues": [],
                "write_date": write_date,
            }
        if channel == self.channel_channel_public_1:
            return {
                "attachment_ids": [],
                "author_guest_id": False,
                "author_id": user_2.partner_id.id,
                "body": ["markup", "<p>test</p>"],
                "create_date": create_date,
                "date": date,
                "default_subject": "public channel 1",
                "email_from": '"test2" <test2@example.com>',
                "id": last_message.id,
                "incoming_email_cc": False,
                "incoming_email_to": False,
                "message_link_preview_ids": [],
                "message_type": "comment",
                "model": "discuss.channel",
                "needaction": True,
                "notification_ids": [last_message.notification_ids.id],
                "thread": {"id": channel.id, "model": "discuss.channel"},
                "parent_id": False,
                "partner_ids": [self.users[0].partner_id.id],
                "pinned_at": False,
                "rating_id": False,
                "reactions": [
                    {"content": "😁", "message": last_message.id},
                    {"content": "😊", "message": last_message.id},
                    {"content": "😏", "message": last_message.id},
                ],
                "record_name": "public channel 1",
                "res_id": channel.id,
                "reply_to": '"test2" <catchall.test@test.mycompany.com>',
                "scheduledDatetime": False,
                "is_bookmarked": True,
                "subject": False,
                "subtype_id": self.env.ref("mail.mt_note").id,
                "trackingValues": [],
                "write_date": write_date,
            }
        if channel == self.channel_channel_public_2:
            return {
                "attachment_ids": [],
                "author_guest_id": False,
                "author_id": user_0.partner_id.id,
                "body": [
                    "markup",
                    '<div class="o_mail_notification">created this channel.</div>',
                ],
                "create_date": create_date,
                "date": date,
                "default_subject": "public channel 2",
                "email_from": '"Ernest Employee" <e.e@example.com>',
                "id": last_message.id,
                "incoming_email_cc": False,
                "incoming_email_to": False,
                "message_link_preview_ids": [],
                "message_type": "notification",
                "model": "discuss.channel",
                "needaction": False,
                "notification_ids": [],
                "thread": {"id": channel.id, "model": "discuss.channel"},
                "parent_id": False,
                "partner_ids": [],
                "pinned_at": False,
                "rating_id": False,
                "reactions": [],
                "record_name": "public channel 2",
                "reply_to": '"Ernest Employee" <catchall.test@test.mycompany.com>',
                "res_id": channel.id,
                "scheduledDatetime": False,
                "is_bookmarked": False,
                "subject": False,
                "subtype_id": self.env.ref("mail.mt_comment").id,
                "trackingValues": [],
                "write_date": write_date,
            }
        if channel == self.channel_channel_group_1:
            return {
                "attachment_ids": [],
                "author_guest_id": False,
                "author_id": self.user_root.partner_id.id,
                "body": [
                    "markup",
                    '<div data-oe-type=\"call\" class="o_mail_notification"></div>',
                ],
                "call_history_ids": [channel.call_history_ids[0].id],
                "create_date": create_date,
                "date": date,
                "default_subject": "group restricted channel 1",
                "email_from": '"OdooBot" <odoobot@example.com>',
                "id": last_message.id,
                "incoming_email_cc": False,
                "incoming_email_to": False,
                "message_link_preview_ids": [],
                "message_type": "notification",
                "model": "discuss.channel",
                "needaction": False,
                "notification_ids": [],
                "thread": {"id": channel.id, "model": "discuss.channel"},
                "parent_id": False,
                "partner_ids": [],
                "pinned_at": False,
                "rating_id": False,
                "reactions": [],
                "record_name": "group restricted channel 1",
                "reply_to": '"OdooBot" <catchall.test@test.mycompany.com>',
                "res_id": channel.id,
                "scheduledDatetime": False,
                "is_bookmarked": False,
                "subject": False,
                "subtype_id": self.env.ref("mail.mt_note").id,
                "trackingValues": [],
                "write_date": write_date,
            }
        if channel == self.channel_channel_group_2:
            return {
                "attachment_ids": [],
                "author_guest_id": False,
                "author_id": user_0.partner_id.id,
                "body": [
                    "markup",
                    '<div class="o_mail_notification">created this channel.</div>',
                ],
                "create_date": create_date,
                "date": date,
                "default_subject": "group restricted channel 2",
                "email_from": '"Ernest Employee" <e.e@example.com>',
                "id": last_message.id,
                "incoming_email_cc": False,
                "incoming_email_to": False,
                "message_link_preview_ids": [],
                "message_type": "notification",
                "model": "discuss.channel",
                "needaction": False,
                "notification_ids": [],
                "thread": {"id": channel.id, "model": "discuss.channel"},
                "parent_id": False,
                "partner_ids": [],
                "pinned_at": False,
                "rating_id": False,
                "reactions": [],
                "record_name": "group restricted channel 2",
                "reply_to": '"Ernest Employee" <catchall.test@test.mycompany.com>',
                "res_id": channel.id,
                "scheduledDatetime": False,
                "is_bookmarked": False,
                "subject": False,
                "subtype_id": self.env.ref("mail.mt_comment").id,
                "trackingValues": [],
                "write_date": write_date,
            }
        if channel == self.channel_channel_group_4:
            return {
                "attachment_ids": [],
                "author_guest_id": False,
                "author_id": user_2.partner_id.id,
                "body": ["markup", "<p>muted_channel's message</p>"],
                "create_date": create_date,
                "date": date,
                "default_subject": "group restricted channel 4 (muted)",
                "email_from": '"test2" <test2@example.com>',
                "id": last_message.id,
                "incoming_email_cc": False,
                "incoming_email_to": False,
                "is_bookmarked": False,
                "message_link_preview_ids": [],
                "message_type": "comment",
                "model": "discuss.channel",
                "needaction": False,
                "notification_ids": [],
                "parent_id": False,
                "partner_ids": [],
                "pinned_at": False,
                "rating_id": False,
                "reactions": [],
                "record_name": "group restricted channel 4 (muted)",
                "reply_to": '"test2" <catchall.test@test.mycompany.com>',
                "res_id": channel.id,
                "scheduledDatetime": False,
                "subject": False,
                "subtype_id": self.env.ref("mail.mt_note").id,
                "thread": {"id": channel.id, "model": "discuss.channel"},
                "trackingValues": [],
                "write_date": write_date,
            }
        if channel == self.channel_livechat_1:
            return {
                "attachment_ids": [],
                "author_guest_id": False,
                "author_id": user_1.partner_id.id,
                "body": ["markup", "<p>test</p>"],
                "create_date": create_date,
                "date": date,
                "default_subject": "test1 Ernest Employee",
                "email_from": '"test1" <test1@example.com>',
                "id": last_message.id,
                "incoming_email_cc": False,
                "incoming_email_to": False,
                "message_link_preview_ids": [],
                "message_type": "comment",
                "model": "discuss.channel",
                "needaction": False,
                "notification_ids": [],
                "thread": {"id": channel.id, "model": "discuss.channel"},
                "parent_id": False,
                "partner_ids": [],
                "pinned_at": False,
                "rating_id": False,
                "reactions": [],
                "record_name": "test1 Ernest Employee",
                "reply_to": '"test1" <catchall.test@test.mycompany.com>',
                "res_id": channel.id,
                "scheduledDatetime": False,
                "is_bookmarked": False,
                "subject": False,
                "subtype_id": self.env.ref("mail.mt_note").id,
                "trackingValues": [],
                "write_date": write_date,
            }
        if channel == self.channel_livechat_2:
            return {
                "attachment_ids": [],
                "author_guest_id": guest.id,
                "author_id": False,
                "body": ["markup", "<p>test</p>"],
                "create_date": create_date,
                "date": date,
                "default_subject": "Visitor Ernest Employee",
                "email_from": False,
                "id": last_message.id,
                "incoming_email_cc": False,
                "incoming_email_to": False,
                "message_link_preview_ids": [],
                "message_type": "comment",
                "model": "discuss.channel",
                "needaction": False,
                "notification_ids": [],
                "thread": {"id": channel.id, "model": "discuss.channel"},
                "parent_id": False,
                "partner_ids": [],
                "pinned_at": False,
                "rating_id": False,
                "reactions": [],
                "record_name": "Visitor Ernest Employee",
                "reply_to": '"Public user" <catchall.test@test.mycompany.com>',
                "res_id": channel.id,
                "scheduledDatetime": False,
                "is_bookmarked": False,
                "subject": False,
                "subtype_id": self.env.ref("mail.mt_note").id,
                "trackingValues": [],
                "write_date": write_date,
            }
        return {}

    def _expected_result_for_message_reactions(self, channel):
        last_message = channel._get_last_messages()
        partner_0 = self.users[0].partner_id.id
        partner_1 = self.users[1].partner_id.id
        partner_2 = self.users[2].partner_id.id
        reactions_0 = last_message.sudo().reaction_ids.filtered(lambda r: r.content == "👍")
        reactions_1 = last_message.sudo().reaction_ids.filtered(lambda r: r.content == "😁")
        reactions_2 = last_message.sudo().reaction_ids.filtered(lambda r: r.content == "😊")
        reactions_3 = last_message.sudo().reaction_ids.filtered(lambda r: r.content == "😏")
        if channel == self.channel_general:
            return [
                {
                    "content": "👍",
                    "count": 1,
                    "guests": [],
                    "message": last_message.id,
                    "partners": [partner_2],
                    "sequence": min(reactions_0.ids),
                },
                {
                    "content": "😁",
                    "count": 2,
                    "guests": [],
                    "message": last_message.id,
                    "partners": [partner_2, partner_1],
                    "sequence": min(reactions_1.ids),
                },
                {
                    "content": "😊",
                    "count": 3,
                    "guests": [],
                    "message": last_message.id,
                    "partners": [partner_2, partner_1, partner_0],
                    "sequence": min(reactions_2.ids),
                },
            ]
        if channel == self.channel_channel_public_1:
            return [
                {
                    "content": "😁",
                    "count": 1,
                    "guests": [],
                    "message": last_message.id,
                    "partners": [partner_2],
                    "sequence": min(reactions_1.ids),
                },
                {
                    "content": "😊",
                    "count": 3,
                    "guests": [],
                    "message": last_message.id,
                    "partners": [partner_2, partner_1, partner_0],
                    "sequence": min(reactions_2.ids),
                },
                {
                    "content": "😏",
                    "count": 2,
                    "guests": [],
                    "message": last_message.id,
                    "partners": [partner_1, partner_0],
                    "sequence": min(reactions_3.ids),
                },
            ]
        return []

    def _expected_result_for_notification(self, channel):
        last_message = channel._get_last_messages()
        if channel == self.channel_channel_public_1:
            return {
                "mail_email_address": False,
                "failure_type": False,
                "id": last_message.notification_ids.id,
                "mail_message_id": last_message.id,
                "notification_status": "sent",
                "notification_type": "inbox",
                "res_partner_id": self.users[0].partner_id.id,
            }
        return {}

    def _expected_result_for_persona(
        self,
        user=None,
        guest=None,
        only_inviting=False,
        also_livechat=False,
        also_notification=False,
    ):
        if user == self.users[0]:
            res = {
                "active": True,
                "avatar_128_access_token": user.partner_id._get_avatar_128_access_token(),
                "email": "e.e@example.com",
                "id": user.partner_id.id,
                "im_status": "online",
                "im_status_access_token": user.partner_id._get_im_status_access_token(),
                "is_company": False,
                "main_user_id": user.id,
                "mention_token": user.partner_id._get_mention_token(),
                "name": "Ernest Employee",
                "tz": "Europe/Brussels",
                "write_date": fields.Datetime.to_string(user.partner_id.write_date),
            }
            if also_livechat:
                res.update(
                    {
                        "country_id": False,
                        "is_public": False,
                        "user_livechat_username": False,
                    }
                )
            if also_notification:
                res["name"] = "Ernest Employee"
            return res
        if user == self.users[1]:
            res = {
                "active": True,
                "avatar_128_access_token": user.partner_id._get_avatar_128_access_token(),
                "country_id": self.env.ref("base.in").id,
                "id": user.partner_id.id,
                "im_status": "offline",
                "im_status_access_token": user.partner_id._get_im_status_access_token(),
                "is_company": False,
                "is_public": False,
                "main_user_id": user.id,
                "name": "test1",
                "mention_token": user.partner_id._get_mention_token(),
                "write_date": fields.Datetime.to_string(user.partner_id.write_date),
            }
            if also_livechat:
                res["offline_since"] = False
                res["user_livechat_username"] = False
                res["email"] = user.email
            return res
        if user == self.users[2]:
            if only_inviting:
                return {
                    "avatar_128_access_token": user.partner_id._get_avatar_128_access_token(),
                    "id": user.partner_id.id,
                    "im_status": "offline",
                    "im_status_access_token": user.partner_id._get_im_status_access_token(),
                    "name": "test2",
                    "main_user_id": user.id,
                    "mention_token": user.partner_id._get_mention_token(),
                    "write_date": fields.Datetime.to_string(user.partner_id.write_date),
                }
            return {
                "active": True,
                "avatar_128_access_token": user.partner_id._get_avatar_128_access_token(),
                "email": "test2@example.com",
                "id": user.partner_id.id,
                "im_status": "offline",
                "im_status_access_token": user.partner_id._get_im_status_access_token(),
                "is_company": False,
                "main_user_id": user.id,
                "mention_token": user.partner_id._get_mention_token(),
                "name": "test2",
                "tz": False,
                "write_date": fields.Datetime.to_string(user.partner_id.write_date),
            }
        if user == self.users[3]:
            return {
                "active": True,
                "avatar_128_access_token": user.partner_id._get_avatar_128_access_token(),
                "email": False,
                "id": user.partner_id.id,
                "im_status": "offline",
                "im_status_access_token": user.partner_id._get_im_status_access_token(),
                "is_company": False,
                "main_user_id": user.id,
                "mention_token": user.partner_id._get_mention_token(),
                "name": "test3",
                "tz": False,
                "write_date": fields.Datetime.to_string(self.users[3].partner_id.write_date),
            }
        if user == self.users[12]:
            return {
                "active": True,
                "avatar_128_access_token": user.partner_id._get_avatar_128_access_token(),
                "email": False,
                "id": user.partner_id.id,
                "im_status": "offline",
                "im_status_access_token": user.partner_id._get_im_status_access_token(),
                "is_company": False,
                "main_user_id": user.id,
                "mention_token": user.partner_id._get_mention_token(),
                "name": "test12",
                "tz": False,
                "write_date": fields.Datetime.to_string(user.partner_id.write_date),
            }
        if user == self.users[14]:
            return {
                "active": True,
                "avatar_128_access_token": user.partner_id._get_avatar_128_access_token(),
                "email": False,
                "id": user.partner_id.id,
                "im_status": "offline",
                "im_status_access_token": user.partner_id._get_im_status_access_token(),
                "is_company": False,
                "main_user_id": user.id,
                "mention_token": user.partner_id._get_mention_token(),
                "name": "test14",
                "tz": False,
                "write_date": fields.Datetime.to_string(user.partner_id.write_date),
            }
        if user == self.users[15]:
            return {
                "active": True,
                "avatar_128_access_token": user.partner_id._get_avatar_128_access_token(),
                "email": False,
                "id": user.partner_id.id,
                "im_status": "offline",
                "im_status_access_token": user.partner_id._get_im_status_access_token(),
                "is_company": False,
                "main_user_id": user.id,
                "mention_token": user.partner_id._get_mention_token(),
                "name": "test15",
                "tz": False,
                "write_date": fields.Datetime.to_string(user.partner_id.write_date),
            }
        if user == self.user_root:
            return {
                "avatar_128_access_token": user.partner_id._get_avatar_128_access_token(),
                "id": user.partner_id.id,
                "is_company": False,
                "main_user_id": user.id,
                "name": "OdooBot",
                "write_date": fields.Datetime.to_string(user.partner_id.write_date),
            }
        if guest:
            return {
                "avatar_128_access_token": self.guest._get_avatar_128_access_token(),
                "country_id": self.guest.country_id.id,
                "id": self.guest.id,
                "im_status": "offline",
                "im_status_access_token": self.guest._get_im_status_access_token(),
                "name": "Visitor",
                "offline_since": False,
                "write_date": fields.Datetime.to_string(self.guest.write_date),
            }
        return {}

    def _expected_result_for_rtc_session(self, channel, user):
        members = channel.channel_member_ids
        member_2 = members.filtered(lambda m: m.partner_id == self.users[2].partner_id)
        if channel == self.channel_channel_group_1 and user == self.users[2]:
            return {
                # sudo: discuss.channel.rtc.session - reading a session in a test file
                "channel_member_id": member_2.id,
                "id": member_2.sudo().rtc_session_ids.id,
                "is_camera_on": False,
                "is_deaf": False,
                "is_screen_sharing_on": False,
                "is_muted": False,
            }
        return {}

    def _expected_result_for_thread(self, channel):
        common_data = {
            "has_mail_thread": True,
            "id": channel.id,
            "model": "discuss.channel",
            "rating_avg": 0.0,
            "rating_count": 0,
        }
        if channel == self.channel_general:
            return {**common_data, "display_name": "general"}
        if channel == self.channel_channel_public_1:
            return {**common_data, "display_name": "public channel 1"}
        if channel == self.channel_channel_public_2:
            return {**common_data, "display_name": "public channel 2"}
        if channel == self.channel_channel_group_1:
            return {**common_data, "display_name": "group restricted channel 1"}
        if channel == self.channel_channel_group_2:
            return {**common_data, "display_name": "group restricted channel 2"}
        if channel == self.channel_channel_group_4:
            return {**common_data, "display_name": "group restricted channel 4 (muted)"}
        if channel == self.channel_livechat_1:
            return {**common_data, "display_name": "test1 Ernest Employee"}
        if channel == self.channel_livechat_2:
            return {**common_data, "display_name": "Visitor Ernest Employee"}
        return {}

    def _res_for_user(self, user, only_inviting=False):
        partner = user.partner_id
        if user == self.users[0]:
            return {
                "all_employee_ids": user.employee_ids.ids,
                "active": True,
                "id": user.id,
                "employee_ids": user.employee_ids.ids,
                "partner_id": partner.id,
                "share": False,
            }
        if user == self.users[1]:
            return {
                "all_employee_ids": user.employee_ids.ids,
                "id": user.id,
                "employee_ids": user.employee_ids.ids,
                "partner_id": partner.id,
                "share": False,
            }
        if user == self.users[2]:
            if only_inviting:
                return {
                    "all_employee_ids": user.employee_ids.ids,
                    "id": user.id,
                    "employee_ids": user.employee_ids.ids,
                    "partner_id": partner.id,
                }
            return {
                "active": True,
                "all_employee_ids": user.employee_ids.ids,
                "id": user.id,
                "employee_ids": user.employee_ids.ids,
                "partner_id": partner.id,
                "share": False,
            }
        if user == self.users[3]:
            return {
                "active": True,
                "all_employee_ids": user.employee_ids.ids,
                "id": user.id,
                "employee_ids": user.employee_ids.ids,
                "partner_id": partner.id,
                "share": False,
            }
        if user == self.users[12]:
            return {
                "active": True,
                "all_employee_ids": user.employee_ids.ids,
                "id": user.id,
                "employee_ids": user.employee_ids.ids,
                "partner_id": partner.id,
                "share": False,
            }
        if user == self.users[14]:
            return {
                "active": True,
                "all_employee_ids": user.employee_ids.ids,
                "id": user.id,
                "employee_ids": user.employee_ids.ids,
                "partner_id": partner.id,
                "share": False,
            }
        if user == self.users[15]:
            return {
                "active": True,
                "all_employee_ids": user.employee_ids.ids,
                "id": user.id,
                "employee_ids": user.employee_ids.ids,
                "partner_id": partner.id,
                "share": False,
            }
        if user == self.user_root:
            return {
                "id": user.id,
                "partner_id": partner.id,
                "share": False,
            }
        return {}

    def _res_for_employee(self, employee):
        return {
            "active": employee.active,
            "company_id": employee.company_id.id,
            "id": employee.id,
            "leave_date_to": False,
            "user_id": employee.user_id.id,
            "work_location_type": False,
        }
