diff --git a/addons/bus/models/ir_websocket.py b/addons/bus/models/ir_websocket.py index 68d187ad974..22a56297a3e 100644 --- a/addons/bus/models/ir_websocket.py +++ b/addons/bus/models/ir_websocket.py @@ -12,7 +12,7 @@ class IrWebsocket(models.AbstractModel): def _get_im_status(self, im_status_ids_by_model): im_status = {} if 'res.partner' in im_status_ids_by_model: - im_status['partners'] = self.env['res.partner'].with_context(active_test=False).search_read( + im_status['Partner'] = self.env['res.partner'].with_context(active_test=False).search_read( [('id', 'in', im_status_ids_by_model['res.partner'])], ['im_status'] ) @@ -47,7 +47,7 @@ class IrWebsocket(models.AbstractModel): ) im_status_notification = self._get_im_status(im_status_ids_by_model) if im_status_notification: - self.env['bus.bus']._sendone(self.env.user.partner_id, 'bus/im_status', im_status_notification) + self.env['bus.bus']._sendone(self.env.user.partner_id, 'mail.record/insert', im_status_notification) @classmethod def _authenticate(cls): diff --git a/addons/bus/static/tests/helpers/mock_server/models/ir_websocket.js b/addons/bus/static/tests/helpers/mock_server/models/ir_websocket.js index 6d5158c5604..45acce77d31 100644 --- a/addons/bus/static/tests/helpers/mock_server/models/ir_websocket.js +++ b/addons/bus/static/tests/helpers/mock_server/models/ir_websocket.js @@ -13,7 +13,7 @@ patch(MockServer.prototype, 'bus/models/ir_websocket', { _mockIrWebsocket__updatePresence(inactivityPeriod, imStatusIdsByModel) { const imStatusNotifications = this._mockIrWebsocket__getImStatus(imStatusIdsByModel); if (Object.keys(imStatusNotifications).length > 0) { - this._mockBusBus__sendone(this.currentPartnerId, 'bus/im_status', imStatusNotifications); + this._mockBusBus__sendone(this.currentPartnerId, 'mail.record/insert', imStatusNotifications); } }, /** @@ -27,7 +27,7 @@ patch(MockServer.prototype, 'bus/models/ir_websocket', { const imStatus = {}; const { 'res.partner': partnerIds } = imStatusIdsByModel; if (partnerIds) { - imStatus['partners'] = this.mockSearchRead('res.partner', [[['id', 'in', partnerIds]]], { context: { 'active_test': false }, fields: ['im_status'] }) + imStatus['Partner'] = this.mockSearchRead('res.partner', [[['id', 'in', partnerIds]]], { context: { 'active_test': false }, fields: ['im_status'] }) } return imStatus; }, diff --git a/addons/im_livechat/models/mail_channel.py b/addons/im_livechat/models/mail_channel.py index 934bfbc748b..9476b58b8b6 100644 --- a/addons/im_livechat/models/mail_channel.py +++ b/addons/im_livechat/models/mail_channel.py @@ -102,9 +102,11 @@ class MailChannel(models.Model): def _message_update_content_after_hook(self, message): self.ensure_one() if self.channel_type == 'livechat': - self.env['bus.bus']._sendone(self.uuid, 'mail.message/insert', { - 'id': message.id, - 'body': message.body, + self.env['bus.bus']._sendone(self.uuid, 'mail.record/insert', { + 'Message': { + 'id': message.id, + 'body': message.body, + } }) return super()._message_update_content_after_hook(message=message) diff --git a/addons/im_livechat/static/src/public_models/public_livechat_global_notification_handler.js b/addons/im_livechat/static/src/public_models/public_livechat_global_notification_handler.js index 04b4b9c3301..3be999bf33b 100644 --- a/addons/im_livechat/static/src/public_models/public_livechat_global_notification_handler.js +++ b/addons/im_livechat/static/src/public_models/public_livechat_global_notification_handler.js @@ -23,10 +23,10 @@ registerModel({ * @param {Object} notification.payload * @param {string} notification.type */ - _handleNotification({ payload, type }) { + _handleNotification({ payload: notifPayload, type }) { switch (type) { case 'im_livechat.history_command': { - if (payload.id !== this.messaging.publicLivechatGlobal.publicLivechat.id) { + if (notifPayload.id !== this.messaging.publicLivechatGlobal.publicLivechat.id) { return; } const cookie = getCookie(this.messaging.publicLivechatGlobal.LIVECHAT_COOKIE_HISTORY); @@ -42,7 +42,7 @@ registerModel({ if (!this.messaging.publicLivechatGlobal.chatWindow || !this.messaging.publicLivechatGlobal.chatWindow.exists()) { return; } - const channelMemberData = payload; + const channelMemberData = notifPayload; if (channelMemberData.channel.id !== this.messaging.publicLivechatGlobal.publicLivechat.id) { return; } @@ -64,10 +64,10 @@ registerModel({ if (!this.messaging.publicLivechatGlobal.chatWindow || !this.messaging.publicLivechatGlobal.chatWindow.exists()) { return; } - if (payload.id !== this.messaging.publicLivechatGlobal.publicLivechat.id) { + if (notifPayload.id !== this.messaging.publicLivechatGlobal.publicLivechat.id) { return; } - const notificationData = payload.message; + const notificationData = notifPayload.message; // If message from notif is already in chatter messages, stop handling if (this.messaging.publicLivechatGlobal.messages.some(message => message.id === notificationData.id)) { return; @@ -80,7 +80,11 @@ registerModel({ this.messaging.publicLivechatGlobal.chatWindow.renderMessages(); return; } - case 'mail.message/insert': { + case 'mail.record/insert': { + const { Message: payload } = notifPayload; + if (!payload) { + return; + } if (!this.messaging.publicLivechatGlobal.chatWindow || !this.messaging.publicLivechatGlobal.chatWindow.exists()) { return; } diff --git a/addons/im_livechat/static/tests/qunit_suite_tests/components/discuss_sidebar_category_tests.js b/addons/im_livechat/static/tests/qunit_suite_tests/components/discuss_sidebar_category_tests.js index bc31c3b88e9..96adbca6b40 100644 --- a/addons/im_livechat/static/tests/qunit_suite_tests/components/discuss_sidebar_category_tests.js +++ b/addons/im_livechat/static/tests/qunit_suite_tests/components/discuss_sidebar_category_tests.js @@ -318,9 +318,11 @@ QUnit.test('livechat - states: close from the bus', async function (assert) { ); await afterNextRender(() => { - pyEnv['bus.bus']._sendone(pyEnv.currentPartner, 'res.users.settings/insert', { - id: resUsersSettingsId1, - 'is_discuss_sidebar_category_livechat_open': false, + pyEnv['bus.bus']._sendone(pyEnv.currentPartner, 'mail.record/insert', { + 'res.users.settings': { + 'id': resUsersSettingsId1, + 'is_discuss_sidebar_category_livechat_open': false, + }, }); }); assert.containsNone( @@ -356,9 +358,11 @@ QUnit.test('livechat - states: open from the bus', async function (assert) { ); await afterNextRender(() => { - pyEnv['bus.bus']._sendone(pyEnv.currentPartner, 'res.users.settings/insert', { - id: resUsersSettingsId1, - 'is_discuss_sidebar_category_livechat_open': true, + pyEnv['bus.bus']._sendone(pyEnv.currentPartner, 'mail.record/insert', { + 'res.users.settings': { + id: resUsersSettingsId1, + 'is_discuss_sidebar_category_livechat_open': true, + }, }); }); assert.containsOnce( diff --git a/addons/mail/models/ir_websocket.py b/addons/mail/models/ir_websocket.py index 07028759b05..9b6b65673cf 100644 --- a/addons/mail/models/ir_websocket.py +++ b/addons/mail/models/ir_websocket.py @@ -9,7 +9,7 @@ class IrWebsocket(models.AbstractModel): def _get_im_status(self, data): im_status = super()._get_im_status(data) if 'mail.guest' in data: - im_status['guests'] = self.env['mail.guest'].sudo().with_context(active_test=False).search_read( + im_status['Guest'] = self.env['mail.guest'].sudo().with_context(active_test=False).search_read( [('id', 'in', data['mail.guest'])], ['im_status'] ) diff --git a/addons/mail/models/mail_channel.py b/addons/mail/models/mail_channel.py index 4ffd8d345a9..15f87277f7a 100644 --- a/addons/mail/models/mail_channel.py +++ b/addons/mail/models/mail_channel.py @@ -263,9 +263,11 @@ class Channel(models.Model): if 'image_128' in vals: notifications = [] for channel in self: - notifications.append([channel, 'mail.channel/insert', { - 'avatarCacheKey': channel._get_avatar_cache_key(), - 'id': channel.id, + notifications.append([channel, 'mail.record/insert', { + 'Channel': { + 'avatarCacheKey': channel._get_avatar_cache_key(), + 'id': channel.id, + } }]) self.env['bus.bus']._sendmany(notifications) return result @@ -314,10 +316,12 @@ class Channel(models.Model): notification = _('
left the channel
') # post 'channel left' message as root since the partner just unsubscribed from the channel self.sudo().message_post(body=notification, subtype_xmlid="mail.mt_comment", author_id=partner.id) - self.env['bus.bus']._sendone(self, 'mail.channel/insert', { - 'channelMembers': [('insert-and-unlink', {'id': member_id})], - 'id': self.id, - 'memberCount': self.member_count, + self.env['bus.bus']._sendone(self, 'mail.record/insert', { + 'Channel': { + 'channelMembers': [('insert-and-unlink', {'id': member_id})], + 'id': self.id, + 'memberCount': self.member_count, + } }) def add_members(self, partner_ids=None, guest_ids=None, invite_to_rtc_call=False, open_chat_window=False, post_joined_message=True): @@ -395,19 +399,23 @@ class Channel(models.Model): notifications.append((guest, 'mail.channel/joined', { 'channel': member.channel_id.sudo().channel_info()[0], })) - notifications.append((channel, 'mail.channel/insert', { - 'channelMembers': [('insert', list(new_members._mail_channel_member_format().values()))], - 'id': channel.id, - 'memberCount': channel.member_count, + notifications.append((channel, 'mail.record/insert', { + 'Channel': { + 'channelMembers': [('insert', list(new_members._mail_channel_member_format().values()))], + 'id': channel.id, + 'memberCount': channel.member_count, + } })) if existing_members: # If the current user invited these members but they are already present, notify the current user about their existence as well. # In particular this fixes issues where the current user is not aware of its own member in the following case: # create channel from form view, and then join from discuss without refreshing the page. - notifications.append((current_partner or current_guest, 'mail.channel/insert', { - 'channelMembers': [('insert', list(existing_members._mail_channel_member_format().values()))], - 'id': channel.id, - 'memberCount': channel.member_count, + notifications.append((current_partner or current_guest, 'mail.record/insert', { + 'Channel': { + 'channelMembers': [('insert', list(existing_members._mail_channel_member_format().values()))], + 'id': channel.id, + 'memberCount': channel.member_count, + } })) if invite_to_rtc_call: for channel in self: @@ -461,16 +469,18 @@ class Channel(models.Model): target = member.partner_id else: target = member.guest_id - invitation_notifications.append((target, 'mail.thread/insert', { - 'id': self.id, - 'model': 'mail.channel', - 'rtcInvitingSession': [('unlink',)], + invitation_notifications.append((target, 'mail.record/insert', { + 'Thread': { + 'id': self.id, + 'model': 'mail.channel', + 'rtcInvitingSession': [('unlink',)], + } })) self.env['bus.bus']._sendmany(invitation_notifications) channel_data = {'id': self.id, 'model': 'mail.channel'} if members: channel_data['invitedMembers'] = [('insert-and-unlink', list(members._mail_channel_member_format(fields={'id': True, 'channel': {}, 'persona': {'partner': {'id', 'name', 'im_status'}, 'guest': {'id', 'name', 'im_status'}}}).values()))] - self.env['bus.bus']._sendone(self, 'mail.thread/insert', channel_data) + self.env['bus.bus']._sendone(self, 'mail.record/insert', {'Thread': channel_data}) return channel_data # ------------------------------------------------------------ @@ -617,10 +627,12 @@ class Channel(models.Model): def _message_update_content_after_hook(self, message): self.ensure_one() - self.env['bus.bus']._sendone(self, 'mail.message/insert', { - 'id': message.id, - 'body': message.body, - 'attachments': message.attachment_ids._attachment_format(), + self.env['bus.bus']._sendone(self, 'mail.record/insert', { + 'Message': { + 'id': message.id, + 'body': message.body, + 'attachments': message.attachment_ids._attachment_format(), + } }) return super()._message_update_content_after_hook(message=message) @@ -633,15 +645,17 @@ class Channel(models.Model): guests = [] partners = [('insert', {'id': self.env.user.partner_id.id})] reactions = self.env['mail.message.reaction'].sudo().search([('message_id', '=', message.id), ('content', '=', content)]) - self.env['bus.bus']._sendone(self, 'mail.message/insert', { - 'id': message.id, - 'messageReactionGroups': [('insert' if len(reactions) > 0 else 'insert-and-unlink', { - 'content': content, - 'count': len(reactions), - 'guests': guests, - 'message': {'id': message.id}, - 'partners': partners, - })], + self.env['bus.bus']._sendone(self, 'mail.record/insert', { + 'Message': { + 'id': message.id, + 'messageReactionGroups': [('insert' if len(reactions) > 0 else 'insert-and-unlink', { + 'content': content, + 'count': len(reactions), + 'guests': guests, + 'message': {'id': message.id}, + 'partners': partners, + })], + } }) return super()._message_add_reaction_after_hook(message=message, content=content) @@ -654,15 +668,17 @@ class Channel(models.Model): guests = [] partners = [('insert-and-unlink', {'id': self.env.user.partner_id.id})] reactions = self.env['mail.message.reaction'].sudo().search([('message_id', '=', message.id), ('content', '=', content)]) - self.env['bus.bus']._sendone(self, 'mail.message/insert', { - 'id': message.id, - 'messageReactionGroups': [('insert' if len(reactions) > 0 else 'insert-and-unlink', { - 'content': content, - 'count': len(reactions), - 'guests': guests, - 'message': {'id': message.id}, - 'partners': partners, - })], + self.env['bus.bus']._sendone(self, 'mail.record/insert', { + 'Message': { + 'id': message.id, + 'messageReactionGroups': [('insert' if len(reactions) > 0 else 'insert-and-unlink', { + 'content': content, + 'count': len(reactions), + 'guests': guests, + 'message': {'id': message.id}, + 'partners': partners, + })], + } }) return super()._message_remove_reaction_after_hook(message=message, content=content) @@ -918,10 +934,12 @@ class Channel(models.Model): vals['is_minimized'] = is_minimized if vals: session_state.write(vals) - self.env['bus.bus']._sendone(self.env.user.partner_id, 'mail.thread/insert', { - 'id': session_state.channel_id.id, - 'model': 'mail.channel', - 'serverFoldState': state, + self.env['bus.bus']._sendone(self.env.user.partner_id, 'mail.record/insert', { + 'Thread': { + 'id': session_state.channel_id.id, + 'model': 'mail.channel', + 'serverFoldState': state, + } }) def channel_pin(self, pinned=False): @@ -1006,27 +1024,33 @@ class Channel(models.Model): self.ensure_one() member = self.env['mail.channel.member'].search([('partner_id', '=', self.env.user.partner_id.id), ('channel_id', '=', self.id)]) member.write({'custom_channel_name': name}) - self.env['bus.bus']._sendone(member.partner_id, 'mail.channel/insert', { - 'custom_channel_name': name, - 'id': self.id, + self.env['bus.bus']._sendone(member.partner_id, 'mail.record/insert', { + 'Channel': { + 'custom_channel_name': name, + 'id': self.id, + } }) def channel_rename(self, name): self.ensure_one() self.write({'name': name}) - self.env['bus.bus']._sendone(self, 'mail.thread/insert', { - 'id': self.id, - 'model': 'mail.channel', - 'name': name, + self.env['bus.bus']._sendone(self, 'mail.record/insert', { + 'Thread': { + 'id': self.id, + 'model': 'mail.channel', + 'name': name, + } }) def channel_change_description(self, description): self.ensure_one() self.write({'description': description}) - self.env['bus.bus']._sendone(self, 'mail.thread/insert', { - 'id': self.id, - 'description': description, - 'model': 'mail.channel', + self.env['bus.bus']._sendone(self, 'mail.record/insert', { + 'Thread': { + 'id': self.id, + 'description': description, + 'model': 'mail.channel', + } }) def channel_join(self): diff --git a/addons/mail/models/mail_channel_member.py b/addons/mail/models/mail_channel_member.py index 3df2841f661..a97f2cd56a1 100644 --- a/addons/mail/models/mail_channel_member.py +++ b/addons/mail/models/mail_channel_member.py @@ -226,14 +226,16 @@ class ChannelMember(models.Model): target = member.partner_id else: target = member.guest_id - invitation_notifications.append((target, 'mail.thread/insert', { - 'id': self.channel_id.id, - 'model': 'mail.channel', - 'rtcInvitingSession': self.rtc_session_ids._mail_rtc_session_format(), + invitation_notifications.append((target, 'mail.record/insert', { + 'Thread': { + 'id': self.channel_id.id, + 'model': 'mail.channel', + 'rtcInvitingSession': self.rtc_session_ids._mail_rtc_session_format(), + } })) self.env['bus.bus']._sendmany(invitation_notifications) if members: channel_data = {'id': self.channel_id.id, 'model': 'mail.channel'} channel_data['invitedMembers'] = [('insert', list(members._mail_channel_member_format(fields={'id': True, 'channel': {}, 'persona': {'partner': {'id', 'name', 'im_status'}, 'guest': {'id', 'name', 'im_status'}}}).values()))] - self.env['bus.bus']._sendone(self.channel_id, 'mail.thread/insert', channel_data) + self.env['bus.bus']._sendone(self.channel_id, 'mail.record/insert', {'Thread': channel_data}) return members diff --git a/addons/mail/models/mail_channel_rtc_session.py b/addons/mail/models/mail_channel_rtc_session.py index 48296304ce3..366bc1c73b4 100644 --- a/addons/mail/models/mail_channel_rtc_session.py +++ b/addons/mail/models/mail_channel_rtc_session.py @@ -62,7 +62,7 @@ class MailRtcSession(models.Model): valid_values = {'is_screen_sharing_on', 'is_camera_on', 'is_muted', 'is_deaf'} self.write({key: values[key] for key in valid_values if key in valid_values}) session_data = self._mail_rtc_session_format() - self.env['bus.bus']._sendone(self.channel_id, 'mail.channel.rtc.session/insert', session_data) + self.env['bus.bus']._sendone(self.channel_id, 'mail.record/insert', {'RtcSession': session_data}) @api.autovacuum def _gc_inactive_sessions(self): diff --git a/addons/mail/models/mail_guest.py b/addons/mail/models/mail_guest.py index 1d2f668dade..7989995f1bf 100644 --- a/addons/mail/models/mail_guest.py +++ b/addons/mail/models/mail_guest.py @@ -85,8 +85,8 @@ class MailGuest(models.Model): 'id': self.id, 'name': self.name } - bus_notifs = [(channel, 'mail.guest/insert', guest_data) for channel in self.channel_ids] - bus_notifs.append((self, 'mail.guest/insert', guest_data)) + bus_notifs = [(channel, 'mail.record/insert', {'Guest': guest_data}) for channel in self.channel_ids] + bus_notifs.append((self, 'mail.record/insert', {'Guest': guest_data})) self.env['bus.bus']._sendmany(bus_notifs) def _update_timezone(self, timezone): diff --git a/addons/mail/models/mail_link_preview.py b/addons/mail/models/mail_link_preview.py index af38b02ec11..37073e6048c 100644 --- a/addons/mail/models/mail_link_preview.py +++ b/addons/mail/models/mail_link_preview.py @@ -49,7 +49,9 @@ class LinkPreview(models.Model): target = guest else: target = self.env.user.partner_id - self.env['bus.bus']._sendmany([(target, 'mail.link.preview/insert', link_previews._link_preview_format())]) + self.env['bus.bus']._sendone(target, 'mail.record/insert', { + 'LinkPreview': link_previews._link_preview_format() + }) @api.model def _create_link_preview(self, url, message_id, request_session): diff --git a/addons/mail/models/res_users_settings.py b/addons/mail/models/res_users_settings.py index 1e2550fea8c..69f3522e4c0 100644 --- a/addons/mail/models/res_users_settings.py +++ b/addons/mail/models/res_users_settings.py @@ -48,7 +48,7 @@ class ResUsersSettings(models.Model): if setting in self._fields and new_settings[setting] != self[setting]: changed_settings[setting] = new_settings[setting] self.write(changed_settings) - self.env['bus.bus']._sendone(self.user_id.partner_id, 'res.users.settings/insert', self._res_users_settings_format([*changed_settings.keys(), 'id'])) + self.env['bus.bus']._sendone(self.user_id.partner_id, 'mail.record/insert', {'res.users.settings': self._res_users_settings_format([*changed_settings.keys(), 'id'])}) def set_volume_setting(self, partner_id, volume, guest_id=None): """ @@ -71,4 +71,4 @@ class ResUsersSettings(models.Model): 'partner_id': partner_id, 'guest_id': guest_id, }) - self.env['bus.bus']._sendone(self.user_id.partner_id, 'res.users.settings.volumes/insert', volume_setting._discuss_users_settings_volume_format()) + self.env['bus.bus']._sendone(self.user_id.partner_id, 'mail.record/insert', {'res.users.settings.volumes': volume_setting._discuss_users_settings_volume_format()}) diff --git a/addons/mail/static/src/model/model_manager.js b/addons/mail/static/src/model/model_manager.js index 916d05f3f93..ae36ca3e78b 100644 --- a/addons/mail/static/src/model/model_manager.js +++ b/addons/mail/static/src/model/model_manager.js @@ -248,6 +248,32 @@ export class ModelManager { return isMulti ? records : records[0]; } + /** + * This method creates or updates records, based on provided data. This + * method assumes that records are uniquely identifiable per "unique find" + * criteria from data on model. + * + * @param {Object} data + * ```javascript + * { + * Partner: { + * ... + * }, + * Guest: [{ + * ... + * }] + * } + * ``` + * @returns void + */ + multiModelInsert(data) { + for (const [modelName, recordsData] of Object.entries(data)) { + const isMulti = typeof recordsData[Symbol.iterator] === 'function'; + this._insert(this.models[modelName], isMulti ? recordsData : [recordsData]); + } + this._flushUpdateCycle(); + } + /** * Returns the messaging singleton associated to this model manager. * diff --git a/addons/mail/static/src/models/messaging_notification_handler.js b/addons/mail/static/src/models/messaging_notification_handler.js index 28eed0a1ca1..381b449d098 100644 --- a/addons/mail/static/src/models/messaging_notification_handler.js +++ b/addons/mail/static/src/models/messaging_notification_handler.js @@ -47,8 +47,9 @@ registerModel({ const proms = notifications.map(message => { if (typeof message === 'object') { switch (message.type) { - case 'bus/im_status': - return this._handleNotificationBusImStatus(message.payload); + case 'mail.record/insert': + this.messaging.modelManager.multiModelInsert(message.payload); + break; case 'ir.attachment/delete': return this._handleNotificationAttachmentDelete(message.payload); case 'mail.channel.member/seen': @@ -70,9 +71,6 @@ registerModel({ return; } return this._handleNotificationChannelMessage(message.payload); - case 'mail.link.preview/insert': - this.messaging.models['LinkPreview'].insert(message.payload); - return; case 'mail.link.preview/delete': { const linkPreview = this.messaging.models['LinkPreview'].findFromIdentifyingData(message.payload); if (linkPreview) { @@ -117,26 +115,12 @@ registerModel({ return this._handleNotificationChannelLastInterestDateTimeChanged(message.payload); case 'mail.channel/legacy_insert': return this.messaging.models['Thread'].insert(this.messaging.models['Thread'].convertData({ model: 'mail.channel', ...message.payload })); - case 'mail.channel/insert': - return this.messaging.models['Channel'].insert(message.payload); - case 'mail.guest/insert': - return this.messaging.models['Guest'].insert(message.payload); - case 'mail.message/insert': - return this.messaging.models['Message'].insert(message.payload); - case 'mail.channel.rtc.session/insert': - return this.messaging.models['RtcSession'].insert(message.payload); case 'mail.channel.rtc.session/peer_notification': return this._handleNotificationRtcPeerToPeer(message.payload); case 'mail.channel/rtc_sessions_update': return this._handleNotificationRtcSessionUpdate(message.payload); case 'mail.channel.rtc.session/ended': return this._handleNotificationRtcSessionEnded(message.payload); - case 'mail.thread/insert': - return this.messaging.models['Thread'].insert(message.payload); - case 'res.users.settings/insert': - return this.messaging.models['res.users.settings'].insert(message.payload); - case 'res.users.settings.volumes/insert': - return this.messaging.models['res.users.settings.volumes'].insert(message.payload); default: return this._handleNotification(message); } @@ -156,14 +140,6 @@ registerModel({ * @param {Object[]} [payload.partners] * @param {Object[]|undefined} [payload.guests] */ - _handleNotificationBusImStatus({ partners, guests }) { - if (partners) { - this.models['Partner'].insert(partners); - } - if (guests) { - this.models['Guest'].insert(guests); - } - }, /** * @private * @param {Object} payload diff --git a/addons/mail/static/tests/helpers/mock_server/models/ir_websocket.js b/addons/mail/static/tests/helpers/mock_server/models/ir_websocket.js index f6e6cc80822..a1de48b9b3e 100644 --- a/addons/mail/static/tests/helpers/mock_server/models/ir_websocket.js +++ b/addons/mail/static/tests/helpers/mock_server/models/ir_websocket.js @@ -18,7 +18,7 @@ patch(MockServer.prototype, 'mail/models/ir_websocket', { const imStatus = this._super(imStatusIdsByModel); const { 'mail.guest': guestIds } = imStatusIdsByModel; if (guestIds) { - imStatus['guests'] = this.pyEnv['mail.guest'].searchRead([['id', 'in', guestIds]], { context: { 'active_test': false }, fields: ['im_status'] }); + imStatus['Guest'] = this.pyEnv['mail.guest'].searchRead([['id', 'in', guestIds]], { context: { 'active_test': false }, fields: ['im_status'] }); } return imStatus; }, diff --git a/addons/mail/static/tests/helpers/mock_server/models/mail_channel.js b/addons/mail/static/tests/helpers/mock_server/models/mail_channel.js index 740ae76ac81..e2cc7b808c0 100644 --- a/addons/mail/static/tests/helpers/mock_server/models/mail_channel.js +++ b/addons/mail/static/tests/helpers/mock_server/models/mail_channel.js @@ -309,10 +309,12 @@ patch(MockServer.prototype, 'mail/models/mail_channel', { is_minimized: foldState !== 'closed', }; this.pyEnv['mail.channel.member'].write([memberOfCurrentUser.id], vals); - this.pyEnv['bus.bus']._sendone(this.pyEnv.currentPartner, 'mail.thread/insert', { - 'id': channel.id, - 'model': 'mail.channel', - 'serverFoldState': memberOfCurrentUser.fold_state, + this.pyEnv['bus.bus']._sendone(this.pyEnv.currentPartner, 'mail.record/insert', { + 'Thread': { + 'id': channel.id, + 'model': 'mail.channel', + 'serverFoldState': memberOfCurrentUser.fold_state, + } }); } }, @@ -490,10 +492,12 @@ patch(MockServer.prototype, 'mail/models/mail_channel', { [channel.id], { name }, ); - this.pyEnv['bus.bus']._sendone(channel, 'mail.thread/insert', { - 'id': channel.id, - 'model': 'mail.channel', - 'name': name, + this.pyEnv['bus.bus']._sendone(channel, 'mail.record/insert', { + 'Thread': { + 'id': channel.id, + 'model': 'mail.channel', + 'name': name, + } }); }, /** @@ -509,9 +513,11 @@ patch(MockServer.prototype, 'mail/models/mail_channel', { [memberIdOfCurrentUser], { custom_channel_name: name }, ); - this.pyEnv['bus.bus']._sendone(this.pyEnv.currentPartner, 'mail.channel/insert', { - 'custom_channel_name': name, - 'id': channelId, + this.pyEnv['bus.bus']._sendone(this.pyEnv.currentPartner, 'mail.record/insert', { + 'Channel': { + 'custom_channel_name': name, + 'id': channelId, + } }); }, /** @@ -634,9 +640,11 @@ patch(MockServer.prototype, 'mail/models/mail_channel', { }, ); const channel = this.pyEnv['mail.channel'].searchRead([['id', '=', id]])[0]; - this.pyEnv['bus.bus']._sendone(channel, 'mail.channel/insert', { - 'avatarCacheKey': channel.avatarCacheKey, - 'id': id, + this.pyEnv['bus.bus']._sendone(channel, 'mail.record/insert', { + 'Channel': { + 'avatarCacheKey': channel.avatarCacheKey, + 'id': id, + } }); }, /** diff --git a/addons/mail/static/tests/helpers/mock_server/models/res_users_settings.js b/addons/mail/static/tests/helpers/mock_server/models/res_users_settings.js index 6557d34ffa4..5efe5145641 100644 --- a/addons/mail/static/tests/helpers/mock_server/models/res_users_settings.js +++ b/addons/mail/static/tests/helpers/mock_server/models/res_users_settings.js @@ -73,6 +73,6 @@ patch(MockServer.prototype, 'mail/models/res_users_settings', { ); const [relatedUser] = this.pyEnv['res.users'].searchRead([['id', '=', oldSettings.user_id]]); const [relatedPartner] = this.pyEnv['res.partner'].searchRead([['id', '=', relatedUser.partner_id]]); - this.pyEnv['bus.bus']._sendone(relatedPartner, 'res.users.settings/insert', { ...changedSettings, id }); + this.pyEnv['bus.bus']._sendone(relatedPartner, 'mail.record/insert', { 'res.users.settings': { ...changedSettings, id } }); }, }); diff --git a/addons/mail/static/tests/qunit_suite_tests/components/discuss_sidebar_category_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/discuss_sidebar_category_tests.js index 7ea799643e1..d5f38978412 100644 --- a/addons/mail/static/tests/qunit_suite_tests/components/discuss_sidebar_category_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/components/discuss_sidebar_category_tests.js @@ -316,9 +316,11 @@ QUnit.test('channel - states: close from the bus', async function (assert) { await openDiscuss(); await afterNextRender(() => { - pyEnv['bus.bus']._sendone(pyEnv.currentPartner, 'res.users.settings/insert', { - id: resUsersSettingsId1, - 'is_discuss_sidebar_category_channel_open': false, + pyEnv['bus.bus']._sendone(pyEnv.currentPartner, 'mail.record/insert', { + 'res.users.settings': { + id: resUsersSettingsId1, + 'is_discuss_sidebar_category_channel_open': false, + }, }); }); assert.containsNone( @@ -341,9 +343,11 @@ QUnit.test('channel - states: open from the bus', async function (assert) { await openDiscuss(); await afterNextRender(() => { - pyEnv['bus.bus']._sendone(pyEnv.currentPartner, 'res.users.settings/insert', { - id: resUsersSettingsId1, - 'is_discuss_sidebar_category_channel_open': true, + pyEnv['bus.bus']._sendone(pyEnv.currentPartner, 'mail.record/insert', { + 'res.users.settings': { + id: resUsersSettingsId1, + 'is_discuss_sidebar_category_channel_open': true, + }, }); }); assert.containsOnce( @@ -651,9 +655,11 @@ QUnit.test('chat - states: close from the bus', async function (assert) { await openDiscuss(); await afterNextRender(() => { - pyEnv['bus.bus']._sendone(pyEnv.currentPartner, 'res.users.settings/insert', { - id: resUsersSettingsId1, - 'is_discuss_sidebar_category_chat_open': false, + pyEnv['bus.bus']._sendone(pyEnv.currentPartner, 'mail.record/insert', { + 'res.users.settings': { + id: resUsersSettingsId1, + 'is_discuss_sidebar_category_chat_open': false, + }, }); }); assert.containsNone( @@ -678,9 +684,11 @@ QUnit.test('chat - states: open from the bus', async function (assert) { await openDiscuss(); await afterNextRender(() => { - pyEnv['bus.bus']._sendone(pyEnv.currentPartner, 'res.users.settings/insert', { - id: resUsersSettingsId1, - 'is_discuss_sidebar_category_chat_open': true, + pyEnv['bus.bus']._sendone(pyEnv.currentPartner, 'mail.record/insert', { + 'res.users.settings': { + id: resUsersSettingsId1, + 'is_discuss_sidebar_category_chat_open': true, + }, }); }); assert.containsOnce( diff --git a/addons/mail/tests/test_link_preview.py b/addons/mail/tests/test_link_preview.py index 7342afc43f9..00f73da973b 100644 --- a/addons/mail/tests/test_link_preview.py +++ b/addons/mail/tests/test_link_preview.py @@ -74,17 +74,19 @@ class TestLinkPreview(MailCommon): self.assertBusNotifications( [(self.cr.dbname, 'mail.channel', self.public_channel.id)], message_items=[{ - 'type': 'mail.link.preview/insert', - 'payload': [{ - 'id': link_preview.id, - 'message': {'id': message.id}, - 'image_mimetype': False, - 'og_description': 'Test description', - 'og_image': False, - 'og_mimetype': False, - 'og_title': 'Test title', - 'og_type': False, - 'source_url': 'https://thisdomainedoentexist.nothing', - } for link_preview in message.link_preview_ids] + 'type': 'mail.record/insert', + 'payload': { + 'LinkPreview': [{ + 'id': link_preview.id, + 'message': {'id': message.id}, + 'image_mimetype': False, + 'og_description': 'Test description', + 'og_image': False, + 'og_mimetype': False, + 'og_title': 'Test title', + 'og_type': False, + 'source_url': 'https://thisdomainedoentexist.nothing', + }] for link_preview in message.link_preview_ids + } }] ) diff --git a/addons/mail/tests/test_mail_channel.py b/addons/mail/tests/test_mail_channel.py index 7a364163d03..a7e09811f9a 100644 --- a/addons/mail/tests/test_mail_channel.py +++ b/addons/mail/tests/test_mail_channel.py @@ -526,10 +526,12 @@ class TestChannelInternals(MailCommon): with self.assertBus( [(self.cr.dbname, 'mail.channel', channel.id)], [{ - "type": "mail.channel/insert", + "type": "mail.record/insert", "payload": { - "avatarCacheKey": avatar_cache_key, - "id": channel.id, + 'Channel': { + "avatarCacheKey": avatar_cache_key, + "id": channel.id, + } }, }] ): diff --git a/addons/mail/tests/test_res_users_settings.py b/addons/mail/tests/test_res_users_settings.py index d58ee7489d7..07ffd74f778 100644 --- a/addons/mail/tests/test_res_users_settings.py +++ b/addons/mail/tests/test_res_users_settings.py @@ -35,10 +35,12 @@ class TestResUsersSettings(MailCommon): with self.assertBus( [(self.cr.dbname, 'res.partner', self.partner_employee.id)], [{ - 'type': 'res.users.settings/insert', + 'type': 'mail.record/insert', 'payload': { - 'id': settings.id, - 'is_discuss_sidebar_category_chat_open': True, + 'res.users.settings': { + 'id': settings.id, + 'is_discuss_sidebar_category_chat_open': True, + }, }, }]): settings.set_res_users_settings({'is_discuss_sidebar_category_chat_open': True}) diff --git a/addons/mail/tests/test_rtc.py b/addons/mail/tests/test_rtc.py index 9e4ded20a2b..8b222039c62 100644 --- a/addons/mail/tests/test_rtc.py +++ b/addons/mail/tests/test_rtc.py @@ -141,21 +141,23 @@ class TestChannelInternals(MailCommon): }, }, { - 'type': 'mail.thread/insert', + 'type': 'mail.record/insert', 'payload': { - 'id': channel.id, - 'model': 'mail.channel', - 'invitedMembers': [('insert', [{ - 'id': channel_member_test_user.id, - 'channel': {'id': channel_member_test_user.channel_id.id}, - 'persona': { - 'partner': { - 'id': channel_member_test_user.partner_id.id, - 'name': channel_member_test_user.partner_id.name, - 'im_status': channel_member_test_user.partner_id.im_status, + 'Thread': { + 'id': channel.id, + 'model': 'mail.channel', + 'invitedMembers': [('insert', [{ + 'id': channel_member_test_user.id, + 'channel': {'id': channel_member_test_user.channel_id.id}, + 'persona': { + 'partner': { + 'id': channel_member_test_user.partner_id.id, + 'name': channel_member_test_user.partner_id.name, + 'im_status': channel_member_test_user.partner_id.im_status, + }, }, - }, - }])], + }])], + } }, }, ] @@ -249,34 +251,36 @@ class TestChannelInternals(MailCommon): }, }, { - 'type': 'mail.thread/insert', + 'type': 'mail.record/insert', 'payload': { - 'id': channel.id, - 'model': 'mail.channel', - 'invitedMembers': [('insert', [ - { - 'id': channel_member_test_user.id, - 'channel': {'id': channel_member_test_user.channel_id.id}, - 'persona': { - 'partner': { - 'id': channel_member_test_user.partner_id.id, - 'name': channel_member_test_user.partner_id.name, - 'im_status': channel_member_test_user.partner_id.im_status, + 'Thread': { + 'id': channel.id, + 'model': 'mail.channel', + 'invitedMembers': [('insert', [ + { + 'id': channel_member_test_user.id, + 'channel': {'id': channel_member_test_user.channel_id.id}, + 'persona': { + 'partner': { + 'id': channel_member_test_user.partner_id.id, + 'name': channel_member_test_user.partner_id.name, + 'im_status': channel_member_test_user.partner_id.im_status, + }, }, }, - }, - { - 'id': channel_member_test_guest.id, - 'channel': {'id': channel_member_test_guest.channel_id.id}, - 'persona': { - 'guest': { - 'id': channel_member_test_guest.guest_id.id, - 'name': channel_member_test_guest.guest_id.name, - 'im_status': channel_member_test_guest.guest_id.im_status, + { + 'id': channel_member_test_guest.id, + 'channel': {'id': channel_member_test_guest.channel_id.id}, + 'persona': { + 'guest': { + 'id': channel_member_test_guest.guest_id.id, + 'name': channel_member_test_guest.guest_id.name, + 'im_status': channel_member_test_guest.guest_id.im_status, + }, }, }, - }, - ])], + ])], + } }, }, ] @@ -328,29 +332,33 @@ class TestChannelInternals(MailCommon): ], [ { - 'type': 'mail.thread/insert', + 'type': 'mail.record/insert', 'payload': { - 'id': channel.id, - 'model': 'mail.channel', - 'rtcInvitingSession': [('unlink',)], + 'Thread': { + 'id': channel.id, + 'model': 'mail.channel', + 'rtcInvitingSession': [('unlink',)], + } }, }, { - 'type': 'mail.thread/insert', + 'type': 'mail.record/insert', 'payload': { - 'id': channel.id, - 'model': 'mail.channel', - 'invitedMembers': [('insert-and-unlink', [{ - 'id': channel_member_test_user.id, - 'channel': {'id': channel_member_test_user.channel_id.id}, - 'persona': { - 'partner': { - 'id': channel_member_test_user.partner_id.id, - 'name': channel_member_test_user.partner_id.name, - 'im_status': channel_member_test_user.partner_id.im_status, + 'Thread': { + 'id': channel.id, + 'model': 'mail.channel', + 'invitedMembers': [('insert-and-unlink', [{ + 'id': channel_member_test_user.id, + 'channel': {'id': channel_member_test_user.channel_id.id}, + 'persona': { + 'partner': { + 'id': channel_member_test_user.partner_id.id, + 'name': channel_member_test_user.partner_id.name, + 'im_status': channel_member_test_user.partner_id.im_status, + }, }, - }, - }])], + }])], + } }, }, { @@ -393,29 +401,33 @@ class TestChannelInternals(MailCommon): ], [ { - 'type': 'mail.thread/insert', + 'type': 'mail.record/insert', 'payload': { - 'id': channel.id, - 'model': 'mail.channel', - 'rtcInvitingSession': [('unlink',)], + 'Thread': { + 'id': channel.id, + 'model': 'mail.channel', + 'rtcInvitingSession': [('unlink',)], + } }, }, { - 'type': 'mail.thread/insert', + 'type': 'mail.record/insert', 'payload': { - 'id': channel.id, - 'model': 'mail.channel', - 'invitedMembers': [('insert-and-unlink', [{ - 'id': channel_member_test_guest.id, - 'channel': {'id': channel_member_test_guest.channel_id.id}, - 'persona': { - 'guest': { - 'id': channel_member_test_guest.guest_id.id, - 'name': channel_member_test_guest.guest_id.name, - 'im_status': channel_member_test_guest.guest_id.im_status, + 'Thread': { + 'id': channel.id, + 'model': 'mail.channel', + 'invitedMembers': [('insert-and-unlink', [{ + 'id': channel_member_test_guest.id, + 'channel': {'id': channel_member_test_guest.channel_id.id}, + 'persona': { + 'guest': { + 'id': channel_member_test_guest.guest_id.id, + 'name': channel_member_test_guest.guest_id.name, + 'im_status': channel_member_test_guest.guest_id.im_status, + }, }, - }, - }])], + }])], + } }, }, { @@ -467,29 +479,33 @@ class TestChannelInternals(MailCommon): ], [ { - 'type': 'mail.thread/insert', + 'type': 'mail.record/insert', 'payload': { - 'id': channel.id, - 'model': 'mail.channel', - 'rtcInvitingSession': [('unlink',)], + 'Thread': { + 'id': channel.id, + 'model': 'mail.channel', + 'rtcInvitingSession': [('unlink',)], + } }, }, { - 'type': 'mail.thread/insert', + 'type': 'mail.record/insert', 'payload': { - 'id': channel.id, - 'model': 'mail.channel', - 'invitedMembers': [('insert-and-unlink', [{ - 'id': channel_member_test_user.id, - 'channel': {'id': channel_member_test_user.channel_id.id}, - 'persona': { - 'partner': { - 'id': channel_member_test_user.partner_id.id, - 'name': channel_member_test_user.partner_id.name, - 'im_status': channel_member_test_user.partner_id.im_status, + 'Thread': { + 'id': channel.id, + 'model': 'mail.channel', + 'invitedMembers': [('insert-and-unlink', [{ + 'id': channel_member_test_user.id, + 'channel': {'id': channel_member_test_user.channel_id.id}, + 'persona': { + 'partner': { + 'id': channel_member_test_user.partner_id.id, + 'name': channel_member_test_user.partner_id.name, + 'im_status': channel_member_test_user.partner_id.im_status, + }, }, - }, - }])], + }])], + } }, }, ] @@ -505,29 +521,33 @@ class TestChannelInternals(MailCommon): ], [ { - 'type': 'mail.thread/insert', + 'type': 'mail.record/insert', 'payload': { - 'id': channel.id, - 'model': 'mail.channel', - 'rtcInvitingSession': [('unlink',)], + 'Thread': { + 'id': channel.id, + 'model': 'mail.channel', + 'rtcInvitingSession': [('unlink',)], + } }, }, { - 'type': 'mail.thread/insert', + 'type': 'mail.record/insert', 'payload': { - 'id': channel.id, - 'model': 'mail.channel', - 'invitedMembers': [('insert-and-unlink', [{ - 'id': channel_member_test_guest.id, - 'channel': {'id': channel_member_test_guest.channel_id.id}, - 'persona': { - 'guest': { - 'id': channel_member_test_guest.guest_id.id, - 'name': channel_member_test_guest.guest_id.name, - 'im_status': channel_member_test_guest.guest_id.im_status, + 'Thread': { + 'id': channel.id, + 'model': 'mail.channel', + 'invitedMembers': [('insert-and-unlink', [{ + 'id': channel_member_test_guest.id, + 'channel': {'id': channel_member_test_guest.channel_id.id}, + 'persona': { + 'guest': { + 'id': channel_member_test_guest.guest_id.id, + 'name': channel_member_test_guest.guest_id.name, + 'im_status': channel_member_test_guest.guest_id.im_status, + }, }, - }, - }])], + }])], + } }, }, ] @@ -563,50 +583,56 @@ class TestChannelInternals(MailCommon): }, }, { - 'type': 'mail.thread/insert', + 'type': 'mail.record/insert', 'payload': { - 'id': channel.id, - 'model': 'mail.channel', - 'rtcInvitingSession': [('unlink',)], + 'Thread': { + 'id': channel.id, + 'model': 'mail.channel', + 'rtcInvitingSession': [('unlink',)], + } }, }, { - 'type': 'mail.thread/insert', + 'type': 'mail.record/insert', 'payload': { - 'id': channel.id, - 'model': 'mail.channel', - 'rtcInvitingSession': [('unlink',)], + 'Thread': { + 'id': channel.id, + 'model': 'mail.channel', + 'rtcInvitingSession': [('unlink',)], + } }, }, { - 'type': 'mail.thread/insert', + 'type': 'mail.record/insert', 'payload': { - 'id': channel.id, - 'model': 'mail.channel', - 'invitedMembers': [('insert-and-unlink', [ - { - 'id': channel_member_test_user.id, - 'channel': {'id': channel_member_test_user.channel_id.id}, - 'persona': { - 'partner': { - 'id': channel_member_test_user.partner_id.id, - 'name': channel_member_test_user.partner_id.name, - 'im_status': channel_member_test_user.partner_id.im_status, + 'Thread': { + 'id': channel.id, + 'model': 'mail.channel', + 'invitedMembers': [('insert-and-unlink', [ + { + 'id': channel_member_test_user.id, + 'channel': {'id': channel_member_test_user.channel_id.id}, + 'persona': { + 'partner': { + 'id': channel_member_test_user.partner_id.id, + 'name': channel_member_test_user.partner_id.name, + 'im_status': channel_member_test_user.partner_id.im_status, + }, }, }, - }, - { - 'id': channel_member_test_guest.id, - 'channel': {'id': channel_member_test_guest.channel_id.id}, - 'persona': { - 'guest': { - 'id': channel_member_test_guest.guest_id.id, - 'name': channel_member_test_guest.guest_id.name, - 'im_status': channel_member_test_guest.guest_id.im_status, + { + 'id': channel_member_test_guest.id, + 'channel': {'id': channel_member_test_guest.channel_id.id}, + 'persona': { + 'guest': { + 'id': channel_member_test_guest.guest_id.id, + 'name': channel_member_test_guest.guest_id.name, + 'im_status': channel_member_test_guest.guest_id.im_status, + }, }, }, - }, - ])], + ])], + } }, }, { @@ -652,84 +678,90 @@ class TestChannelInternals(MailCommon): ], message_items=[ { - 'type': 'mail.thread/insert', + 'type': 'mail.record/insert', 'payload': { - 'id': channel.id, - 'model': 'mail.channel', - 'rtcInvitingSession': { - 'id': channel_member.rtc_session_ids.id, - 'channelMember': { - "id": channel_member.id, - "channel": {"id": channel_member.channel_id.id}, - "persona": { - "partner": { - "id": channel_member.partner_id.id, - "name": channel_member.partner_id.name, - "im_status": channel_member.partner_id.im_status, + 'Thread': { + 'id': channel.id, + 'model': 'mail.channel', + 'rtcInvitingSession': { + 'id': channel_member.rtc_session_ids.id, + 'channelMember': { + "id": channel_member.id, + "channel": {"id": channel_member.channel_id.id}, + "persona": { + "partner": { + "id": channel_member.partner_id.id, + "name": channel_member.partner_id.name, + "im_status": channel_member.partner_id.im_status, + }, }, }, + 'isCameraOn': False, + 'isDeaf': False, + 'isSelfMuted': False, + 'isScreenSharingOn': False, }, - 'isCameraOn': False, - 'isDeaf': False, - 'isSelfMuted': False, - 'isScreenSharingOn': False, - }, + } }, }, { - 'type': 'mail.thread/insert', + 'type': 'mail.record/insert', 'payload': { - 'id': channel.id, - 'model': 'mail.channel', - 'rtcInvitingSession': { - 'id': channel_member.rtc_session_ids.id, - 'channelMember': { - "id": channel_member.id, - "channel": {"id": channel_member.channel_id.id}, - "persona": { - "partner": { - "id": channel_member.partner_id.id, - "name": channel_member.partner_id.name, - "im_status": channel_member.partner_id.im_status, + 'Thread': { + 'id': channel.id, + 'model': 'mail.channel', + 'rtcInvitingSession': { + 'id': channel_member.rtc_session_ids.id, + 'channelMember': { + "id": channel_member.id, + "channel": {"id": channel_member.channel_id.id}, + "persona": { + "partner": { + "id": channel_member.partner_id.id, + "name": channel_member.partner_id.name, + "im_status": channel_member.partner_id.im_status, + }, }, }, + 'isCameraOn': False, + 'isDeaf': False, + 'isSelfMuted': False, + 'isScreenSharingOn': False, }, - 'isCameraOn': False, - 'isDeaf': False, - 'isSelfMuted': False, - 'isScreenSharingOn': False, - }, + } }, }, { - 'type': 'mail.thread/insert', + 'type': 'mail.record/insert', 'payload': { - 'id': channel.id, - 'model': 'mail.channel', - 'invitedMembers': [('insert', [ - { - 'id': channel_member_test_user.id, - 'channel': {'id': channel_member_test_user.channel_id.id}, - 'persona': { - 'partner': { - 'id': channel_member_test_user.partner_id.id, - 'name': channel_member_test_user.partner_id.name, - 'im_status': channel_member_test_user.partner_id.im_status, + 'Thread': { + 'id': channel.id, + 'model': 'mail.channel', + 'invitedMembers': [('insert', [ + { + 'id': channel_member_test_user.id, + 'channel': {'id': channel_member_test_user.channel_id.id}, + 'persona': { + 'partner': { + 'id': channel_member_test_user.partner_id.id, + 'name': channel_member_test_user.partner_id.name, + 'im_status': channel_member_test_user.partner_id.im_status, + }, }, }, - }, - { - 'id': channel_member_test_guest.id, - 'channel': {'id': channel_member_test_guest.channel_id.id}, - 'persona': { - 'guest': { - 'id': channel_member_test_guest.guest_id.id, - 'name': channel_member_test_guest.guest_id.name, - 'im_status': channel_member_test_guest.guest_id.im_status, + { + 'id': channel_member_test_guest.id, + 'channel': {'id': channel_member_test_guest.channel_id.id}, + 'persona': { + 'guest': { + 'id': channel_member_test_guest.guest_id.id, + 'name': channel_member_test_guest.guest_id.name, + 'im_status': channel_member_test_guest.guest_id.im_status, + }, }, }, - }, - ])], + ])], + } }, }, ],