[IMP] mail, *: remove 'public' field in channel

*: im_livechat, website_livechat

Access right should be based on channel type and membership instead.
Chat always private, group always private, channel private should
disapear and be a group instead (migration needed), and other channel
always public (but they can still be further restricted with
the "allowed groups" feature)

task-2632861

closes odoo/odoo#90415

Related: odoo/enterprise#30980
Related: odoo/upgrade#3850
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
This commit is contained in:
Zelong Lin
2022-09-06 10:57:59 +02:00
committed by Louis Wicket (wil)
parent 533ccf7fb0
commit d57c64f95b
39 changed files with 212 additions and 481 deletions
@@ -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'
})
@@ -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):
@@ -136,7 +136,6 @@ patch(MockServer.prototype, 'im_livechat', {
'country_id': country_id,
'channel_type': 'livechat',
'name': membersName.join(' '),
'public': 'private',
};
},
/**
+2 -2
View File
@@ -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,
+13 -62
View File
@@ -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 <b>#%s</b>.", 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)])
+2 -1
View File
@@ -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'])
+1 -1
View File
@@ -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()
+3 -3
View File
@@ -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):
+22 -8
View File
@@ -6,10 +6,17 @@
<field name="name">Mail.channel: access only public and joined groups</field>
<field name="model_id" ref="model_mail_channel"/>
<field name="groups" eval="[Command.link(ref('base.group_user')), Command.link(ref('base.group_portal')), Command.link(ref('base.group_public'))]"/>
<field name="domain_force">['|', '|',
('public', '=', 'public'),
'&amp;', ('public', '=', 'private'), ('is_member', '=', True),
'&amp;', ('public', '=', 'groups'), ('group_public_id', 'in', [g.id for g in user.groups_id])]</field>
<field name="domain_force">[
'|',
'&amp;',
('channel_type', '!=', 'channel'),
('is_member', '=', True),
'&amp;',
('channel_type', '=', 'channel'),
'|',
('group_public_id', '=', False),
('group_public_id', 'in', [g.id for g in user.groups_id])]
</field>
<field name="perm_create" eval="False"/>
</record>
@@ -24,10 +31,17 @@
<field name="name">mail.channel.member: write its own entries</field>
<field name="model_id" ref="model_mail_channel_member"/>
<field name="groups" eval="[(4, ref('base.group_user')), (4, ref('base.group_portal'))]"/>
<field name="domain_force">['|', '|',
('channel_id.public', '=', 'public'),
'&amp;', ('channel_id.public', '=', 'private'), ('channel_id.is_member', '=', True),
'&amp;', ('channel_id.public', '=', 'groups'), ('channel_id.group_public_id', 'in', [g.id for g in user.groups_id])]</field>
<field name="domain_force">[
'|',
'&amp;',
('channel_id.channel_type', '!=', 'channel'),
('channel_id.is_member', '=', True),
'&amp;',
('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])]
</field>
<field name="perm_read" eval="False"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="False"/>
@@ -5,14 +5,11 @@
<t t-if="thread">
<div class="o_ThreadIcon d-flex justify-content-center flex-shrink-0" t-attf-class="{{ className }}" t-ref="root" name="root">
<t t-if="thread.channel and thread.channel.channel_type === 'channel'">
<t t-if="thread.public === 'private'">
<div class="o_ThreadIcon_channelPrivate fa fa-fw fa-lock" title="Private channel"/>
<t t-if="thread.authorizedGroupFullName">
<div class="o_ThreadIcon_groupRestrictedChannel fa fa-fw fa-hashtag" t-att-title="thread.accessRestrictedToGroupText"/>
</t>
<t t-if="thread.public === 'public'">
<div class="o_ThreadIcon_channelPublic fa fa-fw fa-globe" title="Public channel"/>
</t>
<t t-if="thread.public === 'groups'">
<div class="o_ThreadIcon_channelGroups fa fa-fw fa-hashtag" title="Selected group of users"/>
<t t-if="!thread.authorizedGroupFullName">
<div class="o_ThreadIcon_publicChannel fa fa-fw fa-globe" title="Public Channel"/>
</t>
</t>
<t t-elif="thread.channel and thread.channel.channel_type === 'chat' and thread.channel.correspondent">
@@ -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(
+4 -12
View File
@@ -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(
`<strong>${this.env._t('Create %s')}</strong>`,
`<em><span class="fa fa-hashtag"/>${escapedValue}</em>`,
),
escapedValue,
special: 'public'
}, {
label: sprintf(
`<strong>${this.env._t('Create %s')}</strong>`,
`<em><span class="fa fa-lock"/>${escapedValue}</em>`,
),
escapedValue,
special: 'private'
});
res(items);
},
@@ -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']],
});
},
/**
@@ -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':
+3 -3
View File
@@ -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.
+26 -13
View File
@@ -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,
}),
@@ -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
@@ -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({
@@ -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: {
@@ -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();
@@ -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 },
@@ -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(
@@ -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();
@@ -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();
@@ -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,
@@ -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();
@@ -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,
@@ -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",
},
]);
@@ -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;
-1
View File
@@ -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()
+17 -48
View File
@@ -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(("<svg/>").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):
@@ -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):
+68 -86
View File
@@ -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)
+1 -3
View File
@@ -12,7 +12,6 @@
<field name="description"/>
<field name="is_member"/>
<field name="group_ids"/>
<field name="public"/>
<templates>
<t t-name="kanban-description">
<div class="oe_group_description" t-if="record.description.raw_value">
@@ -60,9 +59,8 @@
<notebook>
<page string="Privacy" name="privacy">
<group class="o_label_nowrap">
<field name="public" widget="radio" string="Who can follow the group's activities?"/>
<field name="group_public_id"
attrs="{'invisible': ['|', ('channel_type', '!=', 'channel'), ('public','!=','groups')], 'required': [('public','=','groups')]}"
attrs="{'invisible': [('channel_type', '!=', 'channel')]}"
/>
<field name="group_ids" widget="many2many_tags"
attrs="{'invisible': [('channel_type', '!=', 'channel')]}"
@@ -63,20 +63,15 @@ class TestDiscussFullPerformance(TransactionCase):
self.env['mail.channel'].sudo().search([('id', '!=', self.channel_general.id)]).unlink()
self.user_root = self.env.ref('base.user_root')
# create public channels
self.channel_channel_public_1 = self.env['mail.channel'].browse(self.env['mail.channel'].channel_create(name='public 1', privacy='public', group_id=None)['id'])
self.channel_channel_public_1 = self.env['mail.channel'].browse(self.env['mail.channel'].channel_create(name='public channel 1', group_id=None)['id'])
self.channel_channel_public_1.add_members((self.users[0] + self.users[2] + self.users[3] + self.users[4] + self.users[8]).partner_id.ids)
self.channel_channel_public_2 = self.env['mail.channel'].browse(self.env['mail.channel'].channel_create(name='public 2', privacy='public', group_id=None)['id'])
self.channel_channel_public_2 = self.env['mail.channel'].browse(self.env['mail.channel'].channel_create(name='public channel 2', group_id=None)['id'])
self.channel_channel_public_2.add_members((self.users[0] + self.users[2] + self.users[4] + self.users[7] + self.users[9]).partner_id.ids)
# create groups channels
self.channel_channel_group_1 = self.env['mail.channel'].browse(self.env['mail.channel'].channel_create(name='group 1', privacy='groups', group_id=self.env.ref('base.group_user').id)['id'])
# create group-restricted channels
self.channel_channel_group_1 = self.env['mail.channel'].browse(self.env['mail.channel'].channel_create(name='group restricted channel 1', group_id=self.env.ref('base.group_user').id)['id'])
self.channel_channel_group_1.add_members((self.users[0] + self.users[2] + self.users[3] + self.users[6] + self.users[12]).partner_id.ids)
self.channel_channel_group_2 = self.env['mail.channel'].browse(self.env['mail.channel'].channel_create(name='group 2', privacy='groups', group_id=self.env.ref('base.group_user').id)['id'])
self.channel_channel_group_2 = self.env['mail.channel'].browse(self.env['mail.channel'].channel_create(name='group restricted channel 2', group_id=self.env.ref('base.group_user').id)['id'])
self.channel_channel_group_2.add_members((self.users[0] + self.users[2] + self.users[6] + self.users[7] + self.users[13]).partner_id.ids)
# create private channels
self.channel_channel_private_1 = self.env['mail.channel'].browse(self.env['mail.channel'].channel_create(name='private 1', privacy='private', group_id=None)['id'])
self.channel_channel_private_1.add_members((self.users[0] + self.users[2] + self.users[3] + self.users[5] + self.users[10]).partner_id.ids)
self.channel_channel_private_2 = self.env['mail.channel'].browse(self.env['mail.channel'].channel_create(name='private 2', privacy='private', group_id=None)['id'])
self.channel_channel_private_2.add_members((self.users[0] + self.users[2] + self.users[5] + self.users[7] + self.users[11]).partner_id.ids)
# create chats
self.channel_chat_1 = self.env['mail.channel'].browse(self.env['mail.channel'].channel_get((self.users[0] + self.users[14]).partner_id.ids)['id'])
self.channel_chat_2 = self.env['mail.channel'].browse(self.env['mail.channel'].channel_get((self.users[0] + self.users[15]).partner_id.ids)['id'])
@@ -161,7 +156,6 @@ class TestDiscussFullPerformance(TransactionCase):
'last_message_id': next(res['message_id'] for res in self.channel_general._channel_last_message_ids()),
'message_needaction_counter': 0,
'name': 'general',
'public': 'groups',
'rtcSessions': [('insert', [])],
'seen_message_id': False,
'state': 'open',
@@ -210,8 +204,7 @@ class TestDiscussFullPerformance(TransactionCase):
'last_interest_dt': self.channel_channel_public_1.channel_member_ids.filtered(lambda m: m.partner_id == self.users[0].partner_id).last_interest_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
'last_message_id': next(res['message_id'] for res in self.channel_channel_public_1._channel_last_message_ids()),
'message_needaction_counter': 1,
'name': 'public 1',
'public': 'public',
'name': 'public channel 1',
'rtcSessions': [('insert', [])],
'seen_message_id': next(res['message_id'] for res in self.channel_channel_public_1._channel_last_message_ids()),
'state': 'open',
@@ -260,8 +253,7 @@ class TestDiscussFullPerformance(TransactionCase):
'last_interest_dt': self.channel_channel_public_2.channel_member_ids.filtered(lambda m: m.partner_id == self.users[0].partner_id).last_interest_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
'last_message_id': next(res['message_id'] for res in self.channel_channel_public_2._channel_last_message_ids()),
'message_needaction_counter': 0,
'name': 'public 2',
'public': 'public',
'name': 'public channel 2',
'rtcSessions': [('insert', [])],
'seen_message_id': next(res['message_id'] for res in self.channel_channel_public_2._channel_last_message_ids()),
'state': 'open',
@@ -310,8 +302,7 @@ class TestDiscussFullPerformance(TransactionCase):
'last_interest_dt': self.channel_channel_group_1.channel_member_ids.filtered(lambda m: m.partner_id == self.users[0].partner_id).last_interest_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
'last_message_id': next(res['message_id'] for res in self.channel_channel_group_1._channel_last_message_ids()),
'message_needaction_counter': 0,
'name': 'group 1',
'public': 'groups',
'name': 'group restricted channel 1',
'rtcSessions': [('insert', [])],
'seen_message_id': next(res['message_id'] for res in self.channel_channel_group_1._channel_last_message_ids()),
'state': 'open',
@@ -360,113 +351,12 @@ class TestDiscussFullPerformance(TransactionCase):
'last_interest_dt': self.channel_channel_group_2.channel_member_ids.filtered(lambda m: m.partner_id == self.users[0].partner_id).last_interest_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
'last_message_id': next(res['message_id'] for res in self.channel_channel_group_2._channel_last_message_ids()),
'message_needaction_counter': 0,
'name': 'group 2',
'public': 'groups',
'name': 'group restricted channel 2',
'rtcSessions': [('insert', [])],
'seen_message_id': next(res['message_id'] for res in self.channel_channel_group_2._channel_last_message_ids()),
'state': 'open',
'uuid': self.channel_channel_group_2.uuid,
},
{
'authorizedGroupFullName': False,
'channel': {
'anonymous_country': [('clear',)],
'anonymous_name': False,
'avatarCacheKey': self.channel_channel_private_1._get_avatar_cache_key(),
'channel_type': 'channel',
'channelMembers': [('insert', sorted([{
'channel': {
'id': self.channel_channel_private_1.id,
},
'id': self.channel_channel_private_1.channel_member_ids.filtered(lambda m: m.partner_id == self.users[0].partner_id).id,
'persona': {
'partner': {
'active': True,
'email': 'e.e@example.com',
'id': self.users[0].partner_id.id,
'im_status': 'offline',
'name': 'Ernest Employee',
'out_of_office_date_end': False,
'user': {
'id': self.users[0].id,
'isInternalUser': True,
},
},
},
}], key=lambda member_data: member_data['id']))],
'custom_channel_name': False,
'id': self.channel_channel_private_1.id,
'memberCount': 5,
'serverMessageUnreadCounter': 0,
},
'create_uid': self.env.user.id,
'defaultDisplayMode': False,
'description': False,
'group_based_subscription': False,
'id': self.channel_channel_private_1.id,
'invitedMembers': [('insert', [])],
'is_minimized': False,
'is_pinned': True,
'last_interest_dt': self.channel_channel_private_1.channel_member_ids.filtered(lambda m: m.partner_id == self.users[0].partner_id).last_interest_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
'last_message_id': next(res['message_id'] for res in self.channel_channel_private_1._channel_last_message_ids()),
'message_needaction_counter': 0,
'name': 'private 1',
'public': 'private',
'rtcSessions': [('insert', [])],
'seen_message_id': next(res['message_id'] for res in self.channel_channel_private_1._channel_last_message_ids()),
'state': 'open',
'uuid': self.channel_channel_private_1.uuid,
},
{
'authorizedGroupFullName': False,
'channel': {
'anonymous_country': [('clear',)],
'anonymous_name': False,
'avatarCacheKey': self.channel_channel_private_2._get_avatar_cache_key(),
'channel_type': 'channel',
'channelMembers': [('insert', sorted([{
'channel': {
'id': self.channel_channel_private_2.id,
},
'id': self.channel_channel_private_2.channel_member_ids.filtered(lambda m: m.partner_id == self.users[0].partner_id).id,
'persona': {
'partner': {
'active': True,
'email': 'e.e@example.com',
'id': self.users[0].partner_id.id,
'im_status': 'offline',
'name': 'Ernest Employee',
'out_of_office_date_end': False,
'user': {
'id': self.users[0].id,
'isInternalUser': True,
},
},
},
}], key=lambda member_data: member_data['id']))],
'custom_channel_name': False,
'id': self.channel_channel_private_2.id,
'memberCount': 5,
'serverMessageUnreadCounter': 0,
},
'create_uid': self.env.user.id,
'defaultDisplayMode': False,
'description': False,
'group_based_subscription': False,
'id': self.channel_channel_private_2.id,
'invitedMembers': [('insert', [])],
'is_minimized': False,
'is_pinned': True,
'last_interest_dt': self.channel_channel_private_2.channel_member_ids.filtered(lambda m: m.partner_id == self.users[0].partner_id).last_interest_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
'last_message_id': next(res['message_id'] for res in self.channel_channel_private_2._channel_last_message_ids()),
'message_needaction_counter': 0,
'name': 'private 2',
'public': 'private',
'rtcSessions': [('insert', [])],
'seen_message_id': next(res['message_id'] for res in self.channel_channel_private_2._channel_last_message_ids()),
'state': 'open',
'uuid': self.channel_channel_private_2.uuid,
},
{
'authorizedGroupFullName': False,
'channel': {
@@ -533,7 +423,6 @@ class TestDiscussFullPerformance(TransactionCase):
'last_message_id': False,
'message_needaction_counter': 0,
'name': '',
'public': 'private',
'rtcSessions': [('insert', [])],
'seen_message_id': False,
'seen_partners_info': [
@@ -619,7 +508,6 @@ class TestDiscussFullPerformance(TransactionCase):
'last_message_id': False,
'message_needaction_counter': 0,
'name': 'Ernest Employee, test14',
'public': 'private',
'rtcSessions': [('insert', [])],
'seen_partners_info': [
{
@@ -705,7 +593,6 @@ class TestDiscussFullPerformance(TransactionCase):
'last_message_id': False,
'message_needaction_counter': 0,
'name': 'Ernest Employee, test15',
'public': 'private',
'rtcSessions': [('insert', [])],
'seen_partners_info': [
{
@@ -791,7 +678,6 @@ class TestDiscussFullPerformance(TransactionCase):
'last_message_id': False,
'message_needaction_counter': 0,
'name': 'Ernest Employee, test2',
'public': 'private',
'rtcSessions': [('insert', [])],
'seen_partners_info': [
{
@@ -877,7 +763,6 @@ class TestDiscussFullPerformance(TransactionCase):
'last_message_id': False,
'message_needaction_counter': 0,
'name': 'Ernest Employee, test3',
'public': 'private',
'rtcSessions': [('insert', [])],
'seen_partners_info': [
{
@@ -958,7 +843,6 @@ class TestDiscussFullPerformance(TransactionCase):
'message_needaction_counter': 0,
'name': 'test1 Ernest Employee',
'operator_pid': (self.users[0].partner_id.id, 'Ernest Employee'),
'public': 'private',
'rtcSessions': [('insert', [])],
'seen_partners_info': [
{
@@ -1038,7 +922,6 @@ class TestDiscussFullPerformance(TransactionCase):
'message_needaction_counter': 0,
'name': 'anon 2 Ernest Employee',
'operator_pid': (self.users[0].partner_id.id, 'Ernest Employee'),
'public': 'private',
'rtcSessions': [('insert', [])],
'seen_partners_info': [
{
+4 -4
View File
@@ -331,8 +331,8 @@ class TestMessageAccess(TestMailCommon):
cls.user_public = mail_new_test_user(cls.env, login='bert', groups='base.group_public', name='Bert Tartignole')
cls.user_portal = mail_new_test_user(cls.env, login='chell', groups='base.group_portal', name='Chell Gladys')
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.public_channel = cls.env['mail.channel'].browse(cls.env['mail.channel'].channel_create(name='Public Channel', privacy='public', group_id=None)['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'])
cls.public_channel = cls.env['mail.channel'].browse(cls.env['mail.channel'].channel_create(name='Public Channel', group_id=None)['id'])
cls.private_group = cls.env['mail.channel'].browse(cls.env['mail.channel'].create_group(partners_to=cls.user_employee_1.partner_id.ids, name="Group")['id'])
cls.message = cls.env['mail.message'].create({
'body': 'My Body',
@@ -388,8 +388,8 @@ class TestMessageAccess(TestMailCommon):
messages = self.env['mail.message'].with_user(self.user_portal).search([('subject', 'like', '_ZTest')])
self.assertFalse(messages)
# Test: Portal: 2 messages (public group with a subtype)
self.group_restricted_channel.write({'public': 'public'})
# Test: Portal: 2 messages (public channel)
self.group_restricted_channel.write({'group_public_id': False})
messages = self.env['mail.message'].with_user(self.user_portal).search([('subject', 'like', '_ZTest')])
self.assertEqual(messages, msg4 | msg5)
@@ -26,7 +26,6 @@ class WebsiteLivechatChatbotScriptController(http.Controller):
'anonymous_name': False,
'channel_type': 'livechat',
'name': chatbot_script.title,
'public': 'private',
}
visitor_sudo = request.env['website.visitor']._get_visitor_from_request()
@@ -67,7 +67,6 @@ class WebsiteVisitor(models.Model):
'livechat_channel_id': visitor.website_id.channel_id.id,
'livechat_operator_id': self.env.user.partner_id.id,
'channel_type': 'livechat',
'public': 'private',
'country_id': country.id,
'anonymous_name': visitor_name,
'name': ', '.join([visitor_name, operator.livechat_username if operator.livechat_username else operator.name]),
@@ -75,7 +75,6 @@ patch(MockServer.prototype, 'website_livechat', {
channel_member_ids: membersToAdd,
channel_type: 'livechat',
livechat_operator_id: this.currentPartnerId,
public: 'private',
});
// notify operator
this.pyEnv['bus.bus']._sendone(this.currentPartner, 'website_livechat.send_chat_request',