[FIX] mail.compose.message: fixed send_mail about getting mass_mail values from template; fixed generated body that was adding a signature in reply mode; added the test that trigerred that bug.

bzr revid: tde@openerp.com-20120831171507-1prt4h46zsj77m23
This commit is contained in:
Thibault Delavallée 2012-08-31 19:15:07 +02:00
parent fb7491ed70
commit 0f3101cec5
3 changed files with 46 additions and 50 deletions

View File

@ -208,10 +208,11 @@ class mail_thread(osv.Model):
# mail.message wrappers and tools
#------------------------------------------------------
def _needaction_domain_get(self, cr, uid, context={}):
def _needaction_domain_get(self, cr, uid, context=None):
if self._needaction:
return [('message_unread', '=', True)]
return []
#------------------------------------------------------
# Mail gateway
#------------------------------------------------------

View File

@ -326,6 +326,7 @@ class test_mail(common.TransactionCase):
# Mail data
_subject = 'Pigs'
_subject_reply = 'Re: Pigs'
_mail_subject = '%s posted on %s' % (user_admin.name, group_pigs.name)
_body_text = 'Pigs rules'
_msg_body1 = '<pre>Pigs rules</pre>'
@ -373,22 +374,27 @@ class test_mail(common.TransactionCase):
self.assertEqual(len(notif_ids), 4, 'mail.message: too much notifications created')
self.assertEqual(set(msg_pids), set(test_pids), 'mail.message partner_ids incorrect')
# CASE2: reply to last comment with attachments
# CASE2: reply to last comment (update its subject) with attachments
message.write({'subject': _subject})
compose_id = mail_compose.create(cr, uid,
{'attachment_ids': [(0, 0, _attachments[0]), (0, 0, _attachments[1])]},
{'mail.compose.message.mode': 'reply', 'default_model': 'mail.thread', 'default_res_id': self.group_pigs_id, 'active_id': message.id})
compose = mail_compose.browse(cr, uid, compose_id)
# Test: form view methods
# Test: model, res_id, parent_id
# Test: model, res_id, parent_id, content_subtype
self.assertEqual(compose.model, 'mail.group', 'mail.compose.message incorrect model')
self.assertEqual(compose.res_id, self.group_pigs_id, 'mail.compose.message incorrect res_id')
self.assertEqual(compose.parent_id.id, message.id, 'mail.compose.message incorrect parent_id')
self.assertEqual(compose.content_subtype, 'html', 'mail.compose.message incorrect content_subtype')
# Post the comment, get created message
mail_compose.send_mail(cr, uid, [compose_id])
group_pigs.refresh()
message = group_pigs.message_ids[0]
# Test: subject as Re:.., body in html
self.assertEqual(message.subject, _subject_reply, 'mail.message incorrect subject')
self.assertIn('Administrator wrote:<blockquote><pre>Pigs rules</pre></blockquote></div>', message.body, 'mail.message body is incorrect')
# Test: attachments
for i in range(len(message.attachment_ids)):
self.assertEqual(message.attachment_ids[i].name, _attachments[i]['name'], 'mail.message attachment name incorrect')
@ -406,13 +412,13 @@ class test_mail(common.TransactionCase):
# Post the comment, get created message
mail_compose.send_mail(cr, uid, [compose_id], {'default_res_id': -1, 'active_ids': [self.group_pigs_id]})
group_pigs.refresh()
msg = group_pigs.message_ids[0]
message = group_pigs.message_ids[0]
# Test: last message on Pigs = last created message
test_msg = self.mail_message.browse(cr, uid, self.mail_message.search(cr, uid, [], limit=1))[0]
self.assertEqual(msg.id, test_msg.id, 'Pigs did not receive its mass mailing message')
self.assertEqual(message.id, test_msg.id, 'Pigs did not receive its mass mailing message')
# Test: mail.message: subject, body
self.assertEqual(msg.subject, _subject, 'mail.message subject is incorrect')
self.assertEqual(msg.body, group_pigs.description, 'mail.message body is incorrect')
self.assertEqual(message.subject, _subject, 'mail.message subject is incorrect')
self.assertEqual(message.body, group_pigs.description, 'mail.message body is incorrect')
def test_30_message_read(self):
""" Tests designed for message_read. """

View File

