import tools
from tools.translate import _
-from base.res.res_partner import format_address
-
CRM_LEAD_PENDING_STATES = (
crm.AVAILABLE_STATES[2][0], # Cancelled
crm.AVAILABLE_STATES[3][0], # Done
crm.AVAILABLE_STATES[4][0], # Pending
)
-class crm_lead(base_stage, format_address, osv.osv):
+class crm_lead(base_stage, osv.osv):
""" CRM Lead Case """
_name = "crm.lead"
_description = "Lead/Opportunity"
return result, fold
- def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
- res = super(crm_lead,self).fields_view_get(cr, user, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
- if view_type == 'form':
- res['arch'] = self.fields_view_get_address(cr, user, res['arch'], context=context)
- return res
-
_group_by_full = {
'stage_id': _read_group_stage_ids
}
def stage_set_send_note(self, cr, uid, ids, stage_id, context=None):
""" Override of the (void) default notification method. """
stage_name = self.pool.get('crm.case.stage').name_get(cr, uid, [stage_id], context=context)[0][1]
- return self.message_post(cr, uid, ids, body= _("Stage changed to <b>%s</b>.") % (stage_name), subtype="stage change",context=context)
+ return self.message_post(cr, uid, ids, body= _("Stage changed to <b>%s</b>.") % (stage_name), mail_subtype_new="crm_subtype_stage_change",context=context)
def case_get_note_msg_prefix(self, cr, uid, lead, context=None):
if isinstance(lead, (int, long)):
def create_send_note(self, cr, uid, ids, context=None):
for id in ids:
message = _("%s has been <b>created</b>.")% (self.case_get_note_msg_prefix(cr, uid, id, context=context))
- self.message_post(cr, uid, [id], body=message, subtype="new", context=context)
+ self.message_post(cr, uid, [id], body=message, subtype_xml_id="crm_subtype_new", context=context)
return True
def case_mark_lost_send_note(self, cr, uid, ids, context=None):
message = _("Opportunity has been <b>lost</b>.")
- return self.message_post(cr, uid, ids, body=message,subtype="lost", context=context)
+ return self.message_post(cr, uid, ids, body=message,subtype_xml_id="crm_subtype_lost", context=context)
def case_mark_won_send_note(self, cr, uid, ids, context=None):
message = _("Opportunity has been <b>won</b>.")
- return self.message_post(cr, uid, ids, body=message, subtype="won", context=context)
+ return self.message_post(cr, uid, ids, body=message, subtype_xml_id="crm_subtype_won", context=context)
def schedule_phonecall_send_note(self, cr, uid, ids, phonecall_id, action, context=None):
phonecall = self.pool.get('crm.phonecall').browse(cr, uid, [phonecall_id], context=context)[0]
</record>
<!-- mail subtype -->
- <record id="mail.mail_subtype_new" model="mail.message.subtype">
+ <record id="mail.crm_subtype_new" model="mail.message.subtype">
<field name="name">new</field>
- <field name="model_ids" eval="[(4,ref('crm.model_crm_lead'))]"/>
+ <field name="res_model">crm.lead</field>
<field name="default" eval="False"/>
</record>
- <record id="mail.mail_subtype_won" model="mail.message.subtype">
+ <record id="mail.crm_subtype_won" model="mail.message.subtype">
<field name="name">won</field>
- <field name="model_ids" eval="[(4,ref('crm.model_crm_lead'))]"/>
+ <field name="res_model">crm.lead</field>
</record>
- <record id="mail_subtype_lost" model="mail.message.subtype">
+ <record id="mail.crm_subtype_lost" model="mail.message.subtype">
<field name="name">lost</field>
- <field name="model_ids" eval="[(4, ref('crm.model_crm_lead'))]"/>
+ <field name="res_model">crm.lead</field>
+ <field name="default" eval="False"/>
</record>
- <record id="mail.mail_subtype_stage_change" model="mail.message.subtype">
+ <record id="mail.crm_subtype_stage_change" model="mail.message.subtype">
<field name="name">stage change</field>
- <field name="model_ids" eval="[(4,ref('crm.model_crm_lead'))]"/>
+ <field name="res_model">crm.lead</field>
<field name="default" eval="False"/>
</record>
- <record id="mail.mail_subtype_email" model="mail.message.subtype">
- <field name="model_ids" eval="[(4,ref('crm.model_crm_lead'))]"/>
- </record>
- <record id="mail.mail_subtype_comment" model="mail.message.subtype">
- <field name="model_ids" eval="[(4,ref('crm.model_crm_lead'))]"/>
- </record>
- <record id="mail.mail_subtype_other" model="mail.message.subtype">
- <field name="model_ids" eval="[(4,ref('crm.model_crm_lead'))]"/>
- </record>
</data>
</openerp>
<field eval="'()'" name="args"/>
</record>
- <record id="mail_subtype_other" model="mail.message.subtype">
- <field name="name">other</field>
- <field name="model_ids" eval="[(4,ref('mail.model_mail_group'))]"/>
- <field name="default" eval='False'/>
- </record>
- <record id="mail_subtype_email" model="mail.message.subtype">
- <field name="name">email</field>
- <field name="model_ids" eval="[(4,ref('mail.model_mail_group'))]"/>
- </record>
<record id="mail_subtype_comment" model="mail.message.subtype">
<field name="name">comment</field>
- <field name="model_ids" eval="[(4,ref('mail.model_mail_group'))]"/>
</record>
</data>
</openerp>
##############################################################################
import logging
-import openerp
import tools
from email.header import decode_header
from operator import itemgetter
from osv import osv, fields
-from tools.translate import _
_logger = logging.getLogger(__name__)
text = decode_header(text.replace('\r', ''))
return ''.join([tools.ustr(x[0], x[1]) for x in text])
-
class mail_message(osv.Model):
""" Messages model: system notification (replacing res.log notifications),
comments (OpenChatter discussion) and incoming emails. """
for message in self.browse(cr, uid, ids, context=context):
if not message.model or not message.res_id:
continue
- try:
- result[message.id] = self._shorten_name(self.pool.get(message.model).name_get(cr, uid, [message.res_id], context=context)[0][1])
- except openerp.exceptions.AccessDenied, e:
- pass
+ result[message.id] = self._shorten_name(self.pool.get(message.model).name_get(cr, uid, [message.res_id], context=context)[0][1])
return result
def _get_unread(self, cr, uid, ids, name, arg, context=None):
def _message_dict_get(self, cr, uid, msg, context=None):
""" Return a dict representation of the message browse record. """
- attachment_ids = [{'id': attach[0], 'name': attach[1]} for attach in self.pool.get('ir.attachment').name_get(cr, uid, [x.id for x in msg.attachment_ids], context=context)]
+ attachment_ids = self.pool.get('ir.attachment').name_get(cr, uid, [x.id for x in msg.attachment_ids], context=context)
author_id = self.pool.get('res.partner').name_get(cr, uid, [msg.author_id.id], context=context)[0]
author_user_id = self.pool.get('res.users').name_get(cr, uid, [msg.author_id.user_ids[0].id], context=context)[0]
partner_ids = self.pool.get('res.partner').name_get(cr, uid, [x.id for x in msg.partner_ids], context=context)
def unlink(self, cr, uid, ids, context=None):
# cascade-delete attachments that are directly attached to the message (should only happen
- # for mail.messages that act as parent for a standalone mail.mail record).
+ # for mail.messages that act as parent for a standalone mail.mail record.
attachments_to_delete = []
- for message in self.browse(cr, uid, ids, context=context):
- for attach in message.attachment_ids:
- if attach.res_model == self._name and attach.res_id == message.id:
+ for mail in self.browse(cr, uid, ids, context=context):
+ for attach in mail.attachment_ids:
+ if attach.res_model == 'mail.message' and attach.res_id == mail.id:
attachments_to_delete.append(attach.id)
if attachments_to_delete:
self.pool.get('ir.attachment').unlink(cr, uid, attachments_to_delete, context=context)
- return super(mail_message, self).unlink(cr, uid, ids, context=context)
+ return super(mail_message,self).unlink(cr, uid, ids, context=context)
def notify(self, cr, uid, newid, context=None):
""" Add the related record followers to the destination partner_ids.
follow_ids = followers_obj.search(cr, uid, [('partner_id','=',p_id),('subtype_ids','in',[message.subtype_id.id]),('res_model','=',message.model),('res_id','=',message.res_id)], context=context)
if follow_ids and len(follow_ids):
missing_follow_ids.append(p_id)
+ subtype_record = self.pool.get('mail.message.subtype').browse(cr, uid, message.subtype_id.id,context=context)
+ if not subtype_record.res_model:
+ missing_follow_ids.append(p_id)
message.write({'partner_ids': [(4, p_id) for p_id in missing_follow_ids]})
partners_to_notify |= extra_notified
self.pool.get('mail.notification').notify(cr, uid, list(partners_to_notify), newid, context=context)
default = {}
default.update(message_id=False, headers=False)
return super(mail_message, self).copy(cr, uid, id, default=default, context=context)
-
- #------------------------------------------------------
- # Tools
- #------------------------------------------------------
-
- def check_partners_email(self, cr, uid, partner_ids, context=None):
- """ Verify that selected partner_ids have an email_address defined.
- Otherwise throw a warning. """
- partner_wo_email_lst = []
- for partner in self.pool.get('res.partner').browse(cr, uid, partner_ids, context=context):
- if not partner.email:
- partner_wo_email_lst.append(partner)
- if not partner_wo_email_lst:
- return {}
- warning_msg = _('The following partners chosen as recipients for the email have no email address linked :')
- for partner in partner_wo_email_lst:
- warning_msg += '\n- %s' % (partner.name)
- return {'warning': {
- 'title': _('Partners email addresses not found'),
- 'message': warning_msg,
- }
- }
_columns = {
'name': fields.char('Message Subtype ', size = 128,
required = True, help = 'Message subtype, gives a more precise type on the message, especially for system notifications. For example, it can be a notification related to a new record (New), or to a stage change in a process (Stage change). Message subtypes allow to precisely tune the notifications the user want to receive on its wall.'),
- 'model_ids': fields.many2many('ir.model',
- 'mail_message_subtyp_message_rel',
- 'message_subtype_id', 'model_id', 'Model',
- help = "link some subtypes to several models, for projet/task"),
+ 'res_model': fields.char('Model',size = 128, help = "link subtype to model"),
'default': fields.boolean('Default', help = "When subscribing to the document, users will receive by default messages related to this subtype unless they uncheck this subtype"),
}
_defaults = {
'default': True,
}
- _sql_constraints = [
- ('name_uniq', 'unique (name)', 'The name of the message subtype must be unique !')
- ]
<field name="arch" type="xml">
<tree string="Subtype">
<field name="name"/>
- <field name="model_ids" invisible="1"/>
+ <field name="res_model" invisible="1"/>
<field name="default"/>
</tree>
</field>
<group>
<group>
<field name="name"/>
+ <field name="res_model"/>
</group>
<group>
<field name="default"/>
</group>
</group>
- <separator string="Models"/>
- <field name="model_ids" widget="many2many"/>
</sheet>
</form>
</field>
self.message_post(cr, uid, [id], message, context=context)
def message_post(self, cr, uid, thread_id, body='', subject=False,
- type='notification', parent_id=False, attachments=None, subtype='comment', context=None, **kwargs):
+ type='notification', parent_id=False, attachments=None, subtype_xml_id='mail_subtype_comment', context=None, **kwargs):
""" Post a new message in an existing thread, returning the new
mail.message ID. Extra keyword arguments will be used as default
column values for the new mail.message record.
values = kwargs
subtype_obj = self.pool.get('mail.message.subtype')
- if subtype:
- subtypes = subtype_obj.name_search(cr, uid, subtype,context=context)
- if len(subtypes):
- subtype_browse = subtype_obj.browse(cr, uid, subtypes[0][0],context=context)
- if self._name in [model.model for model in subtype_browse.model_ids]:
- values['subtype_id']=subtype_browse.id
+ ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', subtype_xml_id)
+ if subtype_xml_id:
+ subtype_browse = subtype_obj.browse(cr, uid, ref[1],context=context)
+ if self._name == subtype_browse.res_model:
+ values['subtype_id']=subtype_browse.id
+ else:
+ values['subtype_id']=subtype_browse.id
values.update({
'model': context.get('thread_model', self._name) if thread_id else False,
'res_id': thread_id or False,
partner_ids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, uid, user_ids, context=context)]
return self.message_subscribe(cr, uid, ids, partner_ids, context=context)
- def message_subscribe(self, cr, uid, ids, partner_ids, context=None):
- """ Add partners to the records followers. """
+ def message_subscribe(self, cr, uid, ids, partner_ids,subtype_ids = None, context=None):
+ """ Add partners to the records followers.
+ :param partner_ids: a list of partner_ids to subscribe
+ :param return: new value of followers if read_back key in context
+ """
+ self.write(cr, uid, ids, {'message_follower_ids': [(4, pid) for pid in partner_ids]}, context=context)
if not subtype_ids:
subtype_obj = self.pool.get('mail.message.subtype')
- subtype_ids = subtype_obj.search(cr, uid, [('default', '=', 'true'),('model_ids.model', '=', self._name)],context=context)
+ subtype_ids = subtype_obj.search(cr, uid, [('default', '=', 'true'),('res_model', '=', self._name)],context=context)
if subtype_ids:
self.message_subscribe_udpate_subtypes(cr, uid, ids, partner_ids, subtype_ids, context=context)
- return self.write(cr, uid, ids, {'message_follower_ids': [(4, pid) for pid in partner_ids]}, context=context)
+ if context and context.get('read_back'):
+ return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids]
+ return []
def message_unsubscribe_users(self, cr, uid, ids, user_ids=None, context=None):
""" Wrapper on message_subscribe, using users. If user_ids is not
return self.message_unsubscribe(cr, uid, ids, partner_ids, context=context)
def message_unsubscribe(self, cr, uid, ids, partner_ids, context=None):
- """ Remove partners from the records followers. """
- return self.write(cr, uid, ids, {'message_follower_ids': [(3, pid) for pid in partner_ids]}, context=context)
+ """ Remove partners from the records followers.
+ :param partner_ids: a list of partner_ids to unsubscribe
+ :param return: new value of followers if read_back key in context
+ """
+ self.write(cr, uid, ids, {'message_follower_ids': [(3, pid) for pid in partner_ids]}, context=context)
+ if context and context.get('read_back'):
+ return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids]
+ return []
#------------------------------------------------------
# Thread state
def message_subscribe_udpate_subtypes(self, cr, uid, ids, user_id, subtype_ids,context=None):
followers_obj = self.pool.get('mail.followers')
followers_ids = followers_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)], context=context)
- return followers_obj.write(cr, uid, followers_ids, {'subtype_ids': [(6, 0 , subtype_ids)]}, context = context) #overright or add new one
+ return followers_obj.write(cr, uid, followers_ids, {'subtype_ids': [(6, 0 , subtype_ids)]}, context = context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
},
start: function() {
- // use actual_mode property on view to know if the view is in create mode anymore
+ var self = this;
+ // NB: all the widget should be modified to check the actual_mode property on view, not use
+ // any other method to know if the view is in create mode anymore
this.view.on("change:actual_mode", this, this._check_visibility);
this._check_visibility();
this.fetch_subtype();
+ this.$el.find('ul.oe_mail_recthread_subtype').click(function () {self.update_subtype();})
+ this.$el.find('button.oe_mail_button_follow').click(function () { self.do_follow(); self.fetch_subtype();})
+ .mouseover(function () { $(this).html('Follow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); })
+ .mouseleave(function () { $(this).html('Not following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); });
+ this.$el.find('button.oe_mail_button_unfollow').click(function () { self.do_unfollow(); })
+ .mouseover(function () { $(this).html('Unfollow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); })
+ .mouseleave(function () { $(this).html('Following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); });
this.reinit();
- this.bind_events();
},
_check_visibility: function() {
if (this.view.get("actual_mode") !== "create"){this.fetch_subtype();}
},
+ destroy: function () {
+ this._super.apply(this, arguments);
+ },
+
reinit: function() {
this.$el.find('button.oe_mail_button_follow').hide();
this.$el.find('button.oe_mail_button_unfollow').hide();
- },
-
- bind_events: function() {
- var self = this;
- this.$('button.oe_mail_button_unfollow').on('click', function () { self.do_unfollow(); })
- .mouseover(function () { $(this).html('Unfollow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); })
- .mouseleave(function () { $(this).html('Following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); });
- this.$el.on('click', 'button.oe_mail_button_follow', function () { self.do_follow(); self.fetch_subtype(); });
- this.$el.on('click','ul.oe_mail_recthread_subtype', function () {self.update_subtype();})
- this.$el.on('click', 'button.oe_mail_button_invite', function(event) {
- action = {
- type: 'ir.actions.act_window',
- res_model: 'mail.wizard.invite',
- view_mode: 'form',
- view_type: 'form',
- views: [[false, 'form']],
- target: 'new',
- context: {
- 'default_res_model': self.view.dataset.model,
- 'default_res_id': self.view.datarecord.id
- },
- }
- self.do_action(action, function() { self.read_value(); });
- });
- },
-
- read_value: function() {
- var self = this;
- return this.ds_model.read_ids([this.view.datarecord.id], ['message_follower_ids']).pipe(function (results) {
- return results[0].message_follower_ids;
- }).pipe(this.proxy('set_value'));
+ // this.$el.find('ul.oe_mail_recthread_subtype').hide()
},
set_value: function(value_) {
this.$el.find('div.oe_mail_recthread_aside').hide();
return;
}
- return this.fetch_followers(value_ || this.get_value());
+ return this.fetch_followers(value_);
},
fetch_followers: function (value_) {
- return this.ds_follow.call('read', [value_, ['name', 'user_ids']]).pipe(this.proxy('display_followers'));
+ return this.ds_follow.call('read', [value_ || this.get_value(), ['name', 'user_ids']]).then(this.proxy('display_followers'));
},
/** Display the followers, evaluate is_follower directly */
var node_user_list = this.$el.find('ul.oe_mail_followers_display').empty();
this.$el.find('div.oe_mail_recthread_followers h4').html(this.options.title + ' (' + records.length + ')');
_(records).each(function (record) {
- record.avatar_url = mail.ChatterUtils.get_image(self.session, 'res.partner', 'image_small', record.id);
+ record.avatar_url = mail.ChatterUtils.get_image(self.session.prefix, self.session.session_id, 'res.partner', 'image_small', record.id);
$(session.web.qweb.render('mail.followers.partner', {'record': record})).appendTo(node_user_list);
});
if (this.message_is_follower) {
},
do_follow: function () {
- var context = new session.web.CompoundContext(this.build_context(), {});
- return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('read_value'));
+ var context = new session.web.CompoundContext(this.build_context(), {'read_back': true});
+ return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('set_value'));
},
//fetch subtype from subtype model
fetch_subtype: function () {
var self = this
- var subtype_object = this.sub_model.call('search', [[['model_ids.model','=',this.view.model]]]);
+ var subtype_object = this.sub_model.call('search', [[['res_model','=',this.view.model]]]);
subtype_object.then(function (subtype_ids){
self.sub_model.call('read', [subtype_ids || self.get_value(),['name', 'default']]).then(self.proxy('display_subtype'));
});
},
do_unfollow: function () {
- var context = new session.web.CompoundContext(this.build_context(), {});
- return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('read_value'));
+ var context = new session.web.CompoundContext(this.build_context(), {'read_back': true});
+ return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('set_value'));
},
});
};
#
##############################################################################
-import tools
-
from openerp.tests import common
from openerp.tools.html_sanitize import html_sanitize
From: Sylvie Lelitre <sylvie.lelitre@agrolait.com>
Subject: {subject}
MIME-Version: 1.0
-Content-Type: multipart/alternative;
+Content-Type: multipart/alternative;
boundary="----=_Part_4200734_24778174.1344608186754"
Date: Fri, 10 Aug 2012 14:16:26 +0000
Message-ID: <1198923581.41972151344608186760.JavaMail@agrolait.com>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8" />
</head>=20
<body style=3D"margin: 0; padding: 0; background: #ffffff;-webkit-text-size-adjust: 100%;">=20
-
+
<p>Please call me as soon as possible this afternoon!</p>
-
+
<p>--<br/>
Sylvie
<p>
"""
-class TestMailMockups(common.TransactionCase):
+class test_mail(common.TransactionCase):
def _mock_smtp_gateway(self, *args, **kwargs):
return True
- def _init_mock_build_email(self):
- self._build_email_args_list = []
- self._build_email_kwargs_list = []
-
def _mock_build_email(self, *args, **kwargs):
- self._build_email_args_list.append(args)
- self._build_email_kwargs_list.append(kwargs)
- return self._build_email(*args, **kwargs)
-
- def setUp(self):
- super(TestMailMockups, self).setUp()
- # Install mock SMTP gateway
- self._init_mock_build_email()
- self._build_email = self.registry('ir.mail_server').build_email
- self.registry('ir.mail_server').build_email = self._mock_build_email
- self._send_email = self.registry('ir.mail_server').send_email
- self.registry('ir.mail_server').send_email = self._mock_smtp_gateway
-
- def tearDown(self):
- # Remove mocks
- self.registry('ir.mail_server').build_email = self._build_email
- self.registry('ir.mail_server').send_email = self._send_email
- super(TestMailMockups, self).tearDown()
-
-
-class test_mail(TestMailMockups):
-
- def _mock_send_get_mail_body(self, *args, **kwargs):
- # def _send_get_mail_body(self, cr, uid, mail, partner=None, context=None)
- body = tools.append_content_to_html(args[2].body_html, kwargs.get('partner').name if kwargs.get('partner') else 'No specific partner')
- return body
+ self._build_email_args = args
+ self._build_email_kwargs = kwargs
+ return self.build_email_real(*args, **kwargs)
def setUp(self):
super(test_mail, self).setUp()
self.res_users = self.registry('res.users')
self.res_partner = self.registry('res.partner')
- # Mock send_get_mail_body to test its functionality without other addons override
- self._send_get_mail_body = self.registry('mail.mail').send_get_mail_body
- self.registry('mail.mail').send_get_mail_body = self._mock_send_get_mail_body
+ # Install mock SMTP gateway
+ self.build_email_real = self.registry('ir.mail_server').build_email
+ self.registry('ir.mail_server').build_email = self._mock_build_email
+ self.registry('ir.mail_server').send_email = self._mock_smtp_gateway
# groups@.. will cause the creation of new mail groups
self.mail_group_model_id = self.ir_model.search(self.cr, self.uid, [('model', '=', 'mail.group')])[0]
self.group_pigs_id = self.mail_group.create(self.cr, self.uid,
{'name': 'Pigs', 'description': 'Fans of Pigs, unite !'})
- def tearDown(self):
- # Remove mocks
- self.registry('mail.mail').send_get_mail_body = self._send_get_mail_body
- super(test_mail, self).tearDown()
-
def test_00_message_process(self):
cr, uid = self.cr, self.uid
# Incoming mail creates a new mail_group "frogs"
test_msg_id = '<deadcafe.1337@smtp.agrolait.com>'
mail_text = MAIL_TEMPLATE_PLAINTEXT.format(to='groups@example.com', subject='frogs', extra='', msg_id=test_msg_id)
self.mail_thread.message_process(cr, uid, None, mail_text)
- new_mail = self.mail_message.browse(cr, uid, self.mail_message.search(cr, uid, [('message_id', '=', test_msg_id)])[0])
+ new_mail = self.mail_message.browse(cr, uid, self.mail_message.search(cr, uid, [('message_id','=',test_msg_id)])[0])
self.assertEqual(new_mail.body, '\n<pre>\nPlease call me as soon as possible this afternoon!\n\n--\nSylvie\n</pre>\n',
'plaintext mail incorrectly parsed')
_attachments = [('First', 'My first attachment'), ('Second', 'My second attachment')]
# CASE1: post comment, body and subject specified
- self._init_mock_build_email()
msg_id = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body1, subject=_subject, type='comment')
message = self.mail_message.browse(cr, uid, msg_id)
- sent_emails = self._build_email_kwargs_list
+ sent_email = self._build_email_kwargs
# Test: notifications have been deleted
self.assertFalse(self.mail_mail.search(cr, uid, [('mail_message_id', '=', msg_id)]), 'mail.mail notifications should have been auto-deleted!')
# Test: mail_message: subject is _subject, body is _body1 (no formatting done)
self.assertEqual(message.subject, _subject, 'mail.message subject incorrect')
self.assertEqual(message.body, _body1, 'mail.message body incorrect')
- # Test: sent_email: email send by server: correct subject, body, body_alternative
- for sent_email in sent_emails:
- self.assertEqual(sent_email['subject'], _subject, 'sent_email subject incorrect')
- self.assertEqual(sent_email['body'], _mail_body1 + '\n<pre>Bert Tartopoils</pre>\n', 'sent_email body incorrect')
- self.assertEqual(sent_email['body_alternative'], _mail_bodyalt1 + '\nBert Tartopoils', 'sent_email body_alternative is incorrect')
+ # Test: sent_email: email send by server: correct subject, body; body_alternative
+ self.assertEqual(sent_email['subject'], _subject, 'sent_email subject incorrect')
+ self.assertEqual(sent_email['body'], _mail_body1, 'sent_email body incorrect')
+ self.assertEqual(sent_email['body_alternative'], _mail_bodyalt1, 'sent_email body_alternative is incorrect')
# Test: mail_message: partner_ids = group followers
message_pids = set([partner.id for partner in message.partner_ids])
test_pids = set([p_a_id, p_b_id, p_c_id])
notif_pids = set([notif.partner_id.id for notif in self.mail_notification.browse(cr, uid, notif_ids)])
self.assertEqual(notif_pids, test_pids, 'mail.message notification partners incorrect')
# Test: sent_email: email_to should contain b@b, not c@c (pref email), not a@a (writer)
- for sent_email in sent_emails:
- self.assertEqual(sent_email['email_to'], ['b@b'], 'sent_email email_to is incorrect')
+ self.assertEqual(sent_email['email_to'], ['b@b'], 'sent_email email_to is incorrect')
# CASE2: post an email with attachments, parent_id, partner_ids
# TESTS: automatic subject, signature in body_html, attachments propagation
- self._init_mock_build_email()
msg_id2 = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body2, type='email',
partner_ids=[(6, 0, [p_d_id])], parent_id=msg_id, attachments=_attachments)
message = self.mail_message.browse(cr, uid, msg_id2)
- sent_emails = self._build_email_kwargs_list
+ sent_email = self._build_email_kwargs
self.assertFalse(self.mail_mail.search(cr, uid, [('mail_message_id', '=', msg_id2)]), 'mail.mail notifications should have been auto-deleted!')
# Test: mail_message: subject is False, body is _body2 (no formatting done), parent_id is msg_id
self.assertEqual(message.body, html_sanitize(_body2), 'mail.message body incorrect')
self.assertEqual(message.parent_id.id, msg_id, 'mail.message parent_id incorrect')
# Test: sent_email: email send by server: correct subject, body, body_alternative
- self.assertEqual(len(sent_emails), 2, 'sent_email number of sent emails incorrect')
- for sent_email in sent_emails:
- self.assertEqual(sent_email['subject'], _mail_subject, 'sent_email subject incorrect')
- self.assertIn(_mail_body2, sent_email['body'], 'sent_email body incorrect')
- self.assertIn(_mail_bodyalt2, sent_email['body_alternative'], 'sent_email body_alternative incorrect')
+ self.assertEqual(sent_email['subject'], _mail_subject, 'sent_email subject incorrect')
+ self.assertEqual(sent_email['body'], _mail_body2, 'sent_email body incorrect')
+ self.assertEqual(sent_email['body_alternative'], _mail_bodyalt2, 'sent_email body_alternative incorrect')
# Test: mail_message: partner_ids = group followers
message_pids = set([partner.id for partner in message.partner_ids])
test_pids = set([p_a_id, p_b_id, p_c_id, p_d_id])
notif_pids = set([notif.partner_id.id for notif in self.mail_notification.browse(cr, uid, notif_ids)])
self.assertEqual(notif_pids, test_pids, 'mail.message notification partners incorrect')
# Test: sent_email: email_to should contain b@b, c@c, not a@a (writer)
- for sent_email in sent_emails:
- self.assertTrue(set(sent_email['email_to']).issubset(set(['b@b', 'c@c'])), 'sent_email email_to incorrect')
+ self.assertEqual(set(sent_email['email_to']), set(['b@b', 'c@c']), 'sent_email email_to incorrect')
# Test: attachments
for attach in message.attachment_ids:
self.assertEqual(attach.res_model, 'mail.group', 'mail.message attachment res_model incorrect')
self.assertEqual(compose.content_subtype, 'html', 'mail.compose.message incorrect content_subtype')
# 2. Post the comment, get created message
- parent_id = message.id
mail_compose.send_mail(cr, uid, [compose_id])
group_pigs.refresh()
message = group_pigs.message_ids[0]
- # Test: mail.message: subject as Re:.., body in html, parent_id
+ # Test: mail.message: subject as Re:.., body in html
self.assertEqual(message.subject, _msg_reply, 'mail.message incorrect subject')
self.assertIn('Administrator wrote:<blockquote><pre>Pigs rules</pre></blockquote></div>', message.body, 'mail.message body is incorrect')
- self.assertEqual(message.parent_id and message.parent_id.id, parent_id, 'mail.message parent_id incorrect')
# Test: mail.message: attachments
for attach in message.attachment_ids:
self.assertEqual(attach.res_model, 'mail.group', 'mail.message attachment res_model incorrect')
# It will be updated as soon as we have fixed specs !
cr, uid = self.cr, self.uid
group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
-
def _compare_structures(struct1, struct2, n=0):
# print '%scompare structure' % ('\t' * n)
self.assertEqual(len(struct1), len(struct2), 'message_read structure number of childs incorrect')
_mail_bodyalt2 = 'Pigs rules\nAdmin\n'
filter_subtype_id = self.mail_message_subtype.search(cr, uid, [('default','=',True)])
# Post comment with body and subject, comment preference
- msg_id = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body1, subject=_subject, type='comment',subtype='email')
+ msg_id = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body1, subject=_subject, type='comment',subtype_xml_id='mail_subtype_comment')
notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', msg_id)])
self.assertTrue(len(notif_ids) >= 1,"subtype is email and show notification on wall")
# New post: test automatic subject, signature in html, add a partner, email preference, parent_id previous message
- msg_id2 = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body2,subject=_subject, type='email', subtype='other')
- notif_ids2 = self.mail_notification.search(cr, uid, [('message_id', '=', msg_id2)])
- self.assertTrue(len(notif_ids2) == 0,"subtype is false cannot show notification on wall")
+# msg_id2 = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body2,subject=_subject, type='email', subtype='other')
+# notif_ids2 = self.mail_notification.search(cr, uid, [('message_id', '=', msg_id2)])
+# self.assertTrue(len(notif_ids2) == 0,"subtype is false cannot show notification on wall")