diff --git a/addons/hr_holidays/tests/test_out_of_office.py b/addons/hr_holidays/tests/test_out_of_office.py index 6828acd6721..567ceabff66 100644 --- a/addons/hr_holidays/tests/test_out_of_office.py +++ b/addons/hr_holidays/tests/test_out_of_office.py @@ -46,7 +46,6 @@ class TestOutOfOffice(TestHrHolidaysCommon): 'mail_create_nosubscribe': True, }).create({ 'channel_partner_ids': [(4, partner.id), (4, partner2.id)], - 'public': 'private', 'channel_type': 'chat', 'name': 'test' }) diff --git a/addons/im_livechat/models/im_livechat_channel.py b/addons/im_livechat/models/im_livechat_channel.py index b3f99054ce9..1d88f924fa6 100644 --- a/addons/im_livechat/models/im_livechat_channel.py +++ b/addons/im_livechat/models/im_livechat_channel.py @@ -159,7 +159,6 @@ class ImLivechatChannel(models.Model): 'country_id': country_id, 'channel_type': 'livechat', 'name': name, - 'public': 'private', } def _open_livechat_mail_channel(self, anonymous_name, previous_operator_id=None, chatbot_script=None, user_id=None, country_id=None): diff --git a/addons/im_livechat/static/tests/helpers/mock_server.js b/addons/im_livechat/static/tests/helpers/mock_server.js index e8ea9cbb6d7..e7109d2ccbf 100644 --- a/addons/im_livechat/static/tests/helpers/mock_server.js +++ b/addons/im_livechat/static/tests/helpers/mock_server.js @@ -136,7 +136,6 @@ patch(MockServer.prototype, 'im_livechat', { 'country_id': country_id, 'channel_type': 'livechat', 'name': membersName.join(' '), - 'public': 'private', }; }, /** diff --git a/addons/mail/controllers/discuss.py b/addons/mail/controllers/discuss.py index b3e96cd452b..5adbbe1b001 100644 --- a/addons/mail/controllers/discuss.py +++ b/addons/mail/controllers/discuss.py @@ -54,9 +54,9 @@ class DiscussController(http.Controller): if not channel_sudo: try: channel_sudo = channel_sudo.create({ + 'channel_type': 'channel', 'default_display_mode': default_display_mode, 'name': channel_name or create_token, - 'public': 'public', 'uuid': create_token, }) except IntegrityError as e: @@ -93,7 +93,7 @@ class DiscussController(http.Controller): except UserError: raise NotFound() else: - if channel_sudo.public == 'groups': + if channel_sudo.group_public_id: raise NotFound() guest = channel_sudo.env['mail.guest'].create({ 'country_id': channel_sudo.env['res.country'].search([('code', '=', request.geoip.get('country_code'))], limit=1).id, diff --git a/addons/mail/models/mail_channel.py b/addons/mail/models/mail_channel.py index ff0e3f8edd1..4ffd8d345a9 100644 --- a/addons/mail/models/mail_channel.py +++ b/addons/mail/models/mail_channel.py @@ -75,12 +75,6 @@ class Channel(models.Model): "if necessary.") # access uuid = fields.Char('UUID', size=50, default=_generate_random_token, copy=False) - public = fields.Selection([ - ('public', 'Everyone'), - ('private', 'Invited people only'), - ('groups', 'Selected group of users')], string='Privacy', - required=True, default='groups', - help='This group is visible by non members. Invisible groups can add members through the invite button.') group_public_id = fields.Many2one('res.groups', string='Authorized Group', compute='_compute_group_public_id', readonly=False, store=True) invitation_url = fields.Char('Invitation URL', compute='_compute_invitation_url') @@ -216,9 +210,6 @@ class Channel(models.Model): @api.model_create_multi def create(self, vals_list): - defaults = self.default_get(['public']) - - access_types = [] for vals in vals_list: # find partners to add from partner_ids partner_ids_cmd = vals.get('channel_partner_ids') or [] @@ -241,21 +232,11 @@ class Channel(models.Model): for pid in partner_ids_to_add if pid not in membership_pids ] - # save visibility, apply public visibility for create then set back after creation - # to avoid ACLS issue - access_type = vals.pop('public', defaults['public']) - access_types.append(access_type) - vals['public'] = 'public' - # clean vals vals.pop('channel_partner_ids', False) # Create channel and alias - channels = super(Channel, self.with_context(mail_create_nolog=True, mail_create_nosubscribe=True)).create(vals_list) - - for access_type, channel in zip(access_types, channels): - if access_type != 'public': - channel.sudo().public = access_type + channels = super(Channel, self.with_context(mail_create_bypass_create_check=self.env['mail.channel.member']._bypass_create_check, mail_create_nolog=True, mail_create_nosubscribe=True)).create(vals_list) channels._subscribe_users_automatically() @@ -355,7 +336,7 @@ class Channel(models.Model): notifications = [] for channel in self: members_to_create = [] - if channel.public == 'groups': + if channel.group_public_id: invalid_partners = partners.filtered(lambda partner: channel.group_public_id not in partner.user_ids.groups_id) if invalid_partners: raise UserError(_( @@ -438,17 +419,17 @@ class Channel(models.Model): def _can_invite(self, partner_id): """Return True if the current user can invite the partner to the channel. - * public: ok; - * private: must be member; - * group: both current user and target must have group; + * channel -- public channel: ok; + * -- group restricted channel: both current user and target must in the group; + * chat/group: current user must be member; :return boolean: whether inviting is ok""" partner = self.env['res.partner'].browse(partner_id) for channel in self.sudo(): - if channel.public == 'private' and not channel.is_member: + if channel.channel_type != 'channel' and not channel.is_member: return False - if channel.public == 'groups': + if channel.group_public_id: if not partner.user_ids or channel.group_public_id not in partner.user_ids.groups_id: return False if channel.group_public_id not in self.env.user.groups_id: @@ -792,7 +773,6 @@ class Channel(models.Model): 'uuid': channel.uuid, 'state': 'open', 'is_minimized': False, - 'public': channel.public, 'group_based_subscription': bool(channel.group_ids), 'create_uid': channel.create_uid.id, 'authorizedGroupFullName': channel.group_public_id.full_name, @@ -883,7 +863,6 @@ class Channel(models.Model): SELECT M.channel_id FROM mail_channel C, mail_channel_member M WHERE M.channel_id = C.id - AND C.public LIKE 'private' AND M.partner_id IN %s AND C.channel_type LIKE 'chat' AND NOT EXISTS ( @@ -911,7 +890,6 @@ class Channel(models.Model): # create a new one channel = self.create({ 'channel_partner_ids': [Command.link(partner_id) for partner_id in partners_to], - 'public': 'private', 'channel_type': 'chat', 'name': ', '.join(self.env['res.partner'].sudo().browse(partners_to).mapped('name')), }) @@ -1051,25 +1029,6 @@ class Channel(models.Model): 'model': 'mail.channel', }) - @api.model - def channel_search_to_join(self, name=None, domain=None): - """ Return the channel info of the channel the current partner can join - :param name : the name of the researched channels - :param domain : the base domain of the research - :returns dict : channel dict - """ - if not domain: - domain = [] - domain = expression.AND([ - [('channel_type', '=', 'channel')], - [('channel_partner_ids', 'not in', [self.env.user.partner_id.id])], - [('public', '!=', 'private')], - domain - ]) - if name: - domain = expression.AND([domain, [('name', 'ilike', '%'+name+'%')]]) - return self.search(domain).read(['name', 'public', 'uuid', 'channel_type']) - def channel_join(self): """ Shortcut to add the current user as member of self channels. Prefer calling add_members() directly when possible. @@ -1077,11 +1036,10 @@ class Channel(models.Model): self.add_members(self.env.user.partner_id.ids) @api.model - def channel_create(self, name, group_id, privacy='groups'): + def channel_create(self, name, group_id): """ Create a channel and add the current partner, broadcast it (to make the user directly listen to it when polling) :param name : the name of the channel to create - :param privacy : privacy of the channel. Should be 'public', 'private' or 'groups'. :param group_id : the group allowed to join the channel. :return dict : channel header """ @@ -1089,7 +1047,6 @@ class Channel(models.Model): vals = { 'channel_type': 'channel', 'name': name, - 'public': privacy, } new_channel = self.create(vals) group = self.env['res.groups'].search([('id', '=', group_id)]) if group_id else None @@ -1115,33 +1072,29 @@ class Channel(models.Model): 'channel_type': 'group', 'default_display_mode': default_display_mode, 'name': name, - 'public': 'private', }) channel._broadcast(partners_to) return channel.channel_info()[0] @api.model def get_mention_suggestions(self, search, limit=8): - """ Return 'limit'-first channels' id, name and public fields such that the name matches a - 'search' string. Exclude channels of type chat (DM), and private channels the current - user isn't registered to. """ + """ Return 'limit'-first channels' id, name, channel_type and authorizedGroupFullName fields such that the + name matches a 'search' string. Exclude channels of type chat (DM) and group. + """ domain = expression.AND([ [('name', 'ilike', search)], [('channel_type', '=', 'channel')], - expression.OR([ - [('public', '!=', 'private')], - [('channel_partner_ids', 'in', [self.env.user.partner_id.id])] - ]) + [('channel_partner_ids', 'in', [self.env.user.partner_id.id])] ]) channels = self.search(domain, limit=limit) return [{ + 'authorizedGroupFullName': channel.group_public_id.full_name, 'channel': { 'channel_type': channel.channel_type, 'id': channel.id, }, 'id': channel.id, 'name': channel.name, - 'public': channel.public, } for channel in channels] def channel_fetch_preview(self): @@ -1208,8 +1161,6 @@ class Channel(models.Model): partner = self.env.user.partner_id if self.channel_type == 'channel': msg = _("You are in channel #%s.", self.name) - if self.public == 'private': - msg += _(" This channel is private. People must be invited to join it.") else: all_channel_members = self.env['mail.channel.member'].with_context(active_test=False) channel_members = all_channel_members.search([('partner_id', '!=', partner.id), ('channel_id', '=', self.id)]) diff --git a/addons/mail/models/mail_channel_member.py b/addons/mail/models/mail_channel_member.py index 842f40246ac..3df2841f661 100644 --- a/addons/mail/models/mail_channel_member.py +++ b/addons/mail/models/mail_channel_member.py @@ -12,6 +12,7 @@ class ChannelMember(models.Model): _description = 'Listeners of a Channel' _table = 'mail_channel_member' _rec_names_search = ['partner_id', 'guest_id'] + _bypass_create_check = {} # identity partner_id = fields.Many2one('res.partner', string='Recipient', ondelete='cascade', index=True) @@ -75,7 +76,7 @@ class ChannelMember(models.Model): partner will be added in the channel and the security rule will always authorize the creation. """ - if not self.env.is_admin(): + if not self.env.is_admin() and not self.env.context.get('mail_create_bypass_create_check') is self._bypass_create_check: for vals in vals_list: if 'channel_id' in vals: channel_id = self.env['mail.channel'].browse(vals['channel_id']) diff --git a/addons/mail/models/res_partner.py b/addons/mail/models/res_partner.py index ab16d9093b9..8791059b145 100644 --- a/addons/mail/models/res_partner.py +++ b/addons/mail/models/res_partner.py @@ -186,7 +186,7 @@ class Partner(models.Model): if channel_id: channel = self.env['mail.channel'].search([('id', '=', int(channel_id))]) domain = expression.AND([domain, [('channel_ids', 'not in', channel.id)]]) - if channel.public == 'groups': + if channel.group_public_id: domain = expression.AND([domain, [('user_ids.groups_id', 'in', channel.group_public_id.id)]]) query = self.env['res.partner']._search(domain, order='name, id') query.order = 'LOWER("res_partner"."name"), "res_partner"."id"' # bypass lack of support for case insensitive order in search() diff --git a/addons/mail/models/res_users.py b/addons/mail/models/res_users.py index 714c5c5de20..1d460df266b 100644 --- a/addons/mail/models/res_users.py +++ b/addons/mail/models/res_users.py @@ -128,8 +128,8 @@ class Users(models.Model): return super().unlink() def _unsubscribe_from_non_public_channels(self): - """ This method un-subscribes users from private mail channels. Main purpose of this - method is to prevent sending internal communication to archived / deleted users. + """ This method un-subscribes users from group restricted channels. Main purpose + of this method is to prevent sending internal communication to archived / deleted users. We do not un-subscribes users from public channels because in most common cases, public channels are mailing list (e-mail based) and so users should always receive updates from public channels until they manually un-subscribe themselves. @@ -138,7 +138,7 @@ class Users(models.Model): ('partner_id', 'in', self.partner_id.ids), ]) current_cm.filtered( - lambda cm: cm.channel_id.public != 'public' and cm.channel_id.channel_type == 'channel' + lambda cm: (cm.channel_id.channel_type == 'channel' and cm.channel_id.group_public_id) ).unlink() def _get_portal_access_update_body(self, access_granted): diff --git a/addons/mail/security/mail_security.xml b/addons/mail/security/mail_security.xml index 8a47ad2b406..d924f1aa0e1 100644 --- a/addons/mail/security/mail_security.xml +++ b/addons/mail/security/mail_security.xml @@ -6,10 +6,17 @@ Mail.channel: access only public and joined groups - ['|', '|', -('public', '=', 'public'), -'&', ('public', '=', 'private'), ('is_member', '=', True), -'&', ('public', '=', 'groups'), ('group_public_id', 'in', [g.id for g in user.groups_id])] + [ + '|', + '&', + ('channel_type', '!=', 'channel'), + ('is_member', '=', True), + '&', + ('channel_type', '=', 'channel'), + '|', + ('group_public_id', '=', False), + ('group_public_id', 'in', [g.id for g in user.groups_id])] + @@ -24,10 +31,17 @@ mail.channel.member: write its own entries - ['|', '|', -('channel_id.public', '=', 'public'), -'&', ('channel_id.public', '=', 'private'), ('channel_id.is_member', '=', True), -'&', ('channel_id.public', '=', 'groups'), ('channel_id.group_public_id', 'in', [g.id for g in user.groups_id])] + [ + '|', + '&', + ('channel_id.channel_type', '!=', 'channel'), + ('channel_id.is_member', '=', True), + '&', + ('channel_id.channel_type', '=', 'channel'), + '|', + ('channel_id.group_public_id', '=', False), + ('channel_id.group_public_id', 'in', [g.id for g in user.groups_id])] + diff --git a/addons/mail/static/src/components/thread_icon/thread_icon.xml b/addons/mail/static/src/components/thread_icon/thread_icon.xml index 0a395c29992..b67fc0296cb 100644 --- a/addons/mail/static/src/components/thread_icon/thread_icon.xml +++ b/addons/mail/static/src/components/thread_icon/thread_icon.xml @@ -5,14 +5,11 @@
- -
+ +
- -
- - -
+ +
diff --git a/addons/mail/static/src/models/channel_invitation_form.js b/addons/mail/static/src/models/channel_invitation_form.js index 76171838701..9cd2f57be3e 100644 --- a/addons/mail/static/src/models/channel_invitation_form.js +++ b/addons/mail/static/src/models/channel_invitation_form.js @@ -166,10 +166,7 @@ registerModel({ if (!this.thread) { return clear(); } - if ( - !this.thread.authorizedGroupFullName || - this.thread.public !== 'groups' - ) { + if (!this.thread.authorizedGroupFullName) { return clear(); } return sprintf( diff --git a/addons/mail/static/src/models/discuss.js b/addons/mail/static/src/models/discuss.js index 715eaa16215..eb92377c87f 100644 --- a/addons/mail/static/src/models/discuss.js +++ b/addons/mail/static/src/models/discuss.js @@ -38,11 +38,10 @@ registerModel({ ev.preventDefault(); const name = this.addingChannelValue; this.clearIsAddingItem(); - if (ui.item.special) { + if (ui.item.create) { const channel = await this.messaging.models['Thread'].performRpcCreateChannel({ name, - group_id: ui.item.special === 'private' ? false : this.messaging.internalUserGroupId, - privacy: ui.item.special === 'private' ? 'private' : 'groups', + group_id: this.messaging.internalUserGroupId, }); channel.open(); } else { @@ -77,19 +76,12 @@ registerModel({ // XDU FIXME could use a component but be careful with owl's // renderToString https://github.com/odoo/owl/issues/708 items.push({ + create: true, + escapedValue, label: sprintf( `${this.env._t('Create %s')}`, `${escapedValue}`, ), - escapedValue, - special: 'public' - }, { - label: sprintf( - `${this.env._t('Create %s')}`, - `${escapedValue}`, - ), - escapedValue, - special: 'private' }); res(items); }, diff --git a/addons/mail/static/src/models/discuss_sidebar_category.js b/addons/mail/static/src/models/discuss_sidebar_category.js index 825c4b411d4..bf1ef6fd58c 100644 --- a/addons/mail/static/src/models/discuss_sidebar_category.js +++ b/addons/mail/static/src/models/discuss_sidebar_category.js @@ -314,7 +314,7 @@ registerModel({ type: 'ir.actions.act_window', res_model: 'mail.channel', views: [[false, 'kanban'], [false, 'form']], - domain: [['public', '!=', 'private']], + domain: [['channel_type', '=', 'channel']], }); }, /** diff --git a/addons/mail/static/src/models/discuss_sidebar_category_item.js b/addons/mail/static/src/models/discuss_sidebar_category_item.js index 918d7b33e6c..01b8147458c 100644 --- a/addons/mail/static/src/models/discuss_sidebar_category_item.js +++ b/addons/mail/static/src/models/discuss_sidebar_category_item.js @@ -109,7 +109,7 @@ registerModel({ } switch (this.channel.channel_type) { case 'channel': - return ['private', 'public'].includes(this.thread.public); + return !Boolean(this.thread.authorizedGroupFullName); case 'chat': return true; case 'group': diff --git a/addons/mail/static/src/models/partner.js b/addons/mail/static/src/models/partner.js index 3d680c99c7c..990b7186bee 100644 --- a/addons/mail/static/src/models/partner.js +++ b/addons/mail/static/src/models/partner.js @@ -19,7 +19,7 @@ registerModel({ */ async fetchSuggestions(searchTerm, { thread } = {}) { const kwargs = { search: searchTerm }; - const isNonPublicChannel = thread && thread.model === 'mail.channel' && thread.public !== 'public'; + const isNonPublicChannel = thread && thread.model === 'mail.channel' && (thread.authorizedGroupFullName || thread.channel.channel_type !== 'channel'); if (isNonPublicChannel) { kwargs.channel_id = thread.id; } @@ -153,10 +153,10 @@ registerModel({ */ searchSuggestions(searchTerm, { thread } = {}) { let partners; - const isNonPublicChannel = thread && thread.channel && thread.public !== 'public'; + const isNonPublicChannel = thread && thread.channel && (thread.authorizedGroupFullName || thread.channel.channel_type !== 'channel'); if (isNonPublicChannel) { // Only return the channel members when in the context of a - // non-public channel. Indeed, the message with the mention + // group restricted channel. Indeed, the message with the mention // would be notified to the mentioned partner, so this prevents // from inadvertently leaking the private message to the // mentioned partner. diff --git a/addons/mail/static/src/models/thread.js b/addons/mail/static/src/models/thread.js index d4c4b0a4a91..16423bfe20c 100644 --- a/addons/mail/static/src/models/thread.js +++ b/addons/mail/static/src/models/thread.js @@ -96,9 +96,6 @@ registerModel({ if ('name' in data) { data2.name = data.name; } - if ('public' in data) { - data2.public = data.public; - } if ('seen_message_id' in data) { data2.rawLastSeenByCurrentPartnerMessageId = data.seen_message_id; } @@ -206,12 +203,12 @@ registerModel({ getSuggestionSortFunction(searchTerm, { thread } = {}) { const cleanedSearchTerm = cleanSearchTerm(searchTerm); return (a, b) => { - const isAPublic = a.model === 'mail.channel' && a.public === 'public'; - const isBPublic = b.model === 'mail.channel' && b.public === 'public'; - if (isAPublic && !isBPublic) { + const isAPublicChannel = a.model === 'mail.channel' && a.channel.channel_type === 'channel' && (!a.authorizedGroupFullName); + const isBPublicChannel = b.model === 'mail.channel' && b.channel.channel_type === 'channel' && (!b.authorizedGroupFullName); + if (isAPublicChannel && !isBPublicChannel) { return -1; } - if (!isAPublic && isBPublic) { + if (!isAPublicChannel && isBPublicChannel) { return 1; } const isMemberOfA = a.channel && a.channel.memberOfCurrentUser; @@ -336,14 +333,14 @@ registerModel({ * * @param {Object} param0 * @param {string} param0.name - * @param {string} [param0.privacy] + * @param {integer} param0.group_id * @returns {Thread} the created channel */ - async performRpcCreateChannel({ name, group_id, privacy }) { + async performRpcCreateChannel({ name, group_id }) { const data = await this.messaging.rpc({ model: 'mail.channel', method: 'channel_create', - args: [name, group_id, privacy], + args: [name, group_id], }); return this.messaging.models['Thread'].insert( this.messaging.models['Thread'].convertData(data) @@ -396,9 +393,9 @@ registerModel({ */ searchSuggestions(searchTerm, { thread } = {}) { let threads; - if (thread && thread.model === 'mail.channel' && thread.public !== 'public') { + if (thread && thread.model === 'mail.channel' && (thread.channel.channel_type !== 'channel' || (thread.channel.channel_type === 'channel' && thread.authorizedGroupFullName))) { // Only return the current channel when in the context of a - // non-public channel. Indeed, the message with the mention + // group restricted channel or group or chat. Indeed, the message with the mention // would appear in the target channel, so this prevents from // inadvertently leaking the private message into the mentioned // channel. @@ -974,6 +971,19 @@ registerModel({ this.messaging.chatWindowManager.closeThread(this); this.unpin(); }, + /** + * @private + * @returns {string|FieldCommand} + */ + _computeAccessRestrictedToGroupText() { + if (!this.authorizedGroupFullName) { + return clear(); + } + return sprintf( + this.env._t('Access restricted to group "%(groupFullName)s"'), + { 'groupFullName': this.authorizedGroupFullName } + ); + }, /** * @private * @returns {Attachment[]} @@ -1547,6 +1557,10 @@ registerModel({ }, }, fields: { + accessRestrictedToGroupText: attr({ + compute: '_computeAccessRestrictedToGroupText', + default: '', + }), /** * Determines the `mail.activity` that belong to `this`, assuming `this` * has activities (@see hasActivities). @@ -1993,7 +2007,6 @@ registerModel({ * server. */ pendingSeenMessageId: attr(), - public: attr(), rawLastSeenByCurrentPartnerMessageId: attr({ default: 0, }), diff --git a/addons/mail/static/tests/helpers/mock_server.js b/addons/mail/static/tests/helpers/mock_server.js index bc671b6485c..744990ab00f 100644 --- a/addons/mail/static/tests/helpers/mock_server.js +++ b/addons/mail/static/tests/helpers/mock_server.js @@ -989,7 +989,6 @@ patch(MockServer.prototype, 'mail', { }]), channel_type: 'chat', name: partners.map(partner => partner.name).join(", "), - public: 'private', }); return this._mockMailChannelChannelInfo([id])[0]; }, @@ -1174,7 +1173,6 @@ patch(MockServer.prototype, 'mail', { channel_type: 'group', channel_member_ids: partners.map(partner => [0, 0, { partner_id: partner.id }]), name: '', - public: 'private', }); this._mockMailChannel_broadcast(id, partners.map(partner => partner.id)); return this._mockMailChannelChannelInfo([id])[0]; @@ -1251,13 +1249,13 @@ patch(MockServer.prototype, 'mail', { }).map(channel => { // expected format return { + authorizedGroupFullName: channel.group_public_id ? channel.group_public_id.name : false, channel: { channel_type: channel.channel_type, id: channel.id, }, id: channel.id, name: channel.name, - public: channel.public, }; }); // reduce results to max limit diff --git a/addons/mail/static/tests/qunit_suite_tests/components/channel_invitation_form_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/channel_invitation_form_tests.js index 9abc0f2c5b7..82a53e06923 100644 --- a/addons/mail/static/tests/qunit_suite_tests/components/channel_invitation_form_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/components/channel_invitation_form_tests.js @@ -24,7 +24,6 @@ QUnit.test('should display the channel invitation form after clicking on the inv [0, 0, { partner_id: resPartnerId1 }], ], channel_type: 'chat', - public: 'private', }); const { click, openDiscuss } = await start({ discuss: { @@ -62,7 +61,6 @@ QUnit.test('should be able to search for a new user to invite from an existing c [0, 0, { partner_id: resPartnerId1 }], ], channel_type: 'chat', - public: 'private', }); const { click, insertText, openDiscuss } = await start({ discuss: { @@ -101,7 +99,6 @@ QUnit.test('should be able to create a new group chat from an existing chat', as [0, 0, { partner_id: resPartnerId1 }], ], channel_type: 'chat', - public: 'private', }); const { click, insertText, openDiscuss } = await start({ discuss: { @@ -140,7 +137,6 @@ QUnit.test('Invitation form should display channel group restriction', async fun [0, 0, { partner_id: pyEnv.currentPartnerId }], ], channel_type: 'channel', - public: 'groups', group_public_id: resGroupId1, }); const { click, openDiscuss } = await start({ diff --git a/addons/mail/static/tests/qunit_suite_tests/components/channel_member_list_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/channel_member_list_tests.js index 0b068c79e8c..fc818ca05dd 100644 --- a/addons/mail/static/tests/qunit_suite_tests/components/channel_member_list_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/components/channel_member_list_tests.js @@ -20,7 +20,6 @@ QUnit.test('there should be a button to show member list in the thread view topb [0, 0, { partner_id: resPartnerId1 }], ], channel_type: 'group', - public: 'private', }); const { openDiscuss } = await start({ discuss: { @@ -48,7 +47,6 @@ QUnit.test('should show member list when clicking on show member list button in [0, 0, { partner_id: resPartnerId1 }], ], channel_type: 'group', - public: 'private', }); const { click, openDiscuss } = await start({ discuss: { @@ -77,7 +75,6 @@ QUnit.test('should have correct members in member list', async function (assert) [0, 0, { partner_id: resPartnerId1 }], ], channel_type: 'group', - public: 'private', }); const { click, openDiscuss } = await start({ discuss: { @@ -117,7 +114,6 @@ QUnit.test('there should be a button to hide member list in the thread view topb [0, 0, { partner_id: resPartnerId1 }], ], channel_type: 'group', - public: 'private', }); const { click, openDiscuss } = await start({ discuss: { diff --git a/addons/mail/static/tests/qunit_suite_tests/components/chat_window_manager_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/chat_window_manager_tests.js index 3ee17f98183..5881011f51c 100644 --- a/addons/mail/static/tests/qunit_suite_tests/components/chat_window_manager_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/components/chat_window_manager_tests.js @@ -335,7 +335,6 @@ QUnit.test('new message chat window should close on selecting the user if chat w ], channel_type: "chat", name: "Partner 131", - public: 'private', }); const { afterEvent, click } = await start(); diff --git a/addons/mail/static/tests/qunit_suite_tests/components/composer_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/composer_tests.js index 7fa7300d568..d726142d6f2 100644 --- a/addons/mail/static/tests/qunit_suite_tests/components/composer_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/components/composer_tests.js @@ -403,7 +403,7 @@ QUnit.test('display channel mention suggestions on typing "#"', async function ( assert.expect(2); const pyEnv = await startServer(); - const mailChanelId1 = pyEnv['mail.channel'].create({ name: "General", public: "groups" }); + const mailChanelId1 = pyEnv['mail.channel'].create({ name: "General", channel_type: 'channel' }); const { insertText, openDiscuss } = await start({ discuss: { context: { active_id: mailChanelId1 }, @@ -428,7 +428,7 @@ QUnit.test('mention a channel', async function (assert) { assert.expect(4); const pyEnv = await startServer(); - const mailChanelId1 = pyEnv['mail.channel'].create({ name: "General", public: "groups" }); + const mailChanelId1 = pyEnv['mail.channel'].create({ name: "General", channel_type: 'channel' }); const { click, insertText, openDiscuss } = await start({ discuss: { context: { active_id: mailChanelId1 }, @@ -464,7 +464,7 @@ QUnit.test('mention a channel after some text', async function (assert) { assert.expect(5); const pyEnv = await startServer(); - const mailChanelId1 = pyEnv['mail.channel'].create({ name: "General", public: "groups" }); + const mailChanelId1 = pyEnv['mail.channel'].create({ name: "General", channel_type: 'channel' }); const { click, insertText, openDiscuss } = await start({ discuss: { context: { active_id: mailChanelId1 }, @@ -506,7 +506,7 @@ QUnit.test('add an emoji after a channel mention', async function (assert) { assert.expect(5); const pyEnv = await startServer(); - const mailChanelId1 = pyEnv['mail.channel'].create({ name: "General", public: "groups" }); + const mailChanelId1 = pyEnv['mail.channel'].create({ name: "General", channel_type: 'channel' }); const { click, insertText, openDiscuss } = await start({ discuss: { context: { active_id: mailChanelId1 }, diff --git a/addons/mail/static/tests/qunit_suite_tests/components/discuss_pinned_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/discuss_pinned_tests.js index 08f285ef8ca..d19808872f7 100644 --- a/addons/mail/static/tests/qunit_suite_tests/components/discuss_pinned_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/components/discuss_pinned_tests.js @@ -120,11 +120,7 @@ QUnit.test('sidebar: unpin channel from bus', async function (assert) { // (e.g. from user interaction from another device or browser tab) await afterNextRender(() => { pyEnv['bus.bus']._sendone(pyEnv.currentPartner, 'mail.channel/unpin', { - 'channel_type': 'channel', 'id': mailChannelId1, - 'name': "General", - 'public': 'public', - 'state': 'open', }); }); assert.containsOnce( diff --git a/addons/mail/static/tests/qunit_suite_tests/components/discuss_sidebar_category_item_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/discuss_sidebar_category_item_tests.js index a3cf39cb226..b7c6a5a4f20 100644 --- a/addons/mail/static/tests/qunit_suite_tests/components/discuss_sidebar_category_item_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/components/discuss_sidebar_category_item_tests.js @@ -82,7 +82,6 @@ QUnit.test('chat - avatar: should have correct avatar', async function (assert) [0, 0, { partner_id: resPartnerId1 }], ], channel_type: 'chat', - public: 'private', }); const { openDiscuss } = await start(); await openDiscuss(); @@ -114,7 +113,6 @@ QUnit.test('chat - sorting: should be sorted by last activity time', async funct partner_id: pyEnv.currentPartnerId, }]], channel_type: 'chat', - public: 'private', }, { channel_member_ids: [[0, 0, { @@ -122,7 +120,6 @@ QUnit.test('chat - sorting: should be sorted by last activity time', async funct partner_id: pyEnv.currentPartnerId, }]], channel_type: 'chat', - public: 'private', }, ]); const { click, openDiscuss } = await start(); 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 d4dc0fed57e..7ea799643e1 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 @@ -401,7 +401,6 @@ QUnit.test('chat - counter: should not have a counter if the category is unfolde }], ], channel_type: 'chat', - public: 'private', }); const { openDiscuss } = await start(); @@ -425,7 +424,6 @@ QUnit.test('chat - counter: should not have a counter if the category is unfolde }], ], channel_type: 'chat', - public: 'private', }); const { openDiscuss } = await start(); await openDiscuss(); @@ -448,7 +446,6 @@ QUnit.test('chat - counter: should not have a counter if category is folded and }], ], channel_type: 'chat', - public: 'private', }); const { click, openDiscuss } = await start(); await openDiscuss(); @@ -473,7 +470,6 @@ QUnit.test('chat - counter: should have correct value of unread threads if categ }], ], channel_type: 'chat', - public: 'private', }, { channel_member_ids: [ @@ -483,7 +479,6 @@ QUnit.test('chat - counter: should have correct value of unread threads if categ }], ], channel_type: 'chat', - public: 'private', }, ]); const { click, openDiscuss } = await start(); @@ -532,7 +527,6 @@ QUnit.test('chat - states: close manually by clicking the title', async function const pyEnv = await startServer(); const mailChannelId1 = pyEnv['mail.channel'].create({ channel_type: 'chat', - public: 'private', }); pyEnv['res.users.settings'].create({ user_id: pyEnv.currentUserId, @@ -554,7 +548,6 @@ QUnit.test('chat - states: open manually by clicking the title', async function const pyEnv = await startServer(); const mailChannelId1 = pyEnv['mail.channel'].create({ channel_type: 'chat', - public: 'private', }); pyEnv['res.users.settings'].create({ user_id: pyEnv.currentUserId, @@ -649,7 +642,6 @@ QUnit.test('chat - states: close from the bus', async function (assert) { const pyEnv = await startServer(); const mailChannelId1 = pyEnv['mail.channel'].create({ channel_type: 'chat', - public: 'private', }); const resUsersSettingsId1 = pyEnv['res.users.settings'].create({ user_id: pyEnv.currentUserId, @@ -677,7 +669,6 @@ QUnit.test('chat - states: open from the bus', async function (assert) { const pyEnv = await startServer(); const mailChannelId1 = pyEnv['mail.channel'].create({ channel_type: 'chat', - public: 'private', }); const resUsersSettingsId1 = pyEnv['res.users.settings'].create({ user_id: pyEnv.currentUserId, @@ -705,7 +696,6 @@ QUnit.test('chat - states: the active category item should be visible even if th const pyEnv = await startServer(); const mailChannelId1 = pyEnv['mail.channel'].create({ channel_type: 'chat', - public: 'private', }); const { click, messaging, openDiscuss } = await start(); await openDiscuss(); diff --git a/addons/mail/static/tests/qunit_suite_tests/components/discuss_sidebar_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/discuss_sidebar_tests.js index da15ec803fb..21ab78fd686 100644 --- a/addons/mail/static/tests/qunit_suite_tests/components/discuss_sidebar_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/components/discuss_sidebar_tests.js @@ -18,8 +18,8 @@ QUnit.test('sidebar find shows channels matching search term', async function (a pyEnv['mail.channel'].create({ channel_member_ids: [], channel_type: 'channel', + group_public_id: false, name: 'test', - public: 'public', }); const searchReadDef = makeDeferred(); const { click, openDiscuss } = await start({ @@ -47,11 +47,10 @@ QUnit.test('sidebar find shows channels matching search term', async function (a ); assert.strictEqual( results.length, - // When searching for a single existing channel, the results list will have at least 3 lines: + // When searching for a single existing channel, the results list will have at least 2 lines: // One for the existing channel itself - // One for creating a public channel with the search term - // One for creating a private channel with the search term - 3 + // One for creating a channel with the search term + 2 ); assert.strictEqual( results[0].textContent, @@ -69,8 +68,8 @@ QUnit.test('sidebar find shows channels matching search term even when user is m [0, 0, { partner_id: pyEnv.currentPartnerId }], ], channel_type: 'channel', + group_public_id: false, name: 'test', - public: 'public', }); const searchReadDef = makeDeferred(); const { click, openDiscuss } = await start({ @@ -98,11 +97,10 @@ QUnit.test('sidebar find shows channels matching search term even when user is m ); assert.strictEqual( results.length, - // When searching for a single existing channel, the results list will have at least 3 lines: + // When searching for a single existing channel, the results list will have at least 2 lines: // One for the existing channel itself - // One for creating a public channel with the search term - // One for creating a private channel with the search term - 3 + // One for creating a channel with the search term + 2 ); assert.strictEqual( results[0].textContent, diff --git a/addons/mail/static/tests/qunit_suite_tests/components/discuss_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/discuss_tests.js index e47387529a0..8916485236f 100644 --- a/addons/mail/static/tests/qunit_suite_tests/components/discuss_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/components/discuss_tests.js @@ -535,20 +535,19 @@ QUnit.test('sidebar: channel rendering with needaction counter', async function ); }); -QUnit.test('sidebar: public/private channel rendering', async function (assert) { - assert.expect(5); +QUnit.test('sidebar: public channel rendering', async function (assert) { + assert.expect(3); const pyEnv = await startServer(); - const [mailChannelId1, mailChannelId2] = pyEnv['mail.channel'].create([ - { name: "channel1", public: 'public' }, - { name: "channel2", public: 'private' }, + const mailChannelId1 = pyEnv['mail.channel'].create([ + { name: "channel1", channel_type: 'channel', group_public_id: false}, ]); const { openDiscuss } = await start(); await openDiscuss(); assert.strictEqual( document.querySelectorAll(`.o_DiscussSidebar_categoryChannel .o_DiscussSidebarCategory_item`).length, - 2, - "should have 2 channel items" + 1, + "should have 1 channel items" ); assert.strictEqual( document.querySelectorAll(` @@ -558,31 +557,14 @@ QUnit.test('sidebar: public/private channel rendering', async function (assert) 1, "should have channel 1" ); - assert.strictEqual( - document.querySelectorAll(` - .o_DiscussSidebar_categoryChannel - .o_DiscussSidebarCategory_item[data-channel-id="${mailChannelId2}"] - `).length, - 1, - "should have channel 2" - ); const channel1 = document.querySelector(` .o_DiscussSidebar_categoryChannel .o_DiscussSidebarCategory_item[data-channel-id="${mailChannelId1}"] `); - const channel2 = document.querySelector(` - .o_DiscussSidebar_categoryChannel - .o_DiscussSidebarCategory_item[data-channel-id="${mailChannelId2}"] - `); assert.ok( - channel1.querySelectorAll(`:scope .o_ThreadIcon_channelPublic`).length, + channel1.querySelectorAll(`:scope .o_ThreadIcon_publicChannel`).length, "channel1 (public) should have globe icon" ); - assert.strictEqual( - channel2.querySelectorAll(`:scope .o_ThreadIcon_channelPrivate`).length, - 1, - "channel2 (private) has lock icon" - ); }); QUnit.test('sidebar: basic chat rendering', async function (assert) { @@ -596,7 +578,6 @@ QUnit.test('sidebar: basic chat rendering', async function (assert) { [0, 0, { partner_id: resPartnerId1 }], ], channel_type: 'chat', // testing a chat is the goal of the test - public: 'private', // expected value for testing a chat }); const { openDiscuss } = await start(); await openDiscuss(); @@ -658,7 +639,6 @@ QUnit.test('sidebar: chat rendering with unread counter', async function (assert }], ], channel_type: 'chat', - public: 'private', }); const { openDiscuss } = await start(); await openDiscuss(); @@ -701,7 +681,6 @@ QUnit.test('sidebar: chat im_status rendering', async function (assert) { [0, 0, { partner_id: resPartnerId1 }], ], channel_type: 'chat', - public: 'private', }, { channel_member_ids: [ @@ -709,7 +688,6 @@ QUnit.test('sidebar: chat im_status rendering', async function (assert) { [0, 0, { partner_id: resPartnerId2 }], ], channel_type: 'chat', - public: 'private', }, { channel_member_ids: [ @@ -717,7 +695,6 @@ QUnit.test('sidebar: chat im_status rendering', async function (assert) { [0, 0, { partner_id: resPartnerId3 }], ], channel_type: 'chat', - public: 'private', } ]); const { openDiscuss } = await start(); @@ -794,7 +771,6 @@ QUnit.test('sidebar: chat custom name', async function (assert) { [0, 0, { partner_id: resPartnerId1 }], ], channel_type: 'chat', - public: 'private', }); const { openDiscuss } = await start(); await openDiscuss(); @@ -1947,7 +1923,6 @@ QUnit.test('redirect to author (open chat)', async function (assert) { [0, 0, { partner_id: resPartnerId1 }], ], channel_type: 'chat', - public: 'private', } ]); const mailMessageId1 = pyEnv['mail.message'].create( @@ -3445,8 +3420,8 @@ QUnit.test('receive new chat messages: out of odoo focus (tab title)', async fun let step = 0; const pyEnv = await startServer(); const [mailChannelId1, mailChannelId2] = pyEnv['mail.channel'].create([ - { channel_type: 'chat', public: 'private' }, - { channel_type: 'chat', public: 'private' }, + { channel_type: 'chat' }, + { channel_type: 'chat' }, ]); const { env, openDiscuss } = await start({ services: { @@ -3524,7 +3499,6 @@ QUnit.test('auto-focus composer on opening thread', async function (assert) { [0, 0, { partner_id: resPartnerId1 }], ], channel_type: 'chat', - public: 'private', } ]); const { click, openDiscuss } = await start(); diff --git a/addons/mail/static/tests/qunit_suite_tests/components/message_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/message_tests.js index ba623813aa7..2887d980ce5 100644 --- a/addons/mail/static/tests/qunit_suite_tests/components/message_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/components/message_tests.js @@ -943,7 +943,6 @@ QUnit.test('open chat with author on avatar click should be disabled when curren [0, 0, { partner_id: resPartnerId }], ], channel_type: 'chat', - public: 'private', }); pyEnv['mail.message'].create({ author_id: resPartnerId, diff --git a/addons/mail/static/tests/qunit_suite_tests/components/thread_view_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/thread_view_tests.js index 19679bb0f96..99b5b503a6e 100644 --- a/addons/mail/static/tests/qunit_suite_tests/components/thread_view_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/components/thread_view_tests.js @@ -18,8 +18,8 @@ QUnit.test('dragover files on thread with composer', async function (assert) { const pyEnv = await startServer(); const mailChannelId1 = pyEnv['mail.channel'].create({ channel_type: 'channel', + group_public_id: false, name: "General", - public: 'public', }); const { openDiscuss } = await start({ discuss: { @@ -42,8 +42,8 @@ QUnit.test('message list asc order', async function (assert) { const pyEnv = await startServer(); const mailChannelId1 = pyEnv['mail.channel'].create({ channel_type: 'channel', + group_public_id: false, name: "General", - public: 'public', }); for (let i = 0; i <= 60; i++) { pyEnv['mail.message'].create({ @@ -258,8 +258,8 @@ QUnit.test('show message subject when subject is not the same as the thread name const pyEnv = await startServer(); const mailChannelId1 = pyEnv['mail.channel'].create({ channel_type: 'channel', + group_public_id: false, name: "General", - public: 'public', }); pyEnv['mail.message'].create({ body: "not empty", @@ -296,8 +296,8 @@ QUnit.test('do not show message subject when subject is the same as the thread n const pyEnv = await startServer(); const mailChannelId1 = pyEnv['mail.channel'].create({ channel_type: 'channel', + group_public_id: false, name: "Salutations, voyageur", - public: 'public', }); pyEnv['mail.message'].create({ body: "not empty", @@ -1089,10 +1089,12 @@ QUnit.test('mention 2 different channels that have the same name', async functio const pyEnv = await startServer(); const [mailChannelId1, mailChannelId2] = pyEnv['mail.channel'].create([ { + channel_type: 'channel', + group_public_id: false, name: "my channel", - public: 'public', // mentioning another channel is possible only from a public channel }, { + channel_type: 'channel', name: "my channel", }, ]); diff --git a/addons/mail/static/tests/qunit_suite_tests/models/messaging_tests.js b/addons/mail/static/tests/qunit_suite_tests/models/messaging_tests.js index d4015c16d31..4e33bd00b75 100644 --- a/addons/mail/static/tests/qunit_suite_tests/models/messaging_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/models/messaging_tests.js @@ -87,7 +87,6 @@ QUnit.test('openChat: open existing chat for user', async function (assert) { [0, 0, { partner_id: resPartnerId1 }], ], channel_type: "chat", - public: 'private', }); const { messaging } = await start(); const existingChat = messaging.models['Partner'].findFromIdentifyingData({ id: resPartnerId1 }).dmChatWithCurrentPartner; diff --git a/addons/mail/tests/test_link_preview.py b/addons/mail/tests/test_link_preview.py index d45697a4df3..7342afc43f9 100644 --- a/addons/mail/tests/test_link_preview.py +++ b/addons/mail/tests/test_link_preview.py @@ -43,7 +43,6 @@ class TestLinkPreview(MailCommon): cls.public_channel = cls.env['mail.channel'].create({ 'name': 'Public channel of user 1', - 'public': 'public', 'channel_type': 'channel', }) cls.public_channel.channel_member_ids.unlink() diff --git a/addons/mail/tests/test_mail_channel.py b/addons/mail/tests/test_mail_channel.py index 8b8a7214e7c..7a364163d03 100644 --- a/addons/mail/tests/test_mail_channel.py +++ b/addons/mail/tests/test_mail_channel.py @@ -28,9 +28,9 @@ class TestChannelAccessRights(MailCommon): cls.user_portal = mail_new_test_user(cls.env, login='user_portal', groups='base.group_portal', name='Chell Gladys') # Channel for certain group - cls.group_restricted_channel = cls.env['mail.channel'].browse(cls.env['mail.channel'].channel_create(name='Channel for Groups', privacy='groups', group_id=cls.env.ref('base.group_user').id)['id']) + cls.group_restricted_channel = cls.env['mail.channel'].browse(cls.env['mail.channel'].channel_create(name='Channel for Groups', group_id=cls.env.ref('base.group_user').id)['id']) # Public Channel - cls.public_channel = cls.env['mail.channel'].browse(cls.env['mail.channel'].channel_create(name='Public Channel', privacy='public', group_id=None)['id']) + cls.public_channel = cls.env['mail.channel'].browse(cls.env['mail.channel'].channel_create(name='Public Channel', group_id=None)['id']) # Group cls.private_group = cls.env['mail.channel'].browse(cls.env['mail.channel'].create_group(partners_to=cls.user_employee.partner_id.ids, name="Group")['id']) # Chat @@ -220,11 +220,7 @@ class TestChannelInternals(MailCommon): @classmethod def setUpClass(cls): super(TestChannelInternals, cls).setUpClass() - cls.test_channel = cls.env['mail.channel'].with_context(cls._test_context).create({ - 'channel_type': 'channel', - 'name': 'Channel', - 'public': 'public', - }) + cls.test_channel = cls.env['mail.channel'].browse(cls.env['mail.channel'].with_context(cls._test_context).channel_create(name='Channel', group_id=None)['id']) cls.test_partner = cls.env['res.partner'].with_context(cls._test_context).create({ 'name': 'Test Partner', 'email': 'test_customer@example.com', @@ -240,15 +236,6 @@ class TestChannelInternals(MailCommon): ) cls.partner_employee_nomail = cls.user_employee_nomail.partner_id - @users('employee') - def test_channel_form(self): - """A user that create a private channel should be able to read it.""" - channel_form = Form(self.env['mail.channel'].with_user(self.user_employee)) - channel_form.name = 'Test private channel' - channel_form.public = 'private' - channel = channel_form.save() - self.assertEqual(channel.name, 'Test private channel', 'Must be able to read the created channel') - @users('employee') def test_channel_members(self): channel = self.env['mail.channel'].browse(self.test_channel.ids) @@ -331,27 +318,19 @@ class TestChannelInternals(MailCommon): @mute_logger('odoo.models.unlink') def test_channel_user_synchronize(self): - """Archiving / deleting a user should automatically unsubscribe related partner from private channels""" - test_channel_private = self.env['mail.channel'].with_context(self._test_context).create({ - 'name': 'Winden caves', - 'description': 'Channel to travel through time', - 'public': 'private', - }) - group_restricted_channel = self.env['mail.channel'].browse(self.env['mail.channel'].channel_create(name='Sic Mundus', privacy='groups', group_id=self.env.ref('base.group_user').id)['id']) + """Archiving / deleting a user should automatically unsubscribe related partner from group restricted channels""" + group_restricted_channel = self.env['mail.channel'].browse(self.env['mail.channel'].channel_create(name='Sic Mundus', group_id=self.env.ref('base.group_user').id)['id']) self.test_channel.add_members((self.partner_employee | self.partner_employee_nomail).ids) - test_channel_private.add_members((self.partner_employee | self.partner_employee_nomail).ids) group_restricted_channel.add_members((self.partner_employee | self.partner_employee_nomail).ids) # Unsubscribe archived user from the private channels, but not from public channels self.user_employee.active = False - self.assertEqual(test_channel_private.channel_partner_ids, self.partner_employee_nomail) self.assertEqual(group_restricted_channel.channel_partner_ids, self.partner_employee_nomail) self.assertEqual(self.test_channel.channel_partner_ids, self.user_employee.partner_id | self.partner_employee_nomail) # Unsubscribe deleted user from the private channels, but not from public channels self.user_employee_nomail.unlink() - self.assertEqual(test_channel_private.channel_partner_ids, self.env['res.partner']) self.assertEqual(group_restricted_channel.channel_partner_ids, self.env['res.partner']) self.assertEqual(self.test_channel.channel_partner_ids, self.user_employee.partner_id | self.partner_employee_nomail) @@ -433,15 +412,8 @@ class TestChannelInternals(MailCommon): "name": "Jonas", }) test_partner = test_user.partner_id - test_channel_private = self.env['mail.channel'].with_context(self._test_context).create({ - 'name': 'Winden caves', - 'description': 'Channel to travel through time', - 'public': 'private', - 'channel_partner_ids': [Command.link(self.user_employee.partner_id.id), Command.link(test_partner.id)], - }) group_restricted_channel = self.env['mail.channel'].with_context(self._test_context).create({ 'name': 'Sic Mundus', - 'public': 'groups', 'group_public_id': self.env.ref('base.group_user').id, 'channel_partner_ids': [Command.link(self.user_employee.partner_id.id), Command.link(test_partner.id)], }) @@ -451,21 +423,18 @@ class TestChannelInternals(MailCommon): private_group = self.env['mail.channel'].with_user(self.user_employee).with_context(self._test_context).create({ 'name': 'test', 'channel_type': 'group', - 'public': 'private', 'channel_partner_ids': [Command.link(self.user_employee.partner_id.id), Command.link(test_partner.id)], }) # Unsubscribe archived user from the private channels, but not from public channels and not from group self.user_employee.active = False (private_group | self.test_channel).invalidate_recordset(['channel_partner_ids']) - self.assertEqual(test_channel_private.channel_partner_ids, test_partner) self.assertEqual(group_restricted_channel.channel_partner_ids, test_partner) self.assertEqual(self.test_channel.channel_partner_ids, self.user_employee.partner_id | test_partner) self.assertEqual(private_group.channel_partner_ids, self.user_employee.partner_id | test_partner) # Unsubscribe deleted user from the private channels, but not from public channels and not from group test_user.unlink() - self.assertEqual(test_channel_private.channel_partner_ids, self.env['res.partner']) self.assertEqual(group_restricted_channel.channel_partner_ids, self.env['res.partner']) self.assertEqual(self.test_channel.channel_partner_ids, self.user_employee.partner_id | test_partner) self.assertEqual(private_group.channel_partner_ids, self.user_employee.partner_id | test_partner) @@ -474,8 +443,8 @@ class TestChannelInternals(MailCommon): @mute_logger('odoo.models.unlink') def test_channel_private_unfollow(self): """ Test that a partner can leave (unfollow) a channel/group/chat. """ - group_restricted_channel = self.env['mail.channel'].browse(self.env['mail.channel'].channel_create(name='Channel for Groups', privacy='groups', group_id=self.env.ref('base.group_user').id)['id']) - public_channel = self.env['mail.channel'].browse(self.env['mail.channel'].channel_create(name='Channel for Everyone', privacy='public', group_id=None)['id']) + group_restricted_channel = self.env['mail.channel'].browse(self.env['mail.channel'].channel_create(name='Channel for Groups', group_id=self.env.ref('base.group_user').id)['id']) + public_channel = self.env['mail.channel'].browse(self.env['mail.channel'].channel_create(name='Channel for Everyone', group_id=None)['id']) private_group = self.env['mail.channel'].browse(self.env['mail.channel'].create_group(partners_to=self.user_employee.partner_id.ids, name="Group")['id']) chat_user_current = self.env['mail.channel'].browse(self.env['mail.channel'].channel_get(self.env.user.partner_id.ids)['id']) @@ -566,28 +535,28 @@ class TestChannelInternals(MailCommon): ): channel.image_128 = base64.b64encode(("").encode()) - def test_mail_message_starred_private_channel(self): - """ Test starred message computation for a private channel. A starred - message in a private channel should be considered only if: + def test_mail_message_starred_group(self): + """ Test starred message computation for a group. A starred + message in a group should be considered only if: - It's our message - OR we have access to the channel """ self.assertEqual(self.user_employee._init_messaging()['starred_counter'], 0) - private_channel = self.env['mail.channel'].create({ + test_group = self.env['mail.channel'].create({ 'name': 'Private Channel', - 'public': 'private', + 'channel_type': 'group', 'channel_partner_ids': [(6, 0, self.partner_employee.id)] }) - private_channel_own_message = private_channel.with_user(self.user_employee.id).message_post(body='TestingMessage') - private_channel_own_message.write({'starred_partner_ids': [(6, 0, self.partner_employee.ids)]}) + test_group_own_message = test_group.with_user(self.user_employee.id).message_post(body='TestingMessage') + test_group_own_message.write({'starred_partner_ids': [(6, 0, self.partner_employee.ids)]}) self.assertEqual(self.user_employee.with_user(self.user_employee)._init_messaging()['starred_counter'], 1) - private_channel_message = private_channel.message_post(body='TestingMessage') - private_channel_message.write({'starred_partner_ids': [(6, 0, self.partner_employee.ids)]}) + test_group_message = test_group.message_post(body='TestingMessage') + test_group_message.write({'starred_partner_ids': [(6, 0, self.partner_employee.ids)]}) self.assertEqual(self.user_employee.with_user(self.user_employee)._init_messaging()['starred_counter'], 2) - private_channel.write({'channel_partner_ids': False}) + test_group.write({'channel_partner_ids': False}) self.assertEqual(self.user_employee.with_user(self.user_employee)._init_messaging()['starred_counter'], 1) def test_multi_company_chat(self): diff --git a/addons/mail/tests/test_mail_channel_as_guest.py b/addons/mail/tests/test_mail_channel_as_guest.py index 66bab902d46..2f242e8fdc1 100644 --- a/addons/mail/tests/test_mail_channel_as_guest.py +++ b/addons/mail/tests/test_mail_channel_as_guest.py @@ -12,10 +12,7 @@ class TestMailPublicPage(HttpCase): def setUp(self): super().setUp() - self.channel = self.env['mail.channel'].create({ - 'name': 'Test channel', - 'public': 'public', - }) + self.channel = self.env['mail.channel'].browse(self.env['mail.channel'].channel_create(group_id=None, name='Test channel')['id']) self.tour = "mail/static/tests/tours/discuss_public_tour.js" def _open_channel_page_as_user(self, login): diff --git a/addons/mail/tests/test_mail_channel_member.py b/addons/mail/tests/test_mail_channel_member.py index 623dde5dd68..017a57451fd 100644 --- a/addons/mail/tests/test_mail_channel_member.py +++ b/addons/mail/tests/test_mail_channel_member.py @@ -47,63 +47,57 @@ class TestMailChannelMembers(MailCommon): name='User Public', groups='base.group_public') - cls.private_channel = cls.env['mail.channel'].create({ - 'name': 'Secret channel', - 'public': 'private', - 'channel_type': 'channel', + cls.group = cls.env['mail.channel'].create({ + 'name': 'Group', + 'channel_type': 'group', }) - cls.group_channel = cls.env['mail.channel'].create({ - 'name': 'Group channel', - 'public': 'groups', + cls.group_restricted_channel = cls.env['mail.channel'].create({ + 'name': 'Group restricted channel', 'channel_type': 'channel', 'group_public_id': cls.secret_group.id, }) - cls.public_channel = cls.env['mail.channel'].create({ - 'name': 'Public channel of user 1', - 'public': 'public', - 'channel_type': 'channel', - }) - (cls.private_channel | cls.group_channel | cls.public_channel).channel_member_ids.unlink() + cls.public_channel = cls.env['mail.channel'].browse(cls.env['mail.channel'].channel_create(group_id=None, name='Public channel of user 1')['id']) + (cls.group | cls.group_restricted_channel | cls.public_channel).channel_member_ids.unlink() # ------------------------------------------------------------ - # PRIVATE CHANNELS + # GROUP # ------------------------------------------------------------ - def test_channel_private_01(self): - """Test access on private channel.""" - res = self.env['mail.channel.member'].search([('channel_id', '=', self.private_channel.id)]) + def test_group_01(self): + """Test access on group.""" + res = self.env['mail.channel.member'].search([('channel_id', '=', self.group.id)]) self.assertFalse(res) - # User 1 can join private channel with SUDO - self.private_channel.with_user(self.user_1).sudo().add_members(self.user_1.partner_id.ids) - res = self.env['mail.channel.member'].search([('channel_id', '=', self.private_channel.id)]) + # User 1 can join group with SUDO + self.group.with_user(self.user_1).sudo().add_members(self.user_1.partner_id.ids) + res = self.env['mail.channel.member'].search([('channel_id', '=', self.group.id)]) self.assertEqual(res.partner_id, self.user_1.partner_id) - # User 2 can not join private channel + # User 2 can not join group with self.assertRaises(AccessError): - self.private_channel.with_user(self.user_2).add_members(self.user_2.partner_id.ids) + self.group.with_user(self.user_2).add_members(self.user_2.partner_id.ids) - # User 2 can not create a `mail.channel.member` to join the private channel + # User 2 can not create a `mail.channel.member` to join the group with self.assertRaises(AccessError): self.env['mail.channel.member'].with_user(self.user_2).create({ 'partner_id': self.user_2.partner_id.id, - 'channel_id': self.private_channel.id, + 'channel_id': self.group.id, }) - # User 2 can not write on `mail.channel.member` to join the private channel + # User 2 can not write on `mail.channel.member` to join the group channel_member = self.env['mail.channel.member'].with_user(self.user_2).search([('partner_id', '=', self.user_2.partner_id.id)])[0] with self.assertRaises(AccessError): - channel_member.channel_id = self.private_channel.id + channel_member.channel_id = self.group.id with self.assertRaises(AccessError): - channel_member.write({'channel_id': self.private_channel.id}) + channel_member.write({'channel_id': self.group.id}) # Even with SUDO, channel_id of channel.member should not be changed. with self.assertRaises(AccessError): - channel_member.sudo().channel_id = self.private_channel.id + channel_member.sudo().channel_id = self.group.id # User 2 can not write on the `partner_id` of `mail.channel.member` - # of an other partner to join a private channel - channel_member_1 = self.env['mail.channel.member'].search([('channel_id', '=', self.private_channel.id), ('partner_id', '=', self.user_1.partner_id.id)]) + # of an other partner to join a group + channel_member_1 = self.env['mail.channel.member'].search([('channel_id', '=', self.group.id), ('partner_id', '=', self.user_1.partner_id.id)]) with self.assertRaises(AccessError): channel_member_1.with_user(self.user_2).partner_id = self.user_2.partner_id self.assertEqual(channel_member_1.partner_id, self.user_1.partner_id) @@ -112,64 +106,64 @@ class TestMailChannelMembers(MailCommon): with self.assertRaises(AccessError): channel_member_1.with_user(self.user_2).sudo().partner_id = self.user_2.partner_id - def test_channel_private_members(self): - """Test invitation in private channel part 1 (invite using crud methods).""" - self.private_channel.with_user(self.user_1).sudo().add_members(self.user_1.partner_id.ids) - channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.private_channel.id)]) + def test_group_members(self): + """Test invitation in group part 1 (invite using crud methods).""" + self.group.with_user(self.user_1).sudo().add_members(self.user_1.partner_id.ids) + channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.group.id)]) self.assertEqual(len(channel_members), 1) - # User 2 is not in the private channel, they can not invite user 3 + # User 2 is not in the group, they can not invite user 3 with self.assertRaises(AccessError): self.env['mail.channel.member'].with_user(self.user_2).create({ 'partner_id': self.user_portal.partner_id.id, - 'channel_id': self.private_channel.id, + 'channel_id': self.group.id, }) - # User 1 is in the private channel, they can invite other users + # User 1 is in the group, they can invite other users self.env['mail.channel.member'].with_user(self.user_1).create({ 'partner_id': self.user_portal.partner_id.id, - 'channel_id': self.private_channel.id, + 'channel_id': self.group.id, }) - channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.private_channel.id)]) + channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.group.id)]) self.assertEqual(channel_members.mapped('partner_id'), self.user_1.partner_id | self.user_portal.partner_id) # But User 3 can not write on the `mail.channel.member` of other user - channel_member_1 = self.env['mail.channel.member'].search([('channel_id', '=', self.private_channel.id), ('partner_id', '=', self.user_1.partner_id.id)]) - channel_member_3 = self.env['mail.channel.member'].search([('channel_id', '=', self.private_channel.id), ('partner_id', '=', self.user_portal.partner_id.id)]) + channel_member_1 = self.env['mail.channel.member'].search([('channel_id', '=', self.group.id), ('partner_id', '=', self.user_1.partner_id.id)]) + channel_member_3 = self.env['mail.channel.member'].search([('channel_id', '=', self.group.id), ('partner_id', '=', self.user_portal.partner_id.id)]) channel_member_3.with_user(self.user_portal).custom_channel_name = 'Test' with self.assertRaises(AccessError): channel_member_1.with_user(self.user_2).custom_channel_name = 'Blabla' self.assertNotEqual(channel_member_1.custom_channel_name, 'Blabla') - def test_channel_private_invite(self): - """Test invitation in private channel part 2 (use `invite` action).""" - self.private_channel.with_user(self.user_1).sudo().add_members(self.user_1.partner_id.ids) - channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.private_channel.id)]) + def test_group_invite(self): + """Test invitation in group part 2 (use `invite` action).""" + self.group.with_user(self.user_1).sudo().add_members(self.user_1.partner_id.ids) + channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.group.id)]) self.assertEqual(channel_members.mapped('partner_id'), self.user_1.partner_id) - # User 2 is not in the channel, they can not invite user_portal + # User 2 is not in the group, they can not invite user_portal with self.assertRaises(AccessError): - self.private_channel.with_user(self.user_2).add_members(self.user_portal.partner_id.ids) - channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.private_channel.id)]) + self.group.with_user(self.user_2).add_members(self.user_portal.partner_id.ids) + channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.group.id)]) self.assertEqual(channel_members.mapped('partner_id'), self.user_1.partner_id) - # User 1 is in the channel, they can invite user_portal - self.private_channel.with_user(self.user_1).add_members(self.user_portal.partner_id.ids) - channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.private_channel.id)]) + # User 1 is in the group, they can invite user_portal + self.group.with_user(self.user_1).add_members(self.user_portal.partner_id.ids) + channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.group.id)]) self.assertEqual(channel_members.mapped('partner_id'), self.user_1.partner_id | self.user_portal.partner_id) - def test_channel_private_leave(self): + def test_group_leave(self): """Test kick/leave channel.""" - self.private_channel.with_user(self.user_1).sudo().add_members(self.user_1.partner_id.ids) - self.private_channel.with_user(self.user_portal).sudo().add_members(self.user_portal.partner_id.ids) - channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.private_channel.id)]) + self.group.with_user(self.user_1).sudo().add_members(self.user_1.partner_id.ids) + self.group.with_user(self.user_portal).sudo().add_members(self.user_portal.partner_id.ids) + channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.group.id)]) self.assertEqual(len(channel_members), 2) - # User 2 is not in the channel, they can not kick user 1 + # User 2 is not in the group, they can not kick user 1 with self.assertRaises(AccessError): channel_members.with_user(self.user_2).unlink() - # User 3 is in the channel, they can kick user 1 + # User 3 is in the group, they can kick user 1 channel_members.with_user(self.user_portal).unlink() # ------------------------------------------------------------ @@ -178,34 +172,34 @@ class TestMailChannelMembers(MailCommon): def test_group_restricted_channel(self): """Test basics on group channel.""" - channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.group_channel.id)]) + channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.group_restricted_channel.id)]) self.assertFalse(channel_members) - # user 1 is in the group, they can join the channel - self.group_channel.with_user(self.user_1).add_members(self.user_1.partner_id.ids) - channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.group_channel.id)]) + # user 1 is in the channel, they can join the channel + self.group_restricted_channel.with_user(self.user_1).add_members(self.user_1.partner_id.ids) + channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.group_restricted_channel.id)]) self.assertEqual(channel_members.mapped('partner_id'), self.user_1.partner_id) - # user 3 is not in the group, they can not join + # user 3 is not in the channel, they can not join with self.assertRaises(AccessError): - self.group_channel.with_user(self.user_portal).add_members(self.user_portal.partner_id.ids) + self.group_restricted_channel.with_user(self.user_portal).add_members(self.user_portal.partner_id.ids) - channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.group_channel.id)]) + channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.group_restricted_channel.id)]) with self.assertRaises(AccessError): channel_members.with_user(self.user_portal).partner_id = self.user_portal.partner_id - channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.group_channel.id)]) + channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.group_restricted_channel.id)]) self.assertEqual(channel_members.mapped('partner_id'), self.user_1.partner_id) - # user 1 can not invite user 3 because they are not in the group + # user 1 can not invite user 3 because they are not in the channel with self.assertRaises(UserError): - self.group_channel.with_user(self.user_1).add_members(self.user_portal.partner_id.ids) - channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.group_channel.id)]) + self.group_restricted_channel.with_user(self.user_1).add_members(self.user_portal.partner_id.ids) + channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.group_restricted_channel.id)]) self.assertEqual(channel_members.mapped('partner_id'), self.user_1.partner_id) - # but user 2 is in the group and can be invited by user 1 - self.group_channel.with_user(self.user_1).add_members(self.user_2.partner_id.ids) - channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.group_channel.id)]) + # but user 2 is in the channel and can be invited by user 1 + self.group_restricted_channel.with_user(self.user_1).add_members(self.user_2.partner_id.ids) + channel_members = self.env['mail.channel.member'].search([('channel_id', '=', self.group_restricted_channel.id)]) self.assertEqual(channel_members.mapped('partner_id'), self.user_1.partner_id | self.user_2.partner_id) # ------------------------------------------------------------ @@ -249,11 +243,7 @@ class TestMailChannelMembers(MailCommon): # ------------------------------------------------------------ def test_unread_counter_with_message_post(self): - channel_as_user_1 = self.env['mail.channel'].with_user(self.user_1).create({ - 'name': 'Secret channel', - 'public': 'public', - 'channel_type': 'channel', - }) + channel_as_user_1 = self.env['mail.channel'].browse(self.env['mail.channel'].with_user(self.user_1).channel_create(group_id=None, name='Public channel')['id']) channel_as_user_1.with_user(self.user_1).add_members(self.user_1.partner_id.ids) channel_as_user_1.with_user(self.user_1).add_members(self.user_2.partner_id.ids) channel_1_rel_user_2 = self.env['mail.channel.member'].search([ @@ -270,16 +260,8 @@ class TestMailChannelMembers(MailCommon): self.assertEqual(channel_1_rel_user_2.message_unread_counter, 1, "should have 1 unread message after someone else posted a message") def test_unread_counter_with_message_post_multi_channel(self): - channel_1_as_user_1 = self.env['mail.channel'].with_user(self.user_1).create({ - 'name': 'wololo channel', - 'public': 'public', - 'channel_type': 'channel', - }) - channel_2_as_user_2 = self.env['mail.channel'].with_user(self.user_2).create({ - 'name': 'walala channel', - 'public': 'public', - 'channel_type': 'channel', - }) + channel_1_as_user_1 = self.env['mail.channel'].with_user(self.user_1).browse(self.env['mail.channel'].with_user(self.user_1).channel_create(group_id=None, name='wololo channel')['id']) + channel_2_as_user_2 = self.env['mail.channel'].with_user(self.user_2).browse(self.env['mail.channel'].with_user(self.user_2).channel_create(group_id=None, name='walala channel')['id']) channel_1_as_user_1.add_members(self.user_2.partner_id.ids) channel_2_as_user_2.add_members(self.user_1.partner_id.ids) channel_2_as_user_2.add_members(self.user_3.partner_id.ids) diff --git a/addons/mail/views/mail_channel_views.xml b/addons/mail/views/mail_channel_views.xml index c7489539206..5644424713b 100644 --- a/addons/mail/views/mail_channel_views.xml +++ b/addons/mail/views/mail_channel_views.xml @@ -12,7 +12,6 @@ -
@@ -60,9 +59,8 @@ -