@ -72,12 +72,12 @@ class mail_compose_message(osv.TransientModel):
composition_mode = context.get('default_composition_mode', context.get('mail.compose.message.mode'))
model = context.get('default_model', context.get('active_model'))
res_id = context.get('default_res_id', context.get('active_id'))
active_id = context.get('active_id')
message_id = context.get('default_parent_id', context.get('message_id', context.get('active_id')))
active_ids = context.get('active_ids')
# get default values according to the composition mode
if composition_mode == 'reply':
vals = self.get_message_data(cr, uid, active_id, context=context)
vals = self.get_message_data(cr, uid, message_id, context=context)
elif composition_mode == 'comment' and model and res_id:
vals = self.get_record_data(cr, uid, model, res_id, context=context)
elif composition_mode == 'mass_mail' and model and active_ids:
@ -155,7 +155,7 @@ class mail_compose_message(osv.TransientModel):
message_data = self.pool.get('mail.message').browse(cr, uid, message_id, context=context)
# create subject
re_prefix = _("Re:")
re_prefix = _('Re:')
reply_subject = tools.ustr(message_data.subject or '')
if not (reply_subject.startswith('Re:') or reply_subject.startswith(re_prefix)):
reply_subject = "%s %s" % (re_prefix, reply_subject)
@ -163,7 +163,7 @@ class mail_compose_message(osv.TransientModel):
reply_header = _('On %(date)s, %(sender_name)s wrote:') % {
'date': message_data.date if message_data.date else '',
'sender_name': message_data.author_id.name }
reply_body = '<div>%s<blockquote>%s</blockquote></div>%s' % (reply_header, message_data.body, current_user.signature)
reply_body = '<div>%s<blockquote>%s</blockquote></div>' % (reply_header, message_data.body)
# get partner_ids from original message
partner_ids = [partner.id for partner in message_data.partner_ids] if message_data.partner_ids else []
@ -224,6 +224,22 @@ class mail_compose_message(osv.TransientModel):
res.update(self._verify_partner_email(cr, uid, value[0][2], context=context))
return res
def unlink(self, cr, uid, ids, context=None):
# Cascade delete all attachments, as they are owned by the composition wizard
for wizard in self.read(cr, uid, ids, ['attachment_ids'], context=context):
self.pool.get('ir.attachment').unlink(cr, uid, wizard['attachment_ids'], context=context)
return super(mail_compose_message,self).unlink(cr, uid, ids, context=context)
def dummy(self, cr, uid, ids, context=None):
""" TDE: defined to have buttons that do basically nothing. It is
currently impossible to have buttons that do nothing special
in views (if type not specified, considered as 'object'). """
return True
#------------------------------------------------------
# Wizard validation and send
#------------------------------------------------------
def send_mail(self, cr, uid, ids, context=None):
""" Process the wizard content and proceed with sending the related
email(s), rendering any template patterns on the fly if needed. """
@ -248,14 +264,13 @@ class mail_compose_message(osv.TransientModel):
# mass mailing: render and override default values
if mass_mail_mode and wizard.model:
email_dict = self.render_message(cr, uid, wizard, wizard.model, res_id, context=context)
post_values['subject'] = email_dict.get('subject', False)
post_values['body'] = email_dict.get('body', '')
if email_dict.get('partner_ids'):
post_values['partner_ids'] += [(4, id) for id in email_dict.get('partner_ids')]
if email_dict.get('attachments'):
post_values['attachments'] += [(attach.datas_fname, attach.datas) for attach in email_dict.get('attachments')]
new_partner_ids = email_dict.pop('partner_ids', [])
post_values['partner_ids'] += new_partner_ids
new_attachments = email_dict.pop('attachments', [])
post_values['attachments'] += new_attachments
post_values.update(email_dict)
# post the message
active_model_pool.message_post(cr, uid, res_ids, msg_type='comment', context=context, **post_values)
active_model_pool.message_post(cr, uid, [res_id], msg_type='comment', context=context, **post_values)
return {'type': 'ir.actions.act_window_close'}
@ -264,20 +279,9 @@ class mail_compose_message(osv.TransientModel):
This method is meant to be inherited by email_template that will
produce a more complete dictionary, with email_to, ...
"""
# TDE: TODO: to move into mail.compose.message in email template
# mails = tools.email_split(email_dict.get('email_to', '')) + tools.email_split(email_dict.get('email_cc', ''))
# for mail in mails:
# partner_search_ids = self.pool.get('res.partner').search(cr, uid, [('email', 'ilike', email)], context=context)
# if partner_search_ids:
# partner_ids.append((4, 0, partner_search_ids[0]))
# else:
# partner_id = self.pool.get('res.partner').name_create(cr, uid, values['email_to'], context=context)
# partner_ids.append((4, 0, partner_id))
return {
'subject': self.render_template(cr, uid, wizard.subject, model, res_id, context),
'body': self.render_template(cr, uid, wizard.body, model, res_id, context),
'partner_ids': [],
'attachment_ids': [],
}
def render_template(self, cr, uid, template, model, res_id, context=None):
@ -298,25 +302,10 @@ class mail_compose_message(osv.TransientModel):
context = {}
def merge(match):
exp = str(match.group()[2:-1]).strip()
result = eval(exp,
{
'user' : self.pool.get('res.users').browse(cr, uid, uid, context=context),
'object' : self.pool.get(model).browse(cr, uid, res_id, context=context),
'context': dict(context), # copy context to prevent side-effects of eval
})
if result in (None, False):
return ""
return tools.ustr(result)
result = eval(exp, {
'user' : self.pool.get('res.users').browse(cr, uid, uid, context=context),
'object' : self.pool.get(model).browse(cr, uid, res_id, context=context),
'context': dict(context), # copy context to prevent side-effects of eval
})
return result and tools.ustr(result) or ''
return template and EXPRESSION_PATTERN.sub(merge, template)
def unlink(self, cr, uid, ids, context=None):
# Cascade delete all attachments, as they are owned by the composition wizard
for wizard in self.read(cr, uid, ids, ['attachment_ids'], context=context):
self.pool.get('ir.attachment').unlink(cr, uid, wizard['attachment_ids'], context=context)
return super(mail_compose_message,self).unlink(cr, uid, ids, context=context)
def dummy(self, cr, uid, ids, context=None):
""" TDE: defined to have buttons that do basically nothing. It is
currently impossible to have buttons that do nothing special
in views (if type not specified, considered as 'object'). """
return True