[FIX] mail: fixed message_track (subtype not found, style, var_name; updated tests with new implementation.

bzr revid: tde@openerp.com-20121219110502-j43pilfijv91td2q
This commit is contained in:
Thibault Delavallée 2012-12-19 12:05:02 +01:00
parent cd290565a4
commit 91af1e1e59
3 changed files with 52 additions and 45 deletions

View File

@ -90,7 +90,6 @@ class mail_thread(osv.AbstractModel):
# :param obj: is a browse_record
# :param function lambda: returns whether the tracking should record using this subtype
_track = {}
_TRACK_TEMPLATE = """
%if message_description:
<span>${message_description}</span>
@ -249,7 +248,11 @@ class mail_thread(osv.AbstractModel):
#------------------------------------------------------
def create(self, cr, uid, values, context=None):
""" Override to subscribe the current user. """
""" Chatter override :
- subscribe uid
- subscribe followers of parent
- log a creation message
"""
if context is None:
context = {}
thread_id = super(mail_thread, self).create(cr, uid, values, context=context)
@ -259,8 +262,9 @@ class mail_thread(osv.AbstractModel):
self.message_subscribe_users(cr, uid, [thread_id], [uid], context=context)
self.message_subscribe_from_parent(cr, uid, [thread_id], context=context)
# automatic logging
self.message_post(cr, uid, thread_id, body='Document <b>created</b>.', context=context)
# automatic logging unless asked not to (mainly for various testing purpose)
if not context.get('mail_nolog'):
self.message_post(cr, uid, thread_id, body='Document <b>created</b>.', context=context)
return thread_id
def write(self, cr, uid, ids, values, context=None):
@ -306,14 +310,15 @@ class mail_thread(osv.AbstractModel):
"""
lst = []
for name, column_info in self._all_columns.items():
vis = getattr(column_info.column, 'track_visibility', False)
if (vis==2) or ((vis==1) and (name in updated_fields)) or (name in self._track):
visibility = getattr(column_info.column, 'track_visibility', False)
if visibility == 2 or (visibility == 1 and name in updated_fields) or name in self._track:
lst.append(name)
if not lst:
return lst
return self.fields_get(cr, uid, lst, context=context)
def message_track(self, cr, uid, ids, tracked_fields, initial_values, context=None):
if not tracked_fields:
return True
def convert_for_display(value, field_obj):
if not value:
return ''
@ -323,29 +328,32 @@ class mail_thread(osv.AbstractModel):
return dict(field_obj['selection'])[value]
return value
if not tracked_fields:
return True
for record in self.read(cr, uid, ids, tracked_fields.keys(), context=context):
initial = initial_values[record['id']]
changes = []
tracked_values = {}
# generate tracked_values data structure: {'col_name': {col_info, new_value, old_value}}
for col_name, col_info in tracked_fields.items():
if record[col_name] == initial[col_name] and (getattr(self._all_columns[col_name].column, 'track_visibility', 0) == 2):
if record[col_name] == initial[col_name] and getattr(self._all_columns[col_name].column, 'track_visibility', 0) == 2:
tracked_values[col_name] = dict(col_info=col_info['string'],
new_value=convert_for_display(record[col_name], col_info))
elif record[col_name] != initial[col_name] and (getattr(self._all_columns[col_name].column, 'track_visibility', 0) == 1):
tracked_values[col_name] = dict(col_info=col_info['string'],
old_value=convert_for_display(initial[col_name], col_info),
elif record[col_name] != initial[col_name] and getattr(self._all_columns[col_name].column, 'track_visibility', 0) in [1, 2]:
tracked_values[col_name] = dict(col_info=col_info['string'],
old_value=convert_for_display(initial[col_name], col_info),
new_value=convert_for_display(record[col_name], col_info))
changes.append(col_name)
if not changes:
continue
# find subtypes and post messages or log if no subtype found
subtypes = []
for field, track_info in self._track.items():
if field not in changes: continue
if field not in changes:
continue
for subtype, method in track_info.items():
if method(self, cr, uid, record, context):
subtypes.append(subtype)
@ -353,8 +361,8 @@ class mail_thread(osv.AbstractModel):
posted = False
for subtype in subtypes:
try:
subtype_rec = self.pool.get('ir.model.data').get_object(cr, uid, *subtype.split('.'))
except ValueError, e:
subtype_rec = self.pool.get('ir.model.data').get_object(cr, uid, subtype.split('.')[0], subtype.split('.')[1])
except ValueError:
continue
message = MakoTemplate(self._TRACK_TEMPLATE).render_unicode(message_description=subtype_rec.description, tracked_values=tracked_values)
self.message_post(cr, uid, record['id'], body=message, subtype=subtype, context=context)
@ -642,9 +650,9 @@ class mail_thread(osv.AbstractModel):
alternative = (message.get_content_type() == 'multipart/alternative')
for part in message.walk():
if part.get_content_maintype() == 'multipart':
continue # skip container
filename = part.get_filename() # None if normal part
encoding = part.get_content_charset() # None if attachment
continue # skip container
filename = part.get_filename() # None if normal part
encoding = part.get_content_charset() # None if attachment
# 1) Explicit Attachments -> attachments
if filename or part.get('content-disposition', '').strip().startswith('attachment'):
attachments.append((filename or 'attachment', part.get_payload(decode=True)))

View File

@ -82,7 +82,8 @@ class TestMailBase(common.TransactionCase):
# 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 !'})
{'name': 'Pigs', 'description': 'Fans of Pigs, unite !'},
{'mail_nolog': True})
self.group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
def tearDown(self):

View File

@ -19,8 +19,6 @@
#
##############################################################################
from openerp import tools
from openerp.addons.mail.tests.test_mail_base import TestMailBase
from openerp.tools.mail import html_sanitize, append_content_to_html
@ -121,18 +119,18 @@ class test_mail(TestMailBase):
# Previously-created group can be emailed now - it should have an implicit alias group+frogs@...
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
group_messages = frog_group.message_ids
self.assertTrue(len(group_messages) == 1, 'New group should only have the original message')
self.assertTrue(len(group_messages) == 2, 'New group should only have the original message + creation log')
mail_frog_news = MAIL_TEMPLATE.format(to='Friendly Frogs <group+frogs@example.com>', subject='news', extra='')
self.mail_thread.message_process(cr, uid, None, mail_frog_news)
frog_group.refresh()
self.assertTrue(len(frog_group.message_ids) == 2, 'Group should contain 2 messages now')
self.assertTrue(len(frog_group.message_ids) == 3, 'Group should contain 3 messages now')
# Even with a wrong destination, a reply should end up in the correct thread
mail_reply = MAIL_TEMPLATE.format(to='erroneous@example.com>', subject='Re: news',
extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
self.mail_thread.message_process(cr, uid, None, mail_reply)
frog_group.refresh()
self.assertTrue(len(frog_group.message_ids) == 3, 'Group should contain 3 messages now')
self.assertTrue(len(frog_group.message_ids) == 4, 'Group should contain 4 messages now')
# No model passed and no matching alias must raise
mail_spam = MAIL_TEMPLATE.format(to='noone@example.com', subject='spam', extra='')
@ -206,7 +204,7 @@ class test_mail(TestMailBase):
# Data: create 'disturbing' values in mail.followers: same res_id, other res_model; same res_model, other res_id
group_dummy_id = self.mail_group.create(cr, uid,
{'name': 'Dummy group'})
{'name': 'Dummy group'}, {'mail_nolog': True})
self.mail_followers.create(cr, uid,
{'res_model': 'mail.thread', 'res_id': self.group_pigs_id, 'partner_id': partner_bert_id})
self.mail_followers.create(cr, uid,
@ -445,7 +443,7 @@ class test_mail(TestMailBase):
cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
mail_compose = self.registry('mail.compose.message')
self.res_users.write(cr, uid, [uid], {'signature': 'Admin', 'email': 'a@a'})
group_bird_id = self.mail_group.create(cr, uid, {'name': 'Bird', 'description': 'Bird resistance'})
group_bird_id = self.mail_group.create(cr, uid, {'name': 'Bird', 'description': 'Bird resistance'}, {'mail_nolog': True})
group_bird = self.mail_group.browse(cr, uid, group_bird_id)
# Mail data
@ -604,19 +602,19 @@ class test_mail(TestMailBase):
# Data: custom subtypes
mt_private_id = self.mail_message_subtype.create(cr, uid, {'name': 'private', 'description': 'Private public'})
self.ir_model_data.create(cr, uid, {'name': 'mt_private', 'model': 'mail.group', 'module': 'mail', 'res_id': mt_private_id})
self.ir_model_data.create(cr, uid, {'name': 'mt_private', 'model': 'mail.message.subtype', 'module': 'mail', 'res_id': mt_private_id})
mt_name_supername_id = self.mail_message_subtype.create(cr, uid, {'name': 'name_supername', 'description': 'Supername name'})
self.ir_model_data.create(cr, uid, {'name': 'mt_name_supername', 'model': 'mail.group', 'module': 'mail', 'res_id': mt_name_supername_id})
self.ir_model_data.create(cr, uid, {'name': 'mt_name_supername', 'model': 'mail.message.subtype', 'module': 'mail', 'res_id': mt_name_supername_id})
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.group', 'module': 'mail', 'res_id': mt_group_public_id})
self.ir_model_data.create(cr, uid, {'name': 'mt_group_public', 'model': 'mail.message.subtype', 'module': 'mail', 'res_id': mt_group_public_id})
# Data: alter mail_group model for testing purposes (test on classic, selection and many2one fields)
self.mail_group._track = {
'public': {
'mail.mt_private': lambda self, cr, uid, obj, ctx=None: obj.public == 'private',
'mail.mt_private': lambda self, cr, uid, obj, ctx=None: obj['public'] == 'private',
},
'name': {
'mail.mt_name_supername': lambda self, cr, uid, obj, ctx=None: obj.name == 'supername',
'mail.mt_name_supername': lambda self, cr, uid, obj, ctx=None: obj['name'] == 'supername',
},
'group_public_id': {
'mail.mt_group_public': lambda self, cr, uid, obj, ctx=None: True,
@ -625,9 +623,9 @@ class test_mail(TestMailBase):
public_col = self.mail_group._columns.get('public')
name_col = self.mail_group._columns.get('name')
group_public_col = self.mail_group._columns.get('group_public_id')
public_col._track_visibility = 1
name_col._track_visibility = 2
group_public_col._track_visibility = 1
public_col.track_visibility = 1
name_col.track_visibility = 2
group_public_col.track_visibility = 1
# Test: change name -> always tracked, not related to a subtype
self.mail_group.write(cr, self.user_raoul_id, [self.group_pigs_id], {'public': 'public'})
@ -636,7 +634,7 @@ class test_mail(TestMailBase):
# Test: first produced message: no subtype, name change tracked
last_msg = self.group_pigs.message_ids[-1]
self.assertFalse(last_msg.subtype_id, 'tracked: message should not have been linked to a subtype')
self.assertIn('SelectedGroupOnly-&gt;Public', _strip_string_spaces(last_msg.body), 'tracked: message body incorrect')
self.assertIn('SelectedGroupOnly&#8594;Public', _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
@ -647,13 +645,13 @@ class test_mail(TestMailBase):
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('Pigs-&gt;supername', _strip_string_spaces(last_msg.body), 'tracked: message body incorrect')
self.assertIn('Pigs&#8594;supername', _strip_string_spaces(last_msg.body), 'tracked: message body incorrect')
# Test: second produced message: mt_name_supername
last_msg = self.group_pigs.message_ids[-3]
self.assertEqual(last_msg.subtype_id.id, mt_name_supername_id, 'tracked: message should be linked to mt_name_supername subtype')
self.assertIn('Supername name', last_msg.body, 'tracked: message body does not hold the subtype description')
self.assertIn('Public-&gt;Private', _strip_string_spaces(last_msg.body), 'tracked: message body incorrect')
self.assertIn('Pigs-&gt;supername', _strip_string_spaces(last_msg.body), 'tracked feature: message body does not hold always tracked field')
self.assertIn('Public&#8594;Private', _strip_string_spaces(last_msg.body), 'tracked: message body incorrect')
self.assertIn('Pigs&#8594;supername', _strip_string_spaces(last_msg.body), 'tracked feature: message body does not hold always tracked field')
# Test: change public as public, group_public_id -> 1 subtype, name always tracked
self.mail_group.write(cr, self.user_raoul_id, [self.group_pigs_id], {'public': 'public', 'group_public_id': group_system_id})
@ -663,8 +661,8 @@ class test_mail(TestMailBase):
last_msg = self.group_pigs.message_ids[-4]
self.assertEqual(last_msg.subtype_id.id, mt_group_public_id, 'tracked: message should not be linked to any subtype')
self.assertIn('Group changed', last_msg.body, 'tracked: message body does not hold the subtype description')
self.assertIn('Private-&gt;Public', _strip_string_spaces(last_msg.body), 'tracked: message body does not hold changed tracked field')
self.assertIn('HumanResources/Employee-&gt;Administration/Settings', _strip_string_spaces(last_msg.body), 'tracked: message body does not hold always tracked field')
self.assertIn('Private&#8594;Public', _strip_string_spaces(last_msg.body), 'tracked: message body does not hold changed tracked field')
self.assertIn('HumanResources/Employee&#8594;Administration/Settings', _strip_string_spaces(last_msg.body), 'tracked: message body does not hold always tracked field')
# Test: change not tracked field, no tracking message
self.mail_group.write(cr, self.user_raoul_id, [self.group_pigs_id], {'description': 'Dummy'})
@ -672,7 +670,7 @@ class test_mail(TestMailBase):
self.assertEqual(len(self.group_pigs.message_ids), 4, 'tracked: No message should have been produced')
# Data: removed changes
public_col._track_visibility = False
name_col._track_visibility = False
group_public_col._track_visibility = False
public_col.track_visibility = False
name_col.track_visibility = False
group_public_col.track_visibility = False
self.mail_group._track = {}