[REF] mail: migrated tests to the new API and refactored them.
Tests have been migrated to the new api to prepare the migration of the mail module itself. Moreover tests have been cleaned: redundant tests and unnecessary tests have been removed. As the base test class in mail is used in other addons, other addons have been updated : - portal - project - portal_project - website_project_issue - sale - purchase Future commits will come with somes fixes for issues detected when cleaning the tests.
This commit is contained in:
committed by
Thibault Delavallée
parent
573341c906
commit
b55969a577
@@ -1,22 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from . import test_mail_group, test_mail_message, test_mail_features, test_mail_gateway, test_message_read, test_invite, test_mail, test_ir_actions
|
||||
import test_mail_followers
|
||||
import test_mail_message
|
||||
import test_mail_features
|
||||
import test_mail_group
|
||||
import test_mail_gateway
|
||||
import test_message_read
|
||||
import test_message_track
|
||||
import test_mail_template
|
||||
import test_invite
|
||||
import test_ir_actions
|
||||
|
||||
+127
-90
@@ -1,23 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import socket
|
||||
|
||||
from openerp.tests import common
|
||||
|
||||
@@ -25,108 +8,162 @@ from openerp.tests import common
|
||||
class TestMail(common.TransactionCase):
|
||||
|
||||
def _init_mock_build_email(self):
|
||||
self._build_email_args_list = []
|
||||
self._build_email_kwargs_list = []
|
||||
self._mails_args = []
|
||||
self._mails = []
|
||||
|
||||
def format_and_process(self, template, to='groups@example.com, other@gmail.com', subject='Frogs',
|
||||
extra='', email_from='Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>',
|
||||
cc='', msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>',
|
||||
model=None, target_model='mail.group', target_field='name'):
|
||||
self.assertFalse(self.env[target_model].search([(target_field, '=', subject)]))
|
||||
mail = template.format(to=to, subject=subject, cc=cc, extra=extra, email_from=email_from, msg_id=msg_id)
|
||||
self.env['mail.thread'].message_process(model, mail)
|
||||
return self.env[target_model].search([(target_field, '=', subject)])
|
||||
|
||||
def setUp(self):
|
||||
super(TestMail, self).setUp()
|
||||
cr, uid = self.cr, self.uid
|
||||
|
||||
# Install mock SMTP gateway
|
||||
test = self
|
||||
Test = self
|
||||
|
||||
def build_email(self, *args, **kwargs):
|
||||
test._build_email_args_list.append(args)
|
||||
test._build_email_kwargs_list.append(kwargs)
|
||||
Test._mails_args.append(args)
|
||||
Test._mails.append(kwargs)
|
||||
return build_email.origin(self, *args, **kwargs)
|
||||
|
||||
def send_email(self, cr, uid, message, *args, **kwargs):
|
||||
return message['Message-Id']
|
||||
|
||||
self._init_mock_build_email()
|
||||
self.registry('ir.mail_server')._patch_method('build_email', build_email)
|
||||
self.registry('ir.mail_server')._patch_method('send_email', send_email)
|
||||
self.env['ir.mail_server']._patch_method('build_email', build_email)
|
||||
self.env['ir.mail_server']._patch_method('send_email', send_email)
|
||||
|
||||
# Usefull models
|
||||
self.ir_model = self.registry('ir.model')
|
||||
self.ir_model_data = self.registry('ir.model.data')
|
||||
self.ir_attachment = self.registry('ir.attachment')
|
||||
self.mail_alias = self.registry('mail.alias')
|
||||
self.mail_thread = self.registry('mail.thread')
|
||||
self.mail_group = self.registry('mail.group')
|
||||
self.mail_mail = self.registry('mail.mail')
|
||||
self.mail_message = self.registry('mail.message')
|
||||
self.mail_notification = self.registry('mail.notification')
|
||||
self.mail_followers = self.registry('mail.followers')
|
||||
self.mail_message_subtype = self.registry('mail.message.subtype')
|
||||
self.res_users = self.registry('res.users')
|
||||
self.res_partner = self.registry('res.partner')
|
||||
|
||||
# Find Employee group
|
||||
group_employee_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_user')
|
||||
self.group_employee_id = group_employee_ref and group_employee_ref[1] or False
|
||||
|
||||
# Partner Data
|
||||
# User groups
|
||||
user_group_employee = self.env.ref('base.group_user')
|
||||
user_group_portal = self.env.ref('base.group_portal')
|
||||
user_group_public = self.env.ref('base.group_public')
|
||||
|
||||
# User Data: employee, noone
|
||||
self.user_employee_id = self.res_users.create(cr, uid, {
|
||||
Users = self.env['res.users'].with_context({'no_reset_password': True})
|
||||
self.user_employee = Users.create({
|
||||
'name': 'Ernest Employee',
|
||||
'login': 'ernest',
|
||||
'alias_name': 'ernest',
|
||||
'email': 'e.e@example.com',
|
||||
'signature': '--\nErnest',
|
||||
'notify_email': 'always',
|
||||
'groups_id': [(6, 0, [self.group_employee_id])]
|
||||
}, {'no_reset_password': True})
|
||||
self.user_noone_id = self.res_users.create(cr, uid, {
|
||||
'groups_id': [(6, 0, [user_group_employee.id])]})
|
||||
self.user_employee_2 = Users.create({
|
||||
'name': 'Raoul Grosbedon',
|
||||
'login': 'raoul',
|
||||
'alias_name': 'raoul',
|
||||
'email': 'r.g@example.com',
|
||||
'signature': 'SignRaoul',
|
||||
'notify_email': 'always',
|
||||
'groups_id': [(6, 0, [user_group_employee.id])]})
|
||||
self.user_noone = Users.create({
|
||||
'name': 'Noemie NoOne',
|
||||
'login': 'noemie',
|
||||
'alias_name': 'noemie',
|
||||
'email': 'n.n@example.com',
|
||||
'signature': '--\nNoemie',
|
||||
'notify_email': 'always',
|
||||
'groups_id': [(6, 0, [])]
|
||||
}, {'no_reset_password': True})
|
||||
|
||||
# Test users to use through the various tests
|
||||
self.res_users.write(cr, uid, [uid], {'name': 'Administrator'})
|
||||
self.user_raoul_id = self.res_users.create(cr, uid, {
|
||||
'name': 'Raoul Grosbedon',
|
||||
'signature': 'SignRaoul',
|
||||
'email': 'raoul@raoul.fr',
|
||||
'login': 'raoul',
|
||||
'alias_name': 'raoul',
|
||||
'groups_id': [(6, 0, [self.group_employee_id])]
|
||||
})
|
||||
self.user_bert_id = self.res_users.create(cr, uid, {
|
||||
'groups_id': [(6, 0, [])]})
|
||||
self.user_public = Users.create({
|
||||
'name': 'Bert Tartignole',
|
||||
'signature': 'SignBert',
|
||||
'email': 'bert@bert.fr',
|
||||
'login': 'bert',
|
||||
'alias_name': 'bert',
|
||||
'groups_id': [(6, 0, [])]
|
||||
'email': 'b.t@example.com',
|
||||
'signature': 'SignBert',
|
||||
'notify_email': 'always',
|
||||
'groups_id': [(6, 0, [user_group_public.id])]})
|
||||
self.user_portal = Users.create({
|
||||
'name': 'Chell Gladys',
|
||||
'login': 'chell',
|
||||
'alias_name': 'chell',
|
||||
'email': 'chell@gladys.portal',
|
||||
'signature': 'SignChell',
|
||||
'notify_email': 'always',
|
||||
'groups_id': [(6, 0, [user_group_portal.id])]})
|
||||
self.user_admin = self.env.user
|
||||
# Update admin
|
||||
# Set an email address for the user running the tests, used as Sender for outgoing mails
|
||||
self._company_name = 'TestCompany'
|
||||
self._admin_name = 'Administrator'
|
||||
self._admin_email = 'test@localhost'
|
||||
self.user_admin.write({
|
||||
'email': self._admin_email,
|
||||
'name': self._admin_name,
|
||||
'signature': 'SignAdmin',
|
||||
'notify_email': 'always',
|
||||
})
|
||||
self.user_admin.company_id.write({
|
||||
'name': self._company_name,
|
||||
})
|
||||
self.user_raoul = self.res_users.browse(cr, uid, self.user_raoul_id)
|
||||
self.user_bert = self.res_users.browse(cr, uid, self.user_bert_id)
|
||||
self.user_admin = self.res_users.browse(cr, uid, uid)
|
||||
self.partner_admin_id = self.user_admin.partner_id.id
|
||||
self.partner_raoul_id = self.user_raoul.partner_id.id
|
||||
self.partner_bert_id = self.user_bert.partner_id.id
|
||||
|
||||
# Test 'pigs' group to use through the various tests
|
||||
self.group_pigs_id = self.mail_group.create(
|
||||
cr, uid,
|
||||
{'name': 'Pigs', 'description': 'Fans of Pigs, unite !', 'alias_name': 'group+pigs'},
|
||||
{'mail_create_nolog': True}
|
||||
)
|
||||
self.group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
|
||||
# Test mail.group: public to provide access to everyone
|
||||
self.group_jobs_id = self.mail_group.create(cr, uid, {'name': 'Jobs', 'public': 'public'})
|
||||
# Test mail.group: private to restrict access
|
||||
self.group_priv_id = self.mail_group.create(cr, uid, {'name': 'Private', 'public': 'private'})
|
||||
# Test Data for Partners
|
||||
self.partner_1 = self.env['res.partner'].create({
|
||||
'name': 'Valid Lelitre',
|
||||
'email': 'valid.lelitre@agrolait.com',
|
||||
'notify_email': 'always'})
|
||||
self.partner_2 = self.env['res.partner'].create({
|
||||
'name': 'Valid Poilvache',
|
||||
'email': 'valid.other@gmail.com',
|
||||
'notify_email': 'always'})
|
||||
|
||||
# Create test groups without followers and messages by default
|
||||
TestMailGroup = self.env['mail.group'].with_context({
|
||||
'mail_create_nolog': True,
|
||||
'mail_create_nosubscribe': True
|
||||
})
|
||||
# Pigs: base group for tests
|
||||
self.group_pigs = TestMailGroup.create({
|
||||
'name': 'Pigs',
|
||||
'description': 'Fans of Pigs, unite !',
|
||||
'public': 'groups',
|
||||
'group_public_id': user_group_employee.id,
|
||||
'alias_name': 'pigs',
|
||||
'alias_contact': 'followers'}
|
||||
).with_context({'mail_create_nosubscribe': False})
|
||||
# Jobs: public group
|
||||
self.group_public = TestMailGroup.create({
|
||||
'name': 'Jobs',
|
||||
'description': 'NotFalse',
|
||||
'public': 'public',
|
||||
'alias_name': 'public',
|
||||
'alias_contact': 'everyone'}
|
||||
).with_context({'mail_create_nosubscribe': False})
|
||||
# Private: private group
|
||||
self.group_private = TestMailGroup.create({
|
||||
'name': 'Private',
|
||||
'public': 'private'}
|
||||
).with_context({'mail_create_nosubscribe': False})
|
||||
# Portal: group-based group using portal group
|
||||
self.group_portal = TestMailGroup.create({
|
||||
'name': 'PigsPortal',
|
||||
'public': 'groups',
|
||||
'group_public_id': user_group_portal.id}
|
||||
).with_context({'mail_create_nosubscribe': False})
|
||||
|
||||
# groups@.. will cause the creation of new mail groups
|
||||
self.mail_group_model = self.env['ir.model'].search([('model', '=', 'mail.group')], limit=1)
|
||||
self.alias = self.env['mail.alias'].create({
|
||||
'alias_name': 'groups',
|
||||
'alias_user_id': False,
|
||||
'alias_model_id': self.mail_group_model.id,
|
||||
'alias_contact': 'everyone'})
|
||||
|
||||
# Set a first message on public group to test update and hierarchy
|
||||
self.fake_email = self.env['mail.message'].create({
|
||||
'model': 'mail.group',
|
||||
'res_id': self.group_public.id,
|
||||
'subject': 'Public Discussion',
|
||||
'type': 'email',
|
||||
'author_id': self.partner_1.id,
|
||||
'message_id': '<123456-openerp-%s-mail.group@%s>' % (self.group_public.id, socket.gethostname()),
|
||||
})
|
||||
|
||||
self._init_mock_build_email()
|
||||
|
||||
def tearDown(self):
|
||||
# Remove mocks
|
||||
self.registry('ir.mail_server')._revert_method('build_email')
|
||||
self.registry('ir.mail_server')._revert_method('send_email')
|
||||
self.env['ir.mail_server']._revert_method('build_email')
|
||||
self.env['ir.mail_server']._revert_method('send_email')
|
||||
super(TestMail, self).tearDown()
|
||||
|
||||
@@ -1,48 +1,35 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.mail.tests.common import TestMail
|
||||
from openerp.tools import mute_logger
|
||||
|
||||
|
||||
class test_invite(TestMail):
|
||||
class TestInvite(TestMail):
|
||||
|
||||
def test_00_basic_invite(self):
|
||||
cr, uid = self.cr, self.uid
|
||||
mail_invite = self.registry('mail.wizard.invite')
|
||||
|
||||
# Do: create a mail_wizard_invite, validate it
|
||||
self._init_mock_build_email()
|
||||
context = {'default_res_model': 'mail.group', 'default_res_id': self.group_pigs_id}
|
||||
mail_invite_id = mail_invite.create(cr, self.user_raoul_id, {'partner_ids': [(4, self.partner_bert_id)], 'send_mail': True}, context)
|
||||
mail_invite.add_followers(cr, self.user_raoul_id, [mail_invite_id], {'default_model': 'mail.group', 'default_res_id': 0})
|
||||
@mute_logger('openerp.addons.mail.mail_mail')
|
||||
def test_invite_email(self):
|
||||
mail_invite = self.env['mail.wizard.invite'].with_context({
|
||||
'default_res_model': 'mail.group',
|
||||
'default_res_id': self.group_pigs.id
|
||||
}).sudo(self.user_employee.id).create({
|
||||
'partner_ids': [(4, self.user_portal.partner_id.id), (4, self.user_employee_2.partner_id.id)],
|
||||
'send_mail': True})
|
||||
mail_invite.add_followers()
|
||||
|
||||
# Test: Pigs followers should contain Admin, Bert
|
||||
self.group_pigs.refresh()
|
||||
follower_ids = [follower.id for follower in self.group_pigs.message_follower_ids]
|
||||
self.assertEqual(set(follower_ids), set([self.partner_admin_id, self.partner_bert_id]), 'invite: Pigs followers after invite is incorrect')
|
||||
self.assertEqual(self.group_pigs.message_follower_ids,
|
||||
self.user_portal.partner_id | self.user_employee_2.partner_id,
|
||||
'invite wizard: Pigs followers after invite is incorrect, should be Admin + added follower')
|
||||
|
||||
# Test: (pretend to) send email and check subject, body
|
||||
self.assertEqual(len(self._build_email_kwargs_list), 1, 'sent email number incorrect, should be only for Bert')
|
||||
for sent_email in self._build_email_kwargs_list:
|
||||
self.assertEqual(sent_email.get('subject'), 'Invitation to follow Discussion group: Pigs',
|
||||
'invite: subject of invitation email is incorrect')
|
||||
self.assertIn('Raoul Grosbedon invited you to follow Discussion group document: Pigs', sent_email.get('body'),
|
||||
'invite: body of invitation email is incorrect')
|
||||
self.assertEqual(len(self._mails), 2, 'invite wizard: sent email number incorrect, should be only for Bert')
|
||||
self.assertEqual(self._mails[0].get('subject'), 'Invitation to follow Discussion group: Pigs',
|
||||
'invite wizard: subject of invitation email is incorrect')
|
||||
self.assertEqual(self._mails[1].get('subject'), 'Invitation to follow Discussion group: Pigs',
|
||||
'invite wizard: subject of invitation email is incorrect')
|
||||
self.assertIn('%s invited you to follow Discussion group document: Pigs' % self.user_employee.name,
|
||||
self._mails[0].get('body'),
|
||||
'invite wizard: body of invitation email is incorrect')
|
||||
self.assertIn('%s invited you to follow Discussion group document: Pigs' % self.user_employee.name,
|
||||
self._mails[1].get('body'),
|
||||
'invite wizard: body of invitation email is incorrect')
|
||||
|
||||
@@ -1,23 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2013-TODAY OpenERP S.A. <http://www.openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.base.tests.test_ir_actions import TestServerActionsBase
|
||||
|
||||
@@ -26,10 +7,8 @@ class TestServerActionsEmail(TestServerActionsBase):
|
||||
|
||||
def test_00_state_email(self):
|
||||
""" Test ir.actions.server email type """
|
||||
cr, uid = self.cr, self.uid
|
||||
|
||||
# create email_template
|
||||
template_id = self.registry('mail.template').create(cr, uid, {
|
||||
email_template = self.env['mail.template'].create({
|
||||
'name': 'TestTemplate',
|
||||
'email_from': 'myself@example.com',
|
||||
'email_to': 'brigitte@example.com',
|
||||
@@ -38,18 +17,13 @@ class TestServerActionsEmail(TestServerActionsBase):
|
||||
'subject': 'About ${object.name}',
|
||||
'body_html': '<p>Dear ${object.name}, your parent is ${object.parent_id and object.parent_id.name or "False"}</p>',
|
||||
})
|
||||
|
||||
self.ir_actions_server.write(cr, uid, self.act_id, {
|
||||
'state': 'email',
|
||||
'template_id': template_id,
|
||||
})
|
||||
run_res = self.ir_actions_server.run(cr, uid, [self.act_id], context=self.context)
|
||||
action = self.env['ir.actions.server'].browse(self.act_id)
|
||||
action.write({'state': 'email', 'template_id': email_template.id})
|
||||
run_res = action.with_context(self.context).run()
|
||||
self.assertFalse(run_res, 'ir_actions_server: email server action correctly finished should return False')
|
||||
|
||||
# check an email is waiting for sending
|
||||
mail_ids = self.registry('mail.mail').search(cr, uid, [('subject', '=', 'About TestingPartner')])
|
||||
self.assertEqual(len(mail_ids), 1, 'ir_actions_server: TODO')
|
||||
mail = self.env['mail.mail'].search([('subject', '=', 'About TestingPartner')])
|
||||
self.assertEqual(len(mail.ids), 1, 'ir_actions_server: TODO')
|
||||
# check email content
|
||||
mail = self.registry('mail.mail').browse(cr, uid, mail_ids[0])
|
||||
self.assertEqual(mail.body, '<p>Dear TestingPartner, your parent is False</p>',
|
||||
'ir_actions_server: TODO')
|
||||
|
||||
@@ -1,244 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import base64
|
||||
from openerp.addons.mail.tests.common import TestMail
|
||||
from openerp.tools import mute_logger
|
||||
|
||||
|
||||
class test_message_compose(TestMail):
|
||||
|
||||
def setUp(self):
|
||||
super(test_message_compose, self).setUp()
|
||||
|
||||
# create a 'pigs' and 'bird' groups that will be used through the various tests
|
||||
self.group_bird_id = self.mail_group.create(self.cr, self.uid,
|
||||
{'name': 'Bird', 'description': 'I am angry !'})
|
||||
|
||||
def test_00_message_compose_wizard(self):
|
||||
""" Tests designed for the mail.compose.message wizard updated by email_template. """
|
||||
cr, uid = self.cr, self.uid
|
||||
mail_compose = self.registry('mail.compose.message')
|
||||
self.res_users.write(cr, uid, [uid], {'signature': 'Admin', 'email': 'a@a.a'})
|
||||
user_admin = self.res_users.browse(cr, uid, uid)
|
||||
p_a_id = user_admin.partner_id.id
|
||||
group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
|
||||
group_bird = self.mail_group.browse(cr, uid, self.group_bird_id)
|
||||
|
||||
# Mail data
|
||||
_subject1 = 'Pigs'
|
||||
_subject2 = 'Bird'
|
||||
_body_html1 = 'Fans of Pigs, unite !'
|
||||
_body_html2 = 'I am angry !'
|
||||
_attachments = [
|
||||
{'name': 'First', 'datas_fname': 'first.txt', 'datas': base64.b64encode('My first attachment'), 'res_model': 'res.partner', 'res_id': self.partner_admin_id},
|
||||
{'name': 'Second', 'datas_fname': 'second.txt', 'datas': base64.b64encode('My second attachment'), 'res_model': 'res.partner', 'res_id': self.partner_admin_id},
|
||||
]
|
||||
_attachments_test = [('first.txt', 'My first attachment'), ('second.txt', 'My second attachment')]
|
||||
|
||||
# Create template on mail.group, with attachments
|
||||
group_model_id = self.registry('ir.model').search(cr, uid, [('model', '=', 'mail.group')])[0]
|
||||
email_template = self.registry('mail.template')
|
||||
email_template_id = email_template.create(cr, uid, {
|
||||
'model_id': group_model_id,
|
||||
'name': 'Pigs Template',
|
||||
'subject': '${object.name}',
|
||||
'body_html': '${object.description}',
|
||||
'user_signature': False,
|
||||
'attachment_ids': [(0, 0, _attachments[0]), (0, 0, _attachments[1])],
|
||||
'email_to': 'b@b.b, c@c.c',
|
||||
'email_cc': 'd@d.d'
|
||||
})
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE1: comment and save as template
|
||||
# ----------------------------------------
|
||||
|
||||
# 1. Comment on pigs
|
||||
compose_id = mail_compose.create(cr, uid,
|
||||
{'subject': 'Forget me subject', 'body': '<p>Dummy body</p>'},
|
||||
{'default_composition_mode': 'comment',
|
||||
'default_model': 'mail.group',
|
||||
'default_res_id': self.group_pigs_id,
|
||||
'active_ids': [self.group_pigs_id, self.group_bird_id]})
|
||||
compose = mail_compose.browse(cr, uid, compose_id)
|
||||
|
||||
# 2. Save current composition form as a template
|
||||
mail_compose.save_as_template(cr, uid, [compose_id], context={'default_model': 'mail.group'})
|
||||
# Test: email_template subject, body_html, model
|
||||
last_template_id = email_template.search(cr, uid, [('model', '=', 'mail.group'), ('subject', '=', 'Forget me subject')], limit=1)[0]
|
||||
self.assertTrue(last_template_id, 'email_template not found for model mail.group, subject Forget me subject')
|
||||
last_template = email_template.browse(cr, uid, last_template_id)
|
||||
self.assertEqual(last_template.body_html, '<p>Dummy body</p>', 'email_template incorrect body_html')
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE2: comment with template, save as template
|
||||
# ----------------------------------------
|
||||
|
||||
# 1. Comment on pigs
|
||||
context = {
|
||||
'default_composition_mode': 'comment',
|
||||
'default_model': 'mail.group',
|
||||
'default_res_id': self.group_pigs_id,
|
||||
'default_use_template': False,
|
||||
'default_template_id': email_template_id,
|
||||
'active_ids': [self.group_pigs_id, self.group_bird_id]
|
||||
}
|
||||
compose_id = mail_compose.create(cr, uid, {'subject': 'Forget me subject', 'body': 'Dummy body'}, context)
|
||||
compose = mail_compose.browse(cr, uid, compose_id, context)
|
||||
onchange_res = compose.onchange_template_id(email_template_id, 'comment', 'mail.group', self.group_pigs_id)['value']
|
||||
onchange_res['partner_ids'] = [(4, partner_id) for partner_id in onchange_res.pop('partner_ids', [])]
|
||||
onchange_res['attachment_ids'] = [(4, attachment_id) for attachment_id in onchange_res.pop('attachment_ids', [])]
|
||||
compose.write(onchange_res)
|
||||
compose.refresh()
|
||||
|
||||
message_pids = [partner.id for partner in compose.partner_ids]
|
||||
partner_ids = self.res_partner.search(cr, uid, [('email', 'in', ['b@b.b', 'c@c.c', 'd@d.d'])])
|
||||
# Test: mail.compose.message: subject, body, partner_ids
|
||||
self.assertEqual(compose.subject, _subject1, 'mail.compose.message subject incorrect')
|
||||
self.assertIn(_body_html1, compose.body, 'mail.compose.message body incorrect')
|
||||
self.assertEqual(set(message_pids), set(partner_ids), 'mail.compose.message partner_ids incorrect')
|
||||
# Test: mail.compose.message: attachments (owner has not been modified)
|
||||
for attach in compose.attachment_ids:
|
||||
self.assertEqual(attach.res_model, 'res.partner', 'mail.compose.message attachment res_model through templat was overriden')
|
||||
self.assertEqual(attach.res_id, self.partner_admin_id, 'mail.compose.message attachment res_id incorrect')
|
||||
self.assertIn((attach.datas_fname, base64.b64decode(attach.datas)), _attachments_test,
|
||||
'mail.message attachment name / data incorrect')
|
||||
# Test: mail.message: attachments
|
||||
mail_compose.send_mail(cr, uid, [compose_id])
|
||||
group_pigs.refresh()
|
||||
message_pigs = group_pigs.message_ids[0]
|
||||
for attach in message_pigs.attachment_ids:
|
||||
self.assertEqual(attach.res_model, 'mail.group', 'mail.compose.message attachment res_model through templat was overriden')
|
||||
self.assertEqual(attach.res_id, self.group_pigs_id, 'mail.compose.message attachment res_id incorrect')
|
||||
self.assertIn((attach.datas_fname, base64.b64decode(attach.datas)), _attachments_test,
|
||||
'mail.message attachment name / data incorrect')
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE3: mass_mail with template
|
||||
# ----------------------------------------
|
||||
|
||||
# 1. Mass_mail on pigs and bird, with a default_partner_ids set to check he is correctly added
|
||||
context = {
|
||||
'default_composition_mode': 'mass_mail',
|
||||
'default_notify': True,
|
||||
'default_model': 'mail.group',
|
||||
'default_res_id': self.group_pigs_id,
|
||||
'default_template_id': email_template_id,
|
||||
'default_partner_ids': [p_a_id],
|
||||
'active_ids': [self.group_pigs_id, self.group_bird_id]
|
||||
}
|
||||
compose_id = mail_compose.create(cr, uid, {'subject': 'Forget me subject', 'body': 'Dummy body'}, context)
|
||||
compose = mail_compose.browse(cr, uid, compose_id, context)
|
||||
onchange_res = compose.onchange_template_id(email_template_id, 'mass_mail', 'mail.group', self.group_pigs_id)['value']
|
||||
onchange_res['partner_ids'] = [(4, partner_id) for partner_id in onchange_res.pop('partner_ids', [])]
|
||||
onchange_res['attachment_ids'] = [(4, attachment_id) for attachment_id in onchange_res.pop('attachment_ids', [])]
|
||||
compose.write(onchange_res)
|
||||
compose.refresh()
|
||||
|
||||
message_pids = [partner.id for partner in compose.partner_ids]
|
||||
partner_ids = [p_a_id]
|
||||
self.assertEqual(compose.subject, '${object.name}', 'mail.compose.message subject incorrect')
|
||||
self.assertEqual(compose.body, '<p>${object.description}</p>', 'mail.compose.message body incorrect') # todo: check signature
|
||||
self.assertEqual(set(message_pids), set(partner_ids), 'mail.compose.message partner_ids incorrect')
|
||||
|
||||
# 2. Post the comment, get created message
|
||||
mail_compose.send_mail(cr, uid, [compose_id], context={'default_res_id': -1, 'active_ids': [self.group_pigs_id, self.group_bird_id]})
|
||||
group_pigs.refresh()
|
||||
group_bird.refresh()
|
||||
message_pigs = group_pigs.message_ids[0]
|
||||
message_bird = group_bird.message_ids[0]
|
||||
# Test: subject, body
|
||||
self.assertEqual(message_pigs.subject, _subject1, 'mail.message subject on Pigs incorrect')
|
||||
self.assertEqual(message_bird.subject, _subject2, 'mail.message subject on Bird incorrect')
|
||||
self.assertIn(_body_html1, message_pigs.body, 'mail.message body on Pigs incorrect')
|
||||
self.assertIn(_body_html2, message_bird.body, 'mail.message body on Bird incorrect')
|
||||
# Test: partner_ids: p_a_id (default) + 3 newly created partners
|
||||
# message_pigs_pids = [partner.id for partner in message_pigs.notified_partner_ids]
|
||||
# message_bird_pids = [partner.id for partner in message_bird.notified_partner_ids]
|
||||
# partner_ids = self.res_partner.search(cr, uid, [('email', 'in', ['b@b.b', 'c@c.c', 'd@d.d'])])
|
||||
# partner_ids.append(p_a_id)
|
||||
# self.assertEqual(set(message_pigs_pids), set(partner_ids), 'mail.message on pigs incorrect number of notified_partner_ids')
|
||||
# self.assertEqual(set(message_bird_pids), set(partner_ids), 'mail.message on bird notified_partner_ids incorrect')
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE4: test newly introduced partner_to field
|
||||
# ----------------------------------------
|
||||
|
||||
# get already-created partners back
|
||||
p_b_id = self.res_partner.search(cr, uid, [('email', '=', 'b@b.b')])[0]
|
||||
p_c_id = self.res_partner.search(cr, uid, [('email', '=', 'c@c.c')])[0]
|
||||
p_d_id = self.res_partner.search(cr, uid, [('email', '=', 'd@d.d')])[0]
|
||||
# modify template: use partner_to, use template and email address in email_to to test all features together
|
||||
user_model_id = self.registry('ir.model').search(cr, uid, [('model', '=', 'res.users')])[0]
|
||||
email_template.write(cr, uid, [email_template_id], {
|
||||
'model_id': user_model_id,
|
||||
'body_html': '${object.login}',
|
||||
'email_to': '${object.email}, c@c',
|
||||
'partner_to': '%i,%i' % (p_b_id, p_c_id),
|
||||
'email_cc': 'd@d',
|
||||
})
|
||||
# patner by email + partner by id (no double)
|
||||
send_to = [p_a_id, p_b_id, p_c_id, p_d_id]
|
||||
# Generate messsage with default email and partner on template
|
||||
mail_value = mail_compose.generate_email_for_composer(cr, uid, email_template_id, uid)
|
||||
self.assertEqual(set(mail_value['partner_ids']), set(send_to), 'mail.message partner_ids list created by template is incorrect')
|
||||
|
||||
@mute_logger('openerp.models')
|
||||
def test_10_email_templating(self):
|
||||
""" Tests designed for the mail.compose.message wizard updated by email_template. """
|
||||
cr, uid, context = self.cr, self.uid, {}
|
||||
|
||||
# create the mail.template on mail.group model
|
||||
group_model_id = self.registry('ir.model').search(cr, uid, [('model', '=', 'mail.group')])[0]
|
||||
email_template = self.registry('mail.template')
|
||||
email_template_id = email_template.create(cr, uid, {
|
||||
'model_id': group_model_id,
|
||||
'name': 'Pigs Template',
|
||||
'email_from': 'Raoul Grosbedon <raoul@example.com>',
|
||||
'subject': '${object.name}',
|
||||
'body_html': '${object.description}',
|
||||
'user_signature': True,
|
||||
'email_to': 'b@b.b, c@c.c',
|
||||
'email_cc': 'd@d.d',
|
||||
'partner_to': '${user.partner_id.id},%s,%s,-1' % (self.user_raoul.partner_id.id, self.user_bert.partner_id.id)
|
||||
})
|
||||
|
||||
# not force send: email_recipients is not taken into account
|
||||
msg_id = email_template.send_mail(cr, uid, email_template_id, self.group_pigs_id, context=context)
|
||||
mail = self.mail_mail.browse(cr, uid, msg_id, context=context)
|
||||
self.assertEqual(mail.subject, 'Pigs', 'email_template: send_mail: wrong subject')
|
||||
self.assertEqual(mail.email_to, 'b@b.b, c@c.c', 'email_template: send_mail: wrong email_to')
|
||||
self.assertEqual(mail.email_cc, 'd@d.d', 'email_template: send_mail: wrong email_cc')
|
||||
self.assertEqual(
|
||||
set([partner.id for partner in mail.recipient_ids]),
|
||||
set((self.partner_admin_id, self.user_raoul.partner_id.id, self.user_bert.partner_id.id)),
|
||||
'email_template: send_mail: wrong management of partner_to')
|
||||
|
||||
# force send: take email_recipients into account
|
||||
email_template.send_mail(cr, uid, email_template_id, self.group_pigs_id, force_send=True, context=context)
|
||||
sent_emails = self._build_email_kwargs_list
|
||||
email_to_lst = [
|
||||
['b@b.b', 'c@c.c'], ['Administrator <admin@yourcompany.example.com>'],
|
||||
['Raoul Grosbedon <raoul@raoul.fr>'], ['Bert Tartignole <bert@bert.fr>']]
|
||||
self.assertEqual(len(sent_emails), 4, 'email_template: send_mail: 3 valid email recipients + email_to -> should send 4 emails')
|
||||
for email in sent_emails:
|
||||
self.assertIn(email['email_to'], email_to_lst, 'email_template: send_mail: wrong email_recipients')
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,95 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from openerp.addons.mail.tests.common import TestMail
|
||||
|
||||
|
||||
class TestMailFollowers(TestMail):
|
||||
|
||||
def setUp(self):
|
||||
super(TestMailFollowers, self).setUp()
|
||||
Subtype = self.env['mail.message.subtype']
|
||||
self.mt_mg_def = Subtype.create({'name': 'mt_mg_def', 'default': True, 'res_model': 'mail.group'})
|
||||
self.mt_cl_def = Subtype.create({'name': 'mt_cl_def', 'default': True, 'res_model': 'crm.lead'})
|
||||
self.mt_al_def = Subtype.create({'name': 'mt_al_def', 'default': True, 'res_model': False})
|
||||
self.mt_mg_nodef = Subtype.create({'name': 'mt_mg_nodef', 'default': False, 'res_model': 'mail.group'})
|
||||
self.mt_al_nodef = Subtype.create({'name': 'mt_al_nodef', 'default': False, 'res_model': False})
|
||||
self.default_group_subtypes = Subtype.search([('default', '=', True), '|', ('res_model', '=', 'mail.group'), ('res_model', '=', False)])
|
||||
|
||||
def test_message_follower_ids_commands(self):
|
||||
# Create some dummy data on other groups to ensure they are not altered
|
||||
group_dummy = self.env['mail.group'].with_context({'mail_create_nolog': True}).create({'name': 'Dummy group'})
|
||||
self.env['mail.followers'].create({'res_model': 'mail.thread', 'res_id': group_dummy.id, 'partner_id': self.partner_1.id})
|
||||
|
||||
# Add 2 followers through the (4, ID) command
|
||||
self.group_pigs.write({'message_follower_ids': [(4, self.partner_1.id), (4, self.partner_2.id)]})
|
||||
self.assertEqual(self.group_pigs.message_follower_ids, self.partner_1 | self.partner_2)
|
||||
|
||||
# Remove 1 follower through the (3, ID) command
|
||||
self.group_pigs.write({'message_follower_ids': [(3, self.partner_2.id)]})
|
||||
self.assertEqual(self.group_pigs.message_follower_ids, self.partner_1)
|
||||
|
||||
# Set followers through the (6, 0, IDs) command
|
||||
self.group_pigs.write({'message_follower_ids': [(6, 0, [self.partner_2.id, self.user_employee_2.partner_id.id])]})
|
||||
self.assertEqual(self.group_pigs.message_follower_ids,
|
||||
self.partner_2 | self.user_employee_2.partner_id)
|
||||
|
||||
# Add 1 follower through the (0, 0, values) command
|
||||
self.group_pigs.write({'message_follower_ids': [(0, 0, {'name': 'Patrick Fiori'})]})
|
||||
partner_patrick = self.env['res.partner'].search([('name', '=', 'Patrick Fiori')], limit=1)
|
||||
self.assertEqual(self.group_pigs.message_follower_ids,
|
||||
self.partner_2 | self.user_employee_2.partner_id | partner_patrick)
|
||||
|
||||
# Remove all followers through a (5, 0) command
|
||||
self.group_pigs.write({'message_follower_ids': [(5, 0)]})
|
||||
self.assertFalse(self.group_pigs.message_follower_ids)
|
||||
|
||||
# Test dummy data has not been altered
|
||||
followers = self.env['mail.followers'].search([('res_model', '=', 'mail.thread'), ('res_id', '=', group_dummy.id)])
|
||||
self.assertEqual(followers.mapped('partner_id'), self.partner_1, 'dummy data altered')
|
||||
|
||||
def test_followers_subtypes_default(self):
|
||||
self.group_pigs.message_subscribe_users(user_ids=[self.user_employee.id])
|
||||
self.assertEqual(self.group_pigs.message_follower_ids, self.user_employee.partner_id)
|
||||
follower = self.env['mail.followers'].search([
|
||||
('res_model', '=', 'mail.group'),
|
||||
('res_id', '=', self.group_pigs.id),
|
||||
('partner_id', '=', self.user_employee.partner_id.id)])
|
||||
self.assertEqual(len(follower), 1)
|
||||
self.assertEqual(follower.subtype_ids, self.default_group_subtypes)
|
||||
|
||||
def test_followers_subtypes_specified(self):
|
||||
self.group_pigs.sudo(self.user_employee).message_subscribe_users(subtype_ids=[self.mt_mg_nodef.id])
|
||||
self.assertEqual(self.group_pigs.message_follower_ids, self.user_employee.partner_id)
|
||||
follower = self.env['mail.followers'].search([
|
||||
('res_model', '=', 'mail.group'),
|
||||
('res_id', '=', self.group_pigs.id),
|
||||
('partner_id', '=', self.user_employee.partner_id.id)])
|
||||
self.assertEqual(len(follower), 1)
|
||||
self.assertEqual(follower.subtype_ids, self.mt_mg_nodef)
|
||||
|
||||
def test_followers_multiple_subscription(self):
|
||||
self.group_pigs.sudo(self.user_employee).message_subscribe_users(subtype_ids=[self.mt_mg_nodef.id])
|
||||
self.assertEqual(self.group_pigs.message_follower_ids, self.user_employee.partner_id)
|
||||
follower = self.env['mail.followers'].search([
|
||||
('res_model', '=', 'mail.group'),
|
||||
('res_id', '=', self.group_pigs.id),
|
||||
('partner_id', '=', self.user_employee.partner_id.id)])
|
||||
self.assertEqual(len(follower), 1)
|
||||
self.assertEqual(follower.subtype_ids, self.mt_mg_nodef)
|
||||
|
||||
self.group_pigs.sudo(self.user_employee).message_subscribe_users(subtype_ids=[self.mt_mg_nodef.id, self.mt_al_nodef.id])
|
||||
self.assertEqual(self.group_pigs.message_follower_ids, self.user_employee.partner_id)
|
||||
follower = self.env['mail.followers'].search([
|
||||
('res_model', '=', 'mail.group'),
|
||||
('res_id', '=', self.group_pigs.id),
|
||||
('partner_id', '=', self.user_employee.partner_id.id)])
|
||||
self.assertEqual(len(follower), 1)
|
||||
self.assertEqual(follower.subtype_ids, self.mt_mg_nodef | self.mt_al_nodef)
|
||||
|
||||
def test_subscription_data(self):
|
||||
self.group_pigs.message_subscribe_users(user_ids=[self.user_employee.id])
|
||||
subtype_data = self.group_pigs.sudo(self.user_employee)._get_subscription_data(None, None)[self.group_pigs.id]['message_subtype_data']
|
||||
self.assertEqual(set(subtype_data.keys()), set(['Discussions', 'mt_mg_def', 'mt_al_def', 'mt_mg_nodef', 'mt_al_nodef']), 'mail.group available subtypes incorrect')
|
||||
self.assertTrue(subtype_data['Discussions']['followed'])
|
||||
self.assertFalse(subtype_data['mt_mg_nodef']['followed'])
|
||||
self.assertFalse(subtype_data['mt_al_nodef']['followed'])
|
||||
@@ -1,23 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.mail.tests.common import TestMail
|
||||
from openerp.tools import mute_logger
|
||||
@@ -25,6 +6,7 @@ import socket
|
||||
|
||||
MAIL_TEMPLATE = """Return-Path: <whatever-2a840@postmaster.twitter.com>
|
||||
To: {to}
|
||||
cc: {cc}
|
||||
Received: by mail1.openerp.com (Postfix, from userid 10002)
|
||||
id 5DF9ABFB2A; Fri, 10 Aug 2012 16:16:39 +0200 (CEST)
|
||||
From: {email_from}
|
||||
@@ -88,7 +70,7 @@ Delivered-To: raoul@grosbedon.fr
|
||||
Received: by mail1.grosbedon.com (Postfix, from userid 10002)
|
||||
id E8166BFACA; Fri, 23 Aug 2013 13:18:01 +0200 (CEST)
|
||||
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail1.grosbedon.com
|
||||
X-Spam-Level:
|
||||
X-Spam-Level:
|
||||
X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM,
|
||||
HTML_MESSAGE,RCVD_IN_DNSWL_LOW autolearn=unavailable version=3.3.1
|
||||
Received: from mail-ie0-f173.google.com (mail-ie0-f173.google.com [209.85.223.173])
|
||||
@@ -125,7 +107,7 @@ Content-Type: text/plain; charset=ISO-8859-1
|
||||
|
||||
Should create a multipart/mixed: from gmail, *bold*, with attachment.
|
||||
|
||||
--
|
||||
--
|
||||
Marcel Boitempoils.
|
||||
|
||||
--089e01536c4ed4d16d04e49b8e94
|
||||
@@ -191,548 +173,385 @@ Content-Type: text/html;
|
||||
--Apple-Mail=_9331E12B-8BD2-4EC7-B53E-01F3FBEC9227--
|
||||
"""
|
||||
|
||||
|
||||
class TestMailgateway(TestMail):
|
||||
|
||||
def test_00_message_parse(self):
|
||||
""" Testing incoming emails parsing """
|
||||
cr, uid = self.cr, self.uid
|
||||
|
||||
res = self.mail_thread.message_parse(cr, uid, MAIL_TEMPLATE_PLAINTEXT)
|
||||
self.assertIn('Please call me as soon as possible this afternoon!', res.get('body', ''),
|
||||
@mute_logger('openerp.addons.mail.mail_thread')
|
||||
def test_message_parse(self):
|
||||
""" Test parsing of various scenarios of incoming emails """
|
||||
res = self.env['mail.thread'].message_parse(MAIL_TEMPLATE_PLAINTEXT)
|
||||
self.assertIn('Please call me as soon as possible this afternoon!',
|
||||
res.get('body', ''),
|
||||
'message_parse: missing text in text/plain body after parsing')
|
||||
|
||||
res = self.mail_thread.message_parse(cr, uid, MAIL_TEMPLATE)
|
||||
self.assertIn('<p>Please call me as soon as possible this afternoon!</p>', res.get('body', ''),
|
||||
res = self.env['mail.thread'].message_parse(MAIL_TEMPLATE)
|
||||
self.assertIn('<p>Please call me as soon as possible this afternoon!</p>',
|
||||
res.get('body', ''),
|
||||
'message_parse: missing html in multipart/alternative body after parsing')
|
||||
|
||||
res = self.mail_thread.message_parse(cr, uid, MAIL_MULTIPART_MIXED)
|
||||
self.assertNotIn('Should create a multipart/mixed: from gmail, *bold*, with attachment', res.get('body', ''),
|
||||
res = self.env['mail.thread'].message_parse(MAIL_MULTIPART_MIXED)
|
||||
self.assertNotIn('Should create a multipart/mixed: from gmail, *bold*, with attachment',
|
||||
res.get('body', ''),
|
||||
'message_parse: text version should not be in body after parsing multipart/mixed')
|
||||
self.assertIn('<div dir="ltr">Should create a multipart/mixed: from gmail, <b>bold</b>, with attachment.<br clear="all"><div><br></div>', res.get('body', ''),
|
||||
self.assertIn('<div dir="ltr">Should create a multipart/mixed: from gmail, <b>bold</b>, with attachment.<br clear="all"><div><br></div>',
|
||||
res.get('body', ''),
|
||||
'message_parse: html version should be in body after parsing multipart/mixed')
|
||||
|
||||
res = self.mail_thread.message_parse(cr, uid, MAIL_MULTIPART_MIXED_TWO)
|
||||
self.assertNotIn('First and second part', res.get('body', ''),
|
||||
res = self.env['mail.thread'].message_parse(MAIL_MULTIPART_MIXED_TWO)
|
||||
self.assertNotIn('First and second part',
|
||||
res.get('body', ''),
|
||||
'message_parse: text version should not be in body after parsing multipart/mixed')
|
||||
self.assertIn('First part', res.get('body', ''),
|
||||
self.assertIn('First part',
|
||||
res.get('body', ''),
|
||||
'message_parse: first part of the html version should be in body after parsing multipart/mixed')
|
||||
self.assertIn('Second part', res.get('body', ''),
|
||||
self.assertIn('Second part',
|
||||
res.get('body', ''),
|
||||
'message_parse: second part of the html version should be in body after parsing multipart/mixed')
|
||||
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models')
|
||||
def test_10_message_process(self):
|
||||
""" Testing incoming emails processing. """
|
||||
cr, uid, user_raoul = self.cr, self.uid, self.user_raoul
|
||||
def test_message_process_alias_basic(self):
|
||||
""" Incoming email on an alias creating a new record + message_new + message details """
|
||||
new_groups = self.format_and_process(MAIL_TEMPLATE, subject='My Frogs', to='groups@example.com, other@gmail.com')
|
||||
|
||||
def format_and_process(template, to='groups@example.com, other@gmail.com', subject='Frogs',
|
||||
extra='', email_from='Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>',
|
||||
msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>',
|
||||
model=None):
|
||||
self.assertEqual(self.mail_group.search(cr, uid, [('name', '=', subject)]), [])
|
||||
mail = template.format(to=to, subject=subject, extra=extra, email_from=email_from, msg_id=msg_id)
|
||||
self.mail_thread.message_process(cr, uid, model, mail)
|
||||
return self.mail_group.search(cr, uid, [('name', '=', subject)])
|
||||
|
||||
# --------------------------------------------------
|
||||
# Data creation
|
||||
# --------------------------------------------------
|
||||
|
||||
# groups@.. will cause the creation of new mail groups
|
||||
self.mail_group_model_id = self.ir_model.search(cr, uid, [('model', '=', 'mail.group')])[0]
|
||||
alias_id = self.mail_alias.create(cr, uid, {
|
||||
'alias_name': 'groups',
|
||||
'alias_user_id': False,
|
||||
'alias_model_id': self.mail_group_model_id,
|
||||
'alias_parent_model_id': self.mail_group_model_id,
|
||||
'alias_parent_thread_id': self.group_pigs_id,
|
||||
'alias_contact': 'everyone'})
|
||||
|
||||
# --------------------------------------------------
|
||||
# Test1: new record creation
|
||||
# --------------------------------------------------
|
||||
|
||||
# Do: incoming mail from an unknown partner on an alias creates a new mail_group "frogs"
|
||||
self._init_mock_build_email()
|
||||
frog_groups = format_and_process(MAIL_TEMPLATE, to='groups@example.com, other@gmail.com')
|
||||
sent_emails = self._build_email_kwargs_list
|
||||
# Test: one group created by mailgateway administrator
|
||||
self.assertEqual(len(frog_groups), 1, 'message_process: a new mail.group should have been created')
|
||||
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||
res = self.mail_group.get_metadata(cr, uid, [frog_group.id])[0].get('create_uid') or [None]
|
||||
self.assertEqual(res[0], uid,
|
||||
'message_process: group should have been created by uid as alias_user__id is False on the alias')
|
||||
self.assertEqual(len(new_groups), 1, 'message_process: a new mail.group should have been created')
|
||||
res = new_groups.get_metadata()[0].get('create_uid') or [None]
|
||||
self.assertEqual(res[0], self.env.uid,
|
||||
'message_process: group should have been created by uid as alias_user_id is False on the alias')
|
||||
|
||||
# Test: one message that is the incoming email
|
||||
self.assertEqual(len(frog_group.message_ids), 1,
|
||||
self.assertEqual(len(new_groups.message_ids), 1,
|
||||
'message_process: newly created group should have the incoming email in message_ids')
|
||||
msg = frog_group.message_ids[0]
|
||||
self.assertEqual('Frogs', msg.subject,
|
||||
msg = new_groups.message_ids[0]
|
||||
self.assertEqual(msg.subject, 'My Frogs',
|
||||
'message_process: newly created group should have the incoming email as first message')
|
||||
self.assertIn('Please call me as soon as possible this afternoon!', msg.body,
|
||||
'message_process: newly created group should have the incoming email as first message')
|
||||
self.assertEqual('email', msg.type,
|
||||
self.assertEqual(msg.type, 'email',
|
||||
'message_process: newly created group should have an email as first message')
|
||||
self.assertEqual('Discussions', msg.subtype_id.name,
|
||||
self.assertEqual(msg.subtype_id, self.env.ref('mail.mt_comment'),
|
||||
'message_process: newly created group should not have a log first message but an email')
|
||||
# Test: message: unknown email address -> message has email_from, not author_id
|
||||
self.assertFalse(msg.author_id,
|
||||
'message_process: message on created group should not have an author_id')
|
||||
self.assertIn('test.sylvie.lelitre@agrolait.com', msg.email_from,
|
||||
'message_process: message on created group should have an email_from')
|
||||
# Test: followers: nobody
|
||||
self.assertEqual(len(frog_group.message_follower_ids), 0, 'message_process: newly create group should not have any follower')
|
||||
# Test: sent emails: no-one
|
||||
self.assertEqual(len(sent_emails), 0,
|
||||
'message_process: should create emails without any follower added')
|
||||
# Data: unlink group
|
||||
frog_group.unlink()
|
||||
|
||||
# Do: incoming email from an unknown partner on a Partners only alias -> bounce
|
||||
self._init_mock_build_email()
|
||||
self.mail_alias.write(cr, uid, [alias_id], {'alias_contact': 'partners'})
|
||||
frog_groups = format_and_process(MAIL_TEMPLATE, to='groups@example.com, other2@gmail.com')
|
||||
# Test: no group created
|
||||
self.assertTrue(len(frog_groups) == 0)
|
||||
# Test: email bounced
|
||||
sent_emails = self._build_email_kwargs_list
|
||||
self.assertEqual(len(sent_emails), 1,
|
||||
# Test: sent emails: no-one
|
||||
self.assertEqual(len(self._mails), 0,
|
||||
'message_process: should create emails without any follower added')
|
||||
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models')
|
||||
def test_message_process_alias_user_id(self):
|
||||
""" Test alias ownership """
|
||||
self.alias.write({'alias_user_id': self.user_employee.id})
|
||||
new_groups = self.format_and_process(MAIL_TEMPLATE, to='groups@example.com, other@gmail.com')
|
||||
|
||||
# Test: one group created by mailgateway administrator
|
||||
self.assertEqual(len(new_groups), 1, 'message_process: a new mail.group should have been created')
|
||||
res = new_groups.get_metadata()[0].get('create_uid') or [None]
|
||||
self.assertEqual(res[0], self.user_employee.id,
|
||||
'message_process: group should have been created by alias_user_id')
|
||||
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models')
|
||||
def test_message_process_email_email_from(self):
|
||||
""" Incoming email: not recognized author: email_from, no author_id, no followers """
|
||||
new_groups = self.format_and_process(MAIL_TEMPLATE, to='groups@example.com, other@gmail.com')
|
||||
|
||||
self.assertFalse(new_groups.message_ids[0].author_id,
|
||||
'message_process: unrecognized email -> no author_id')
|
||||
self.assertIn('test.sylvie.lelitre@agrolait.com', new_groups.message_ids[0].email_from,
|
||||
'message_process: unrecognized email -> email_from')
|
||||
|
||||
self.assertEqual(len(new_groups.message_follower_ids), 0,
|
||||
'message_process: newly create group should not have any follower')
|
||||
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models')
|
||||
def test_message_process_email_author(self):
|
||||
""" Incoming email: recognized author: email_from, author_id, added as follower """
|
||||
new_groups = self.format_and_process(MAIL_TEMPLATE, email_from='Valid Lelitre <valid.lelitre@agrolait.com>', to='groups@example.com, valid.other@gmail.com')
|
||||
|
||||
self.assertEqual(new_groups.message_ids[0].author_id, self.partner_1,
|
||||
'message_process: recognized email -> author_id')
|
||||
self.assertIn('Valid Lelitre <valid.lelitre@agrolait.com>', new_groups.message_ids[0].email_from,
|
||||
'message_process: recognized email -> email_from')
|
||||
|
||||
self.assertEqual(new_groups.message_follower_ids, self.partner_1,
|
||||
'message_process: recognized email -> added as follower')
|
||||
|
||||
self.assertEqual(len(self._mails), 0,
|
||||
'message_process: no bounce or notificatoin email should be sent with follower = author')
|
||||
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models', 'openerp.addons.mail.mail_mail')
|
||||
def test_message_process_alias_partners_bounce(self):
|
||||
""" Incoming email from an unknown partner on a Partners only alias -> bounce """
|
||||
self.alias.write({'alias_contact': 'partners'})
|
||||
|
||||
# Test: no group created, email bounced
|
||||
new_groups = self.format_and_process(MAIL_TEMPLATE, subject='New Frogs', to='groups@example.com, other@gmail.com')
|
||||
self.assertTrue(len(new_groups) == 0)
|
||||
self.assertEqual(len(self._mails), 1,
|
||||
'message_process: incoming email on Partners alias should send a bounce email')
|
||||
self.assertIn('Frogs', sent_emails[0].get('subject'),
|
||||
self.assertIn('New Frogs', self._mails[0].get('subject'),
|
||||
'message_process: bounce email on Partners alias should contain the original subject')
|
||||
self.assertIn('test.sylvie.lelitre@agrolait.com', sent_emails[0].get('email_to'),
|
||||
self.assertIn('test.sylvie.lelitre@agrolait.com', self._mails[0].get('email_to'),
|
||||
'message_process: bounce email on Partners alias should have original email sender as recipient')
|
||||
|
||||
# Do: incoming email from an unknown partner on a Followers only alias -> bounce
|
||||
self._init_mock_build_email()
|
||||
self.mail_alias.write(cr, uid, [alias_id], {'alias_contact': 'followers'})
|
||||
frog_groups = format_and_process(MAIL_TEMPLATE, to='groups@example.com, other3@gmail.com')
|
||||
# Test: no group created
|
||||
self.assertTrue(len(frog_groups) == 0)
|
||||
# Test: email bounced
|
||||
sent_emails = self._build_email_kwargs_list
|
||||
self.assertEqual(len(sent_emails), 1,
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models', 'openerp.addons.mail.mail_mail')
|
||||
def test_message_process_alias_followers_bounce(self):
|
||||
""" Incoming email from unknown partner / not follower partner on a Followers only alias -> bounce """
|
||||
self.alias.write({
|
||||
'alias_contact': 'followers',
|
||||
'alias_parent_model_id': self.mail_group_model.id,
|
||||
'alias_parent_thread_id': self.group_pigs.id})
|
||||
|
||||
# Test: unknown on followers alias -> bounce
|
||||
new_groups = self.format_and_process(MAIL_TEMPLATE, to='groups@example.com, other@gmail.com')
|
||||
self.assertEqual(len(new_groups), 0, 'message_process: should have bounced')
|
||||
self.assertEqual(len(self._mails), 1,
|
||||
'message_process: incoming email on Followers alias should send a bounce email')
|
||||
self.assertIn('Frogs', sent_emails[0].get('subject'),
|
||||
'message_process: bounce email on Followers alias should contain the original subject')
|
||||
self.assertIn('test.sylvie.lelitre@agrolait.com', sent_emails[0].get('email_to'),
|
||||
'message_process: bounce email on Followers alias should have original email sender as recipient')
|
||||
|
||||
# Do: incoming email from a known partner on a Partners alias -> ok (+ test on alias.user_id)
|
||||
self.mail_alias.write(cr, uid, [alias_id], {'alias_user_id': self.user_raoul_id, 'alias_contact': 'partners'})
|
||||
p1id = self.res_partner.create(cr, uid, {'name': 'Sylvie Lelitre', 'email': 'test.sylvie.lelitre@agrolait.com'})
|
||||
p2id = self.res_partner.create(cr, uid, {'name': 'Other Poilvache', 'email': 'other4@gmail.com'})
|
||||
# Test: partner on followers alias -> bounce
|
||||
self._init_mock_build_email()
|
||||
frog_groups = format_and_process(MAIL_TEMPLATE, to='groups@example.com, other4@gmail.com')
|
||||
sent_emails = self._build_email_kwargs_list
|
||||
# Test: one group created by Raoul
|
||||
self.assertEqual(len(frog_groups), 1, 'message_process: a new mail.group should have been created')
|
||||
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||
res = self.mail_group.get_metadata(cr, uid, [frog_group.id])[0].get('create_uid') or [None]
|
||||
self.assertEqual(res[0], self.user_raoul_id,
|
||||
'message_process: group should have been created by alias_user_id')
|
||||
new_groups = self.format_and_process(MAIL_TEMPLATE, email_from='Valid Lelitre <valid.lelitre@agrolait.com>', to='groups@example.com, other@gmail.com')
|
||||
self.assertTrue(len(new_groups) == 0, 'message_process: should have bounced')
|
||||
self.assertEqual(len(self._mails), 1,
|
||||
'message_process: incoming email on Followers alias should send a bounce email')
|
||||
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models')
|
||||
def test_message_process_alias_partner(self):
|
||||
""" Incoming email from a known partner on a Partners alias -> ok (+ test on alias.user_id) """
|
||||
self.alias.write({'alias_contact': 'partners'})
|
||||
new_groups = self.format_and_process(MAIL_TEMPLATE, email_from='Valid Lelitre <valid.lelitre@agrolait.com>', to='groups@example.com, valid.other@gmail.com')
|
||||
|
||||
# Test: one group created by alias user
|
||||
self.assertEqual(len(new_groups), 1, 'message_process: a new mail.group should have been created')
|
||||
|
||||
# Test: one message that is the incoming email
|
||||
self.assertEqual(len(frog_group.message_ids), 1,
|
||||
self.assertEqual(len(new_groups.message_ids), 1,
|
||||
'message_process: newly created group should have the incoming email in message_ids')
|
||||
msg = frog_group.message_ids[0]
|
||||
# Test: message: author found
|
||||
self.assertEqual(p1id, msg.author_id.id,
|
||||
'message_process: message on created group should have Sylvie as author_id')
|
||||
self.assertIn('Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>', msg.email_from,
|
||||
'message_process: message on created group should have have an email_from')
|
||||
# Test: author (not recipient and not Raoul (as alias owner)) added as follower
|
||||
frog_follower_ids = set([p.id for p in frog_group.message_follower_ids])
|
||||
self.assertEqual(frog_follower_ids, set([p1id]),
|
||||
'message_process: newly created group should have 1 follower (author, not creator, not recipients)')
|
||||
# Test: sent emails: no-one, no bounce effet
|
||||
sent_emails = self._build_email_kwargs_list
|
||||
self.assertEqual(len(sent_emails), 0,
|
||||
'message_process: should not bounce incoming emails')
|
||||
# Data: unlink group
|
||||
frog_group.unlink()
|
||||
|
||||
# Do: incoming email from a not follower Partner on a Followers only alias -> bounce
|
||||
self._init_mock_build_email()
|
||||
self.mail_alias.write(cr, uid, [alias_id], {'alias_user_id': False, 'alias_contact': 'followers'})
|
||||
frog_groups = format_and_process(MAIL_TEMPLATE, to='groups@example.com, other5@gmail.com')
|
||||
# Test: no group created
|
||||
self.assertTrue(len(frog_groups) == 0)
|
||||
# Test: email bounced
|
||||
sent_emails = self._build_email_kwargs_list
|
||||
self.assertEqual(len(sent_emails), 1,
|
||||
'message_process: incoming email on Partners alias should send a bounce email')
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models')
|
||||
def test_message_process_alias_followers(self):
|
||||
""" Incoming email from a parent document follower on a Followers only alias -> ok """
|
||||
self.alias.write({
|
||||
'alias_contact': 'followers',
|
||||
'alias_parent_model_id': self.mail_group_model.id,
|
||||
'alias_parent_thread_id': self.group_pigs.id})
|
||||
self.group_pigs.message_subscribe(partner_ids=[self.partner_1.id])
|
||||
new_groups = self.format_and_process(MAIL_TEMPLATE, email_from='Valid Lelitre <valid.lelitre@agrolait.com>', to='groups@example.com, other6@gmail.com')
|
||||
|
||||
# Do: incoming email from a parent document follower on a Followers only alias -> ok
|
||||
self._init_mock_build_email()
|
||||
self.mail_group.message_subscribe(cr, uid, [self.group_pigs_id], [p1id])
|
||||
frog_groups = format_and_process(MAIL_TEMPLATE, to='groups@example.com, other6@gmail.com')
|
||||
# Test: one group created by Raoul (or Sylvie maybe, if we implement it)
|
||||
self.assertEqual(len(frog_groups), 1, 'message_process: a new mail.group should have been created')
|
||||
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||
# Test: one message that is the incoming email
|
||||
self.assertEqual(len(frog_group.message_ids), 1,
|
||||
'message_process: newly created group should have the incoming email in message_ids')
|
||||
# Test: author (and not recipient) added as follower
|
||||
frog_follower_ids = set([p.id for p in frog_group.message_follower_ids])
|
||||
self.assertEqual(frog_follower_ids, set([p1id]),
|
||||
'message_process: newly created group should have 1 follower (author, not creator, not recipients)')
|
||||
# Test: sent emails: no-one, no bounce effet
|
||||
sent_emails = self._build_email_kwargs_list
|
||||
self.assertEqual(len(sent_emails), 0,
|
||||
'message_process: should not bounce incoming emails')
|
||||
self.assertEqual(len(new_groups), 1, 'message_process: a new mail.group should have been created')
|
||||
|
||||
# --------------------------------------------------
|
||||
# Test2: update-like alias
|
||||
# --------------------------------------------------
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models', 'openerp.addons.mail.mail_mail')
|
||||
def test_message_process_alias_update(self):
|
||||
""" Incoming email update discussion + notification email """
|
||||
self.alias.write({'alias_force_thread_id': self.group_public.id})
|
||||
|
||||
# Do: Pigs alias is restricted, should bounce
|
||||
self._init_mock_build_email()
|
||||
self.mail_group.write(cr, uid, [frog_group.id], {'alias_name': 'frogs', 'alias_contact': 'followers', 'alias_force_thread_id': frog_group.id})
|
||||
frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other4@gmail.com',
|
||||
msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>',
|
||||
to='frogs@example.com>', subject='Re: news')
|
||||
# Test: no group 'Re: news' created, still only 1 Frogs group
|
||||
self.assertEqual(len(frog_groups), 0,
|
||||
self.group_public.message_subscribe(partner_ids=[self.partner_1.id])
|
||||
new_groups = self.format_and_process(
|
||||
MAIL_TEMPLATE, email_from='valid.other@gmail.com',
|
||||
msg_id='<1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>',
|
||||
to='groups@example.com>', subject='Re: cats')
|
||||
|
||||
# Test: no new group + new message
|
||||
self.assertEqual(len(new_groups), 0,
|
||||
'message_process: reply on Frogs should not have created a new group with new subject')
|
||||
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
||||
self.assertEqual(len(frog_groups), 1,
|
||||
'message_process: reply on Frogs should not have created a duplicate group with old subject')
|
||||
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||
# Test: email bounced
|
||||
sent_emails = self._build_email_kwargs_list
|
||||
self.assertEqual(len(sent_emails), 1,
|
||||
'message_process: incoming email on Followers alias should send a bounce email')
|
||||
self.assertIn('Re: news', sent_emails[0].get('subject'),
|
||||
'message_process: bounce email on Followers alias should contain the original subject')
|
||||
|
||||
# Do: Pigs alias is restricted, should accept Followers
|
||||
self._init_mock_build_email()
|
||||
self.mail_group.message_subscribe(cr, uid, [frog_group.id], [p2id])
|
||||
frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other4@gmail.com',
|
||||
msg_id='<1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>',
|
||||
to='frogs@example.com>', subject='Re: cats')
|
||||
# Test: no group 'Re: news' created, still only 1 Frogs group
|
||||
self.assertEqual(len(frog_groups), 0,
|
||||
'message_process: reply on Frogs should not have created a new group with new subject')
|
||||
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
||||
self.assertEqual(len(frog_groups), 1,
|
||||
'message_process: reply on Frogs should not have created a duplicate group with old subject')
|
||||
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||
# Test: one new message
|
||||
self.assertEqual(len(frog_group.message_ids), 2, 'message_process: group should contain 2 messages after reply')
|
||||
# Test: sent emails: 1 (Sylvie copy of the incoming email, but no bounce)
|
||||
sent_emails = self._build_email_kwargs_list
|
||||
self.assertEqual(len(sent_emails), 1,
|
||||
self.assertEqual(len(self.group_public.message_ids), 2, 'message_process: group should contain one new message')
|
||||
# Test: sent emails: 1 (Sylvie copy of the incoming email)
|
||||
self.assertEqual(len(self._mails), 1,
|
||||
'message_process: one email should have been generated')
|
||||
self.assertIn('test.sylvie.lelitre@agrolait.com', sent_emails[0].get('email_to')[0],
|
||||
self.assertIn('valid.lelitre@agrolait.com', self._mails[0].get('email_to')[0],
|
||||
'message_process: email should be sent to Sylvie')
|
||||
self.mail_group.message_unsubscribe(cr, uid, [frog_group.id], [p2id])
|
||||
|
||||
# --------------------------------------------------
|
||||
# Test3: discussion and replies
|
||||
# --------------------------------------------------
|
||||
|
||||
# Do: even with a wrong destination, a reply should end up in the correct thread
|
||||
frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other4@gmail.com',
|
||||
msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>',
|
||||
to='erroneous@example.com>', subject='Re: news',
|
||||
extra='In-Reply-To: <1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>\n')
|
||||
# Test: no group 'Re: news' created, still only 1 Frogs group
|
||||
self.assertEqual(len(frog_groups), 0,
|
||||
'message_process: reply on Frogs should not have created a new group with new subject')
|
||||
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
||||
self.assertEqual(len(frog_groups), 1,
|
||||
'message_process: reply on Frogs should not have created a duplicate group with old subject')
|
||||
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||
# Test: one new message
|
||||
self.assertEqual(len(frog_group.message_ids), 3, 'message_process: group should contain 3 messages after reply')
|
||||
# Test: author (and not recipient) added as follower
|
||||
frog_follower_ids = set([p.id for p in frog_group.message_follower_ids])
|
||||
self.assertEqual(frog_follower_ids, set([p1id, p2id]),
|
||||
self.assertEqual(self.group_public.message_follower_ids, self.partner_1 | self.partner_2,
|
||||
'message_process: after reply, group should have 2 followers')
|
||||
|
||||
# Do: incoming email with ref holding model / res_id but that does not match any message in the thread: must raise since OpenERP saas-3
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models')
|
||||
def test_message_process_in_reply_to(self):
|
||||
""" Incoming email using in-rely-to should go into the right destination event with a wrong destination """
|
||||
self.format_and_process(
|
||||
MAIL_TEMPLATE, email_from='valid.other@gmail.com',
|
||||
msg_id='<1198923581.41972151344608186800.JavaMail.diff1@agrolait.com>',
|
||||
to='erroneous@example.com>', subject='Re: news',
|
||||
extra='In-Reply-To: %s\n' % self.fake_email.message_id)
|
||||
|
||||
self.assertEqual(len(self.group_public.message_ids), 2, 'message_process: group should contain one new message')
|
||||
self.assertEqual(len(self.fake_email.child_ids), 1, 'message_process: new message should be children of the existing one')
|
||||
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models')
|
||||
def test_message_process_references(self):
|
||||
""" Incoming email using in-rely-to should go into the right destination event with a wrong destination """
|
||||
self.format_and_process(
|
||||
MAIL_TEMPLATE, to='erroneous@example.com',
|
||||
extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % self.fake_email.message_id,
|
||||
msg_id='<1198923581.41972151344608186800.JavaMail.4@agrolait.com>')
|
||||
|
||||
self.assertEqual(len(self.group_public.message_ids), 2, 'message_process: group should contain one new message')
|
||||
self.assertEqual(len(self.fake_email.child_ids), 1, 'message_process: new message should be children of the existing one')
|
||||
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models')
|
||||
def test_message_process_model_res_id(self):
|
||||
""" Incoming email with ref holding model / res_id but that does not match any message in the thread: must raise since OpenERP saas-3 """
|
||||
self.assertRaises(ValueError,
|
||||
format_and_process,
|
||||
MAIL_TEMPLATE, email_from='other5@gmail.com',
|
||||
self.format_and_process,
|
||||
MAIL_TEMPLATE, email_from='valid.lelitre@agrolait.com',
|
||||
to='noone@example.com', subject='spam',
|
||||
extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>' % frog_group.id,
|
||||
msg_id='<1.1.JavaMail.new@agrolait.com>')
|
||||
extra='In-Reply-To: <12321321-openerp-%d-mail.group@%s>' % (self.group_public.id, socket.gethostname()),
|
||||
msg_id='<1198923581.41972151344608186802.JavaMail.diff1@agrolait.com>')
|
||||
|
||||
# When 6.1 messages are present, compat mode is available
|
||||
# Create a fake 6.1 message
|
||||
tmp_msg_id = self.mail_message.create(cr, uid, {'model': 'mail.group', 'res_id': frog_group.id})
|
||||
self.mail_message.write(cr, uid, [tmp_msg_id], {'message_id': False})
|
||||
# when 6.1 messages are present, compat mode is available
|
||||
self.fake_email.write({'message_id': False})
|
||||
# Do: compat mode accepts partial-matching emails
|
||||
frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other5@gmail.com',
|
||||
msg_id='<1.2.JavaMail.new@agrolait.com>',
|
||||
to='noone@example.com>', subject='spam',
|
||||
extra='In-Reply-To: <12321321-openerp-%d-mail.group@%s>' % (frog_group.id, socket.gethostname()))
|
||||
self.mail_message.unlink(cr, uid, [tmp_msg_id])
|
||||
# Test: no group 'Re: news' created, still only 1 Frogs group
|
||||
self.assertEqual(len(frog_groups), 0,
|
||||
'message_process: reply on Frogs should not have created a new group with new subject')
|
||||
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
||||
self.assertEqual(len(frog_groups), 1,
|
||||
'message_process: reply on Frogs should not have created a duplicate group with old subject')
|
||||
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||
# Test: one new message
|
||||
self.assertEqual(len(frog_group.message_ids), 4, 'message_process: group should contain 4 messages after reply')
|
||||
frog_groups = self.format_and_process(
|
||||
MAIL_TEMPLATE, email_from='other5@gmail.com',
|
||||
msg_id='<1.2.JavaMail.new@agrolait.com>',
|
||||
to='noone@example.com>', subject='spam',
|
||||
extra='In-Reply-To: <12321321-openerp-%d-mail.group@%s>' % (self.group_public.id, socket.gethostname()))
|
||||
|
||||
# 6.1 compat mode should not work if hostname does not match!
|
||||
tmp_msg_id = self.mail_message.create(cr, uid, {'model': 'mail.group', 'res_id': frog_group.id})
|
||||
self.mail_message.write(cr, uid, [tmp_msg_id], {'message_id': False})
|
||||
# 3''. 6.1 compat mode should not work if hostname does not match!
|
||||
self.assertRaises(ValueError,
|
||||
format_and_process,
|
||||
self.format_and_process,
|
||||
MAIL_TEMPLATE, email_from='other5@gmail.com',
|
||||
msg_id='<1.3.JavaMail.new@agrolait.com>',
|
||||
to='noone@example.com>', subject='spam',
|
||||
extra='In-Reply-To: <12321321-openerp-%d-mail.group@neighbor.com>' % frog_group.id)
|
||||
self.mail_message.unlink(cr, uid, [tmp_msg_id])
|
||||
extra='In-Reply-To: <12321321-openerp-%d-mail.group@neighbor.com>' % frog_groups.id)
|
||||
|
||||
# 4. Subject contains [<ID>] + model passed to message+process -> only attached to group, but not to mail (not in msg1.child_ids)
|
||||
self.format_and_process(
|
||||
MAIL_TEMPLATE,
|
||||
to='erroneous@example.com', email_from='other6@gmail.com',
|
||||
extra='', subject='Re: [%s] 1' % self.group_public.id, model='mail.group',
|
||||
msg_id='<1198923581.41972151344608186803.JavaMail.5@agrolait.com>')
|
||||
|
||||
# Test created messages
|
||||
self.assertEqual(len(self.group_public.message_ids), 3, 'message_process: group should contain 6 messages')
|
||||
self.assertEqual(len(self.group_public.message_ids[0].child_ids), 0, 'message_process: msg1 should not have children')
|
||||
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models')
|
||||
def test_message_process_duplicate(self):
|
||||
""" Duplicate emails (same message_id) are not processed """
|
||||
self.alias.write({'alias_force_thread_id': self.group_public.id,})
|
||||
|
||||
# Post a base message
|
||||
frog_groups = self.format_and_process(
|
||||
MAIL_TEMPLATE, email_from='valid.other@gmail.com', subject='Re: super cats',
|
||||
msg_id='<1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>')
|
||||
|
||||
# Do: due to some issue, same email goes back into the mailgateway
|
||||
frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other4@gmail.com',
|
||||
msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>',
|
||||
subject='Re: news', extra='In-Reply-To: <1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>\n')
|
||||
frog_groups = self.format_and_process(
|
||||
MAIL_TEMPLATE, email_from='other4@gmail.com', subject='Re: news',
|
||||
msg_id='<1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>',
|
||||
extra='In-Reply-To: <1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>\n')
|
||||
|
||||
# Test: no group 'Re: news' created, still only 1 Frogs group
|
||||
self.assertEqual(len(frog_groups), 0,
|
||||
'message_process: reply on Frogs should not have created a new group with new subject')
|
||||
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
||||
self.assertEqual(len(frog_groups), 1,
|
||||
'message_process: reply on Frogs should not have created a duplicate group with old subject')
|
||||
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||
|
||||
# Test: no new message
|
||||
self.assertEqual(len(frog_group.message_ids), 4, 'message_process: message with already existing message_id should not have been duplicated')
|
||||
self.assertEqual(len(self.group_public.message_ids), 2, 'message_process: message with already existing message_id should not have been duplicated')
|
||||
# Test: message_id is still unique
|
||||
msg_ids = self.mail_message.search(cr, uid, [('message_id', 'ilike', '<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>')])
|
||||
self.assertEqual(len(msg_ids), 1,
|
||||
no_of_msg = self.env['mail.message'].search_count([('message_id', 'ilike', '<1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>')])
|
||||
self.assertEqual(no_of_msg, 1,
|
||||
'message_process: message with already existing message_id should not have been duplicated')
|
||||
|
||||
# --------------------------------------------------
|
||||
# Test4: email_from and partner finding
|
||||
# --------------------------------------------------
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models')
|
||||
def test_message_process_partner_find(self):
|
||||
""" Finding the partner based on email, based on partner / user / follower """
|
||||
from_1 = self.env['res.partner'].create({'name': 'A', 'email': 'from.test@example.com'})
|
||||
|
||||
# Data: extra partner with Raoul's email -> test the 'better author finding'
|
||||
extra_partner_id = self.res_partner.create(cr, uid, {'name': 'A-Raoul', 'email': 'test_raoul@email.com'})
|
||||
self.format_and_process(MAIL_TEMPLATE, to='public@example.com', msg_id='<1>', email_from='Brice Denisse <from.test@example.com>')
|
||||
self.assertEqual(self.group_public.message_ids[0].author_id, from_1, 'message_process: email_from -> author_id wrong')
|
||||
self.group_public.message_unsubscribe(partner_ids=[from_1.id])
|
||||
|
||||
# Do: post a new message, with a known partner -> duplicate emails -> partner
|
||||
format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>',
|
||||
subject='Re: news (2)',
|
||||
msg_id='<1198923581.41972151344608186760.JavaMail.new1@agrolait.com>',
|
||||
extra='In-Reply-To: <1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>')
|
||||
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
||||
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||
# Test: author is A-Raoul (only existing)
|
||||
self.assertEqual(frog_group.message_ids[0].author_id.id, extra_partner_id,
|
||||
'message_process: email_from -> author_id wrong')
|
||||
from_2 = self.env['res.users'].with_context({'no_reset_password': True}).create({'name': 'B', 'login': 'B', 'email': 'from.test@example.com'})
|
||||
|
||||
# Do: post a new message with a non-existant email that is a substring of a partner email
|
||||
format_and_process(MAIL_TEMPLATE, email_from='Not really Lombrik Lubrik <oul@email.com>',
|
||||
subject='Re: news (2)',
|
||||
msg_id='<zzzbbbaaaa@agrolait.com>',
|
||||
extra='In-Reply-To: <1198923581.41972151344608186760.JavaMail@agrolait.com>\n')
|
||||
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
||||
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||
# Test: author must not be set, otherwise the system is confusing different users
|
||||
self.assertFalse(frog_group.message_ids[0].author_id, 'message_process: email_from -> mismatching author_id')
|
||||
self.format_and_process(MAIL_TEMPLATE, to='public@example.com', msg_id='<2>', email_from='Brice Denisse <from.test@example.com>')
|
||||
self.assertEqual(self.group_public.message_ids[0].author_id, from_2.partner_id, 'message_process: email_from -> author_id wrong')
|
||||
self.group_public.message_unsubscribe(partner_ids=[from_2.id])
|
||||
|
||||
# Do: post a new message, with a known partner -> duplicate emails -> user
|
||||
frog_group.message_unsubscribe([extra_partner_id])
|
||||
self.res_users.write(cr, uid, self.user_raoul_id, {'email': 'test_raoul@email.com'})
|
||||
format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>',
|
||||
to='groups@example.com', subject='Re: news (3)',
|
||||
msg_id='<1198923581.41972151344608186760.JavaMail.new2@agrolait.com>',
|
||||
extra='In-Reply-To: <1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>')
|
||||
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
||||
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||
# Test: author is Raoul (user), not A-Raoul
|
||||
self.assertEqual(frog_group.message_ids[0].author_id.id, self.partner_raoul_id,
|
||||
'message_process: email_from -> author_id wrong')
|
||||
from_3 = self.env['res.partner'].create({'name': 'C', 'email': 'from.test@example.com'})
|
||||
self.group_public.message_subscribe(partner_ids=[from_3.id])
|
||||
|
||||
# Do: post a new message, with a known partner -> duplicate emails -> partner because is follower
|
||||
frog_group.message_unsubscribe([self.partner_raoul_id])
|
||||
frog_group.message_subscribe([extra_partner_id])
|
||||
raoul_email = self.user_raoul.email
|
||||
self.res_users.write(cr, uid, self.user_raoul_id, {'email': 'test_raoul@email.com'})
|
||||
format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>',
|
||||
to='groups@example.com', subject='Re: news (3)',
|
||||
msg_id='<1198923581.41972151344608186760.JavaMail.new3@agrolait.com>',
|
||||
extra='In-Reply-To: <1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>')
|
||||
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
||||
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||
# Test: author is Raoul (user), not A-Raoul
|
||||
self.assertEqual(frog_group.message_ids[0].author_id.id, extra_partner_id,
|
||||
'message_process: email_from -> author_id wrong')
|
||||
self.format_and_process(MAIL_TEMPLATE, to='public@example.com', msg_id='<3>', email_from='Brice Denisse <from.test@example.com>')
|
||||
self.assertEqual(self.group_public.message_ids[0].author_id, from_3, 'message_process: email_from -> author_id wrong')
|
||||
|
||||
self.res_users.write(cr, uid, self.user_raoul_id, {'email': raoul_email})
|
||||
|
||||
# --------------------------------------------------
|
||||
# Test5: misc gateway features
|
||||
# --------------------------------------------------
|
||||
|
||||
# Do: incoming email with model that does not accepts incoming emails must raise
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models')
|
||||
def test_message_process_crash_wrong_model(self):
|
||||
""" Incoming email with model that does not accepts incoming emails must raise """
|
||||
self.assertRaises(ValueError,
|
||||
format_and_process,
|
||||
self.format_and_process,
|
||||
MAIL_TEMPLATE,
|
||||
to='noone@example.com', subject='spam', extra='', model='res.country',
|
||||
msg_id='<1198923581.41972151344608186760.JavaMail.new4@agrolait.com>')
|
||||
|
||||
# Do: incoming email without model and without alias must raise
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models')
|
||||
def test_message_process_crash_no_data(self):
|
||||
""" Incoming email without model and without alias must raise """
|
||||
self.assertRaises(ValueError,
|
||||
format_and_process,
|
||||
self.format_and_process,
|
||||
MAIL_TEMPLATE,
|
||||
to='noone@example.com', subject='spam', extra='',
|
||||
msg_id='<1198923581.41972151344608186760.JavaMail.new5@agrolait.com>')
|
||||
|
||||
# Do: incoming email with model that accepting incoming emails as fallback
|
||||
frog_groups = format_and_process(MAIL_TEMPLATE,
|
||||
to='noone@example.com',
|
||||
subject='Spammy', extra='', model='mail.group',
|
||||
msg_id='<1198923581.41972151344608186760.JavaMail.new6@agrolait.com>')
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models')
|
||||
def test_message_process_fallback(self):
|
||||
""" Incoming email with model that accepting incoming emails as fallback """
|
||||
frog_groups = self.format_and_process(
|
||||
MAIL_TEMPLATE, to='noone@example.com', subject='Spammy', extra='', model='mail.group',
|
||||
msg_id='<1198923581.41972151344608186760.JavaMail.new6@agrolait.com>')
|
||||
self.assertEqual(len(frog_groups), 1,
|
||||
'message_process: erroneous email but with a fallback model should have created a new mail.group')
|
||||
|
||||
# Do: incoming email in plaintext should be stored as html
|
||||
frog_groups = format_and_process(MAIL_TEMPLATE_PLAINTEXT,
|
||||
to='groups@example.com', subject='Frogs Return', extra='',
|
||||
msg_id='<deadcafe.1337@smtp.agrolait.com>')
|
||||
# Test: one group created with one message
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models')
|
||||
def test_message_process_plain_text(self):
|
||||
""" Incoming email in plaintext should be stored as html """
|
||||
frog_groups = self.format_and_process(
|
||||
MAIL_TEMPLATE_PLAINTEXT, to='groups@example.com', subject='Frogs Return', extra='',
|
||||
msg_id='<deadcafe.1337@smtp.agrolait.com>')
|
||||
self.assertEqual(len(frog_groups), 1, 'message_process: a new mail.group should have been created')
|
||||
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||
msg = frog_group.message_ids[0]
|
||||
# Test: plain text content should be wrapped and stored as html
|
||||
msg = frog_groups.message_ids[0]
|
||||
self.assertIn('<pre>\nPlease call me as soon as possible this afternoon!\n\n--\nSylvie\n</pre>', msg.body,
|
||||
'message_process: plaintext incoming email incorrectly parsed')
|
||||
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models')
|
||||
def test_20_thread_parent_resolution(self):
|
||||
""" Testing parent/child relationships are correctly established when processing incoming mails """
|
||||
cr, uid = self.cr, self.uid
|
||||
|
||||
def format(template, to='Pretty Pigs <group+pigs@example.com>, other@gmail.com', subject='Re: 1',
|
||||
extra='', email_from='Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>',
|
||||
msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>'):
|
||||
return template.format(to=to, subject=subject, extra=extra, email_from=email_from, msg_id=msg_id)
|
||||
|
||||
group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
|
||||
msg1 = group_pigs.message_post(body='My Body', subject='1')
|
||||
msg2 = group_pigs.message_post(body='My Body', subject='2')
|
||||
msg1, msg2 = self.mail_message.browse(cr, uid, [msg1, msg2])
|
||||
self.assertTrue(msg1.message_id, "message_process: new message should have a proper message_id")
|
||||
|
||||
# Reply to msg1, make sure the reply is properly attached using the various reply identification mechanisms
|
||||
# 0. Direct alias match
|
||||
reply_msg1 = format(MAIL_TEMPLATE, to='Pretty Pigs <group+pigs@example.com>',
|
||||
extra='In-Reply-To: %s' % msg1.message_id,
|
||||
msg_id='<1198923581.41972151344608186760.JavaMail.2@agrolait.com>')
|
||||
self.mail_group.message_process(cr, uid, None, reply_msg1)
|
||||
|
||||
# 1. In-Reply-To header
|
||||
reply_msg2 = format(MAIL_TEMPLATE, to='erroneous@example.com',
|
||||
extra='In-Reply-To: %s' % msg1.message_id,
|
||||
msg_id='<1198923581.41972151344608186760.JavaMail.3@agrolait.com>')
|
||||
self.mail_group.message_process(cr, uid, None, reply_msg2)
|
||||
|
||||
# 2. References header
|
||||
reply_msg3 = format(MAIL_TEMPLATE, to='erroneous@example.com',
|
||||
extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % msg1.message_id,
|
||||
msg_id='<1198923581.41972151344608186760.JavaMail.4@agrolait.com>')
|
||||
self.mail_group.message_process(cr, uid, None, reply_msg3)
|
||||
|
||||
# 3. Subject contains [<ID>] + model passed to message+process -> only attached to group, but not to mail (not in msg1.child_ids)
|
||||
reply_msg4 = format(MAIL_TEMPLATE, to='erroneous@example.com',
|
||||
extra='', subject='Re: [%s] 1' % self.group_pigs_id,
|
||||
msg_id='<1198923581.41972151344608186760.JavaMail.5@agrolait.com>')
|
||||
self.mail_group.message_process(cr, uid, 'mail.group', reply_msg4)
|
||||
|
||||
group_pigs.refresh()
|
||||
msg1.refresh()
|
||||
self.assertEqual(6, len(group_pigs.message_ids), 'message_process: group should contain 6 messages')
|
||||
self.assertEqual(3, len(msg1.child_ids), 'message_process: msg1 should have 3 children now')
|
||||
|
||||
def test_30_private_discussion(self):
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models', 'openerp.addons.mail.mail_mail')
|
||||
def test_private_discussion(self):
|
||||
""" Testing private discussion between partners. """
|
||||
cr, uid = self.cr, self.uid
|
||||
|
||||
def format(template, to='Pretty Pigs <group+pigs@example.com>, other@gmail.com', subject='Re: 1',
|
||||
extra='', email_from='Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>',
|
||||
msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>'):
|
||||
return template.format(to=to, subject=subject, extra=extra, email_from=email_from, msg_id=msg_id)
|
||||
msg1_pids = [self.user_employee_2.partner_id.id, self.partner_1.id]
|
||||
|
||||
# Do: Raoul writes to Bert and Administrator, with a thread_model in context that should not be taken into account
|
||||
msg1_pids = [self.partner_admin_id, self.partner_bert_id]
|
||||
msg1_id = self.mail_thread.message_post(
|
||||
cr, self.user_raoul_id, False,
|
||||
partner_ids=msg1_pids,
|
||||
subtype='mail.mt_comment',
|
||||
context={'thread_model': 'mail.group'}
|
||||
)
|
||||
msg1_id = self.env['mail.thread'].with_context({
|
||||
'thread_model': 'mail.group'
|
||||
}).sudo(self.user_employee).message_post(partner_ids=msg1_pids, subtype='mail.mt_comment')
|
||||
|
||||
# Test: message recipients
|
||||
msg = self.mail_message.browse(cr, uid, msg1_id)
|
||||
msg_pids = [p.id for p in msg.partner_ids]
|
||||
msg_nids = [p.id for p in msg.notified_partner_ids]
|
||||
test_pids = msg1_pids
|
||||
test_nids = msg1_pids
|
||||
self.assertEqual(set(msg_pids), set(test_pids),
|
||||
msg = self.env['mail.message'].browse(msg1_id)
|
||||
self.assertEqual(msg.partner_ids, self.user_employee_2.partner_id | self.partner_1,
|
||||
'message_post: private discussion: incorrect recipients')
|
||||
self.assertEqual(set(msg_nids), set(test_nids),
|
||||
self.assertEqual(msg.notified_partner_ids, self.user_employee_2.partner_id | self.partner_1,
|
||||
'message_post: private discussion: incorrect notified recipients')
|
||||
self.assertEqual(msg.model, False,
|
||||
'message_post: private discussion: context key "thread_model" not correctly ignored when having no res_id')
|
||||
# Test: message-id
|
||||
self.assertIn('openerp-private', msg.message_id,
|
||||
'message_post: private discussion: message-id should contain the private keyword')
|
||||
self.assertIn('openerp-private', msg.message_id, 'message_post: private discussion: message-id should contain the private keyword')
|
||||
|
||||
# Do: Bert replies through mailgateway (is a customer)
|
||||
reply_message = format(MAIL_TEMPLATE, to='not_important@mydomain.com',
|
||||
email_from='bert@bert.fr',
|
||||
extra='In-Reply-To: %s' % msg.message_id,
|
||||
msg_id='<test30.JavaMail.0@agrolait.com>')
|
||||
self.mail_thread.message_process(cr, uid, None, reply_message)
|
||||
self.format_and_process(
|
||||
MAIL_TEMPLATE, to='not_important@mydomain.com', email_from='valid.lelitre@agrolait.com',
|
||||
extra='In-Reply-To: %s' % msg.message_id, msg_id='<test30.JavaMail.0@agrolait.com>')
|
||||
|
||||
# Test: last mail_message created
|
||||
msg2_id = self.mail_message.search(cr, uid, [], limit=1)[0]
|
||||
|
||||
msg = self.env['mail.message'].search([], limit=1)
|
||||
# Test: message recipients
|
||||
msg = self.mail_message.browse(cr, uid, msg2_id)
|
||||
msg_pids = [p.id for p in msg.partner_ids]
|
||||
msg_nids = [p.id for p in msg.notified_partner_ids]
|
||||
test_pids = [self.partner_admin_id, self.partner_raoul_id]
|
||||
test_nids = test_pids
|
||||
self.assertEqual(msg.author_id.id, self.partner_bert_id,
|
||||
self.assertEqual(msg.author_id, self.partner_1,
|
||||
'message_post: private discussion: wrong author through mailgatewya based on email')
|
||||
self.assertEqual(set(msg_pids), set(test_pids),
|
||||
self.assertEqual(msg.partner_ids, self.user_employee.partner_id | self.user_employee_2.partner_id,
|
||||
'message_post: private discussion: incorrect recipients when replying')
|
||||
self.assertEqual(set(msg_nids), set(test_nids),
|
||||
self.assertEqual(msg.notified_partner_ids, self.user_employee.partner_id | self.user_employee_2.partner_id,
|
||||
'message_post: private discussion: incorrect notified recipients when replying')
|
||||
|
||||
# Do: Bert replies through chatter (is a customer)
|
||||
msg3_id = self.mail_thread.message_post(
|
||||
cr, uid, False,
|
||||
author_id=self.partner_bert_id,
|
||||
parent_id=msg1_id, subtype='mail.mt_comment')
|
||||
msg3_id = self.env['mail.thread'].message_post(author_id=self.partner_1.id, parent_id=msg1_id, subtype='mail.mt_comment')
|
||||
|
||||
# Test: message recipients
|
||||
msg = self.mail_message.browse(cr, uid, msg3_id)
|
||||
msg_pids = [p.id for p in msg.partner_ids]
|
||||
msg_nids = [p.id for p in msg.notified_partner_ids]
|
||||
test_pids = [self.partner_admin_id, self.partner_raoul_id]
|
||||
test_nids = test_pids
|
||||
self.assertEqual(set(msg_pids), set(test_pids),
|
||||
msg = self.env['mail.message'].browse(msg3_id)
|
||||
self.assertEqual(msg.partner_ids, self.user_employee.partner_id | self.user_employee_2.partner_id,
|
||||
'message_post: private discussion: incorrect recipients when replying')
|
||||
self.assertEqual(set(msg_nids), set(test_nids),
|
||||
'message_post: private discussion: incorrect notified recipients when replying')
|
||||
|
||||
# Do: Administrator replies
|
||||
msg3_id = self.mail_thread.message_post(cr, uid, False, parent_id=msg3_id, subtype='mail.mt_comment')
|
||||
|
||||
# Test: message recipients
|
||||
msg = self.mail_message.browse(cr, uid, msg3_id)
|
||||
msg_pids = [p.id for p in msg.partner_ids]
|
||||
msg_nids = [p.id for p in msg.notified_partner_ids]
|
||||
test_pids = [self.partner_bert_id, self.partner_raoul_id]
|
||||
test_nids = test_pids
|
||||
self.assertEqual(set(msg_pids), set(test_pids),
|
||||
'message_post: private discussion: incorrect recipients when replying')
|
||||
self.assertEqual(set(msg_nids), set(test_nids),
|
||||
self.assertEqual(msg.notified_partner_ids, self.user_employee.partner_id | self.user_employee_2.partner_id,
|
||||
'message_post: private discussion: incorrect notified recipients when replying')
|
||||
|
||||
@@ -1,71 +1,79 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.mail.tests.common import TestMail
|
||||
from openerp.exceptions import AccessError
|
||||
from openerp.exceptions import except_orm
|
||||
from openerp.tools import mute_logger
|
||||
|
||||
|
||||
class TestMailGroup(TestMail):
|
||||
|
||||
@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models')
|
||||
def test_00_mail_group_access_rights(self):
|
||||
""" Testing mail_group access rights and basic mail_thread features """
|
||||
cr, uid, user_noone_id, user_employee_id = self.cr, self.uid, self.user_noone_id, self.user_employee_id
|
||||
def test_access_rights_public(self):
|
||||
# Read public group -> ok
|
||||
self.group_public.sudo(self.user_public).read()
|
||||
|
||||
# Do: Bert reads Jobs -> ok, public
|
||||
self.mail_group.read(cr, user_noone_id, [self.group_jobs_id])
|
||||
# Do: Bert read Pigs -> ko, restricted to employees
|
||||
with self.assertRaises(AccessError):
|
||||
self.mail_group.read(cr, user_noone_id, [self.group_pigs_id])
|
||||
# Do: Raoul read Pigs -> ok, belong to employees
|
||||
self.mail_group.read(cr, user_employee_id, [self.group_pigs_id])
|
||||
# Read Pigs -> ko, restricted to employees
|
||||
# TODO: Change the except_orm to Warning ( Because here it's call check_access_rule
|
||||
# which still generate exception in except_orm.So we need to change all
|
||||
# except_orm to warning in mail module.)
|
||||
with self.assertRaises(except_orm):
|
||||
self.group_pigs.sudo(self.user_public).read()
|
||||
|
||||
# Do: Bert creates a group -> ko, no access rights
|
||||
with self.assertRaises(AccessError):
|
||||
self.mail_group.create(cr, user_noone_id, {'name': 'Test'})
|
||||
# Do: Raoul creates a restricted group -> ok
|
||||
new_group_id = self.mail_group.create(cr, user_employee_id, {'name': 'Test'})
|
||||
# Do: Bert added in followers, read -> ok, in followers
|
||||
self.mail_group.message_subscribe_users(cr, uid, [new_group_id], [user_noone_id])
|
||||
self.mail_group.read(cr, user_noone_id, [new_group_id])
|
||||
# Read a private group when being a follower: ok
|
||||
self.group_private.message_subscribe_users(user_ids=[self.user_public.id])
|
||||
self.group_private.sudo(self.user_public).read()
|
||||
|
||||
# Do: Raoul reads Priv -> ko, private
|
||||
# Create group: ko, no access rights
|
||||
with self.assertRaises(AccessError):
|
||||
self.mail_group.read(cr, user_employee_id, [self.group_priv_id])
|
||||
# Do: Raoul added in follower, read -> ok, in followers
|
||||
self.mail_group.message_subscribe_users(cr, uid, [self.group_priv_id], [user_employee_id])
|
||||
self.mail_group.read(cr, user_employee_id, [self.group_priv_id])
|
||||
self.env['mail.group'].sudo(self.user_public).create({'name': 'Test'})
|
||||
|
||||
# Do: Raoul write on Jobs -> ok
|
||||
self.mail_group.write(cr, user_employee_id, [self.group_priv_id], {'name': 'modified'})
|
||||
# Do: Bert cannot write on Private -> ko (read but no write)
|
||||
# Update group: ko, no access rights
|
||||
with self.assertRaises(AccessError):
|
||||
self.mail_group.write(cr, user_noone_id, [self.group_priv_id], {'name': 're-modified'})
|
||||
# Test: Bert cannot unlink the group
|
||||
self.group_public.sudo(self.user_public).write({'name': 'Broutouschnouk'})
|
||||
|
||||
# Unlink group: ko, no access rights
|
||||
with self.assertRaises(AccessError):
|
||||
self.mail_group.unlink(cr, user_noone_id, [self.group_priv_id])
|
||||
# Do: Raoul unlinks the group, there are no followers and messages left
|
||||
self.mail_group.unlink(cr, user_employee_id, [self.group_priv_id])
|
||||
fol_ids = self.mail_followers.search(cr, uid, [('res_model', '=', 'mail.group'), ('res_id', '=', self.group_priv_id)])
|
||||
self.assertFalse(fol_ids, 'unlinked document should not have any followers left')
|
||||
msg_ids = self.mail_message.search(cr, uid, [('model', '=', 'mail.group'), ('res_id', '=', self.group_priv_id)])
|
||||
self.assertFalse(msg_ids, 'unlinked document should not have any followers left')
|
||||
self.group_public.sudo(self.user_public).unlink()
|
||||
|
||||
@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models')
|
||||
def test_access_rights_groups(self):
|
||||
# Employee read employee-based group: ok
|
||||
# TODO Change the except_orm to Warning
|
||||
self.group_pigs.sudo(self.user_employee).read()
|
||||
|
||||
# Employee can create a group
|
||||
self.env['mail.group'].sudo(self.user_employee).create({'name': 'Test'})
|
||||
|
||||
# Employee update employee-based group: ok
|
||||
self.group_pigs.sudo(self.user_employee).write({'name': 'modified'})
|
||||
|
||||
# Employee unlink employee-based group: ok
|
||||
self.group_pigs.sudo(self.user_employee).unlink()
|
||||
|
||||
# Employee cannot read a private group
|
||||
with self.assertRaises(except_orm):
|
||||
self.group_private.sudo(self.user_employee).read()
|
||||
|
||||
# Employee cannot write on private
|
||||
with self.assertRaises(AccessError):
|
||||
self.group_private.sudo(self.user_employee).write({'name': 're-modified'})
|
||||
|
||||
def test_access_rights_followers_ko(self):
|
||||
with self.assertRaises(AccessError):
|
||||
self.group_private.sudo(self.user_portal).name
|
||||
|
||||
def test_access_rights_followers_portal(self):
|
||||
# Do: Chell is added into Pigs followers and browse it -> ok for messages, ko for partners (no read permission)
|
||||
self.group_private.message_subscribe_users(user_ids=[self.user_portal.id])
|
||||
chell_pigs = self.group_private.sudo(self.user_portal)
|
||||
trigger_read = chell_pigs.name
|
||||
for message in chell_pigs.message_ids:
|
||||
trigger_read = message.subject
|
||||
for partner in chell_pigs.message_follower_ids:
|
||||
if partner.id == self.user_portal.partner_id.id:
|
||||
# Chell can read her own partner record
|
||||
continue
|
||||
# TODO Change the except_orm to Warning
|
||||
with self.assertRaises(except_orm):
|
||||
trigger_read = partner.name
|
||||
|
||||
@@ -1,446 +1,294 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.mail.tests.common import TestMail
|
||||
from openerp.exceptions import AccessError
|
||||
from openerp.exceptions import except_orm
|
||||
from openerp.tools import mute_logger
|
||||
|
||||
|
||||
class TestMailMail(TestMail):
|
||||
|
||||
def test_00_partner_find_from_email(self):
|
||||
""" Tests designed for partner fetch based on emails. """
|
||||
cr, uid, user_raoul, group_pigs = self.cr, self.uid, self.user_raoul, self.group_pigs
|
||||
|
||||
# --------------------------------------------------
|
||||
# Data creation
|
||||
# --------------------------------------------------
|
||||
# 1 - Partner ARaoul
|
||||
p_a_id = self.res_partner.create(cr, uid, {'name': 'ARaoul', 'email': 'test@test.fr'})
|
||||
|
||||
# --------------------------------------------------
|
||||
# CASE1: without object
|
||||
# --------------------------------------------------
|
||||
|
||||
# Do: find partner with email -> first partner should be found
|
||||
partner_info = self.mail_thread.message_partner_info_from_emails(cr, uid, None, ['Maybe Raoul <test@test.fr>'], link_mail=False)[0]
|
||||
self.assertEqual(partner_info['full_name'], 'Maybe Raoul <test@test.fr>',
|
||||
'mail_thread: message_partner_info_from_emails did not handle email')
|
||||
self.assertEqual(partner_info['partner_id'], p_a_id,
|
||||
'mail_thread: message_partner_info_from_emails wrong partner found')
|
||||
|
||||
# Data: add some data about partners
|
||||
# 2 - User BRaoul
|
||||
p_b_id = self.res_partner.create(cr, uid, {'name': 'BRaoul', 'email': 'test@test.fr', 'user_ids': [(4, user_raoul.id)]})
|
||||
|
||||
# Do: find partner with email -> first user should be found
|
||||
partner_info = self.mail_thread.message_partner_info_from_emails(cr, uid, None, ['Maybe Raoul <test@test.fr>'], link_mail=False)[0]
|
||||
self.assertEqual(partner_info['partner_id'], p_b_id,
|
||||
'mail_thread: message_partner_info_from_emails wrong partner found')
|
||||
|
||||
# --------------------------------------------------
|
||||
# CASE1: with object
|
||||
# --------------------------------------------------
|
||||
|
||||
# Do: find partner in group where there is a follower with the email -> should be taken
|
||||
self.mail_group.message_subscribe(cr, uid, [group_pigs.id], [p_b_id])
|
||||
partner_info = self.mail_group.message_partner_info_from_emails(cr, uid, group_pigs.id, ['Maybe Raoul <test@test.fr>'], link_mail=False)[0]
|
||||
self.assertEqual(partner_info['partner_id'], p_b_id,
|
||||
'mail_thread: message_partner_info_from_emails wrong partner found')
|
||||
|
||||
|
||||
class TestMailMessage(TestMail):
|
||||
|
||||
def test_00_mail_message_values(self):
|
||||
""" Tests designed for testing email values based on mail.message, aliases, ... """
|
||||
cr, uid, user_raoul_id = self.cr, self.uid, self.user_raoul_id
|
||||
def setUp(self):
|
||||
super(TestMailMessage, self).setUp()
|
||||
self.attachment = self.env['ir.attachment'].create({
|
||||
'datas': 'My attachment'.encode('base64'),
|
||||
'name': 'doc.txt',
|
||||
'datas_fname': 'doc.txt'})
|
||||
self.message = self.env['mail.message'].create({
|
||||
'body': 'My Body',
|
||||
'model': 'mail.group',
|
||||
'res_id': self.group_private.id,
|
||||
'attachment_ids': [(4, self.attachment.id)],
|
||||
})
|
||||
|
||||
# Data: update + generic variables
|
||||
reply_to1 = '_reply_to1@example.com'
|
||||
reply_to2 = '_reply_to2@example.com'
|
||||
email_from1 = 'from@example.com'
|
||||
alias_domain = 'schlouby.fr'
|
||||
raoul_from = 'Raoul Grosbedon <raoul@raoul.fr>'
|
||||
raoul_from_alias = 'Raoul Grosbedon <raoul@schlouby.fr>'
|
||||
raoul_reply_alias = 'YourCompany Pigs <group+pigs@schlouby.fr>'
|
||||
def test_mail_message_values_basic(self):
|
||||
self.env['ir.config_parameter'].search([('key', '=', 'mail.catchall.domain')]).unlink()
|
||||
|
||||
# --------------------------------------------------
|
||||
# Case1: without alias_domain
|
||||
# --------------------------------------------------
|
||||
param_ids = self.registry('ir.config_parameter').search(cr, uid, [('key', '=', 'mail.catchall.domain')])
|
||||
self.registry('ir.config_parameter').unlink(cr, uid, param_ids)
|
||||
msg = self.env['mail.message'].sudo(self.user_employee).create({
|
||||
'reply_to': 'test.reply@example.com',
|
||||
'email_from': 'test.from@example.com',
|
||||
})
|
||||
self.assertIn('-private', msg.message_id, 'mail_message: message_id for a void message should be a "private" one')
|
||||
self.assertEqual(msg.reply_to, 'test.reply@example.com')
|
||||
self.assertEqual(msg.email_from, 'test.from@example.com')
|
||||
|
||||
# Do: free message; specified values > default values
|
||||
msg_id = self.mail_message.create(cr, user_raoul_id, {'no_auto_thread': True, 'reply_to': reply_to1, 'email_from': email_from1})
|
||||
msg = self.mail_message.browse(cr, user_raoul_id, msg_id)
|
||||
# Test: message content
|
||||
self.assertIn('reply_to', msg.message_id,
|
||||
'mail_message: message_id should be specific to a mail_message with a given reply_to')
|
||||
self.assertEqual(msg.reply_to, reply_to1,
|
||||
'mail_message: incorrect reply_to: should come from values')
|
||||
self.assertEqual(msg.email_from, email_from1,
|
||||
'mail_message: incorrect email_from: should come from values')
|
||||
def test_mail_message_values_default(self):
|
||||
self.env['ir.config_parameter'].search([('key', '=', 'mail.catchall.domain')]).unlink()
|
||||
|
||||
# Do: create a mail_mail with the previous mail_message + specified reply_to
|
||||
mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel', 'reply_to': reply_to2})
|
||||
mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
|
||||
# Test: mail_mail content
|
||||
self.assertEqual(mail.reply_to, reply_to2,
|
||||
'mail_mail: incorrect reply_to: should come from values')
|
||||
self.assertEqual(mail.email_from, email_from1,
|
||||
'mail_mail: incorrect email_from: should come from mail.message')
|
||||
msg = self.env['mail.message'].sudo(self.user_employee).create({})
|
||||
self.assertIn('-private', msg.message_id, 'mail_message: message_id for a void message should be a "private" one')
|
||||
self.assertEqual(msg.reply_to, '%s <%s>' % (self.user_employee.name, self.user_employee.email))
|
||||
self.assertEqual(msg.email_from, '%s <%s>' % (self.user_employee.name, self.user_employee.email))
|
||||
|
||||
# Do: mail_message attached to a document
|
||||
msg_id = self.mail_message.create(cr, user_raoul_id, {'model': 'mail.group', 'res_id': self.group_pigs_id})
|
||||
msg = self.mail_message.browse(cr, user_raoul_id, msg_id)
|
||||
# Test: message content
|
||||
self.assertIn('mail.group', msg.message_id,
|
||||
'mail_message: message_id should contain model')
|
||||
self.assertIn('%s' % self.group_pigs_id, msg.message_id,
|
||||
'mail_message: message_id should contain res_id')
|
||||
self.assertEqual(msg.reply_to, raoul_from,
|
||||
'mail_message: incorrect reply_to: should be Raoul')
|
||||
self.assertEqual(msg.email_from, raoul_from,
|
||||
'mail_message: incorrect email_from: should be Raoul')
|
||||
def test_mail_message_values_alias(self):
|
||||
alias_domain = 'example.com'
|
||||
self.env['ir.config_parameter'].set_param('mail.catchall.domain', alias_domain)
|
||||
self.env['ir.config_parameter'].search([('key', '=', 'mail.catchall.alias')]).unlink()
|
||||
|
||||
# --------------------------------------------------
|
||||
# Case2: with alias_domain, without catchall alias
|
||||
# --------------------------------------------------
|
||||
self.registry('ir.config_parameter').set_param(cr, uid, 'mail.catchall.domain', alias_domain)
|
||||
self.registry('ir.config_parameter').unlink(cr, uid, self.registry('ir.config_parameter').search(cr, uid, [('key', '=', 'mail.catchall.alias')]))
|
||||
msg = self.env['mail.message'].sudo(self.user_employee).create({})
|
||||
self.assertIn('-private', msg.message_id, 'mail_message: message_id for a void message should be a "private" one')
|
||||
self.assertEqual(msg.reply_to, '%s <%s@%s>' % (self.user_employee.name, self.user_employee.alias_name, alias_domain))
|
||||
self.assertEqual(msg.email_from, '%s <%s@%s>' % (self.user_employee.name, self.user_employee.alias_name, alias_domain))
|
||||
|
||||
# Update message
|
||||
msg_id = self.mail_message.create(cr, user_raoul_id, {'model': 'mail.group', 'res_id': self.group_pigs_id})
|
||||
msg = self.mail_message.browse(cr, user_raoul_id, msg_id)
|
||||
# Test: generated reply_to
|
||||
self.assertEqual(msg.reply_to, raoul_reply_alias,
|
||||
'mail_mail: incorrect reply_to: should be Pigs alias')
|
||||
def test_mail_message_values_alias_catchall(self):
|
||||
alias_domain = 'example.com'
|
||||
alias_catchall = 'pokemon'
|
||||
self.env['ir.config_parameter'].set_param('mail.catchall.domain', alias_domain)
|
||||
self.env['ir.config_parameter'].set_param('mail.catchall.alias', alias_catchall)
|
||||
|
||||
# Update message: test alias on email_from
|
||||
msg_id = self.mail_message.create(cr, user_raoul_id, {})
|
||||
msg = self.mail_message.browse(cr, user_raoul_id, msg_id)
|
||||
# Test: generated reply_to
|
||||
self.assertEqual(msg.reply_to, raoul_from_alias,
|
||||
'mail_mail: incorrect reply_to: should be message email_from using Raoul alias')
|
||||
msg = self.env['mail.message'].sudo(self.user_employee).create({})
|
||||
self.assertIn('-private', msg.message_id, 'mail_message: message_id for a void message should be a "private" one')
|
||||
self.assertEqual(msg.reply_to, '%s <%s@%s>' % (self._company_name, alias_catchall, alias_domain))
|
||||
self.assertEqual(msg.email_from, '%s <%s@%s>' % (self.user_employee.name, self.user_employee.alias_name, alias_domain))
|
||||
|
||||
# --------------------------------------------------
|
||||
# Case2: with alias_domain and catchall alias
|
||||
# --------------------------------------------------
|
||||
self.registry('ir.config_parameter').set_param(self.cr, self.uid, 'mail.catchall.alias', 'gateway')
|
||||
def test_mail_message_values_document_no_alias(self):
|
||||
self.env['ir.config_parameter'].search([('key', '=', 'mail.catchall.domain')]).unlink()
|
||||
|
||||
# Update message
|
||||
msg_id = self.mail_message.create(cr, user_raoul_id, {})
|
||||
msg = self.mail_message.browse(cr, user_raoul_id, msg_id)
|
||||
# Test: generated reply_to
|
||||
self.assertEqual(msg.reply_to, 'YourCompany <gateway@schlouby.fr>',
|
||||
'mail_mail: reply_to should equal the catchall email alias')
|
||||
msg = self.env['mail.message'].sudo(self.user_employee).create({
|
||||
'model': 'mail.group',
|
||||
'res_id': self.group_pigs.id
|
||||
})
|
||||
self.assertIn('-openerp-%d-mail.group' % self.group_pigs.id, msg.message_id, 'mail_message: message_id for a void message should be a "private" one')
|
||||
self.assertEqual(msg.reply_to, '%s <%s>' % (self.user_employee.name, self.user_employee.email))
|
||||
self.assertEqual(msg.email_from, '%s <%s>' % (self.user_employee.name, self.user_employee.email))
|
||||
|
||||
# Do: create a mail_mail
|
||||
mail_id = self.mail_mail.create(cr, uid, {'state': 'cancel', 'reply_to': 'someone@example.com'})
|
||||
mail = self.mail_mail.browse(cr, uid, mail_id)
|
||||
# Test: mail_mail content
|
||||
self.assertEqual(mail.reply_to, 'someone@example.com',
|
||||
'mail_mail: reply_to should equal the rpely_to given to create')
|
||||
def test_mail_message_values_document_alias(self):
|
||||
alias_domain = 'example.com'
|
||||
self.env['ir.config_parameter'].set_param('mail.catchall.domain', alias_domain)
|
||||
self.env['ir.config_parameter'].search([('key', '=', 'mail.catchall.alias')]).unlink()
|
||||
|
||||
@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models')
|
||||
def test_10_mail_message_search_access_rights(self):
|
||||
""" Testing mail_message.search() using specific _search implementation """
|
||||
cr, uid, group_pigs_id = self.cr, self.uid, self.group_pigs_id
|
||||
# Data: comment subtype for mail.message creation
|
||||
ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'mail', 'mt_comment')
|
||||
subtype_id = ref and ref[1] or False
|
||||
msg = self.env['mail.message'].sudo(self.user_employee).create({
|
||||
'model': 'mail.group',
|
||||
'res_id': self.group_pigs.id
|
||||
})
|
||||
self.assertIn('-openerp-%d-mail.group' % self.group_pigs.id, msg.message_id, 'mail_message: message_id for a void message should be a "private" one')
|
||||
self.assertEqual(msg.reply_to, '%s %s <%s@%s>' % (self._company_name, self.group_pigs.name, self.group_pigs.alias_name, alias_domain))
|
||||
self.assertEqual(msg.email_from, '%s <%s@%s>' % (self.user_employee.name, self.user_employee.alias_name, alias_domain))
|
||||
|
||||
# Data: Birds group, private
|
||||
group_birds_id = self.mail_group.create(self.cr, self.uid, {'name': 'Birds', 'public': 'private'})
|
||||
# Data: Raoul is member of Pigs
|
||||
self.mail_group.message_subscribe(cr, uid, [group_pigs_id], [self.partner_raoul_id])
|
||||
def test_mail_message_values_document_alias_catchall(self):
|
||||
alias_domain = 'example.com'
|
||||
alias_catchall = 'pokemon'
|
||||
self.env['ir.config_parameter'].set_param('mail.catchall.domain', alias_domain)
|
||||
self.env['ir.config_parameter'].set_param('mail.catchall.alias', alias_catchall)
|
||||
|
||||
msg = self.env['mail.message'].sudo(self.user_employee).create({
|
||||
'model': 'mail.group',
|
||||
'res_id': self.group_pigs.id
|
||||
})
|
||||
self.assertIn('-openerp-%d-mail.group' % self.group_pigs.id, msg.message_id, 'mail_message: message_id for a void message should be a "private" one')
|
||||
self.assertEqual(msg.reply_to, '%s %s <%s@%s>' % (self._company_name, self.group_pigs.name, self.group_pigs.alias_name, alias_domain))
|
||||
self.assertEqual(msg.email_from, '%s <%s@%s>' % (self.user_employee.name, self.user_employee.alias_name, alias_domain))
|
||||
|
||||
def test_mail_message_values_no_auto_thread(self):
|
||||
msg = self.env['mail.message'].sudo(self.user_employee).create({
|
||||
'model': 'mail.group',
|
||||
'res_id': self.group_pigs.id,
|
||||
'no_auto_thread': True,
|
||||
})
|
||||
self.assertIn('reply_to', msg.message_id)
|
||||
self.assertNotIn('mail.group', msg.message_id)
|
||||
self.assertNotIn('-%d-' % self.group_pigs.id, msg.message_id)
|
||||
|
||||
@mute_logger('openerp.addons.mail.mail_mail')
|
||||
def test_mail_message_access_search(self):
|
||||
# Data: various author_ids, partner_ids, documents
|
||||
msg_id1 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A', 'subtype_id': subtype_id})
|
||||
msg_id2 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A+B', 'partner_ids': [(6, 0, [self.partner_bert_id])], 'subtype_id': subtype_id})
|
||||
msg_id3 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A Pigs', 'model': 'mail.group', 'res_id': group_pigs_id, 'subtype_id': subtype_id})
|
||||
msg_id4 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A+B Pigs', 'model': 'mail.group', 'res_id': group_pigs_id, 'partner_ids': [(6, 0, [self.partner_bert_id])], 'subtype_id': subtype_id})
|
||||
msg_id5 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A+R Pigs', 'model': 'mail.group', 'res_id': group_pigs_id, 'partner_ids': [(6, 0, [self.partner_raoul_id])], 'subtype_id': subtype_id})
|
||||
msg_id6 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A Birds', 'model': 'mail.group', 'res_id': group_birds_id, 'subtype_id': subtype_id})
|
||||
msg_id7 = self.mail_message.create(cr, self.user_raoul_id, {'subject': '_Test', 'body': 'B', 'subtype_id': subtype_id})
|
||||
msg_id8 = self.mail_message.create(cr, self.user_raoul_id, {'subject': '_Test', 'body': 'B+R', 'partner_ids': [(6, 0, [self.partner_raoul_id])], 'subtype_id': subtype_id})
|
||||
msg1 = self.env['mail.message'].create({
|
||||
'subject': '_Test', 'body': 'A', 'subtype_id': self.ref('mail.mt_comment')})
|
||||
msg2 = self.env['mail.message'].create({
|
||||
'subject': '_Test', 'body': 'A+B', 'subtype_id': self.ref('mail.mt_comment'),
|
||||
'partner_ids': [(6, 0, [self.user_public.partner_id.id])]})
|
||||
msg3 = self.env['mail.message'].create({
|
||||
'subject': '_Test', 'body': 'A Pigs', 'subtype_id': False,
|
||||
'model': 'mail.group', 'res_id': self.group_pigs.id})
|
||||
msg4 = self.env['mail.message'].create({
|
||||
'subject': '_Test', 'body': 'A+P Pigs', 'subtype_id': self.ref('mail.mt_comment'),
|
||||
'model': 'mail.group', 'res_id': self.group_pigs.id,
|
||||
'partner_ids': [(6, 0, [self.user_public.partner_id.id])]})
|
||||
msg5 = self.env['mail.message'].create({
|
||||
'subject': '_Test', 'body': 'A+E Pigs', 'subtype_id': self.ref('mail.mt_comment'),
|
||||
'model': 'mail.group', 'res_id': self.group_pigs.id,
|
||||
'partner_ids': [(6, 0, [self.user_employee.partner_id.id])]})
|
||||
msg6 = self.env['mail.message'].create({
|
||||
'subject': '_Test', 'body': 'A Birds', 'subtype_id': self.ref('mail.mt_comment'),
|
||||
'model': 'mail.group', 'res_id': self.group_private.id})
|
||||
msg7 = self.env['mail.message'].sudo(self.user_employee).create({
|
||||
'subject': '_Test', 'body': 'B', 'subtype_id': self.ref('mail.mt_comment')})
|
||||
msg8 = self.env['mail.message'].sudo(self.user_employee).create({
|
||||
'subject': '_Test', 'body': 'B+E', 'subtype_id': self.ref('mail.mt_comment'),
|
||||
'partner_ids': [(6, 0, [self.user_employee.partner_id.id])]})
|
||||
|
||||
# Test: Public: 2 messages (recipient)
|
||||
messages = self.env['mail.message'].sudo(self.user_public).search([('subject', 'like', '_Test')])
|
||||
self.assertEqual(messages, msg2 | msg4)
|
||||
|
||||
# Test: Employee: 3 messages on Pigs Raoul can read (employee can read group with default values)
|
||||
messages = self.env['mail.message'].sudo(self.user_employee).search([('subject', 'like', '_Test'), ('body', 'ilike', 'A')])
|
||||
self.assertEqual(messages, msg3 | msg4 | msg5)
|
||||
|
||||
# Test: Bert: 2 messages that have Bert in partner_ids
|
||||
msg_ids = self.mail_message.search(cr, self.user_bert_id, [('subject', 'like', '_Test')])
|
||||
self.assertEqual(set([msg_id2, msg_id4]), set(msg_ids), 'mail_message search failed')
|
||||
# Test: Raoul: 3 messages on Pigs Raoul can read (employee can read group with default values), 0 on Birds (private group)
|
||||
msg_ids = self.mail_message.search(cr, self.user_raoul_id, [('subject', 'like', '_Test'), ('body', 'like', 'A')])
|
||||
self.assertEqual(set([msg_id3, msg_id4, msg_id5]), set(msg_ids), 'mail_message search failed')
|
||||
# Test: Raoul: 3 messages on Pigs Raoul can read (employee can read group with default values), 0 on Birds (private group) + 2 messages as author
|
||||
msg_ids = self.mail_message.search(cr, self.user_raoul_id, [('subject', 'like', '_Test')])
|
||||
self.assertEqual(set([msg_id3, msg_id4, msg_id5, msg_id7, msg_id8]), set(msg_ids), 'mail_message search failed')
|
||||
messages = self.env['mail.message'].sudo(self.user_employee).search([('subject', 'like', '_Test')])
|
||||
self.assertEqual(messages, msg3 | msg4 | msg5 | msg7 | msg8)
|
||||
|
||||
# Test: Admin: all messages
|
||||
msg_ids = self.mail_message.search(cr, uid, [('subject', 'like', '_Test')])
|
||||
self.assertEqual(set([msg_id1, msg_id2, msg_id3, msg_id4, msg_id5, msg_id6, msg_id7, msg_id8]), set(msg_ids), 'mail_message search failed')
|
||||
messages = self.env['mail.message'].search([('subject', 'like', '_Test')])
|
||||
self.assertEqual(messages, msg1 | msg2 | msg3 | msg4 | msg5 | msg6 | msg7 | msg8)
|
||||
|
||||
# Test: Portal: 0 (no access to groups, not recipient)
|
||||
messages = self.env['mail.message'].sudo(self.user_portal).search([('subject', 'like', '_Test')])
|
||||
self.assertFalse(messages)
|
||||
|
||||
# Test: Portal: 2 messages (public group with a subtype)
|
||||
self.group_pigs.write({'public': 'public'})
|
||||
messages = self.env['mail.message'].sudo(self.user_portal).search([('subject', 'like', '_Test')])
|
||||
self.assertEqual(messages, msg4 | msg5)
|
||||
|
||||
@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models')
|
||||
def test_15_mail_message_check_access_rule(self):
|
||||
""" Testing mail_message.check_access_rule() """
|
||||
cr, uid = self.cr, self.uid
|
||||
partner_bert_id, partner_raoul_id = self.partner_bert_id, self.partner_raoul_id
|
||||
user_bert_id, user_raoul_id = self.user_bert_id, self.user_raoul_id
|
||||
def test_mail_message_access_read_crash(self):
|
||||
# TODO: Change the except_orm to Warning ( Because here it's call check_access_rule
|
||||
# which still generate exception in except_orm.So we need to change all
|
||||
# except_orm to warning in mail module.)
|
||||
with self.assertRaises(except_orm):
|
||||
self.message.sudo(self.user_employee).read()
|
||||
|
||||
# Prepare groups: Pigs (employee), Jobs (public)
|
||||
pigs_msg_id = self.mail_group.message_post(cr, uid, self.group_pigs_id, body='Message')
|
||||
priv_msg_id = self.mail_group.message_post(cr, uid, self.group_priv_id, body='Message')
|
||||
def test_mail_message_access_read_crash_portal(self):
|
||||
with self.assertRaises(except_orm):
|
||||
self.message.sudo(self.user_portal).read(['body', 'type', 'subtype_id'])
|
||||
|
||||
# prepare an attachment
|
||||
attachment_id = self.ir_attachment.create(cr, uid, {'datas': 'My attachment'.encode('base64'), 'name': 'doc.txt', 'datas_fname': 'doc.txt'})
|
||||
def test_mail_message_access_read_ok_portal(self):
|
||||
self.message.write({'subtype_id': self.ref('mail.mt_comment'), 'res_id': self.group_public.id})
|
||||
self.message.sudo(self.user_portal).read(['body', 'type', 'subtype_id'])
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE1: read
|
||||
# ----------------------------------------
|
||||
|
||||
# Do: create a new mail.message
|
||||
message_id = self.mail_message.create(cr, uid, {'body': 'My Body', 'attachment_ids': [(4, attachment_id)]})
|
||||
|
||||
# Test: Bert reads the message, crash because not notification/not in doc followers/not read on doc
|
||||
with self.assertRaises(AccessError):
|
||||
self.mail_message.read(cr, user_bert_id, message_id)
|
||||
# Do: message is pushed to Bert
|
||||
notif_id = self.mail_notification.create(cr, uid, {'message_id': message_id, 'partner_id': partner_bert_id})
|
||||
# Test: Bert reads the message, ok because notification pushed
|
||||
self.mail_message.read(cr, user_bert_id, message_id)
|
||||
def test_mail_message_access_read_notification(self):
|
||||
self.env['mail.notification'].create({'message_id': self.message.id, 'partner_id': self.user_employee.partner_id.id})
|
||||
self.message.sudo(self.user_employee).read()
|
||||
# Test: Bert downloads attachment, ok because he can read message
|
||||
self.mail_message.download_attachment(cr, user_bert_id, message_id, attachment_id)
|
||||
# Do: remove notification
|
||||
self.mail_notification.unlink(cr, uid, notif_id)
|
||||
# Test: Bert reads the message, crash because not notification/not in doc followers/not read on doc
|
||||
with self.assertRaises(AccessError):
|
||||
self.mail_message.read(cr, self.user_bert_id, message_id)
|
||||
# Test: Bert downloads attachment, crash because he can't read message
|
||||
with self.assertRaises(AccessError):
|
||||
self.mail_message.download_attachment(cr, user_bert_id, message_id, attachment_id)
|
||||
# Do: Bert is now the author
|
||||
self.mail_message.write(cr, uid, [message_id], {'author_id': partner_bert_id})
|
||||
# Test: Bert reads the message, ok because Bert is the author
|
||||
self.mail_message.read(cr, user_bert_id, message_id)
|
||||
# Do: Bert is not the author anymore
|
||||
self.mail_message.write(cr, uid, [message_id], {'author_id': partner_raoul_id})
|
||||
# Test: Bert reads the message, crash because not notification/not in doc followers/not read on doc
|
||||
with self.assertRaises(AccessError):
|
||||
self.mail_message.read(cr, user_bert_id, message_id)
|
||||
# Do: message is attached to a document Bert can read, Jobs
|
||||
self.mail_message.write(cr, uid, [message_id], {'model': 'mail.group', 'res_id': self.group_jobs_id})
|
||||
self.env['mail.message'].sudo(self.user_employee).download_attachment(self.message.id, self.attachment.id)
|
||||
|
||||
def test_mail_message_access_read_author(self):
|
||||
self.message.write({'author_id': self.user_employee.partner_id.id})
|
||||
self.message.sudo(self.user_employee).read()
|
||||
|
||||
def test_mail_message_access_read_doc(self):
|
||||
self.message.write({'model': 'mail.group', 'res_id': self.group_public.id})
|
||||
# Test: Bert reads the message, ok because linked to a doc he is allowed to read
|
||||
self.mail_message.read(cr, user_bert_id, message_id)
|
||||
# Do: message is attached to a document Bert cannot read, Pigs
|
||||
self.mail_message.write(cr, uid, [message_id], {'model': 'mail.group', 'res_id': self.group_pigs_id})
|
||||
# Test: Bert reads the message, crash because not notification/not in doc followers/not read on doc
|
||||
with self.assertRaises(AccessError):
|
||||
self.mail_message.read(cr, user_bert_id, message_id)
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE2: create
|
||||
# ----------------------------------------
|
||||
self.message.sudo(self.user_employee).read()
|
||||
|
||||
@mute_logger('openerp.addons.base.ir.ir_model')
|
||||
def test_mail_message_access_create_crash_public(self):
|
||||
# Do: Bert creates a message on Pigs -> ko, no creation rights
|
||||
with self.assertRaises(AccessError):
|
||||
self.mail_message.create(cr, user_bert_id, {'model': 'mail.group', 'res_id': self.group_pigs_id, 'body': 'Test'})
|
||||
self.env['mail.message'].sudo(self.user_public).create({'model': 'mail.group', 'res_id': self.group_pigs.id, 'body': 'Test'})
|
||||
|
||||
# Do: Bert create a message on Jobs -> ko, no creation rights
|
||||
with self.assertRaises(AccessError):
|
||||
self.mail_message.create(cr, user_bert_id, {'model': 'mail.group', 'res_id': self.group_jobs_id, 'body': 'Test'})
|
||||
self.env['mail.message'].sudo(self.user_public).create({'model': 'mail.group', 'res_id': self.group_public.id, 'body': 'Test'})
|
||||
|
||||
def test_mail_message_access_create_crash(self):
|
||||
# Do: Bert create a private message -> ko, no creation rights
|
||||
with self.assertRaises(AccessError):
|
||||
self.mail_message.create(cr, user_bert_id, {'body': 'Test'})
|
||||
with self.assertRaises(except_orm):
|
||||
self.env['mail.message'].sudo(self.user_employee).create({'model': 'mail.group', 'res_id': self.group_private.id, 'body': 'Test'})
|
||||
|
||||
@mute_logger('openerp.models')
|
||||
def test_mail_message_access_create_doc(self):
|
||||
# TODO Change the except_orm to Warning
|
||||
Message = self.env['mail.message'].sudo(self.user_employee)
|
||||
# Do: Raoul creates a message on Jobs -> ok, write access to the related document
|
||||
self.mail_message.create(cr, user_raoul_id, {'model': 'mail.group', 'res_id': self.group_jobs_id, 'body': 'Test'})
|
||||
Message.create({'model': 'mail.group', 'res_id': self.group_public.id, 'body': 'Test'})
|
||||
# Do: Raoul creates a message on Priv -> ko, no write access to the related document
|
||||
with self.assertRaises(AccessError):
|
||||
self.mail_message.create(cr, user_raoul_id, {'model': 'mail.group', 'res_id': self.group_priv_id, 'body': 'Test'})
|
||||
# Do: Raoul creates a private message -> ok
|
||||
self.mail_message.create(cr, user_raoul_id, {'body': 'Test'})
|
||||
# Do: Raoul creates a reply to a message on Priv -> ko
|
||||
with self.assertRaises(AccessError):
|
||||
self.mail_message.create(cr, user_raoul_id, {'model': 'mail.group', 'res_id': self.group_priv_id, 'body': 'Test', 'parent_id': priv_msg_id})
|
||||
# Do: Raoul creates a reply to a message on Priv-> ok if has received parent
|
||||
self.mail_notification.create(cr, uid, {'message_id': priv_msg_id, 'partner_id': self.partner_raoul_id})
|
||||
self.mail_message.create(cr, user_raoul_id, {'model': 'mail.group', 'res_id': self.group_priv_id, 'body': 'Test', 'parent_id': priv_msg_id})
|
||||
with self.assertRaises(except_orm):
|
||||
Message.create({'model': 'mail.group', 'res_id': self.group_private.id, 'body': 'Test'})
|
||||
|
||||
def test_20_message_set_star(self):
|
||||
""" Tests for starring messages and its related access rights """
|
||||
cr, uid = self.cr, self.uid
|
||||
# Data: post a message on Pigs
|
||||
def test_mail_message_access_create_private(self):
|
||||
self.env['mail.message'].sudo(self.user_employee).create({'body': 'Test'})
|
||||
|
||||
def test_mail_message_access_create_reply(self):
|
||||
self.env['mail.notification'].create({'message_id': self.message.id, 'partner_id': self.user_employee.partner_id.id})
|
||||
self.env['mail.message'].sudo(self.user_employee).create({'model': 'mail.group', 'res_id': self.group_private.id, 'body': 'Test', 'parent_id': self.message.id})
|
||||
|
||||
def test_message_set_star(self):
|
||||
msg_id = self.group_pigs.message_post(body='My Body', subject='1')
|
||||
msg = self.mail_message.browse(cr, uid, msg_id)
|
||||
msg_raoul = self.mail_message.browse(cr, self.user_raoul_id, msg_id)
|
||||
msg = self.env['mail.message'].browse(msg_id)
|
||||
msg_emp = self.env['mail.message'].sudo(self.user_employee).browse(msg_id)
|
||||
|
||||
# Do: Admin stars msg
|
||||
self.mail_message.set_message_starred(cr, uid, [msg.id], True)
|
||||
msg.refresh()
|
||||
# Test: notification exists
|
||||
notif_ids = self.mail_notification.search(cr, uid, [('partner_id', '=', self.partner_admin_id), ('message_id', '=', msg.id)])
|
||||
self.assertEqual(len(notif_ids), 1, 'mail_message set_message_starred: more than one notification created')
|
||||
# Test: notification starred
|
||||
notif = self.mail_notification.browse(cr, uid, notif_ids[0])
|
||||
self.assertTrue(notif.starred, 'mail_notification starred failed')
|
||||
self.assertTrue(msg.starred, 'mail_message starred failed')
|
||||
# Admin set as starred
|
||||
msg.set_message_starred(True)
|
||||
notification = self.env['mail.notification'].search([('partner_id', '=', self.env.user.partner_id.id), ('message_id', '=', msg.id)])
|
||||
self.assertEqual(len(notification), 1)
|
||||
self.assertTrue(notification.starred)
|
||||
self.assertTrue(msg.starred)
|
||||
|
||||
# Do: Raoul stars msg
|
||||
self.mail_message.set_message_starred(cr, self.user_raoul_id, [msg.id], True)
|
||||
msg_raoul.refresh()
|
||||
# Test: notification exists
|
||||
notif_ids = self.mail_notification.search(cr, uid, [('partner_id', '=', self.partner_raoul_id), ('message_id', '=', msg.id)])
|
||||
self.assertEqual(len(notif_ids), 1, 'mail_message set_message_starred: more than one notification created')
|
||||
# Test: notification starred
|
||||
notif = self.mail_notification.browse(cr, uid, notif_ids[0])
|
||||
self.assertTrue(notif.starred, 'mail_notification starred failed')
|
||||
self.assertTrue(msg_raoul.starred, 'mail_message starred failed')
|
||||
# Employee set as starred
|
||||
msg_emp.set_message_starred(True)
|
||||
notification = self.env['mail.notification'].search([('partner_id', '=', self.user_employee.partner_id.id), ('message_id', '=', msg.id)])
|
||||
self.assertEqual(len(notification), 1)
|
||||
self.assertTrue(notification.starred)
|
||||
self.assertTrue(msg_emp.starred)
|
||||
|
||||
# Do: Admin unstars msg
|
||||
self.mail_message.set_message_starred(cr, uid, [msg.id], False)
|
||||
msg.refresh()
|
||||
msg_raoul.refresh()
|
||||
# Test: msg unstarred for Admin, starred for Raoul
|
||||
self.assertFalse(msg.starred, 'mail_message starred failed')
|
||||
self.assertTrue(msg_raoul.starred, 'mail_message starred failed')
|
||||
msg.set_message_starred(False)
|
||||
self.assertFalse(msg.starred)
|
||||
self.assertTrue(msg_emp.starred)
|
||||
|
||||
def test_30_message_set_read(self):
|
||||
""" Tests for reading messages and its related access rights """
|
||||
cr, uid = self.cr, self.uid
|
||||
# Data: post a message on Pigs
|
||||
def test_message_set_read(self):
|
||||
msg_id = self.group_pigs.message_post(body='My Body', subject='1')
|
||||
msg = self.mail_message.browse(cr, uid, msg_id)
|
||||
msg_raoul = self.mail_message.browse(cr, self.user_raoul_id, msg_id)
|
||||
msg = self.env['mail.message'].browse(msg_id)
|
||||
msg_emp = self.env['mail.message'].sudo(self.user_employee).browse(msg_id)
|
||||
|
||||
# Do: Admin reads msg
|
||||
self.mail_message.set_message_read(cr, uid, [msg.id], True)
|
||||
msg.refresh()
|
||||
# Test: notification exists
|
||||
notif_ids = self.mail_notification.search(cr, uid, [('partner_id', '=', self.partner_admin_id), ('message_id', '=', msg.id)])
|
||||
self.assertEqual(len(notif_ids), 1, 'mail_message set_message_read: more than one notification created')
|
||||
# Test: notification read
|
||||
notif = self.mail_notification.browse(cr, uid, notif_ids[0])
|
||||
self.assertTrue(notif['is_read'], 'mail_notification read failed')
|
||||
self.assertFalse(msg.to_read, 'mail_message read failed')
|
||||
# Admin set as read
|
||||
msg.set_message_read(True)
|
||||
notification = self.env['mail.notification'].search([('partner_id', '=', self.env.user.partner_id.id), ('message_id', '=', msg.id)])
|
||||
self.assertEqual(len(notification), 1)
|
||||
self.assertTrue(notification.is_read)
|
||||
self.assertFalse(msg.to_read)
|
||||
|
||||
# Do: Raoul reads msg
|
||||
self.mail_message.set_message_read(cr, self.user_raoul_id, [msg.id], True)
|
||||
msg_raoul.refresh()
|
||||
# Test: notification exists
|
||||
notif_ids = self.mail_notification.search(cr, uid, [('partner_id', '=', self.partner_raoul_id), ('message_id', '=', msg.id)])
|
||||
self.assertEqual(len(notif_ids), 1, 'mail_message set_message_read: more than one notification created')
|
||||
# Test: notification read
|
||||
notif = self.mail_notification.browse(cr, uid, notif_ids[0])
|
||||
self.assertTrue(notif['is_read'], 'mail_notification starred failed')
|
||||
self.assertFalse(msg_raoul.to_read, 'mail_message starred failed')
|
||||
# Employee set as read
|
||||
msg_emp.set_message_read(True)
|
||||
notification = self.env['mail.notification'].search([('partner_id', '=', self.user_employee.partner_id.id), ('message_id', '=', msg.id)])
|
||||
self.assertEqual(len(notification), 1, 'mail_message set_message_read: more than one notification created')
|
||||
self.assertTrue(notification.is_read)
|
||||
self.assertFalse(msg_emp.to_read)
|
||||
|
||||
# Do: Admin unreads msg
|
||||
self.mail_message.set_message_read(cr, uid, [msg.id], False)
|
||||
msg.refresh()
|
||||
msg_raoul.refresh()
|
||||
# Test: msg unread for Admin, read for Raoul
|
||||
self.assertTrue(msg.to_read, 'mail_message read failed')
|
||||
self.assertFalse(msg_raoul.to_read, 'mail_message read failed')
|
||||
msg.set_message_read(False)
|
||||
self.assertTrue(msg.to_read)
|
||||
self.assertFalse(msg_emp.to_read)
|
||||
|
||||
def test_40_message_vote(self):
|
||||
""" Test designed for the vote/unvote feature. """
|
||||
cr, uid = self.cr, self.uid
|
||||
# Data: post a message on Pigs
|
||||
def test_message_vote(self):
|
||||
msg_id = self.group_pigs.message_post(body='My Body', subject='1')
|
||||
msg = self.mail_message.browse(cr, uid, msg_id)
|
||||
msg_raoul = self.mail_message.browse(cr, self.user_raoul_id, msg_id)
|
||||
msg = self.env['mail.message'].browse(msg_id)
|
||||
msg_emp = self.env['mail.message'].sudo(self.user_employee).browse(msg_id)
|
||||
|
||||
# Do: Admin vote for msg
|
||||
self.mail_message.vote_toggle(cr, uid, [msg.id])
|
||||
msg.refresh()
|
||||
# Test: msg has Admin as voter
|
||||
self.assertEqual(set(msg.vote_user_ids), set([self.user_admin]), 'mail_message vote: after voting, Admin should be in the voter')
|
||||
msg.vote_toggle()
|
||||
self.assertEqual(msg.vote_user_ids, self.user_admin)
|
||||
|
||||
# Do: Bert vote for msg
|
||||
self.mail_message.vote_toggle(cr, self.user_raoul_id, [msg.id])
|
||||
msg_raoul.refresh()
|
||||
msg_emp.vote_toggle()
|
||||
# Test: msg has Admin and Bert as voters
|
||||
self.assertEqual(set(msg_raoul.vote_user_ids), set([self.user_admin, self.user_raoul]), 'mail_message vote: after voting, Admin and Bert should be in the voters')
|
||||
self.assertEqual(msg_emp.vote_user_ids, self.user_admin | self.user_employee)
|
||||
|
||||
# Do: Admin unvote for msg
|
||||
self.mail_message.vote_toggle(cr, uid, [msg.id])
|
||||
msg.refresh()
|
||||
msg_raoul.refresh()
|
||||
msg.vote_toggle()
|
||||
# Test: msg has Bert as voter
|
||||
self.assertEqual(set(msg.vote_user_ids), set([self.user_raoul]), 'mail_message vote: after unvoting, Bert should be in the voter')
|
||||
self.assertEqual(set(msg_raoul.vote_user_ids), set([self.user_raoul]), 'mail_message vote: after unvoting, Bert should be in the voter')
|
||||
|
||||
@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models')
|
||||
def test_50_mail_flow_access_rights(self):
|
||||
""" Test a Chatter-looks alike flow to test access rights """
|
||||
cr, uid = self.cr, self.uid
|
||||
mail_compose = self.registry('mail.compose.message')
|
||||
partner_bert_id, partner_raoul_id = self.partner_bert_id, self.partner_raoul_id
|
||||
user_bert_id, user_raoul_id = self.user_bert_id, self.user_raoul_id
|
||||
|
||||
# Prepare groups: Pigs (employee), Jobs (public)
|
||||
pigs_msg_id = self.mail_group.message_post(cr, uid, self.group_pigs_id, body='Message', partner_ids=[self.partner_admin_id])
|
||||
jobs_msg_id = self.mail_group.message_post(cr, uid, self.group_jobs_id, body='Message', partner_ids=[self.partner_admin_id])
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE1: Bert, without groups
|
||||
# ----------------------------------------
|
||||
|
||||
# Do: Bert reads Jobs basic fields, ok because public = read access on the group
|
||||
self.mail_group.read(cr, user_bert_id, [self.group_jobs_id], ['name', 'description'])
|
||||
# Do: Bert reads Jobs messages, ok because read access on the group => read access on its messages
|
||||
jobs_message_ids = self.mail_group.read(cr, user_bert_id, [self.group_jobs_id], ['message_ids'])[0]['message_ids']
|
||||
self.mail_message.read(cr, user_bert_id, jobs_message_ids)
|
||||
# Do: Bert browses Jobs, ok (no direct browse of partners), ok for messages, ko for followers (accessible to employees or partner manager)
|
||||
bert_jobs = self.mail_group.browse(cr, user_bert_id, self.group_jobs_id)
|
||||
trigger_read = bert_jobs.name
|
||||
for message in bert_jobs.message_ids:
|
||||
trigger_read = message.subject
|
||||
for partner in bert_jobs.message_follower_ids:
|
||||
with self.assertRaises(AccessError):
|
||||
trigger_read = partner.name
|
||||
# Do: Bert comments Jobs, ko because no creation right
|
||||
with self.assertRaises(AccessError):
|
||||
self.mail_group.message_post(cr, user_bert_id, self.group_jobs_id, body='I love Pigs')
|
||||
|
||||
# Do: Bert writes on its own profile, ko because no message create access
|
||||
with self.assertRaises(AccessError):
|
||||
self.res_users.message_post(cr, user_bert_id, user_bert_id, body='I love Bert')
|
||||
self.res_partner.message_post(cr, user_bert_id, partner_bert_id, body='I love Bert')
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE2: Raoul, employee
|
||||
# ----------------------------------------
|
||||
|
||||
# Do: Raoul browses Jobs -> ok, ok for message_ids, of for message_follower_ids
|
||||
raoul_jobs = self.mail_group.browse(cr, user_raoul_id, self.group_jobs_id)
|
||||
trigger_read = raoul_jobs.name
|
||||
for message in raoul_jobs.message_ids:
|
||||
trigger_read = message.subject
|
||||
for partner in raoul_jobs.message_follower_ids:
|
||||
trigger_read = partner.name
|
||||
|
||||
# Do: Raoul comments Jobs, ok
|
||||
self.mail_group.message_post(cr, user_raoul_id, self.group_jobs_id, body='I love Pigs')
|
||||
# Do: Raoul create a mail.compose.message record on Jobs, because he uses the wizard
|
||||
compose_id = mail_compose.create(cr, user_raoul_id,
|
||||
{'subject': 'Subject', 'body': 'Body text', 'partner_ids': []},
|
||||
{'default_composition_mode': 'comment', 'default_model': 'mail.group', 'default_res_id': self.group_jobs_id})
|
||||
mail_compose.send_mail(cr, user_raoul_id, [compose_id])
|
||||
# Do: Raoul replies to a Jobs message using the composer
|
||||
compose_id = mail_compose.create(cr, user_raoul_id,
|
||||
{'subject': 'Subject', 'body': 'Body text'},
|
||||
{'default_composition_mode': 'comment', 'default_parent_id': pigs_msg_id})
|
||||
mail_compose.send_mail(cr, user_raoul_id, [compose_id])
|
||||
self.assertEqual(msg.vote_user_ids, self.user_employee)
|
||||
self.assertEqual(msg_emp.vote_user_ids, self.user_employee)
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import base64
|
||||
|
||||
from openerp.addons.mail.tests.common import TestMail
|
||||
from openerp.tools import mute_logger
|
||||
|
||||
|
||||
class TestMailTemplate(TestMail):
|
||||
|
||||
def setUp(self):
|
||||
super(TestMailTemplate, self).setUp()
|
||||
|
||||
self._attachments = [{
|
||||
'name': '_Test_First',
|
||||
'datas_fname':
|
||||
'first.txt',
|
||||
'datas': base64.b64encode('My first attachment'),
|
||||
'res_model': 'res.partner',
|
||||
'res_id': self.user_admin.partner_id.id
|
||||
}, {
|
||||
'name': '_Test_Second',
|
||||
'datas_fname': 'second.txt',
|
||||
'datas': base64.b64encode('My second attachment'),
|
||||
'res_model': 'res.partner',
|
||||
'res_id': self.user_admin.partner_id.id
|
||||
}]
|
||||
|
||||
self.email_1 = 'test1@example.com'
|
||||
self.email_2 = 'test2@example.com'
|
||||
self.email_3 = self.partner_1.email
|
||||
self.email_template = self.env['mail.template'].create({
|
||||
'model_id': self.env['ir.model'].search([('model', '=', 'mail.group')], limit=1).id,
|
||||
'name': 'Pigs Template',
|
||||
'subject': '${object.name}',
|
||||
'body_html': '${object.description}',
|
||||
'user_signature': False,
|
||||
'attachment_ids': [(0, 0, self._attachments[0]), (0, 0, self._attachments[1])],
|
||||
'partner_to': '%s,%s' % (self.partner_2.id, self.user_employee.partner_id.id),
|
||||
'email_to': '%s, %s' % (self.email_1, self.email_2),
|
||||
'email_cc': '%s' % self.email_3})
|
||||
|
||||
def test_composer_template_onchange(self):
|
||||
composer = self.env['mail.compose.message'].with_context({
|
||||
'default_composition_mode': 'comment',
|
||||
'default_model': 'mail.group',
|
||||
'default_res_id': self.group_pigs.id,
|
||||
'default_use_template': False,
|
||||
'default_template_id': False
|
||||
}).create({'subject': 'Forget me subject', 'body': 'Dummy body'})
|
||||
|
||||
values = composer.onchange_template_id(self.email_template.id, 'comment', 'mail.group', self.group_pigs.id)['value']
|
||||
recipients = self.env['res.partner'].browse(values['partner_ids'])
|
||||
attachments = self.env['ir.attachment'].browse(values['attachment_ids'])
|
||||
test_recipients = self.env['res.partner'].search([('email', 'in', ['test1@example.com', 'test2@example.com'])]) | self.partner_1 | self.partner_2 | self.user_employee.partner_id
|
||||
test_attachments = self.env['ir.attachment'].search([('name', 'in', ['_Test_First', '_Test_Second'])])
|
||||
self.assertEqual(values['subject'], self.group_pigs.name)
|
||||
self.assertEqual(values['body'], '<p>%s</p>' % self.group_pigs.description)
|
||||
self.assertEqual(recipients, test_recipients)
|
||||
self.assertEqual(set(recipients.mapped('email')), set([self.email_1, self.email_2, self.partner_1.email, self.partner_2.email, self.user_employee.email]))
|
||||
self.assertEqual(attachments, test_attachments)
|
||||
self.assertEqual(set(attachments.mapped('res_model')), set(['res.partner']))
|
||||
self.assertEqual(set(attachments.mapped('res_id')), set([self.user_admin.partner_id.id]))
|
||||
|
||||
@mute_logger('openerp.addons.mail.mail_mail')
|
||||
def test_composer_template_send(self):
|
||||
composer = self.env['mail.compose.message'].with_context({
|
||||
'default_composition_mode': 'comment',
|
||||
'default_model': 'mail.group',
|
||||
'default_res_id': self.group_pigs.id,
|
||||
'default_use_template': False,
|
||||
'default_template_id': self.email_template.id,
|
||||
}).create({}).send_mail()
|
||||
|
||||
message = self.group_pigs.message_ids[0]
|
||||
test_recipients = self.env['res.partner'].search([('email', 'in', ['test1@example.com', 'test2@example.com'])]) | self.partner_1 | self.partner_2 | self.user_employee.partner_id
|
||||
self.assertEqual(message.subject, self.group_pigs.name)
|
||||
self.assertEqual(message.body, '<p>%s</p>' % self.group_pigs.description)
|
||||
self.assertEqual(message.partner_ids, test_recipients)
|
||||
self.assertEqual(message.notified_partner_ids, test_recipients)
|
||||
self.assertEqual(set(message.attachment_ids.mapped('res_model')), set(['mail.group']))
|
||||
self.assertEqual(set(message.attachment_ids.mapped('res_id')), set([self.group_pigs.id]))
|
||||
# self.assertIn((attach.datas_fname, base64.b64decode(attach.datas)), _attachments_test,
|
||||
# 'mail.message attachment name / data incorrect')
|
||||
|
||||
@mute_logger('openerp.addons.mail.mail_mail')
|
||||
def test_composer_template_mass_mailing(self):
|
||||
composer = self.env['mail.compose.message'].with_context({
|
||||
'default_composition_mode': 'mass_mail',
|
||||
'default_notify': True,
|
||||
'default_model': 'mail.group',
|
||||
'default_res_id': self.group_pigs.id,
|
||||
'default_template_id': self.email_template.id,
|
||||
'active_ids': [self.group_pigs.id, self.group_public.id]
|
||||
}).create({})
|
||||
values = composer.onchange_template_id(self.email_template.id, 'mass_mail', 'mail.group', self.group_pigs.id)['value']
|
||||
composer.write(values)
|
||||
composer.send_mail()
|
||||
|
||||
message_1 = self.group_pigs.message_ids[0]
|
||||
message_2 = self.group_public.message_ids[0]
|
||||
|
||||
self.assertEqual(message_1.subject, self.group_pigs.name, 'mail.message subject on Pigs incorrect')
|
||||
self.assertEqual(message_2.subject, self.group_public.name, 'mail.message subject on Bird incorrect')
|
||||
self.assertIn(self.group_pigs.description, message_1.body, 'mail.message body on Pigs incorrect')
|
||||
self.assertIn(self.group_public.description, message_2.body, 'mail.message body on Bird incorrect')
|
||||
# todo for JDC: ! (False -> <p>False</p>)
|
||||
|
||||
def test_mail_template(self):
|
||||
mail_id = self.email_template.send_mail(self.group_pigs.id)
|
||||
mail = self.env['mail.mail'].browse(mail_id)
|
||||
self.assertEqual(mail.subject, self.group_pigs.name)
|
||||
self.assertEqual(mail.email_to, self.email_template.email_to)
|
||||
self.assertEqual(mail.email_cc, self.email_template.email_cc)
|
||||
self.assertEqual(mail.recipient_ids, self.partner_2 | self.user_employee.partner_id)
|
||||
|
||||
def test_message_compose_template_save(self):
|
||||
self.env['mail.compose.message'].with_context(
|
||||
{'default_composition_mode': 'comment',
|
||||
'default_model': 'mail.group',
|
||||
'default_res_id': self.group_pigs.id,
|
||||
'active_ids': [self.group_pigs.id, self.group_public.id]
|
||||
}).create({
|
||||
'subject': 'Forget me subject',
|
||||
'body': '<p>Dummy body</p>'
|
||||
}).with_context({'default_model': 'mail.group'}).save_as_template()
|
||||
# Test: email_template subject, body_html, model
|
||||
last_template = self.env['mail.template'].search([('model', '=', 'mail.group'), ('subject', '=', 'Forget me subject')], limit=1)
|
||||
self.assertEqual(last_template.body_html, '<p>Dummy body</p>', 'email_template incorrect body_html')
|
||||
|
||||
@@ -1,85 +1,59 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.mail.tests.common import TestMail
|
||||
from openerp.tools import mute_logger
|
||||
|
||||
|
||||
class test_mail_access_rights(TestMail):
|
||||
class TestMessageRead(TestMail):
|
||||
|
||||
def test_00_message_read(self):
|
||||
""" Tests for message_read and expandables. """
|
||||
cr, uid, user_admin, user_raoul, group_pigs = self.cr, self.uid, self.user_admin, self.user_raoul, self.group_pigs
|
||||
self.mail_group.message_subscribe_users(cr, uid, [group_pigs.id], [user_raoul.id])
|
||||
pigs_domain = [('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)]
|
||||
@mute_logger('openerp.addons.mail.mail_mail')
|
||||
def setUp(self):
|
||||
super(TestMessageRead, self).setUp()
|
||||
self.group_pigs.message_subscribe_users([self.user_employee.id])
|
||||
self.msg_id0 = self.group_pigs.message_post(body='0', subtype='mt_comment')
|
||||
self.msg_id1 = self.group_pigs.message_post(body='1', subtype='mt_comment')
|
||||
self.msg_id2 = self.group_pigs.message_post(body='2', subtype='mt_comment')
|
||||
self.msg_id3 = self.group_pigs.message_post(body='1-1', subtype='mt_comment', parent_id=self.msg_id1)
|
||||
self.msg_id4 = self.group_pigs.message_post(body='2-1', subtype='mt_comment', parent_id=self.msg_id2)
|
||||
self.msg_id5 = self.group_pigs.message_post(body='1-2', subtype='mt_comment', parent_id=self.msg_id1)
|
||||
self.msg_id6 = self.group_pigs.message_post(body='2-2', subtype='mt_comment', parent_id=self.msg_id2)
|
||||
self.msg_id7 = self.group_pigs.message_post(body='1-1-1', subtype='mt_comment', parent_id=self.msg_id3)
|
||||
self.msg_id8 = self.group_pigs.message_post(body='2-1-1', subtype='mt_comment', parent_id=self.msg_id4)
|
||||
self.msg_id9 = self.group_pigs.message_post(body='1-1-1', subtype='mt_comment', parent_id=self.msg_id3)
|
||||
self.msg_id10 = self.group_pigs.message_post(body='2-1-1', subtype='mt_comment', parent_id=self.msg_id4)
|
||||
self.msg_ids = [self.msg_id10, self.msg_id9, self.msg_id8, self.msg_id7, self.msg_id6, self.msg_id5, self.msg_id4, self.msg_id3, self.msg_id2, self.msg_id1, self.msg_id0]
|
||||
self.ordered_msg_ids = [self.msg_id2, self.msg_id4, self.msg_id6, self.msg_id8, self.msg_id10, self.msg_id1, self.msg_id3, self.msg_id5, self.msg_id7, self.msg_id9, self.msg_id0]
|
||||
|
||||
# Data: create a discussion in Pigs (3 threads, with respectively 0, 4 and 4 answers)
|
||||
msg_id0 = self.group_pigs.message_post(body='0', subtype='mt_comment')
|
||||
msg_id1 = self.group_pigs.message_post(body='1', subtype='mt_comment')
|
||||
msg_id2 = self.group_pigs.message_post(body='2', subtype='mt_comment')
|
||||
msg_id3 = self.group_pigs.message_post(body='1-1', subtype='mt_comment', parent_id=msg_id1)
|
||||
msg_id4 = self.group_pigs.message_post(body='2-1', subtype='mt_comment', parent_id=msg_id2)
|
||||
msg_id5 = self.group_pigs.message_post(body='1-2', subtype='mt_comment', parent_id=msg_id1)
|
||||
msg_id6 = self.group_pigs.message_post(body='2-2', subtype='mt_comment', parent_id=msg_id2)
|
||||
msg_id7 = self.group_pigs.message_post(body='1-1-1', subtype='mt_comment', parent_id=msg_id3)
|
||||
msg_id8 = self.group_pigs.message_post(body='2-1-1', subtype='mt_comment', parent_id=msg_id4)
|
||||
msg_id9 = self.group_pigs.message_post(body='1-1-1', subtype='mt_comment', parent_id=msg_id3)
|
||||
msg_id10 = self.group_pigs.message_post(body='2-1-1', subtype='mt_comment', parent_id=msg_id4)
|
||||
msg_ids = [msg_id10, msg_id9, msg_id8, msg_id7, msg_id6, msg_id5, msg_id4, msg_id3, msg_id2, msg_id1, msg_id0]
|
||||
ordered_msg_ids = [msg_id2, msg_id4, msg_id6, msg_id8, msg_id10, msg_id1, msg_id3, msg_id5, msg_id7, msg_id9, msg_id0]
|
||||
# TODO: with_context({'mail_read_set_read': True})
|
||||
|
||||
# Test: raoul received notifications
|
||||
raoul_notification_ids = self.mail_notification.search(cr, user_raoul.id, [('is_read', '=', False), ('message_id', 'in', msg_ids), ('partner_id', '=', user_raoul.partner_id.id)])
|
||||
self.assertEqual(len(raoul_notification_ids), 11, 'message_post: wrong number of produced notifications')
|
||||
def test_message_read_ids(self):
|
||||
""" message_read: test reading specific ids """
|
||||
messages = self.env['mail.message'].sudo(self.user_employee).message_read(self.msg_ids[2:4], domain=[('body', 'like', 'dummy')])
|
||||
read_msg_ids = [msg.get('id') for msg in messages]
|
||||
self.assertEqual(read_msg_ids, self.msg_ids[2:4], 'message_read with direct ids should read only the requested ids')
|
||||
|
||||
# Test: read some specific ids
|
||||
read_msg_list = self.mail_message.message_read(cr, user_raoul.id, ids=msg_ids[2:4], domain=[('body', 'like', 'dummy')], context={'mail_read_set_read': True})
|
||||
read_msg_ids = [msg.get('id') for msg in read_msg_list]
|
||||
self.assertEqual(msg_ids[2:4], read_msg_ids, 'message_read with direct ids should read only the requested ids')
|
||||
def test_message_read_domain(self):
|
||||
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs.id)], limit=200)
|
||||
read_msg_ids = [msg.get('id') for msg in messages]
|
||||
self.assertEqual(read_msg_ids, self.msg_ids, 'message_read flat with domain on Pigs should equal all messages of Pigs')
|
||||
|
||||
# Test: read messages of Pigs through a domain, being thread or not threaded
|
||||
read_msg_list = self.mail_message.message_read(cr, user_raoul.id, domain=pigs_domain, limit=200)
|
||||
read_msg_ids = [msg.get('id') for msg in read_msg_list]
|
||||
self.assertEqual(msg_ids, read_msg_ids, 'message_read flat with domain on Pigs should equal all messages of Pigs')
|
||||
read_msg_list = self.mail_message.message_read(cr, user_raoul.id, domain=pigs_domain, limit=200, thread_level=1)
|
||||
read_msg_ids = [msg.get('id') for msg in read_msg_list]
|
||||
self.assertEqual(ordered_msg_ids, read_msg_ids,
|
||||
'message_read threaded with domain on Pigs should equal all messages of Pigs, and sort them with newer thread first, last message last in thread')
|
||||
def test_message_read_domain_thread(self):
|
||||
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs.id)], limit=200, thread_level=1)
|
||||
read_msg_ids = [msg.get('id') for msg in messages]
|
||||
self.assertEqual(read_msg_ids, self.ordered_msg_ids, 'message_read threaded with domain on Pigs should equal all messages of Pigs, and sort them with newer thread first, last message last in thread')
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE1: message_read with domain, threaded
|
||||
# We simulate an entire flow, using the expandables to test them
|
||||
# ----------------------------------------
|
||||
|
||||
# Do: read last message, threaded
|
||||
read_msg_list = self.mail_message.message_read(cr, uid, domain=pigs_domain, limit=1, thread_level=1)
|
||||
read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
|
||||
def test_message_read_expandable(self):
|
||||
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs.id)], limit=1, thread_level=1)
|
||||
read_msg_ids = [msg.get('id') for msg in messages if msg.get('type') != 'expandable']
|
||||
# TDE TODO: test expandables order
|
||||
type_list = map(lambda item: item.get('type'), read_msg_list)
|
||||
type_list = map(lambda item: item.get('type'), messages)
|
||||
# Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
|
||||
self.assertEqual(len(read_msg_list), 4, 'message_read on last Pigs message should return 2 messages and 2 expandables')
|
||||
self.assertEqual(set([msg_id2, msg_id10]), set(read_msg_ids), 'message_read on the last Pigs message should also get its parent')
|
||||
self.assertEqual(read_msg_list[1].get('parent_id'), read_msg_list[0].get('id'), 'message_read should set the ancestor to the thread header')
|
||||
self.assertEqual(len(messages), 4, 'message_read on last Pigs message should return 2 messages and 2 expandables')
|
||||
self.assertEqual(set([self.msg_id2, self.msg_id10]), set(read_msg_ids), 'message_read on the last Pigs message should also get its parent')
|
||||
self.assertEqual(messages[1].get('parent_id'), messages[0].get('id'), 'message_read should set the ancestor to the thread header')
|
||||
# Data: get expandables
|
||||
new_threads_exp, new_msg_exp = None, None
|
||||
for msg in read_msg_list:
|
||||
for msg in messages:
|
||||
if msg.get('type') == 'expandable' and msg.get('nb_messages') == -1 and msg.get('max_limit'):
|
||||
new_threads_exp = msg
|
||||
elif msg.get('type') == 'expandable':
|
||||
@@ -89,101 +63,98 @@ class test_mail_access_rights(TestMail):
|
||||
self.assertIsNotNone(new_msg_exp, 'message_read on last Pigs message should have returned a new messages expandable')
|
||||
domain = new_msg_exp.get('domain', [])
|
||||
# Test: expandable, conditions in domain
|
||||
self.assertIn(('id', 'child_of', msg_id2), domain, 'new messages expandable domain should contain a child_of condition')
|
||||
self.assertIn(('id', '>=', msg_id4), domain, 'new messages expandable domain should contain an id greater than condition')
|
||||
self.assertIn(('id', '<=', msg_id8), domain, 'new messages expandable domain should contain an id less than condition')
|
||||
self.assertEqual(new_msg_exp.get('parent_id'), msg_id2, 'new messages expandable should have parent_id set to the thread header')
|
||||
self.assertIn(('id', 'child_of', self.msg_id2), domain, 'new messages expandable domain should contain a child_of condition')
|
||||
self.assertIn(('id', '>=', self.msg_id4), domain, 'new messages expandable domain should contain an id greater than condition')
|
||||
self.assertIn(('id', '<=', self.msg_id8), domain, 'new messages expandable domain should contain an id less than condition')
|
||||
self.assertEqual(new_msg_exp.get('parent_id'), self.msg_id2, 'new messages expandable should have parent_id set to the thread header')
|
||||
# Do: message_read with domain, thread_level=0, parent_id=msg_id2 (should be imposed by JS), 2 messages
|
||||
read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=2, thread_level=0, parent_id=msg_id2)
|
||||
read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
|
||||
new_msg_exp = [msg for msg in read_msg_list if msg.get('type') == 'expandable'][0]
|
||||
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=domain, limit=2, thread_level=0, parent_id=self.msg_id2)
|
||||
read_msg_ids = [msg.get('id') for msg in messages if msg.get('type') != 'expandable']
|
||||
new_msg_exp = [msg for msg in messages if msg.get('type') == 'expandable'][0]
|
||||
# Test: structure content, 2 messages and 1 thread expandable
|
||||
self.assertEqual(len(read_msg_list), 3, 'message_read in Pigs thread should return 2 messages and 1 expandables')
|
||||
self.assertEqual(set([msg_id6, msg_id8]), set(read_msg_ids), 'message_read in Pigs thread should return 2 more previous messages in thread')
|
||||
self.assertEqual(len(messages), 3, 'message_read in Pigs thread should return 2 messages and 1 expandables')
|
||||
self.assertEqual(set([self.msg_id6, self.msg_id8]), set(read_msg_ids), 'message_read in Pigs thread should return 2 more previous messages in thread')
|
||||
# Do: read the last message
|
||||
read_msg_list = self.mail_message.message_read(cr, uid, domain=new_msg_exp.get('domain'), limit=2, thread_level=0, parent_id=msg_id2)
|
||||
read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
|
||||
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=new_msg_exp.get('domain'), limit=2, thread_level=0, parent_id=self.msg_id2)
|
||||
read_msg_ids = [msg.get('id') for msg in messages if msg.get('type') != 'expandable']
|
||||
# Test: structure content, 1 message
|
||||
self.assertEqual(len(read_msg_list), 1, 'message_read in Pigs thread should return 1 message')
|
||||
self.assertEqual(set([msg_id4]), set(read_msg_ids), 'message_read in Pigs thread should return the last message in thread')
|
||||
|
||||
self.assertEqual(len(messages), 1, 'message_read in Pigs thread should return 1 message')
|
||||
self.assertEqual(set([self.msg_id4]), set(read_msg_ids), 'message_read in Pigs thread should return the last message in thread')
|
||||
# Do: fetch a new thread, domain from expandable
|
||||
self.assertIsNotNone(new_threads_exp, 'message_read on last Pigs message should have returned a new threads expandable')
|
||||
domain = new_threads_exp.get('domain', [])
|
||||
# Test: expandable, conditions in domain
|
||||
for condition in pigs_domain:
|
||||
for condition in [('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs.id)]:
|
||||
self.assertIn(condition, domain, 'new threads expandable domain should contain the message_read domain parameter')
|
||||
self.assertFalse(new_threads_exp.get('parent_id'), 'new threads expandable should not have an parent_id')
|
||||
# Do: message_read with domain, thread_level=1 (should be imposed by JS)
|
||||
read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=1, thread_level=1)
|
||||
read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
|
||||
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=domain, limit=1, thread_level=1)
|
||||
read_msg_ids = [msg.get('id') for msg in messages if msg.get('type') != 'expandable']
|
||||
# Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
|
||||
self.assertEqual(len(read_msg_list), 4, 'message_read on Pigs should return 2 messages and 2 expandables')
|
||||
self.assertEqual(set([msg_id1, msg_id9]), set(read_msg_ids), 'message_read on a Pigs message should also get its parent')
|
||||
self.assertEqual(read_msg_list[1].get('parent_id'), read_msg_list[0].get('id'), 'message_read should set the ancestor to the thread header')
|
||||
self.assertEqual(len(messages), 4, 'message_read on Pigs should return 2 messages and 2 expandables')
|
||||
self.assertEqual(set([self.msg_id1, self.msg_id9]), set(read_msg_ids), 'message_read on a Pigs message should also get its parent')
|
||||
self.assertEqual(messages[1].get('parent_id'), messages[0].get('id'), 'message_read should set the ancestor to the thread header')
|
||||
# Data: get expandables
|
||||
new_threads_exp, new_msg_exp = None, None
|
||||
for msg in read_msg_list:
|
||||
for msg in messages:
|
||||
if msg.get('type') == 'expandable' and msg.get('nb_messages') == -1 and msg.get('max_limit'):
|
||||
new_threads_exp = msg
|
||||
elif msg.get('type') == 'expandable':
|
||||
new_msg_exp = msg
|
||||
|
||||
# Do: fetch new messages in second thread, domain from expandable
|
||||
self.assertIsNotNone(new_msg_exp, 'message_read on Pigs message should have returned a new messages expandable')
|
||||
domain = new_msg_exp.get('domain', [])
|
||||
# Test: expandable, conditions in domain
|
||||
self.assertIn(('id', 'child_of', msg_id1), domain, 'new messages expandable domain should contain a child_of condition')
|
||||
self.assertIn(('id', '>=', msg_id3), domain, 'new messages expandable domain should contain an id greater than condition')
|
||||
self.assertIn(('id', '<=', msg_id7), domain, 'new messages expandable domain should contain an id less than condition')
|
||||
self.assertEqual(new_msg_exp.get('parent_id'), msg_id1, 'new messages expandable should have ancestor_id set to the thread header')
|
||||
self.assertIn(('id', 'child_of', self.msg_id1), domain, 'new messages expandable domain should contain a child_of condition')
|
||||
self.assertIn(('id', '>=', self.msg_id3), domain, 'new messages expandable domain should contain an id greater than condition')
|
||||
self.assertIn(('id', '<=', self.msg_id7), domain, 'new messages expandable domain should contain an id less than condition')
|
||||
self.assertEqual(new_msg_exp.get('parent_id'), self.msg_id1, 'new messages expandable should have ancestor_id set to the thread header')
|
||||
# Do: message_read with domain, thread_level=0, parent_id=msg_id1 (should be imposed by JS)
|
||||
read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=200, thread_level=0, parent_id=msg_id1)
|
||||
read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
|
||||
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=domain, limit=200, thread_level=0, parent_id=self.msg_id1)
|
||||
read_msg_ids = [msg.get('id') for msg in messages if msg.get('type') != 'expandable']
|
||||
# Test: other message in thread have been fetch
|
||||
self.assertEqual(set([msg_id3, msg_id5, msg_id7]), set(read_msg_ids), 'message_read on the last Pigs message should also get its parent')
|
||||
self.assertEqual(set([self.msg_id3, self.msg_id5, self.msg_id7]), set(read_msg_ids), 'message_read on the last Pigs message should also get its parent')
|
||||
|
||||
# Test: fetch a new thread, domain from expandable
|
||||
self.assertIsNotNone(new_threads_exp, 'message_read should have returned a new threads expandable')
|
||||
domain = new_threads_exp.get('domain', [])
|
||||
# Test: expandable, conditions in domain
|
||||
for condition in pigs_domain:
|
||||
for condition in [('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs.id)]:
|
||||
self.assertIn(condition, domain, 'general expandable domain should contain the message_read domain parameter')
|
||||
# Do: message_read with domain, thread_level=1 (should be imposed by JS)
|
||||
read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=1, thread_level=1)
|
||||
read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
|
||||
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=domain, limit=1, thread_level=1)
|
||||
read_msg_ids = [msg.get('id') for msg in messages if msg.get('type') != 'expandable']
|
||||
# Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
|
||||
self.assertEqual(len(read_msg_list), 1, 'message_read on Pigs should return 1 message because everything else has been fetched')
|
||||
self.assertEqual([msg_id0], read_msg_ids, 'message_read after 2 More should return only 1 last message')
|
||||
self.assertEqual(len(messages), 1, 'message_read on Pigs should return 1 message because everything else has been fetched')
|
||||
self.assertEqual([self.msg_id0], read_msg_ids, 'message_read after 2 More should return only 1 last message')
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE2: message_read with domain, flat
|
||||
# ----------------------------------------
|
||||
|
||||
# Do: read 2 lasts message, flat
|
||||
read_msg_list = self.mail_message.message_read(cr, uid, domain=pigs_domain, limit=2, thread_level=0)
|
||||
read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
|
||||
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs.id)], limit=2, thread_level=0)
|
||||
read_msg_ids = [msg.get('id') for msg in messages if msg.get('type') != 'expandable']
|
||||
# Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is not set, 1 expandable
|
||||
self.assertEqual(len(read_msg_list), 3, 'message_read on last Pigs message should return 2 messages and 1 expandable')
|
||||
self.assertEqual(set([msg_id9, msg_id10]), set(read_msg_ids), 'message_read flat on Pigs last messages should only return those messages')
|
||||
self.assertFalse(read_msg_list[0].get('parent_id'), 'message_read flat should set the ancestor as False')
|
||||
self.assertFalse(read_msg_list[1].get('parent_id'), 'message_read flat should set the ancestor as False')
|
||||
self.assertEqual(len(messages), 3, 'message_read on last Pigs message should return 2 messages and 1 expandable')
|
||||
self.assertEqual(set([self.msg_id9, self.msg_id10]), set(read_msg_ids), 'message_read flat on Pigs last messages should only return those messages')
|
||||
self.assertFalse(messages[0].get('parent_id'), 'message_read flat should set the ancestor as False')
|
||||
self.assertFalse(messages[1].get('parent_id'), 'message_read flat should set the ancestor as False')
|
||||
# Data: get expandables
|
||||
new_threads_exp, new_msg_exp = None, None
|
||||
for msg in read_msg_list:
|
||||
for msg in messages:
|
||||
if msg.get('type') == 'expandable' and msg.get('nb_messages') == -1 and msg.get('max_limit'):
|
||||
new_threads_exp = msg
|
||||
|
||||
# Do: fetch new messages, domain from expandable
|
||||
self.assertIsNotNone(new_threads_exp, 'message_read flat on the 2 last Pigs messages should have returns a new threads expandable')
|
||||
domain = new_threads_exp.get('domain', [])
|
||||
# Test: expandable, conditions in domain
|
||||
for condition in pigs_domain:
|
||||
for condition in [('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs.id)]:
|
||||
self.assertIn(condition, domain, 'new threads expandable domain should contain the message_read domain parameter')
|
||||
# Do: message_read with domain, thread_level=0 (should be imposed by JS)
|
||||
read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=20, thread_level=0)
|
||||
read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
|
||||
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=domain, limit=20, thread_level=0)
|
||||
read_msg_ids = [msg.get('id') for msg in messages if msg.get('type') != 'expandable']
|
||||
# Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
|
||||
self.assertEqual(len(read_msg_list), 9, 'message_read on Pigs should return 9 messages and 0 expandable')
|
||||
self.assertEqual([msg_id8, msg_id7, msg_id6, msg_id5, msg_id4, msg_id3, msg_id2, msg_id1, msg_id0], read_msg_ids,
|
||||
self.assertEqual(len(messages), 9, 'message_read on Pigs should return 9 messages and 0 expandable')
|
||||
self.assertEqual([self.msg_id8, self.msg_id7, self.msg_id6, self.msg_id5, self.msg_id4, self.msg_id3, self.msg_id2, self.msg_id1, self.msg_id0], read_msg_ids,
|
||||
'message_read, More on flat, should return all remaning messages')
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from openerp.addons.mail.tests.common import TestMail
|
||||
|
||||
|
||||
class TestTracking(TestMail):
|
||||
|
||||
def test_message_track(self):
|
||||
""" Testing auto tracking of fields. Warning, it has not be cleaned and
|
||||
should probably be. """
|
||||
def _strip_string_spaces(body):
|
||||
return body.replace(' ', '').replace('\n', '')
|
||||
self.group_pigs.message_subscribe_users(user_ids=[self.user_employee.id])
|
||||
# Data: res.users.group, to test group_public_id automatic logging
|
||||
group_system_id = self.env['ir.model.data'].xmlid_to_res_id('base.group_system') or False
|
||||
|
||||
# Data: custom subtypes
|
||||
Subtype = self.env['mail.message.subtype']
|
||||
Data = self.env['ir.model.data']
|
||||
mt_private = Subtype.create({'name': 'private', 'description': 'Private public'})
|
||||
Data.create({'name': 'mt_private', 'model': 'mail.message.subtype', 'module': 'mail', 'res_id': mt_private.id})
|
||||
mt_name_supername = Subtype.create({'name': 'name_supername', 'description': 'Supername name'})
|
||||
Data.create({'name': 'mt_name_supername', 'model': 'mail.message.subtype', 'module': 'mail', 'res_id': mt_name_supername.id})
|
||||
mt_group_public_set = Subtype.create({'name': 'group_public_set', 'description': 'Group set'})
|
||||
Data.create({'name': 'mt_group_public_set', 'model': 'mail.message.subtype', 'module': 'mail', 'res_id': mt_group_public_set.id})
|
||||
mt_group_public = Subtype.create({'name': 'group_public', 'description': 'Group changed'})
|
||||
Data.create({'name': 'mt_group_public', 'model': 'mail.message.subtype', 'module': 'mail', 'res_id': mt_group_public.id})
|
||||
|
||||
def _track_subtype(self, cr, uid, ids, init_values, context=None):
|
||||
record = self.browse(cr, uid, ids[0], context=context)
|
||||
if 'public' in init_values and record.public == 'private':
|
||||
return 'mail.mt_private'
|
||||
elif 'name' in init_values and record.name == 'supername':
|
||||
return 'mail.mt_name_supername'
|
||||
elif 'group_public_id' in init_values and record.group_public_id:
|
||||
return 'mail.mt_group_public_set'
|
||||
elif 'group_public_id' in init_values and not record.group_public_id:
|
||||
return 'mail.mt_group_public'
|
||||
return False
|
||||
self.registry('mail.group')._patch_method('_track_subtype', _track_subtype)
|
||||
|
||||
visibility = {'public': 'onchange', 'name': 'always', 'group_public_id': 'onchange'}
|
||||
cls = type(self.env['mail.group'])
|
||||
for key in visibility:
|
||||
self.assertFalse(hasattr(getattr(cls, key), 'track_visibility'))
|
||||
getattr(cls, key).track_visibility = visibility[key]
|
||||
|
||||
@self.addCleanup
|
||||
def cleanup():
|
||||
for key in visibility:
|
||||
del getattr(cls, key).track_visibility
|
||||
|
||||
# Test: change name -> always tracked, not related to a subtype
|
||||
self.group_pigs.sudo(self.user_employee).write({'public': 'public'})
|
||||
self.assertEqual(len(self.group_pigs.message_ids.ids), 1, 'tracked: a message should have been produced')
|
||||
# Test: first produced message: no subtype, name change tracked
|
||||
last_msg = self.group_pigs.message_ids[-1]
|
||||
self.assertFalse(last_msg.subtype_id.id, 'tracked: message should not have been linked to a subtype')
|
||||
self.assertIn(u"Selectedgroupofusers\u2192Everyone", _strip_string_spaces(last_msg.body), 'tracked: message body incorrect')
|
||||
self.assertIn('Pigs', _strip_string_spaces(last_msg.body), 'tracked: message body does not hold always tracked field')
|
||||
# Test: change name as supername, public as private -> 2 subtypes
|
||||
self.group_pigs.sudo(self.user_employee).write({'name': 'supername', 'public': 'private'})
|
||||
self.assertEqual(len(self.group_pigs.message_ids.ids), 2, 'tracked: two messages should have been produced')
|
||||
# Test: first produced message: mt_name_supername
|
||||
last_msg = self.group_pigs.message_ids[-2]
|
||||
self.assertEqual(last_msg.subtype_id.id, mt_private.id, 'tracked: message should be linked to mt_private subtype')
|
||||
self.assertIn('Private public', last_msg.body, 'tracked: message body does not hold the subtype description')
|
||||
self.assertIn(u'Pigs\u2192supername', _strip_string_spaces(last_msg.body), 'tracked: message body incorrect')
|
||||
|
||||
# Test: change public as public, group_public_id -> 1 subtype, name always tracked
|
||||
self.group_pigs.sudo(self.user_employee).write({'public': 'public', 'group_public_id': group_system_id})
|
||||
self.assertEqual(len(self.group_pigs.message_ids), 3, 'tracked: one message should have been produced')
|
||||
# Test: first produced message: mt_group_public_set_id, with name always tracked, public tracked on change
|
||||
last_msg = self.group_pigs.message_ids[-3]
|
||||
self.assertEqual(last_msg.subtype_id, mt_group_public_set, 'tracked: message should be linked to mt_group_public_set_id')
|
||||
self.assertIn('Group set', last_msg.body, 'tracked: message body does not hold the subtype description')
|
||||
self.assertIn(u"Invitedpeopleonly\u2192Everyone", _strip_string_spaces(last_msg.body), 'tracked: message body does not hold changed tracked field')
|
||||
self.assertIn(u'HumanResources/Employee\u2192Administration/Settings', _strip_string_spaces(last_msg.body), 'tracked: message body does not hold always tracked field')
|
||||
|
||||
# Test: change group_public_id to False -> 1 subtype, name always tracked
|
||||
self.group_pigs.sudo(self.user_employee).write({'group_public_id': False})
|
||||
self.assertEqual(len(self.group_pigs.message_ids), 4, 'tracked: one message should have been produced')
|
||||
# Test: first produced message: mt_group_public_set_id, with name always tracked, public tracked on change
|
||||
last_msg = self.group_pigs.message_ids[-4]
|
||||
self.assertEqual(last_msg.subtype_id, mt_group_public, 'tracked: message should be linked to mt_group_public_id')
|
||||
self.assertIn('Group changed', last_msg.body, 'tracked: message body does not hold the subtype description')
|
||||
self.assertIn(u'Administration/Settings\u2192', _strip_string_spaces(last_msg.body), 'tracked: message body does not hold always tracked field')
|
||||
# Test: change not tracked field, no tracking message
|
||||
self.group_pigs.sudo(self.user_employee).write({'description': 'Dummy'})
|
||||
self.assertEqual(len(self.group_pigs.message_ids), 4, 'tracked: No message should have been produced')
|
||||
@@ -1,22 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from . import test_portal
|
||||
|
||||
from . import test_portal
|
||||
|
||||
@@ -1,228 +1,97 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.mail.tests.common import TestMail
|
||||
from openerp.exceptions import AccessError
|
||||
from openerp.tools.misc import mute_logger
|
||||
|
||||
|
||||
class test_portal(TestMail):
|
||||
|
||||
def setUp(self):
|
||||
super(test_portal, self).setUp()
|
||||
cr, uid = self.cr, self.uid
|
||||
def test_mail_compose_access_rights(self):
|
||||
port_msg_id = self.group_portal.message_post(body='Message')
|
||||
|
||||
# Find Portal group
|
||||
group_portal = self.registry('ir.model.data').get_object(cr, uid, 'base', 'group_portal')
|
||||
self.group_portal_id = group_portal.id
|
||||
|
||||
# Create Chell (portal user)
|
||||
self.user_chell_id = self.res_users.create(cr, uid, {'name': 'Chell Gladys', 'login': 'chell', 'email': 'chell@gladys.portal', 'groups_id': [(6, 0, [self.group_portal_id])]})
|
||||
self.user_chell = self.res_users.browse(cr, uid, self.user_chell_id)
|
||||
self.partner_chell_id = self.user_chell.partner_id.id
|
||||
|
||||
# Create a PigsPortal group
|
||||
self.group_port_id = self.mail_group.create(cr, uid,
|
||||
{'name': 'PigsPortal', 'public': 'groups', 'group_public_id': self.group_portal_id},
|
||||
{'mail_create_nolog': True})
|
||||
|
||||
# Set an email address for the user running the tests, used as Sender for outgoing mails
|
||||
self.res_users.write(cr, uid, uid, {'email': 'test@localhost'})
|
||||
|
||||
@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models')
|
||||
def test_00_mail_access_rights(self):
|
||||
""" Test basic mail_message and mail_group access rights for portal users. """
|
||||
cr, uid = self.cr, self.uid
|
||||
mail_compose = self.registry('mail.compose.message')
|
||||
|
||||
# Prepare group: Pigs and PigsPortal
|
||||
pigs_msg_id = self.mail_group.message_post(cr, uid, self.group_pigs_id, body='Message')
|
||||
port_msg_id = self.mail_group.message_post(cr, uid, self.group_port_id, body='Message')
|
||||
|
||||
# Do: Chell browses Pigs -> ko, employee group
|
||||
chell_pigs = self.mail_group.browse(cr, self.user_chell_id, self.group_pigs_id)
|
||||
with self.assertRaises(AccessError):
|
||||
trigger_read = chell_pigs.name
|
||||
|
||||
# Do: Chell posts a message on Pigs, crash because can not write on group or is not in the followers
|
||||
with self.assertRaises(AccessError):
|
||||
self.mail_group.message_post(cr, self.user_chell_id, self.group_pigs_id, body='Message')
|
||||
|
||||
# Do: Chell is added into Pigs followers and browse it -> ok for messages, ko for partners (no read permission)
|
||||
self.mail_group.message_subscribe_users(cr, uid, [self.group_pigs_id], [self.user_chell_id])
|
||||
chell_pigs = self.mail_group.browse(cr, self.user_chell_id, self.group_pigs_id)
|
||||
trigger_read = chell_pigs.name
|
||||
for message in chell_pigs.message_ids:
|
||||
trigger_read = message.subject
|
||||
for partner in chell_pigs.message_follower_ids:
|
||||
if partner.id == self.partner_chell_id:
|
||||
# Chell can read her own partner record
|
||||
continue
|
||||
with self.assertRaises(AccessError):
|
||||
trigger_read = partner.name
|
||||
|
||||
# Do: Chell comments Pigs, ok because he is now in the followers
|
||||
self.mail_group.message_post(cr, self.user_chell_id, self.group_pigs_id, body='I love Pigs')
|
||||
# Do: Chell comments Pigs, ok because can write on it (public group)
|
||||
self.group_portal.sudo(self.user_portal).message_post(body='I love Pigs')
|
||||
# Do: Chell creates a mail.compose.message record on Pigs, because he uses the wizard
|
||||
compose_id = mail_compose.create(cr, self.user_chell_id,
|
||||
{'subject': 'Subject', 'body': 'Body text', 'partner_ids': []},
|
||||
{'default_composition_mode': 'comment', 'default_model': 'mail.group', 'default_res_id': self.group_pigs_id})
|
||||
mail_compose.send_mail(cr, self.user_chell_id, [compose_id])
|
||||
compose = self.env['mail.compose.message'].with_context({
|
||||
'default_composition_mode': 'comment',
|
||||
'default_model': 'mail.group',
|
||||
'default_res_id': self.group_portal.id
|
||||
}).sudo(self.user_portal).create({
|
||||
'subject': 'Subject',
|
||||
'body': 'Body text',
|
||||
'partner_ids': []})
|
||||
compose.send_mail()
|
||||
|
||||
# Do: Chell replies to a Pigs message using the composer
|
||||
compose_id = mail_compose.create(cr, self.user_chell_id,
|
||||
{'subject': 'Subject', 'body': 'Body text'},
|
||||
{'default_composition_mode': 'comment', 'default_parent_id': pigs_msg_id})
|
||||
mail_compose.send_mail(cr, self.user_chell_id, [compose_id])
|
||||
compose = self.env['mail.compose.message'].with_context({
|
||||
'default_composition_mode': 'comment',
|
||||
'default_parent_id': port_msg_id
|
||||
}).sudo(self.user_portal).create({
|
||||
'subject': 'Subject',
|
||||
'body': 'Body text'})
|
||||
compose.send_mail()
|
||||
|
||||
# Do: Chell browses PigsPortal -> ok because groups security, ko for partners (no read permission)
|
||||
chell_port = self.mail_group.browse(cr, self.user_chell_id, self.group_port_id)
|
||||
trigger_read = chell_port.name
|
||||
for message in chell_port.message_ids:
|
||||
trigger_read = message.subject
|
||||
for partner in chell_port.message_follower_ids:
|
||||
with self.assertRaises(AccessError):
|
||||
trigger_read = partner.name
|
||||
|
||||
def test_10_mail_invite(self):
|
||||
cr, uid = self.cr, self.uid
|
||||
mail_invite = self.registry('mail.wizard.invite')
|
||||
base_url = self.registry('ir.config_parameter').get_param(cr, uid, 'web.base.url', default='')
|
||||
@mute_logger('openerp.addons.mail.mail_mail')
|
||||
def test_invite_email_portal(self):
|
||||
group_pigs = self.group_pigs
|
||||
base_url = self.env['ir.config_parameter'].get_param('web.base.url', default='')
|
||||
# Carine Poilvache, with email, should receive emails for comments and emails
|
||||
partner_carine_id = self.res_partner.create(cr, uid, {'name': 'Carine Poilvache', 'email': 'c@c'})
|
||||
partner_carine = self.env['res.partner'].create({'name': 'Carine Poilvache', 'email': 'c@c'})
|
||||
|
||||
# Do: create a mail_wizard_invite, validate it
|
||||
self._init_mock_build_email()
|
||||
context = {'default_res_model': 'mail.group', 'default_res_id': self.group_pigs_id}
|
||||
mail_invite_id = mail_invite.create(cr, uid, {'partner_ids': [(4, partner_carine_id)], 'send_mail': True}, context)
|
||||
mail_invite.add_followers(cr, uid, [mail_invite_id])
|
||||
|
||||
mail_invite = self.env['mail.wizard.invite'].with_context({
|
||||
'default_res_model': 'mail.group',
|
||||
'default_res_id': group_pigs.id}).create({
|
||||
'partner_ids': [(4, partner_carine.id)], 'send_mail': True})
|
||||
mail_invite.add_followers()
|
||||
# Test: Pigs followers should contain Admin and Bert
|
||||
group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
|
||||
follower_ids = [follower.id for follower in group_pigs.message_follower_ids]
|
||||
self.assertEqual(set(follower_ids), set([self.partner_admin_id, partner_carine_id]), 'Pigs followers after invite is incorrect')
|
||||
|
||||
self.assertEqual(group_pigs.message_follower_ids, partner_carine)
|
||||
# Test: partner must have been prepared for signup
|
||||
partner_carine = self.res_partner.browse(cr, uid, partner_carine_id)
|
||||
self.assertTrue(partner_carine.signup_valid, 'partner has not been prepared for signup')
|
||||
self.assertTrue(base_url in partner_carine.signup_url, 'signup url is incorrect')
|
||||
self.assertTrue(cr.dbname in partner_carine.signup_url, 'signup url is incorrect')
|
||||
self.assertTrue(self.env.cr.dbname in partner_carine.signup_url, 'signup url is incorrect')
|
||||
self.assertTrue(partner_carine.signup_token in partner_carine.signup_url, 'signup url is incorrect')
|
||||
|
||||
# Test: (pretend to) send email and check subject, body
|
||||
self.assertEqual(len(self._build_email_kwargs_list), 1, 'sent email number incorrect, should be only for Bert')
|
||||
for sent_email in self._build_email_kwargs_list:
|
||||
self.assertEqual(sent_email.get('subject'), 'Invitation to follow Discussion group: Pigs',
|
||||
'invite: subject of invitation email is incorrect')
|
||||
self.assertIn('Administrator invited you to follow Discussion group document: Pigs', sent_email.get('body'),
|
||||
'invite: body of invitation email is incorrect')
|
||||
self.assertIn(partner_carine.signup_token, sent_email.get('body'),
|
||||
'invite: body of invitation email does not contain signup token')
|
||||
self.assertEqual(len(self._mails), 1, 'sent email number incorrect, should be only for Bert')
|
||||
for sent_email in self._mails:
|
||||
self.assertEqual(
|
||||
sent_email.get('subject'), 'Invitation to follow Discussion group: Pigs',
|
||||
'invite: subject of invitation email is incorrect')
|
||||
self.assertIn(
|
||||
'Administrator invited you to follow Discussion group document: Pigs', sent_email.get('body'),
|
||||
'invite: body of invitation email is incorrect')
|
||||
self.assertIn(
|
||||
partner_carine.signup_token, sent_email.get('body'),
|
||||
'invite: body of invitation email does not contain signup token')
|
||||
|
||||
def test_20_notification_url(self):
|
||||
""" Tests designed to test the URL added in notification emails. """
|
||||
cr, uid, group_pigs = self.cr, self.uid, self.group_pigs
|
||||
|
||||
# Partner data
|
||||
partner_raoul = self.res_partner.browse(cr, uid, self.partner_raoul_id)
|
||||
partner_bert_id = self.res_partner.create(cr, uid, {'name': 'bert'})
|
||||
partner_bert = self.res_partner.browse(cr, uid, partner_bert_id)
|
||||
def test_mail_notification_url_partner_portal(self):
|
||||
# Mail data
|
||||
mail_mail_id = self.mail_mail.create(cr, uid, {'state': 'exception'})
|
||||
mail = self.mail_mail.browse(cr, uid, mail_mail_id)
|
||||
|
||||
mail = self.env['mail.mail'].create({'state': 'exception'})
|
||||
# Test: link for nobody -> None
|
||||
url = self.mail_mail._get_partner_access_link(cr, uid, mail)
|
||||
url = self.env['mail.mail']._get_partner_access_link(mail)
|
||||
self.assertEqual(url, None,
|
||||
'notification email: mails not send to a specific partner should not have any URL')
|
||||
|
||||
'notification email: mails not send to a specific partner should not have any URL')
|
||||
# Test: link for partner -> signup URL
|
||||
url = self.mail_mail._get_partner_access_link(cr, uid, mail, partner=partner_bert)
|
||||
self.assertIn(partner_bert.signup_token, url,
|
||||
'notification email: mails send to a not-user partner should contain the signup token')
|
||||
|
||||
url = self.env['mail.mail']._get_partner_access_link(mail, partner=self.partner_1)
|
||||
self.assertIn(self.partner_1.signup_token, url,
|
||||
'notification email: mails send to a not-user partner should contain the signup token')
|
||||
# Test: link for user -> signin
|
||||
url = self.mail_mail._get_partner_access_link(cr, uid, mail, partner=partner_raoul)
|
||||
url = self.env['mail.mail']._get_partner_access_link(mail, partner=self.user_employee.partner_id)
|
||||
self.assertIn('action=mail.action_mail_redirect', url,
|
||||
'notification email: link should contain the redirect action')
|
||||
self.assertIn('login=%s' % partner_raoul.user_ids[0].login, url,
|
||||
'notification email: link should contain the user login')
|
||||
'notification email: link should contain the redirect action')
|
||||
self.assertIn('login=%s' % self.user_employee.login, url,
|
||||
'notification email: link should contain the user login')
|
||||
|
||||
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.models')
|
||||
def test_21_inbox_redirection(self):
|
||||
""" Tests designed to test the inbox redirection of emails notification URLs. """
|
||||
cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
|
||||
model, act_id = self.ir_model_data.get_object_reference(cr, uid, 'mail', 'action_mail_inbox_feeds')
|
||||
model, port_act_id = self.ir_model_data.get_object_reference(cr, uid, 'portal', 'action_mail_inbox_feeds_portal')
|
||||
@mute_logger('openerp.addons.mail.mail_mail', 'openerp.models')
|
||||
def test_inbox_redirection_portal(self):
|
||||
group_pigs = self.group_pigs
|
||||
port_act_id = self.ref('portal.action_mail_inbox_feeds_portal')
|
||||
# Data: post a message on pigs
|
||||
msg_id = self.group_pigs.message_post(body='My body', partner_ids=[self.partner_bert_id, self.partner_chell_id], type='comment', subtype='mail.mt_comment')
|
||||
|
||||
# No specific parameters -> should redirect to Inbox
|
||||
action = self.mail_thread.message_redirect_action(cr, self.user_raoul_id, {'params': {}})
|
||||
self.assertEqual(action.get('type'), 'ir.actions.client',
|
||||
'URL redirection: action without parameters should redirect to client action Inbox')
|
||||
self.assertEqual(action.get('id'), act_id,
|
||||
'URL redirection: action without parameters should redirect to client action Inbox')
|
||||
|
||||
# Bert has read access to Pigs -> should redirect to form view of Pigs
|
||||
action = self.mail_thread.message_redirect_action(cr, self.user_raoul_id, {'params': {'message_id': msg_id}})
|
||||
self.assertEqual(action.get('type'), 'ir.actions.act_window',
|
||||
'URL redirection: action with message_id for read-accredited user should redirect to Pigs')
|
||||
self.assertEqual(action.get('res_id'), group_pigs.id,
|
||||
'URL redirection: action with message_id for read-accredited user should redirect to Pigs')
|
||||
|
||||
# Bert has no read access to Pigs -> should redirect to Inbox
|
||||
action = self.mail_thread.message_redirect_action(cr, self.user_bert_id, {'params': {'message_id': msg_id}})
|
||||
self.assertEqual(action.get('type'), 'ir.actions.client',
|
||||
'URL redirection: action without parameters should redirect to client action Inbox')
|
||||
self.assertEqual(action.get('id'), act_id,
|
||||
'URL redirection: action without parameters should redirect to client action Inbox')
|
||||
|
||||
msg_id = group_pigs.message_post(body='My body', partner_ids=[self.user_employee.partner_id.id, self.user_portal.partner_id.id], type='comment', subtype='mail.mt_comment')
|
||||
# Chell has no read access to pigs -> should redirect to Portal Inbox
|
||||
action = self.mail_thread.message_redirect_action(cr, self.user_chell_id, {'params': {'message_id': msg_id}})
|
||||
action = self.env['mail.thread'].with_context({'params': {'message_id': msg_id}}).sudo(self.user_portal).message_redirect_action()
|
||||
self.assertEqual(action.get('type'), 'ir.actions.client',
|
||||
'URL redirection: action without parameters should redirect to client action Inbox')
|
||||
self.assertEqual(action.get('id'), port_act_id,
|
||||
'URL redirection: action without parameters should redirect to client action Inbox')
|
||||
|
||||
def test_30_message_read(self):
|
||||
cr, uid, group_port_id = self.cr, self.uid, self.group_port_id
|
||||
|
||||
# Data: custom subtypes
|
||||
mt_group_public_id = self.mail_message_subtype.create(cr, uid, {'name': 'group_public', 'description': 'Group changed'})
|
||||
self.ir_model_data.create(cr, uid, {'name': 'mt_group_public', 'model': 'mail.message.subtype', 'module': 'mail', 'res_id': mt_group_public_id})
|
||||
# Data: post messages with various subtypes
|
||||
msg1_id = self.mail_group.message_post(cr, uid, group_port_id, body='Body1', type='comment', subtype='mail.mt_comment')
|
||||
msg2_id = self.mail_group.message_post(cr, uid, group_port_id, body='Body2', type='comment', subtype='mail.mt_group_public')
|
||||
msg3_id = self.mail_group.message_post(cr, uid, group_port_id, body='Body3', type='comment', subtype='mail.mt_comment')
|
||||
msg4_id = self.mail_group.message_post(cr, uid, group_port_id, body='Body4', type='comment')
|
||||
# msg5_id = self.mail_group.message_post(cr, uid, group_port_id, body='Body5', type='notification')
|
||||
|
||||
# Do: Chell search messages: should not see internal notes (comment without subtype)
|
||||
msg_ids = self.mail_message.search(cr, self.user_chell_id, [('model', '=', 'mail.group'), ('res_id', '=', group_port_id)])
|
||||
self.assertEqual(set(msg_ids), set([msg1_id, msg2_id, msg3_id]),
|
||||
'mail_message: portal user has access to messages he should not read')
|
||||
|
||||
# Do: Chell read messages she can read
|
||||
self.mail_message.read(cr, self.user_chell_id, msg_ids, ['body', 'type', 'subtype_id'])
|
||||
|
||||
# Do: Chell read a message she should not be able to read
|
||||
with self.assertRaises(AccessError):
|
||||
self.mail_message.read(cr, self.user_chell_id, [msg4_id], ['body', 'type', 'subtype_id'])
|
||||
|
||||
@@ -29,234 +29,185 @@ class TestPortalProjectBase(TestProjectBase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestPortalProjectBase, self).setUp()
|
||||
cr, uid = self.cr, self.uid
|
||||
|
||||
# Find Portal group
|
||||
group_portal_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_portal')
|
||||
self.group_portal_id = group_portal_ref and group_portal_ref[1] or False
|
||||
|
||||
# Find Public group
|
||||
group_public_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_public')
|
||||
self.group_public_id = group_public_ref and group_public_ref[1] or False
|
||||
|
||||
# # Test users to use through the various tests
|
||||
self.user_portal_id = self.res_users.create(cr, uid, {
|
||||
'name': 'Chell Portal',
|
||||
'login': 'chell',
|
||||
'alias_name': 'chell',
|
||||
'groups_id': [(6, 0, [self.group_portal_id])]
|
||||
})
|
||||
self.user_public_id = self.res_users.create(cr, uid, {
|
||||
'name': 'Donovan Public',
|
||||
'login': 'donovan',
|
||||
'alias_name': 'donovan',
|
||||
'groups_id': [(6, 0, [self.group_public_id])]
|
||||
})
|
||||
self.user_manager_id = self.res_users.create(cr, uid, {
|
||||
'name': 'Eustache Manager',
|
||||
'login': 'eustache',
|
||||
'alias_name': 'eustache',
|
||||
'groups_id': [(6, 0, [self.group_project_manager_id])]
|
||||
})
|
||||
|
||||
# Test 'Pigs' project
|
||||
self.project_pigs_id = self.project_project.create(cr, uid, {
|
||||
'name': 'Pigs', 'privacy_visibility': 'public'}, {'mail_create_nolog': True})
|
||||
# Various test tasks
|
||||
self.task_1_id = self.project_task.create(cr, uid, {
|
||||
'name': 'Test1', 'user_id': False, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.task_2_id = self.project_task.create(cr, uid, {
|
||||
'name': 'Test2', 'user_id': False, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.task_3_id = self.project_task.create(cr, uid, {
|
||||
'name': 'Test3', 'user_id': False, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.task_4_id = self.project_task.create(cr, uid, {
|
||||
'name': 'Test4', 'user_id': self.user_projectuser_id, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.task_5_id = self.project_task.create(cr, uid, {
|
||||
'name': 'Test5', 'user_id': self.user_portal_id, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.task_6_id = self.project_task.create(cr, uid, {
|
||||
'name': 'Test6', 'user_id': self.user_public_id, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.task_3 = self.env['project.task'].with_context({'mail_create_nolog': True}).create({
|
||||
'name': 'Test3', 'user_id': self.user_portal.id, 'project_id': self.project_pigs.id})
|
||||
self.task_4 = self.env['project.task'].with_context({'mail_create_nolog': True}).create({
|
||||
'name': 'Test4', 'user_id': self.user_public.id, 'project_id': self.project_pigs.id})
|
||||
self.task_5 = self.env['project.task'].with_context({'mail_create_nolog': True}).create({
|
||||
'name': 'Test5', 'user_id': False, 'project_id': self.project_pigs.id})
|
||||
self.task_6 = self.env['project.task'].with_context({'mail_create_nolog': True}).create({
|
||||
'name': 'Test5', 'user_id': False, 'project_id': self.project_pigs.id})
|
||||
|
||||
|
||||
class TestPortalProject(TestPortalProjectBase):
|
||||
@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models')
|
||||
def test_00_project_access_rights(self):
|
||||
""" Test basic project access rights, for project and portal_project """
|
||||
cr, uid, pigs_id = self.cr, self.uid, self.project_pigs_id
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE1: public project
|
||||
# ----------------------------------------
|
||||
@mute_logger('openerp.addons.base.ir.ir_model')
|
||||
def test_public_project_access_rights(self):
|
||||
pigs = self.project_pigs
|
||||
|
||||
# Do: Alfred reads project -> ok (employee ok public)
|
||||
self.project_project.read(cr, self.user_projectuser_id, [pigs_id], ['state'])
|
||||
pigs.sudo(self.user_projectuser.id).read(['state'])
|
||||
# Test: all project tasks visible
|
||||
task_ids = self.project_task.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
test_task_ids = set([self.task_1_id, self.task_2_id, self.task_3_id, self.task_4_id, self.task_5_id, self.task_6_id])
|
||||
self.assertEqual(set(task_ids), test_task_ids,
|
||||
'access rights: project user cannot see all tasks of a public project')
|
||||
tasks = self.env['project.task'].sudo(self.user_projectuser.id).search([('project_id', '=', pigs.id)])
|
||||
self.assertEqual(tasks, self.task_1 | self.task_2 | self.task_3 | self.task_4 | self.task_5 | self.task_6,
|
||||
'access rights: project user should see all tasks of public project')
|
||||
# Test: all project tasks readable
|
||||
self.project_task.read(cr, self.user_projectuser_id, task_ids, ['name'])
|
||||
tasks.read(['name'])
|
||||
# Test: all project tasks writable
|
||||
self.project_task.write(cr, self.user_projectuser_id, task_ids, {'description': 'TestDescription'})
|
||||
tasks.write({'description': 'TestDescription'})
|
||||
|
||||
# Need to check assertRaises
|
||||
# Do: Bert reads project -> crash, no group
|
||||
self.assertRaises(AccessError, self.project_project.read, cr, self.user_none_id, [pigs_id], ['state'])
|
||||
self.assertRaises(AccessError, pigs.sudo(self.user_noone).read, ['state'])
|
||||
# Test: no project task visible
|
||||
self.assertRaises(AccessError, self.project_task.search, cr, self.user_none_id, [('project_id', '=', pigs_id)])
|
||||
self.assertRaises(AccessError, self.env['project.task'].sudo(self.user_noone).search, [('project_id', '=', pigs.id)])
|
||||
# Test: no project task readable
|
||||
self.assertRaises(AccessError, self.project_task.read, cr, self.user_none_id, task_ids, ['name'])
|
||||
self.assertRaises(AccessError, tasks.sudo(self.user_noone).read, ['name'])
|
||||
# Test: no project task writable
|
||||
self.assertRaises(AccessError, self.project_task.write, cr, self.user_none_id, task_ids, {'description': 'TestDescription'})
|
||||
self.assertRaises(AccessError, tasks.sudo(self.user_noone).write, {'description': 'TestDescription'})
|
||||
|
||||
# Do: Chell reads project -> ok (portal ok public)
|
||||
self.project_project.read(cr, self.user_portal_id, [pigs_id], ['state'])
|
||||
pigs.sudo(self.user_portal).read(['state'])
|
||||
# Test: all project tasks visible
|
||||
task_ids = self.project_task.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(task_ids), test_task_ids,
|
||||
'access rights: project user cannot see all tasks of a public project')
|
||||
tasks = self.env['project.task'].sudo(self.user_portal).search([('project_id', '=', pigs.id)])
|
||||
self.assertEqual(tasks, self.task_1 | self.task_2 | self.task_3 | self.task_4 | self.task_5 | self.task_6,
|
||||
'access rights: portal user should see all tasks of a public project')
|
||||
# Test: all project tasks readable
|
||||
self.project_task.read(cr, self.user_portal_id, task_ids, ['name'])
|
||||
tasks.read(['name'])
|
||||
# Test: no project task writable
|
||||
self.assertRaises(AccessError, self.project_task.write, cr, self.user_portal_id, task_ids, {'description': 'TestDescription'})
|
||||
self.assertRaises(AccessError, tasks.write, {'description': 'TestDescription'})
|
||||
|
||||
# Do: Donovan reads project -> ok (public)
|
||||
self.project_project.read(cr, self.user_public_id, [pigs_id], ['state'])
|
||||
pigs.sudo(self.user_public).read(['state'])
|
||||
# Test: all project tasks visible
|
||||
task_ids = self.project_task.search(cr, self.user_public_id, [('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(task_ids), test_task_ids,
|
||||
'access rights: public user cannot see all tasks of a public project')
|
||||
tasks = self.env['project.task'].sudo(self.user_public.id).search([('project_id', '=', pigs.id)])
|
||||
self.assertEqual(tasks, self.task_1 | self.task_2 | self.task_3 | self.task_4 | self.task_5 | self.task_6,
|
||||
'access rights: public user should see all tasks of a public project')
|
||||
# Test: all project tasks readable
|
||||
self.project_task.read(cr, self.user_public_id, task_ids, ['name'])
|
||||
tasks.read(['name'])
|
||||
# Test: no project task writable
|
||||
self.assertRaises(AccessError, self.project_task.write, cr, self.user_public_id, task_ids, {'description': 'TestDescription'})
|
||||
self.assertRaises(AccessError, tasks.write, {'description': 'TestDescription'})
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE2: portal project
|
||||
# ----------------------------------------
|
||||
self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'portal'})
|
||||
self.project_project.invalidate_cache(cr, uid)
|
||||
@mute_logger('openerp.addons.base.ir.ir_model')
|
||||
def test_portal_project_access_rights(self):
|
||||
pigs = self.project_pigs
|
||||
pigs.write({'privacy_visibility': 'portal'})
|
||||
|
||||
# Do: Alfred reads project -> ok (employee ok public)
|
||||
self.project_project.read(cr, self.user_projectuser_id, [pigs_id], ['state'])
|
||||
pigs.sudo(self.user_projectuser).read(['state'])
|
||||
# Test: all project tasks visible
|
||||
task_ids = self.project_task.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(task_ids), test_task_ids,
|
||||
'access rights: project user cannot see all tasks of a portal project')
|
||||
tasks = self.env['project.task'].sudo(self.user_projectuser).search([('project_id', '=', pigs.id)])
|
||||
self.assertEqual(tasks, self.task_1 | self.task_2 | self.task_3 | self.task_4 | self.task_5 | self.task_6,
|
||||
'access rights: project user should see all tasks of a portal project')
|
||||
|
||||
# Do: Bert reads project -> crash, no group
|
||||
self.assertRaises(AccessError, self.project_project.read, cr, self.user_none_id, [pigs_id], ['state'])
|
||||
self.assertRaises(AccessError, pigs.sudo(self.user_noone).read, ['state'])
|
||||
# Test: no project task searchable
|
||||
self.assertRaises(AccessError, self.project_task.search, cr, self.user_none_id, [('project_id', '=', pigs_id)])
|
||||
self.assertRaises(AccessError, self.env['project.task'].sudo(self.user_noone).search, [('project_id', '=', pigs.id)])
|
||||
|
||||
# Data: task follower
|
||||
self.project_project.message_subscribe_users(cr, self.user_manager_id, [pigs_id], [self.user_portal_id])
|
||||
self.project_task.message_subscribe_users(cr, self.user_projectuser_id, [self.task_1_id, self.task_3_id], [self.user_portal_id])
|
||||
|
||||
# Do: Chell reads project -> ok (portal ok portal)
|
||||
self.project_project.read(cr, self.user_portal_id, [pigs_id], ['state'])
|
||||
|
||||
pigs.sudo(self.user_projectmanager).message_subscribe_users(user_ids=[self.user_portal.id])
|
||||
self.task_1.sudo(self.user_projectuser).message_subscribe_users(user_ids=[self.user_portal.id])
|
||||
self.task_3.sudo(self.user_projectuser).message_subscribe_users(user_ids=[self.user_portal.id])
|
||||
# Do: Chell reads project -> ok (portal ok public)
|
||||
pigs.sudo(self.user_portal).read(['state'])
|
||||
# Do: Donovan reads project -> ko (public ko portal)
|
||||
self.assertRaises(AccessError, self.project_project.read, cr, self.user_public_id, [pigs_id], ['state'])
|
||||
# TODO: Change the except_orm to Warning ( Because here it's call check_access_rule
|
||||
# which still generate exception in except_orm.)
|
||||
self.assertRaises(except_orm, pigs.sudo(self.user_public).read, ['state'])
|
||||
# Test: no project task visible
|
||||
task_ids = self.project_task.search(cr, self.user_public_id, [('project_id', '=', pigs_id)])
|
||||
self.assertFalse(task_ids, 'access rights: public user should not see tasks of a portal project')
|
||||
|
||||
tasks = self.env['project.task'].sudo(self.user_public).search([('project_id', '=', pigs.id)])
|
||||
self.assertFalse(tasks, 'access rights: public user should not see tasks of a portal project')
|
||||
# Data: task follower cleaning
|
||||
self.project_task.message_unsubscribe_users(cr, self.user_projectuser_id, [self.task_1_id, self.task_3_id], [self.user_portal_id])
|
||||
self.task_1.sudo(self.user_projectuser).message_unsubscribe_users(user_ids=[self.user_portal.id])
|
||||
self.task_3.sudo(self.user_projectuser).message_unsubscribe_users(user_ids=[self.user_portal.id])
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE3: employee project
|
||||
# ----------------------------------------
|
||||
self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'employees'})
|
||||
self.project_project.invalidate_cache(cr, uid)
|
||||
@mute_logger('openerp.addons.base.ir.ir_model')
|
||||
def test_employee_project_access_rights(self):
|
||||
pigs = self.project_pigs
|
||||
|
||||
pigs.write({'privacy_visibility': 'employees'})
|
||||
# Do: Alfred reads project -> ok (employee ok employee)
|
||||
self.project_project.read(cr, self.user_projectuser_id, [pigs_id], ['state'])
|
||||
pigs.sudo(self.user_projectuser).read(['state'])
|
||||
# Test: all project tasks visible
|
||||
task_ids = self.project_task.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
test_task_ids = set([self.task_1_id, self.task_2_id, self.task_3_id, self.task_4_id, self.task_5_id, self.task_6_id])
|
||||
self.assertEqual(set(task_ids), test_task_ids,
|
||||
'access rights: project user cannot see all tasks of an employees project')
|
||||
|
||||
tasks = self.env['project.task'].sudo(self.user_projectuser).search([('project_id', '=', pigs.id)])
|
||||
test_task_ids = set([self.task_1.id, self.task_2.id, self.task_3.id, self.task_4.id, self.task_5.id, self.task_6.id])
|
||||
self.assertEqual(set(tasks.ids), test_task_ids,
|
||||
'access rights: project user cannot see all tasks of an employees project')
|
||||
# Do: Bert reads project -> crash, no group
|
||||
self.assertRaises(AccessError, self.project_project.read, cr, self.user_none_id, [pigs_id], ['state'])
|
||||
|
||||
self.assertRaises(AccessError, pigs.sudo(self.user_noone).read, ['state'])
|
||||
# Do: Chell reads project -> ko (portal ko employee)
|
||||
self.assertRaises(AccessError, self.project_project.read, cr, self.user_portal_id, [pigs_id], ['state'])
|
||||
# TODO Change the except_orm to Warning
|
||||
self.assertRaises(except_orm, pigs.sudo(self.user_portal).read, ['state'])
|
||||
# Test: no project task visible + assigned
|
||||
task_ids = self.project_task.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
|
||||
self.assertFalse(task_ids, 'access rights: portal user should not see tasks of an employees project, even if assigned')
|
||||
|
||||
tasks = self.env['project.task'].sudo(self.user_portal).search([('project_id', '=', pigs.id)])
|
||||
self.assertFalse(tasks.ids, 'access rights: portal user should not see tasks of an employees project, even if assigned')
|
||||
# Do: Donovan reads project -> ko (public ko employee)
|
||||
self.assertRaises(AccessError, self.project_project.read, cr, self.user_public_id, [pigs_id], ['state'])
|
||||
# TODO Change the except_orm to Warning
|
||||
self.assertRaises(except_orm, pigs.sudo(self.user_public).read, ['state'])
|
||||
# Test: no project task visible
|
||||
task_ids = self.project_task.search(cr, self.user_public_id, [('project_id', '=', pigs_id)])
|
||||
self.assertFalse(task_ids, 'access rights: public user should not see tasks of an employees project')
|
||||
tasks = self.env['project.task'].sudo(self.user_public).search([('project_id', '=', pigs.id)])
|
||||
self.assertFalse(tasks.ids, 'access rights: public user should not see tasks of an employees project')
|
||||
|
||||
# Do: project user is employee and can create a task
|
||||
tmp_task_id = self.project_task.create(cr, self.user_projectuser_id, {
|
||||
'name': 'Pigs task', 'project_id': pigs_id
|
||||
}, {'mail_create_nolog': True})
|
||||
self.project_task.unlink(cr, self.user_projectuser_id, [tmp_task_id])
|
||||
tmp_task = self.env['project.task'].sudo(self.user_projectuser).with_context({'mail_create_nolog': True}).create({
|
||||
'name': 'Pigs task',
|
||||
'project_id': pigs.id})
|
||||
tmp_task.sudo(self.user_projectuser).unlink()
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE4: followers project
|
||||
# ----------------------------------------
|
||||
self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'followers'})
|
||||
self.project_project.invalidate_cache(cr, uid)
|
||||
@mute_logger('openerp.addons.base.ir.ir_model')
|
||||
def test_followers_project_access_rights(self):
|
||||
pigs = self.project_pigs
|
||||
pigs.write({'privacy_visibility': 'followers'})
|
||||
|
||||
# Do: Alfred reads project -> ko (employee ko followers)
|
||||
self.assertRaises(AccessError, self.project_project.read, cr, self.user_projectuser_id, [pigs_id], ['state'])
|
||||
# TODO Change the except_orm to Warning
|
||||
self.assertRaises(AccessError, pigs.sudo(self.user_projectuser).read, ['state'])
|
||||
# Test: no project task visible
|
||||
task_ids = self.project_task.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
test_task_ids = set([self.task_4_id])
|
||||
self.assertEqual(set(task_ids), test_task_ids,
|
||||
tasks = self.env['project.task'].sudo(self.user_projectuser).search([('project_id', '=', pigs.id)])
|
||||
self.assertEqual(tasks, self.task_1,
|
||||
'access rights: employee user should not see tasks of a not-followed followers project, only assigned')
|
||||
|
||||
# Do: Bert reads project -> crash, no group
|
||||
self.assertRaises(AccessError, self.project_project.read, cr, self.user_none_id, [pigs_id], ['state'])
|
||||
|
||||
# Do: Chell reads project -> ko (portal ko followers)
|
||||
self.project_project.message_unsubscribe_users(cr, self.user_portal_id, [pigs_id], [self.user_portal_id])
|
||||
self.assertRaises(except_orm, self.project_project.read, cr, self.user_portal_id, [pigs_id], ['state'])
|
||||
self.assertRaises(AccessError, pigs.sudo(self.user_noone).read, ['state'])
|
||||
|
||||
# Do: Chell reads project -> ko (portal ko employee)
|
||||
self.assertRaises(except_orm, pigs.sudo(self.user_portal).read, ['state'])
|
||||
# Test: no project task visible
|
||||
task_ids = self.project_task.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
|
||||
test_task_ids = set([self.task_5_id])
|
||||
self.assertEqual(set(task_ids), test_task_ids,
|
||||
tasks = self.env['project.task'].sudo(self.user_portal).search([('project_id', '=', pigs.id)])
|
||||
self.assertEqual(tasks, self.task_3,
|
||||
'access rights: portal user should not see tasks of a not-followed followers project, only assigned')
|
||||
|
||||
# Do: Donovan reads project -> ko (public ko employee)
|
||||
self.assertRaises(AccessError, self.project_project.read, cr, self.user_public_id, [pigs_id], ['state'])
|
||||
# TODO Change the except_orm to Warning
|
||||
self.assertRaises(except_orm, pigs.sudo(self.user_public).read, ['state'])
|
||||
# Test: no project task visible
|
||||
task_ids = self.project_task.search(cr, self.user_public_id, [('project_id', '=', pigs_id)])
|
||||
self.assertFalse(task_ids, 'access rights: public user should not see tasks of a followers project')
|
||||
tasks = self.env['project.task'].sudo(self.user_public).search([('project_id', '=', pigs.id)])
|
||||
self.assertFalse(tasks, 'access rights: public user should not see tasks of a followers project')
|
||||
|
||||
# Data: subscribe Alfred, Chell and Donovan as follower
|
||||
self.project_project.message_subscribe_users(cr, uid, [pigs_id], [self.user_projectuser_id, self.user_portal_id, self.user_public_id])
|
||||
self.project_task.message_subscribe_users(cr, self.user_manager_id, [self.task_1_id, self.task_3_id], [self.user_portal_id, self.user_projectuser_id])
|
||||
pigs.message_subscribe_users(user_ids=[self.user_projectuser.id, self.user_portal.id, self.user_public.id])
|
||||
self.task_1.sudo(self.user_projectmanager).message_subscribe_users(user_ids=[self.user_portal.id, self.user_projectuser.id])
|
||||
self.task_3.sudo(self.user_projectmanager).message_subscribe_users(user_ids=[self.user_portal.id, self.user_projectuser.id])
|
||||
|
||||
# Do: Alfred reads project -> ok (follower ok followers)
|
||||
self.project_project.read(cr, self.user_projectuser_id, [pigs_id], ['state'])
|
||||
|
||||
pigs.sudo(self.user_projectuser).read(['state'])
|
||||
# Do: Chell reads project -> ok (follower ok follower)
|
||||
self.project_project.read(cr, self.user_portal_id, [pigs_id], ['state'])
|
||||
|
||||
pigs.sudo(self.user_portal).read(['state'])
|
||||
# Do: Donovan reads project -> ko (public ko follower even if follower)
|
||||
|
||||
self.assertRaises(except_orm, self.project_project.read, cr, self.user_public_id, [pigs_id], ['state'])
|
||||
|
||||
# TODO Change the except_orm to Warning
|
||||
self.assertRaises(except_orm, pigs.sudo(self.user_public).read, ['state'])
|
||||
# Do: project user is follower of the project and can create a task
|
||||
self.project_task.create(cr, self.user_projectuser_id, {
|
||||
'name': 'Pigs task', 'project_id': pigs_id
|
||||
}, {'mail_create_nolog': True})
|
||||
|
||||
self.env['project.task'].sudo(self.user_projectuser.id).with_context({'mail_create_nolog': True}).create({
|
||||
'name': 'Pigs task', 'project_id': pigs.id
|
||||
})
|
||||
# not follower user should not be able to create a task
|
||||
self.project_project.message_unsubscribe_users(cr, self.user_projectuser_id, [pigs_id], [self.user_projectuser_id])
|
||||
self.assertRaises(except_orm,
|
||||
self.project_task.create, cr, self.user_projectuser_id, {'name': 'Pigs task', 'project_id': pigs_id}, {'mail_create_nolog': True}
|
||||
)
|
||||
pigs.sudo(self.user_projectuser).message_unsubscribe_users(user_ids=[self.user_projectuser.id])
|
||||
self.assertRaises(except_orm, self.env['project.task'].sudo(self.user_projectuser).with_context({
|
||||
'mail_create_nolog': True}).create, {'name': 'Pigs task', 'project_id': pigs.id})
|
||||
|
||||
# Do: project user can create a task without project
|
||||
self.project_task.create(cr, self.user_projectuser_id, {'name': 'Pigs task', 'project_id': False}, {'mail_create_nolog': True})
|
||||
|
||||
self.assertRaises(except_orm, self.env['project.task'].sudo(self.user_projectuser).with_context({
|
||||
'mail_create_nolog': True}).create, {'name': 'Pigs task', 'project_id': pigs.id})
|
||||
|
||||
|
||||
@@ -1,23 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2013-TODAY OpenERP S.A. <http://www.openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from . import test_project_flow
|
||||
|
||||
from . import test_project_base, test_project_flow
|
||||
|
||||
@@ -1,23 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2013-TODAY OpenERP S.A. <http://www.openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.mail.tests.common import TestMail
|
||||
|
||||
@@ -26,74 +7,39 @@ class TestProjectBase(TestMail):
|
||||
|
||||
def setUp(self):
|
||||
super(TestProjectBase, self).setUp()
|
||||
cr, uid = self.cr, self.uid
|
||||
|
||||
# Usefull models
|
||||
self.project_project = self.registry('project.project')
|
||||
self.project_task = self.registry('project.task')
|
||||
self.project_task_delegate = self.registry('project.task.delegate')
|
||||
|
||||
# Find Project User group
|
||||
group_project_user_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'project', 'group_project_user')
|
||||
self.group_project_user_id = group_project_user_ref and group_project_user_ref[1] or False
|
||||
|
||||
# Find Project Manager group
|
||||
group_project_manager_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'project', 'group_project_manager')
|
||||
self.group_project_manager_id = group_project_manager_ref and group_project_manager_ref[1] or False
|
||||
|
||||
# Test partners to use through the various tests
|
||||
self.project_partner_id = self.res_partner.create(cr, uid, {
|
||||
'name': 'Gertrude AgrolaitPartner',
|
||||
'email': 'gertrude.partner@agrolait.com',
|
||||
})
|
||||
self.email_partner_id = self.res_partner.create(cr, uid, {
|
||||
'name': 'Patrick Ratatouille',
|
||||
'email': 'patrick.ratatouille@agrolait.com',
|
||||
})
|
||||
user_group_employee = self.env.ref('base.group_user')
|
||||
user_group_project_user = self.env.ref('project.group_project_user')
|
||||
user_group_project_manager = self.env.ref('project.group_project_manager')
|
||||
|
||||
# Test users to use through the various tests
|
||||
self.user_projectuser_id = self.res_users.create(cr, uid, {
|
||||
Users = self.env['res.users'].with_context({'no_reset_password': True})
|
||||
self.user_projectuser = Users.create({
|
||||
'name': 'Armande ProjectUser',
|
||||
'login': 'Armande',
|
||||
'alias_name': 'armande',
|
||||
'email': 'armande.projectuser@example.com',
|
||||
'groups_id': [(6, 0, [self.group_employee_id, self.group_project_user_id])]
|
||||
'groups_id': [(6, 0, [user_group_employee.id, user_group_project_user.id])]
|
||||
})
|
||||
self.user_projectmanager_id = self.res_users.create(cr, uid, {
|
||||
self.user_projectmanager = Users.create({
|
||||
'name': 'Bastien ProjectManager',
|
||||
'login': 'bastien',
|
||||
'alias_name': 'bastien',
|
||||
'email': 'bastien.projectmanager@example.com',
|
||||
'groups_id': [(6, 0, [self.group_employee_id, self.group_project_manager_id])]
|
||||
})
|
||||
self.user_none_id = self.res_users.create(cr, uid, {
|
||||
'name': 'Charlie Avotbonkeur',
|
||||
'login': 'charlie',
|
||||
'alias_name': 'charlie',
|
||||
'email': 'charlie.noone@example.com',
|
||||
'groups_id': [(6, 0, [])]
|
||||
})
|
||||
self.user_projectuser = self.res_users.browse(cr, uid, self.user_projectuser_id)
|
||||
self.user_projectmanager = self.res_users.browse(cr, uid, self.user_projectmanager_id)
|
||||
self.partner_projectuser_id = self.user_projectuser.partner_id.id
|
||||
self.partner_projectmanager_id = self.user_projectmanager.partner_id.id
|
||||
'groups_id': [(6, 0, [user_group_employee.id, user_group_project_manager.id])]})
|
||||
|
||||
# Test 'Pigs' project
|
||||
self.project_pigs_id = self.project_project.create(cr, uid, {
|
||||
self.project_pigs = self.env['project.project'].with_context({'mail_create_nolog': True}).create({
|
||||
'name': 'Pigs',
|
||||
'privacy_visibility': 'public',
|
||||
'alias_name': 'project+pigs',
|
||||
'partner_id': self.partner_raoul_id,
|
||||
}, {'mail_create_nolog': True})
|
||||
|
||||
'partner_id': self.user_employee_2.partner_id.id})
|
||||
# Already-existing tasks in Pigs
|
||||
self.task_1_id = self.project_task.create(cr, uid, {
|
||||
self.task_1 = self.env['project.task'].with_context({'mail_create_nolog': True}).create({
|
||||
'name': 'Pigs UserTask',
|
||||
'user_id': self.user_projectuser_id,
|
||||
'project_id': self.project_pigs_id,
|
||||
}, {'mail_create_nolog': True})
|
||||
self.task_2_id = self.project_task.create(cr, uid, {
|
||||
'user_id': self.user_projectuser.id,
|
||||
'project_id': self.project_pigs.id})
|
||||
self.task_2 = self.env['project.task'].with_context({'mail_create_nolog': True}).create({
|
||||
'name': 'Pigs ManagerTask',
|
||||
'user_id': self.user_projectmanager_id,
|
||||
'project_id': self.project_pigs_id,
|
||||
}, {'mail_create_nolog': True})
|
||||
'user_id': self.user_projectmanager.id,
|
||||
'project_id': self.project_pigs.id})
|
||||
|
||||
@@ -25,9 +25,9 @@ from openerp.tools import mute_logger
|
||||
|
||||
|
||||
EMAIL_TPL = """Return-Path: <whatever-2a840@postmaster.twitter.com>
|
||||
X-Original-To: {email_to}
|
||||
Delivered-To: {email_to}
|
||||
To: {email_to}
|
||||
X-Original-To: {to}
|
||||
Delivered-To: {to}
|
||||
To: {to}
|
||||
cc: {cc}
|
||||
Received: by mail1.openerp.com (Postfix, from userid 10002)
|
||||
id 5DF9ABFB2A; Fri, 10 Aug 2012 16:16:39 +0200 (CEST)
|
||||
@@ -53,120 +53,80 @@ Integrator at Agrolait"""
|
||||
class TestProjectFlow(TestProjectBase):
|
||||
|
||||
@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models')
|
||||
def test_00_project_process(self):
|
||||
""" Testing project management """
|
||||
cr, uid, user_projectuser_id, user_projectmanager_id, project_pigs_id = self.cr, self.uid, self.user_projectuser_id, self.user_projectmanager_id, self.project_pigs_id
|
||||
def test_project_process_project_user(self):
|
||||
self.assertRaises(AccessError, self.project_pigs.sudo(self.user_projectuser).set_template)
|
||||
|
||||
# ProjectUser: set project as template -> raise
|
||||
self.assertRaises(AccessError, self.project_project.set_template, cr, user_projectuser_id, [project_pigs_id])
|
||||
def test_project_process_project_manager_set_template(self):
|
||||
pigs = self.project_pigs.sudo(self.user_projectmanager)
|
||||
pigs.set_template()
|
||||
self.assertEqual(pigs.state, 'template')
|
||||
self.assertEqual(len(pigs.tasks), 0, 'project: set_template: project tasks should have been set inactive')
|
||||
|
||||
# Other tests are done using a ProjectManager
|
||||
project = self.project_project.browse(cr, user_projectmanager_id, project_pigs_id)
|
||||
self.assertNotEqual(project.state, 'template', 'project: incorrect state, should not be a template')
|
||||
# pigs.reset_project()
|
||||
# self.assertEqual(pigs.state, 'open')
|
||||
# self.assertEqual(len(pigs.tasks), 2, 'project: reset_project: project tasks should have been set active')
|
||||
|
||||
# Set test project as template
|
||||
self.project_project.set_template(cr, user_projectmanager_id, [project_pigs_id])
|
||||
project.refresh()
|
||||
self.assertEqual(project.state, 'template', 'project: set_template: project state should be template')
|
||||
self.assertEqual(len(project.tasks), 0, 'project: set_template: project tasks should have been set inactive')
|
||||
|
||||
# Duplicate template
|
||||
new_template_act = self.project_project.duplicate_template(cr, user_projectmanager_id, [project_pigs_id])
|
||||
new_project = self.project_project.browse(cr, user_projectmanager_id, new_template_act['res_id'])
|
||||
self.assertEqual(new_project.state, 'open', 'project: incorrect duplicate_template')
|
||||
def test_project_process_project_manager_duplicate(self):
|
||||
pigs = self.project_pigs.sudo(self.user_projectmanager)
|
||||
new_template_act = pigs.duplicate_template()
|
||||
new_project = self.env['project.project'].sudo(self.user_projectmanager).browse(new_template_act['res_id'])
|
||||
self.assertEqual(new_project.state, 'open')
|
||||
self.assertEqual(len(new_project.tasks), 2, 'project: duplicating a project template should duplicate its tasks')
|
||||
|
||||
# Convert into real project
|
||||
self.project_project.reset_project(cr, user_projectmanager_id, [project_pigs_id])
|
||||
project.refresh()
|
||||
self.assertEqual(project.state, 'open', 'project: resetted project should be in open state')
|
||||
self.assertEqual(len(project.tasks), 2, 'project: reset_project: project tasks should have been set active')
|
||||
|
||||
# Put as pending
|
||||
self.project_project.set_pending(cr, user_projectmanager_id, [project_pigs_id])
|
||||
project.refresh()
|
||||
self.assertEqual(project.state, 'pending', 'project: should be in pending state')
|
||||
|
||||
def test_project_process_project_manager_state(self):
|
||||
pigs = self.project_pigs.sudo(self.user_projectmanager)
|
||||
pigs.set_pending()
|
||||
self.assertEqual(pigs.state, 'pending')
|
||||
# Re-open
|
||||
self.project_project.set_open(cr, user_projectmanager_id, [project_pigs_id])
|
||||
project.refresh()
|
||||
self.assertEqual(project.state, 'open', 'project: reopened project should be in open state')
|
||||
|
||||
pigs.set_open()
|
||||
self.assertEqual(pigs.state, 'open')
|
||||
# Close project
|
||||
self.project_project.set_done(cr, user_projectmanager_id, [project_pigs_id])
|
||||
project.refresh()
|
||||
self.assertEqual(project.state, 'close', 'project: closed project should be in close state')
|
||||
|
||||
pigs.set_done()
|
||||
self.assertEqual(pigs.state, 'close')
|
||||
# Re-open
|
||||
self.project_project.set_open(cr, user_projectmanager_id, [project_pigs_id])
|
||||
project.refresh()
|
||||
|
||||
pigs.set_open()
|
||||
# Re-convert into a template and schedule tasks
|
||||
self.project_project.set_template(cr, user_projectmanager_id, [project_pigs_id])
|
||||
self.project_project.schedule_tasks(cr, user_projectmanager_id, [project_pigs_id])
|
||||
|
||||
pigs.set_template()
|
||||
pigs.schedule_tasks()
|
||||
# Copy the project
|
||||
new_project_id = self.project_project.copy(cr, user_projectmanager_id, project_pigs_id)
|
||||
new_project = self.project_project.browse(cr, user_projectmanager_id, new_project_id)
|
||||
new_project = pigs.copy()
|
||||
self.assertEqual(len(new_project.tasks), 2, 'project: copied project should have copied task')
|
||||
|
||||
# Cancel the project
|
||||
self.project_project.set_cancel(cr, user_projectmanager_id, [project_pigs_id])
|
||||
self.assertEqual(project.state, 'cancelled', 'project: cancelled project should be in cancel state')
|
||||
|
||||
def test_10_task_process(self):
|
||||
""" Testing task creation and management """
|
||||
cr, uid, user_projectuser_id, user_projectmanager_id, project_pigs_id = self.cr, self.uid, self.user_projectuser_id, self.user_projectmanager_id, self.project_pigs_id
|
||||
|
||||
# create new partner
|
||||
self.partner_id = self.registry('res.partner').create(cr, uid, {
|
||||
'name': 'Pigs',
|
||||
'email': 'otherid@gmail.com',
|
||||
}, {'mail_create_nolog': True})
|
||||
|
||||
def format_and_process(template, email_to='project+pigs@mydomain.com, other@gmail.com', cc='otherid@gmail.com', subject='Frogs',
|
||||
email_from='Patrick Ratatouille <patrick.ratatouille@agrolait.com>',
|
||||
msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>'):
|
||||
self.assertEqual(self.project_task.search(cr, uid, [('name', '=', subject)]), [])
|
||||
mail = template.format(email_to=email_to, cc=cc, subject=subject, email_from=email_from, msg_id=msg_id)
|
||||
self.mail_thread.message_process(cr, uid, None, mail)
|
||||
return self.project_task.search(cr, uid, [('name', '=', subject)])
|
||||
pigs.set_cancel()
|
||||
self.assertEqual(pigs.state, 'cancelled', 'project: cancelled project should be in cancel state')
|
||||
|
||||
@mute_logger('openerp.addons.mail.mail_thread')
|
||||
def test_task_process(self):
|
||||
# Do: incoming mail from an unknown partner on an alias creates a new task 'Frogs'
|
||||
frogs = format_and_process(EMAIL_TPL)
|
||||
task = self.format_and_process(
|
||||
EMAIL_TPL, to='project+pigs@mydomain.com, valid.lelitre@agrolait.com', cc='valid.other@gmail.com',
|
||||
email_from='%s' % self.user_projectuser.email,
|
||||
subject='Frogs', msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>',
|
||||
target_model='project.task')
|
||||
|
||||
# Test: one task created by mailgateway administrator
|
||||
self.assertEqual(len(frogs), 1, 'project: message_process: a new project.task should have been created')
|
||||
task = self.project_task.browse(cr, user_projectuser_id, frogs[0])
|
||||
|
||||
self.assertEqual(len(task), 1, 'project: message_process: a new project.task should have been created')
|
||||
# Test: check partner in message followers
|
||||
self.assertTrue((self.partner_id in [follower.id for follower in task.message_follower_ids]),"Partner in message cc is not added as a task followers.")
|
||||
|
||||
res = self.project_task.get_metadata(cr, uid, [task.id])[0].get('create_uid') or [None]
|
||||
self.assertEqual(res[0], uid,
|
||||
'project: message_process: task should have been created by uid as alias_user_id is False on the alias')
|
||||
self.assertIn(self.partner_2, task.message_follower_ids, "Partner in message cc is not added as a task followers.")
|
||||
# Test: messages
|
||||
self.assertEqual(len(task.message_ids), 2,
|
||||
'project: message_process: newly created task should have 2 messages: creation and email')
|
||||
self.assertEqual(task.message_ids[1].subtype_id.name, 'Task Opened',
|
||||
'project: message_process: first message of new task should have Task Created subtype')
|
||||
self.assertEqual(task.message_ids[0].author_id.id, self.email_partner_id,
|
||||
self.assertEqual(task.message_ids[0].author_id, self.user_projectuser.partner_id,
|
||||
'project: message_process: second message should be the one from Agrolait (partner failed)')
|
||||
self.assertEqual(task.message_ids[0].subject, 'Frogs',
|
||||
'project: message_process: second message should be the one from Agrolait (subject failed)')
|
||||
# Test: task content
|
||||
self.assertEqual(task.name, 'Frogs', 'project_task: name should be the email subject')
|
||||
self.assertEqual(task.project_id.id, self.project_pigs_id, 'project_task: incorrect project')
|
||||
self.assertEqual(task.project_id.id, self.project_pigs.id, 'project_task: incorrect project')
|
||||
self.assertEqual(task.stage_id.sequence, 1, 'project_task: should have a stage with sequence=1')
|
||||
|
||||
# Open the delegation wizard
|
||||
delegate_id = self.project_task_delegate.create(cr, user_projectuser_id, {
|
||||
'user_id': user_projectuser_id,
|
||||
'planned_hours': 12.0,
|
||||
'planned_hours_me': 2.0,
|
||||
}, {'active_id': task.id})
|
||||
self.project_task_delegate.delegate(cr, user_projectuser_id, [delegate_id], {'active_id': task.id})
|
||||
|
||||
self.env['project.task.delegate'].with_context({
|
||||
'active_id': task.id}).sudo(self.user_projectuser).create({
|
||||
'user_id': self.user_projectuser.id,
|
||||
'planned_hours': 12.0,
|
||||
'planned_hours_me': 2.0,
|
||||
}).with_context({'active_id': task.id}).delegate()
|
||||
# Check delegation details
|
||||
task.refresh()
|
||||
self.assertEqual(task.planned_hours, 2, 'project_task_delegate: planned hours is not correct after delegation')
|
||||
|
||||
@@ -1,93 +1,46 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2013-TODAY OpenERP S.A. <http://www.openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.mail.tests.common import TestMail
|
||||
from openerp.tools import mute_logger
|
||||
from datetime import datetime
|
||||
from openerp.tests import common
|
||||
|
||||
|
||||
class TestPurchase(TestMail):
|
||||
@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.osv.orm')
|
||||
|
||||
def setUp(self):
|
||||
super(TestPurchase, self).setUp()
|
||||
|
||||
class TestPurchase(common.TransactionCase):
|
||||
|
||||
def test_purchase_to_invoice(self):
|
||||
""" Testing for invoice create,validate and pay with invoicing and payment user."""
|
||||
cr, uid = self.cr, self.uid
|
||||
|
||||
# Usefull models
|
||||
data_obj = self.registry('ir.model.data')
|
||||
user_obj = self.registry('res.users')
|
||||
partner_obj = self.registry('res.partner')
|
||||
purchase_obj = self.registry('purchase.order')
|
||||
purchase_order_line = self.registry('purchase.order.line')
|
||||
invoice_obj = self.registry('account.invoice')
|
||||
|
||||
# Usefull record id
|
||||
group_id = data_obj.get_object_reference(cr, uid, 'account', 'group_account_invoice')[1]
|
||||
product_ref = data_obj.get_object_reference(cr, uid, 'product', 'product_category_3')
|
||||
product_id = product_ref and product_ref[1] or False
|
||||
company_id = data_obj.get_object_reference(cr, uid, 'base', 'main_company')[1]
|
||||
location_id = data_obj.get_object_reference(cr, uid, 'stock', 'stock_location_3')[1]
|
||||
|
||||
group_id = self.ref('account.group_account_invoice')
|
||||
product_id = self.ref('product.product_category_3')
|
||||
company_id = self.ref('base.main_company')
|
||||
location_id = self.ref('stock.stock_location_3')
|
||||
# In order to test, I create new user and applied Invoicing & Payments group.
|
||||
user_id = user_obj.create(cr, uid, {
|
||||
user = self.env['res.users'].with_context({'no_reset_password': True}).create({
|
||||
'name': 'Test User',
|
||||
'login': 'test@test.com',
|
||||
'company_id': 1,
|
||||
'groups_id': [(6, 0, [group_id])]
|
||||
})
|
||||
assert user_id, "User will not created."
|
||||
|
||||
'company_id': company_id,
|
||||
'groups_id': [(6, 0, [group_id])]})
|
||||
assert user, "User will not created."
|
||||
# I create partner for purchase order.
|
||||
partner_id = partner_obj.create(cr, uid, {
|
||||
partner = self.env['res.partner'].create({
|
||||
'name': 'Test Customer',
|
||||
'email': 'testcustomer@test.com',
|
||||
})
|
||||
|
||||
'email': 'testcustomer@test.com'})
|
||||
# In order to test I create purchase order and confirmed it.
|
||||
order_id = purchase_obj.create(cr, uid, {
|
||||
'partner_id': partner_id,
|
||||
order = self.env['purchase.order'].create({
|
||||
'partner_id': partner.id,
|
||||
'location_id': location_id,
|
||||
'pricelist_id': 1,
|
||||
})
|
||||
order_line = purchase_order_line.create(cr, uid, {
|
||||
'order_id': order_id,
|
||||
'product_id': product_id,
|
||||
'product_qty': 100.0,
|
||||
'product_uom': 1,
|
||||
'price_unit': 89.0,
|
||||
'name': 'Service',
|
||||
'date_planned': '2014-05-31',
|
||||
})
|
||||
assert order_id, "purchase order will not created."
|
||||
|
||||
context = {"active_model": 'purchase.order', "active_ids": [order_id], "active_id":order_id}
|
||||
purchase_obj.wkf_confirm_order(cr, uid, [order_id], context=context)
|
||||
|
||||
'pricelist_id': 1})
|
||||
self.env['purchase.order.line'].create({
|
||||
'order_id': order.id,
|
||||
'product_id': product_id,
|
||||
'product_qty': 100.0,
|
||||
'product_uom': 1,
|
||||
'price_unit': 89.0,
|
||||
'name': 'Service',
|
||||
'date_planned': '2014-05-31'})
|
||||
assert order, "purchase order will not created."
|
||||
context = {"active_model": 'purchase.order', "active_ids": [order.id], "active_id": order.id}
|
||||
order.with_context(context).wkf_confirm_order()
|
||||
# In order to test I create invoice.
|
||||
invoice_id = purchase_obj.action_invoice_create(cr, uid, [order_id], context=context)
|
||||
assert invoice_id,"No any invoice is created for this purchase order"
|
||||
|
||||
invoice = order.with_context(context).action_invoice_create()
|
||||
assert invoice, "No any invoice is created for this purchase order"
|
||||
# In order to test I validate invoice wihth Test User(invoicing and payment).
|
||||
res = invoice_obj.invoice_validate(cr, uid, [invoice_id], context=context)
|
||||
res = self.env['account.invoice'].browse(invoice).with_context(context).invoice_validate()
|
||||
self.assertTrue(res, 'Invoice will not validated')
|
||||
|
||||
@@ -26,82 +26,58 @@ from datetime import datetime
|
||||
|
||||
class TestSale(TestMail):
|
||||
@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.osv.orm')
|
||||
|
||||
def setUp(self):
|
||||
super(TestSale, self).setUp()
|
||||
|
||||
|
||||
def test_sale_to_invoice(self):
|
||||
""" Testing for invoice create,validate and pay with invoicing and payment user."""
|
||||
cr, uid = self.cr, self.uid
|
||||
|
||||
# Usefull models
|
||||
data_obj = self.registry('ir.model.data')
|
||||
user_obj = self.registry('res.users')
|
||||
partner_obj = self.registry('res.partner')
|
||||
sale_obj = self.registry('sale.order')
|
||||
sale_order_line = self.registry('sale.order.line')
|
||||
sale_advance_payment_inv = self.registry('sale.advance.payment.inv')
|
||||
invoice_obj = self.registry('account.invoice')
|
||||
voucher_obj = self.registry('account.voucher')
|
||||
|
||||
IrModelData = self.env['ir.model.data']
|
||||
# Usefull record id
|
||||
group_id = data_obj.get_object_reference(cr, uid, 'account', 'group_account_invoice')[1]
|
||||
product_ref = data_obj.get_object_reference(cr, uid, 'product', 'product_category_3')
|
||||
product_id = product_ref and product_ref[1] or False
|
||||
account_id = data_obj.get_object_reference(cr, uid, 'account', 'cash')[1]
|
||||
company_id = data_obj.get_object_reference(cr, uid, 'base', 'main_company')[1]
|
||||
journal_id = data_obj.get_object_reference(cr, uid, 'account', 'bank_journal')[1]
|
||||
period_id = data_obj.get_object_reference(cr, uid, 'account', 'period_8')[1]
|
||||
|
||||
group_id = IrModelData.xmlid_to_res_id('account.group_account_invoice') or False
|
||||
product_id = IrModelData.xmlid_to_res_id('product.product_category_3') or False
|
||||
account_id = IrModelData.xmlid_to_res_id('account.cash') or False
|
||||
company_id = IrModelData.xmlid_to_res_id('base.main_company') or False
|
||||
journal_id = IrModelData.xmlid_to_res_id('account.bank_journal') or False
|
||||
period_id = IrModelData.xmlid_to_res_id('account.period_8') or False
|
||||
|
||||
# In order to test, I create new user and applied Invoicing & Payments group.
|
||||
user_id = user_obj.create(cr, uid, {
|
||||
user = self.env['res.users'].create({
|
||||
'name': 'Test User',
|
||||
'login': 'test@test.com',
|
||||
'company_id': 1,
|
||||
'groups_id': [(6, 0, [group_id])]
|
||||
})
|
||||
assert user_id, "User will not created."
|
||||
|
||||
'groups_id': [(6, 0, [group_id])]})
|
||||
assert user, "User will not created."
|
||||
# I create partner for sale order.
|
||||
partner_id = partner_obj.create(cr, uid, {
|
||||
partner = self.env['res.partner'].create({
|
||||
'name': 'Test Customer',
|
||||
'email': 'testcustomer@test.com',
|
||||
})
|
||||
|
||||
'email': 'testcustomer@test.com'})
|
||||
# In order to test I create sale order and confirmed it.
|
||||
order_id = sale_obj.create(cr, uid, {
|
||||
'partner_id': partner_id,
|
||||
'date_order': datetime.today(),
|
||||
})
|
||||
order_line = sale_order_line.create(cr, uid, {
|
||||
'order_id': order_id,
|
||||
'product_id': product_id,
|
||||
})
|
||||
assert order_id, "Sale order will not created."
|
||||
|
||||
context = {"active_model": 'sale.order', "active_ids": [order_id], "active_id":order_id}
|
||||
sale_obj.action_button_confirm(cr, uid, [order_id], context=context)
|
||||
|
||||
order = self.env['sale.order'].create({
|
||||
'partner_id': partner.id,
|
||||
'date_order': datetime.today()})
|
||||
order_line = self.env['sale.order.line'].create({
|
||||
'order_id': order.id,
|
||||
'product_id': product_id})
|
||||
assert order, "Sale order will not created."
|
||||
context = {"active_model": 'sale.order', "active_ids": [order.id], "active_id": order.id}
|
||||
order.with_context(context).action_button_confirm()
|
||||
# Now I create invoice.
|
||||
pay_id = sale_advance_payment_inv.create(cr, uid, {'advance_payment_method': 'fixed', 'amount': 5})
|
||||
inv = sale_advance_payment_inv.create_invoices(cr, uid, [pay_id], context=context)
|
||||
invoice_ids = sale_obj.browse(cr, uid, order_id).invoice_ids
|
||||
assert invoice_ids,"No any invoice is created for this sale order"
|
||||
|
||||
payment = self.env['sale.advance.payment.inv'].create({'advance_payment_method': 'fixed', 'amount': 5})
|
||||
invoice = payment.with_context(context).create_invoices()
|
||||
assert order.invoice_ids, "No any invoice is created for this sale order"
|
||||
# Now I validate pay invoice wihth Test User(invoicing and payment).
|
||||
for invoice in invoice_ids:
|
||||
invoice_obj.invoice_validate(cr, uid, [invoice.id], context=context)
|
||||
|
||||
for invoice in order.invoice_ids:
|
||||
invoice.with_context(context).invoice_validate()
|
||||
# Now I create and post an account voucher of amount 75.0 for the partner Test Customer.
|
||||
voucher_id = voucher_obj.create(cr, uid, {
|
||||
voucher = self.env['account.voucher'].create({
|
||||
'account_id': account_id,
|
||||
'amount': 75.0,
|
||||
'company_id': company_id,
|
||||
'journal_id': journal_id,
|
||||
'partner_id': partner_id,
|
||||
'partner_id': partner.id,
|
||||
'period_id': period_id,
|
||||
'type': 'receipt',
|
||||
})
|
||||
assert voucher_id,"Voucher will not created."
|
||||
voucher = voucher_obj.browse(cr, uid, voucher_id)
|
||||
assert voucher, "Voucher will not created."
|
||||
voucher.signal_workflow('proforma_voucher')
|
||||
|
||||
@@ -1,23 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2013-TODAY OpenERP S.A. <http://openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.portal_project.tests.test_access_rights import TestPortalProjectBase
|
||||
from openerp.exceptions import AccessError
|
||||
@@ -28,31 +9,28 @@ class TestPortalProjectBase(TestPortalProjectBase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestPortalProjectBase, self).setUp()
|
||||
cr, uid = self.cr, self.uid
|
||||
|
||||
# Useful models
|
||||
self.project_issue = self.registry('project.issue')
|
||||
|
||||
# Various test issues
|
||||
self.issue_1_id = self.project_issue.create(cr, uid, {
|
||||
'name': 'Test1', 'user_id': False, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.issue_2_id = self.project_issue.create(cr, uid, {
|
||||
'name': 'Test2', 'user_id': False, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.issue_3_id = self.project_issue.create(cr, uid, {
|
||||
'name': 'Test3', 'user_id': False, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.issue_4_id = self.project_issue.create(cr, uid, {
|
||||
'name': 'Test4', 'user_id': self.user_projectuser_id, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.issue_5_id = self.project_issue.create(cr, uid, {
|
||||
'name': 'Test5', 'user_id': self.user_portal_id, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.issue_6_id = self.project_issue.create(cr, uid, {
|
||||
'name': 'Test6', 'user_id': self.user_public_id, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
Issue = self.env['project.issue'].with_context({'mail_create_nolog': True})
|
||||
self.issue_1 = Issue.create({
|
||||
'name': 'Test1', 'user_id': False, 'project_id': self.project_pigs.id})
|
||||
self.issue_2 = Issue.create({
|
||||
'name': 'Test2', 'user_id': False, 'project_id': self.project_pigs.id})
|
||||
self.issue_3 = Issue.create({
|
||||
'name': 'Test3', 'user_id': False, 'project_id': self.project_pigs.id})
|
||||
self.issue_4 = Issue.create({
|
||||
'name': 'Test4', 'user_id': self.user_projectuser.id, 'project_id': self.project_pigs.id})
|
||||
self.issue_5 = Issue.create({
|
||||
'name': 'Test5', 'user_id': self.user_portal.id, 'project_id': self.project_pigs.id})
|
||||
self.issue_6 = Issue.create({
|
||||
'name': 'Test6', 'user_id': self.user_public.id, 'project_id': self.project_pigs.id})
|
||||
|
||||
|
||||
class TestPortalIssue(TestPortalProjectBase):
|
||||
@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models')
|
||||
def test_00_project_access_rights(self):
|
||||
""" Test basic project access rights, for project and portal_project """
|
||||
cr, uid, pigs_id = self.cr, self.uid, self.project_pigs_id
|
||||
pigs_id = self.project_pigs.id
|
||||
Issue = self.env['project.issue']
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE1: public project
|
||||
@@ -60,117 +38,115 @@ class TestPortalIssue(TestPortalProjectBase):
|
||||
|
||||
# Do: Alfred reads project -> ok (employee ok public)
|
||||
# Test: all project issues visible
|
||||
issue_ids = self.project_issue.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
test_issue_ids = set([self.issue_1_id, self.issue_2_id, self.issue_3_id, self.issue_4_id, self.issue_5_id, self.issue_6_id])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
issues = Issue.sudo(self.user_projectuser.id).search([('project_id', '=', pigs_id)])
|
||||
test_issue_ids = set([self.issue_1.id, self.issue_2.id, self.issue_3.id, self.issue_4.id, self.issue_5.id, self.issue_6.id])
|
||||
self.assertEqual(set(issues.ids), test_issue_ids,
|
||||
'access rights: project user cannot see all issues of a public project')
|
||||
# Test: all project issues readable
|
||||
self.project_issue.read(cr, self.user_projectuser_id, issue_ids, ['name'])
|
||||
issues.read(['name'])
|
||||
# Test: all project issues writable
|
||||
self.project_issue.write(cr, self.user_projectuser_id, issue_ids, {'description': 'TestDescription'})
|
||||
issues.sudo(self.user_projectuser.id).write({'description': 'TestDescription'})
|
||||
|
||||
# Do: Bert reads project -> crash, no group
|
||||
# Test: no project issue visible
|
||||
self.assertRaises(AccessError, self.project_issue.search, cr, self.user_none_id, [('project_id', '=', pigs_id)])
|
||||
self.assertRaises(AccessError, Issue.sudo(self.user_noone.id).search, [('project_id', '=', pigs_id)])
|
||||
# Test: no project issue readable
|
||||
self.assertRaises(AccessError, self.project_issue.read, cr, self.user_none_id, issue_ids, ['name'])
|
||||
self.assertRaises(AccessError, issues.sudo(self.user_noone.id).read, ['name'])
|
||||
# Test: no project issue writable
|
||||
self.assertRaises(AccessError, self.project_issue.write, cr, self.user_none_id, issue_ids, {'description': 'TestDescription'})
|
||||
self.assertRaises(AccessError, issues.sudo(self.user_noone.id).write, {'description': 'TestDescription'})
|
||||
|
||||
# Do: Chell reads project -> ok (portal ok public)
|
||||
# Test: all project issues visible
|
||||
issue_ids = self.project_issue.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
issues = Issue.sudo(self.user_portal.id).search([('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(issues.ids), test_issue_ids,
|
||||
'access rights: project user cannot see all issues of a public project')
|
||||
# Test: all project issues readable
|
||||
self.project_issue.read(cr, self.user_portal_id, issue_ids, ['name'])
|
||||
issues.sudo(self.user_portal.id).read(['name'])
|
||||
# Test: no project issue writable
|
||||
self.assertRaises(AccessError, self.project_issue.write, cr, self.user_portal_id, issue_ids, {'description': 'TestDescription'})
|
||||
self.assertRaises(AccessError, issues.sudo(self.user_portal.id).write, {'description': 'TestDescription'})
|
||||
|
||||
# Do: Donovan reads project -> ok (public ok public)
|
||||
# Test: all project issues visible
|
||||
issue_ids = self.project_issue.search(cr, self.user_public_id, [('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
issues = Issue.sudo(self.user_public.id).search([('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(issues.ids), test_issue_ids,
|
||||
'access rights: project user cannot see all issues of a public project')
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE2: portal project
|
||||
# ----------------------------------------
|
||||
self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'portal'})
|
||||
self.project_pigs.write({'privacy_visibility': 'portal'})
|
||||
|
||||
# Do: Alfred reads project -> ok (employee ok public)
|
||||
# Test: all project issues visible
|
||||
issue_ids = self.project_issue.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
issues = Issue.sudo(self.user_projectuser.id).search([('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(issues.ids), test_issue_ids,
|
||||
'access rights: project user cannot see all issues of a portal project')
|
||||
|
||||
# Do: Bert reads project -> crash, no group
|
||||
# Test: no project issue searchable
|
||||
self.assertRaises(AccessError, self.project_issue.search, cr, self.user_none_id, [('project_id', '=', pigs_id)])
|
||||
self.assertRaises(AccessError, Issue.sudo(self.user_noone.id).search, [('project_id', '=', pigs_id)])
|
||||
|
||||
# Data: issue follower
|
||||
self.project_issue.message_subscribe_users(cr, self.user_projectuser_id, [self.issue_1_id, self.issue_3_id], [self.user_portal_id])
|
||||
self.issue_1.sudo(self.user_projectuser.id).message_subscribe_users(user_ids=[self.user_portal.id])
|
||||
self.issue_3.sudo(self.user_projectuser.id).message_subscribe_users(user_ids=[self.user_portal.id])
|
||||
|
||||
# Do: Chell reads project -> ok (portal ok public)
|
||||
# Test: only followed project issues visible + assigned
|
||||
issue_ids = self.project_issue.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
|
||||
test_issue_ids = set([self.issue_1_id, self.issue_3_id, self.issue_5_id])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
issues = Issue.sudo(self.user_portal.id).search([('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(issues.ids), set([self.issue_1.id, self.issue_3.id, self.issue_5.id]),
|
||||
'access rights: portal user should see the followed issues of a portal project')
|
||||
|
||||
# Data: issue follower cleaning
|
||||
self.project_issue.message_unsubscribe_users(cr, self.user_projectuser_id, [self.issue_1_id, self.issue_3_id], [self.user_portal_id])
|
||||
self.issue_1.sudo(self.user_projectuser.id).message_unsubscribe_users(user_ids=[self.user_portal.id])
|
||||
self.issue_3.sudo(self.user_projectuser.id).message_unsubscribe_users(user_ids=[self.user_portal.id])
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE3: employee project
|
||||
# ----------------------------------------
|
||||
self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'employees'})
|
||||
self.project_pigs.write({'privacy_visibility': 'employees'})
|
||||
|
||||
# Do: Alfred reads project -> ok (employee ok employee)
|
||||
# Test: all project issues visible
|
||||
issue_ids = self.project_issue.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
test_issue_ids = set([self.issue_1_id, self.issue_2_id, self.issue_3_id, self.issue_4_id, self.issue_5_id, self.issue_6_id])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
'access rights: project user cannot see all issues of an employees project')
|
||||
issues = Issue.sudo(self.user_projectuser.id).search([('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(issues.ids), set([self.issue_1.id, self.issue_2.id, self.issue_3.id,
|
||||
self.issue_4.id, self.issue_5.id, self.issue_6.id]),
|
||||
'access rights: project user cannot see all issues of an employees project')
|
||||
|
||||
# Do: Chell reads project -> ko (portal ko employee)
|
||||
# Test: no project issue visible + assigned
|
||||
issue_ids = self.project_issue.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
|
||||
self.assertFalse(issue_ids, 'access rights: portal user should not see issues of an employees project, even if assigned')
|
||||
issues = Issue.sudo(self.user_portal.id).search([('project_id', '=', pigs_id)])
|
||||
self.assertFalse(issues.ids, 'access rights: portal user should not see issues of an employees project, even if assigned')
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE4: followers project
|
||||
# ----------------------------------------
|
||||
self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'followers'})
|
||||
self.project_pigs.write({'privacy_visibility': 'followers'})
|
||||
|
||||
# Do: Alfred reads project -> ko (employee ko followers)
|
||||
# Test: no project issue visible
|
||||
issue_ids = self.project_issue.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
test_issue_ids = set([self.issue_4_id])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
issues = Issue.sudo(self.user_projectuser.id).search([('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(issues.ids), set([self.issue_4.id]),
|
||||
'access rights: employee user should not see issues of a not-followed followers project, only assigned')
|
||||
|
||||
# Do: Chell reads project -> ko (portal ko employee)
|
||||
# Test: no project issue visible
|
||||
issue_ids = self.project_issue.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
|
||||
test_issue_ids = set([self.issue_5_id])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
issues = Issue.sudo(self.user_portal.id).search([('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(issues.ids), set([self.issue_5.id]),
|
||||
'access rights: portal user should not see issues of a not-followed followers project, only assigned')
|
||||
|
||||
# Data: subscribe Alfred, Chell and Donovan as follower
|
||||
self.project_project.message_subscribe_users(cr, uid, [pigs_id], [self.user_projectuser_id, self.user_portal_id, self.user_public_id])
|
||||
self.project_issue.message_subscribe_users(cr, self.user_manager_id, [self.issue_1_id, self.issue_3_id], [self.user_portal_id, self.user_projectuser_id])
|
||||
self.project_pigs.message_subscribe_users(user_ids=[self.user_projectuser.id, self.user_portal.id, self.user_public.id])
|
||||
self.issue_1.sudo(self.user_projectmanager.id).message_subscribe_users(user_ids=[self.user_portal.id, self.user_projectuser.id])
|
||||
self.issue_3.sudo(self.user_projectmanager.id).message_subscribe_users(user_ids=[self.user_portal.id, self.user_projectuser.id])
|
||||
|
||||
# Do: Alfred reads project -> ok (follower ok followers)
|
||||
# Test: followed + assigned issues visible
|
||||
issue_ids = self.project_issue.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
test_issue_ids = set([self.issue_1_id, self.issue_3_id, self.issue_4_id])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
issues = Issue.sudo(self.user_projectuser.id).search([('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(issues.ids), set([self.issue_1.id, self.issue_3.id, self.issue_4.id]),
|
||||
'access rights: employee user should not see followed + assigned issues of a follower project')
|
||||
|
||||
# Do: Chell reads project -> ok (follower ok follower)
|
||||
# Test: followed + assigned issues visible
|
||||
issue_ids = self.project_issue.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
|
||||
test_issue_ids = set([self.issue_1_id, self.issue_3_id, self.issue_5_id])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
issues = Issue.sudo(self.user_portal.id).search([('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(issues.ids), set([self.issue_1.id, self.issue_3.id, self.issue_5.id]),
|
||||
'access rights: employee user should not see followed + assigned issues of a follower project')
|
||||
|
||||
Reference in New Issue
Block a user