summaryrefslogtreecommitdiff
path: root/addons/mail
diff options
context:
space:
mode:
authorRaphael Collet <rco@openerp.com>2014-07-06 16:44:26 +0200
committerAntony Lesuisse <al@openerp.com>2014-07-06 17:05:41 +0200
commitcbe2dbb672a6c55d86f2e515f9d1cdfee426ef80 (patch)
treed6ff62b719fce32392397783c961b734b1e4c50e /addons/mail
parentd78192c489d3be66cd6487b39f5ce7ba4733a187 (diff)
[MERGE] new v8 api by rco
A squashed merge is required as the conversion of the apiculture branch from bzr to git was not correctly done. The git history contains irrelevant blobs and commits. This branch brings a lot of changes and fixes, too many to list exhaustively. - New orm api, objects are now used instead of ids - Environements to encapsulates cr uid context while maintaining backward compatibility - Field compute attribute is a new object oriented way to define function fields - Shared browse record cache - New onchange protocol - Optional copy flag on fields - Documentation update - Dead code cleanup - Lots of fixes
Diffstat (limited to 'addons/mail')
-rw-r--r--addons/mail/mail_followers.py31
-rw-r--r--addons/mail/mail_group.py11
-rw-r--r--addons/mail/mail_group_menu.py2
-rw-r--r--addons/mail/mail_mail.py13
-rw-r--r--addons/mail/mail_message.py45
-rw-r--r--addons/mail/mail_thread.py32
-rw-r--r--addons/mail/res_users.py2
-rw-r--r--addons/mail/static/scripts/__init__.py22
-rwxr-xr-xaddons/mail/static/scripts/openerp_mailgate.py8
-rw-r--r--addons/mail/static/scripts/openerp_mailgate/__init__.py22
-rw-r--r--addons/mail/static/src/js/mail_followers.js4
-rw-r--r--addons/mail/tests/common.py30
-rw-r--r--addons/mail/tests/test_mail_features.py14
-rw-r--r--addons/mail/tests/test_mail_gateway.py12
-rw-r--r--addons/mail/tests/test_mail_group.py2
-rw-r--r--addons/mail/tests/test_mail_message.py61
-rw-r--r--addons/mail/tests/test_message_read.py2
-rw-r--r--addons/mail/update.py2
-rw-r--r--addons/mail/wizard/mail_compose_message.py3
19 files changed, 141 insertions, 177 deletions
diff --git a/addons/mail/mail_followers.py b/addons/mail/mail_followers.py
index 2045353b0e5..42238e75553 100644
--- a/addons/mail/mail_followers.py
+++ b/addons/mail/mail_followers.py
@@ -48,6 +48,25 @@ class mail_followers(osv.Model):
help="Message subtypes followed, meaning subtypes that will be pushed onto the user's Wall."),
}
+ #
+ # Modifying followers change access rights to individual documents. As the
+ # cache may contain accessible/inaccessible data, one has to refresh it.
+ #
+ def create(self, cr, uid, vals, context=None):
+ res = super(mail_followers, self).create(cr, uid, vals, context=context)
+ self.invalidate_cache(cr, uid, context=context)
+ return res
+
+ def write(self, cr, uid, ids, vals, context=None):
+ res = super(mail_followers, self).write(cr, uid, ids, vals, context=context)
+ self.invalidate_cache(cr, uid, context=context)
+ return res
+
+ def unlink(self, cr, uid, ids, context=None):
+ res = super(mail_followers, self).unlink(cr, uid, ids, context=context)
+ self.invalidate_cache(cr, uid, context=context)
+ return res
+
class mail_notification(osv.Model):
""" Class holding notifications pushed to partners. Followers and partners
@@ -60,7 +79,7 @@ class mail_notification(osv.Model):
_columns = {
'partner_id': fields.many2one('res.partner', string='Contact',
ondelete='cascade', required=True, select=1),
- 'read': fields.boolean('Read', select=1),
+ 'is_read': fields.boolean('Read', select=1),
'starred': fields.boolean('Starred', select=1,
help='Starred message that goes into the todo mailbox'),
'message_id': fields.many2one('mail.message', string='Message',
@@ -68,14 +87,14 @@ class mail_notification(osv.Model):
}
_defaults = {
- 'read': False,
+ 'is_read': False,
'starred': False,
}
def init(self, cr):
cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('mail_notification_partner_id_read_starred_message_id',))
if not cr.fetchone():
- cr.execute('CREATE INDEX mail_notification_partner_id_read_starred_message_id ON mail_notification (partner_id, read, starred, message_id)')
+ cr.execute('CREATE INDEX mail_notification_partner_id_read_starred_message_id ON mail_notification (partner_id, is_read, starred, message_id)')
def get_partners_to_email(self, cr, uid, ids, message, context=None):
""" Return the list of partners to notify, based on their preferences.
@@ -86,7 +105,7 @@ class mail_notification(osv.Model):
"""
notify_pids = []
for notification in self.browse(cr, uid, ids, context=context):
- if notification.read:
+ if notification.is_read:
continue
partner = notification.partner_id
# Do not send to partners without email address defined
@@ -148,12 +167,12 @@ class mail_notification(osv.Model):
existing_pids.add(notification.partner_id.id)
# update existing notifications
- self.write(cr, uid, ids, {'read': False}, context=context)
+ self.write(cr, uid, ids, {'is_read': False}, context=context)
# create new notifications
new_pids = set(partner_ids) - existing_pids
for new_pid in new_pids:
- new_notif_ids.append(self.create(cr, uid, {'message_id': message_id, 'partner_id': new_pid, 'read': False}, context=context))
+ new_notif_ids.append(self.create(cr, uid, {'message_id': message_id, 'partner_id': new_pid, 'is_read': False}, context=context))
return new_notif_ids
def _notify_email(self, cr, uid, ids, message_id, force_send=False, user_signature=True, context=None):
diff --git a/addons/mail/mail_group.py b/addons/mail/mail_group.py
index 9881e6422c6..eaca5c1182e 100644
--- a/addons/mail/mail_group.py
+++ b/addons/mail/mail_group.py
@@ -37,7 +37,7 @@ class mail_group(osv.Model):
_inherits = {'mail.alias': 'alias_id'}
def _get_image(self, cr, uid, ids, name, args, context=None):
- result = dict.fromkeys(ids, False)
+ result = {}
for obj in self.browse(cr, uid, ids, context=context):
result[obj.id] = tools.image_get_resized_images(obj.image)
return result
@@ -163,15 +163,14 @@ class mail_group(osv.Model):
def unlink(self, cr, uid, ids, context=None):
groups = self.browse(cr, uid, ids, context=context)
- # Cascade-delete mail aliases as well, as they should not exist without the mail group.
- mail_alias = self.pool.get('mail.alias')
alias_ids = [group.alias_id.id for group in groups if group.alias_id]
+ menu_ids = [group.menu_id.id for group in groups if group.menu_id]
# Delete mail_group
res = super(mail_group, self).unlink(cr, uid, ids, context=context)
- # Delete alias
- mail_alias.unlink(cr, SUPERUSER_ID, alias_ids, context=context)
+ # Cascade-delete mail aliases as well, as they should not exist without the mail group.
+ self.pool.get('mail.alias').unlink(cr, SUPERUSER_ID, alias_ids, context=context)
# Cascade-delete menu entries as well
- self.pool.get('ir.ui.menu').unlink(cr, SUPERUSER_ID, [group.menu_id.id for group in groups if group.menu_id], context=context)
+ self.pool.get('ir.ui.menu').unlink(cr, SUPERUSER_ID, menu_ids, context=context)
return res
def write(self, cr, uid, ids, vals, context=None):
diff --git a/addons/mail/mail_group_menu.py b/addons/mail/mail_group_menu.py
index 56d4b5dd564..3e849e62ac5 100644
--- a/addons/mail/mail_group_menu.py
+++ b/addons/mail/mail_group_menu.py
@@ -42,7 +42,7 @@ class ir_ui_menu(osv.osv):
following. Access are done using SUPERUSER_ID to avoid access
rights issues for an internal back-end algorithm. """
ids = super(ir_ui_menu, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=False)
- partner_id = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
+ partner_id = self.pool.get('res.users').read(cr, uid, [uid], ['partner_id'], context=context)[0]['partner_id'][0]
follower_obj = self.pool.get('mail.followers')
for menu in self.browse(cr, uid, ids, context=context):
if menu.mail_group_id:
diff --git a/addons/mail/mail_mail.py b/addons/mail/mail_mail.py
index 0a6a250bcaa..aeea2c0b1a5 100644
--- a/addons/mail/mail_mail.py
+++ b/addons/mail/mail_mail.py
@@ -24,7 +24,7 @@ import logging
import re
from urlparse import urljoin
-from openerp import tools
+from openerp import api, tools
from openerp import SUPERUSER_ID
from openerp.addons.base.ir.ir_mail_server import MailDeliveryException
from openerp.osv import fields, osv
@@ -51,7 +51,7 @@ class mail_mail(osv.Model):
('received', 'Received'),
('exception', 'Delivery Failed'),
('cancel', 'Cancelled'),
- ], 'Status', readonly=True),
+ ], 'Status', readonly=True, copy=False),
'auto_delete': fields.boolean('Auto Delete',
help="Permanently delete this email after sending it, to save space"),
'references': fields.text('References', help='Message references, such as identifiers of previous messages', readonly=1),
@@ -59,7 +59,7 @@ class mail_mail(osv.Model):
'recipient_ids': fields.many2many('res.partner', string='To (Partners)'),
'email_cc': fields.char('Cc', help='Carbon copy message recipients'),
'body_html': fields.text('Rich-text Contents', help="Rich-text/HTML message"),
- 'headers': fields.text('Headers'),
+ 'headers': fields.text('Headers', copy=False),
# Auto-detected based on create() - if 'mail_message_id' was passed then this mail is a notification
# and during unlink() we will not cascade delete the parent and its attachments
'notification': fields.boolean('Is Notification',
@@ -98,6 +98,7 @@ class mail_mail(osv.Model):
def cancel(self, cr, uid, ids, context=None):
return self.write(cr, uid, ids, {'state': 'cancel'}, context=context)
+ @api.cr_uid
def process_email_queue(self, cr, uid, ids=None, context=None):
"""Send immediately queued messages, committing after each
message is sent - this is not transactional and should
@@ -226,8 +227,7 @@ class mail_mail(osv.Model):
email sending process has failed
:return: True
"""
- if context is None:
- context = {}
+ context = dict(context or {})
ir_mail_server = self.pool.get('ir.mail_server')
ir_attachment = self.pool['ir.attachment']
for mail in self.browse(cr, SUPERUSER_ID, ids, context=context):
@@ -301,8 +301,9 @@ class mail_mail(osv.Model):
# /!\ can't use mail.state here, as mail.refresh() will cause an error
# see revid:odo@openerp.com-20120622152536-42b2s28lvdv3odyr in 6.1
+ if mail_sent:
+ _logger.info('Mail with ID %r and Message-Id %r successfully sent', mail.id, mail.message_id)
self._postprocess_sent_message(cr, uid, mail, context=context, mail_sent=mail_sent)
- _logger.info('Mail with ID %r and Message-Id %r successfully sent', mail.id, mail.message_id)
except MemoryError:
# prevent catching transient MemoryErrors, bubble up to notify user or abort cron job
# instead of marking the mail as failed
diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py
index 42aaef80703..d11495289f7 100644
--- a/addons/mail/mail_message.py
+++ b/addons/mail/mail_message.py
@@ -24,7 +24,7 @@ import logging
from openerp import tools
from email.header import decode_header
-from openerp import SUPERUSER_ID
+from openerp import SUPERUSER_ID, api
from openerp.osv import osv, orm, fields
from openerp.tools import html_email_clean
from openerp.tools.translate import _
@@ -88,7 +88,7 @@ class mail_message(osv.Model):
notif_ids = notif_obj.search(cr, uid, [
('partner_id', 'in', [partner_id]),
('message_id', 'in', ids),
- ('read', '=', False),
+ ('is_read', '=', False),
], context=context)
for notif in notif_obj.browse(cr, uid, notif_ids, context=context):
res[notif.message_id.id] = True
@@ -96,8 +96,8 @@ class mail_message(osv.Model):
def _search_to_read(self, cr, uid, obj, name, domain, context=None):
""" Search for messages to read by the current user. Condition is
- inversed because we search unread message on a read column. """
- return ['&', ('notification_ids.partner_id.user_ids', 'in', [uid]), ('notification_ids.read', '=', not domain[0][2])]
+ inversed because we search unread message on a is_read column. """
+ return ['&', ('notification_ids.partner_id.user_ids', 'in', [uid]), ('notification_ids.is_read', '=', not domain[0][2])]
def _get_starred(self, cr, uid, ids, name, arg, context=None):
""" Compute if the message is unread by the current user. """
@@ -114,8 +114,7 @@ class mail_message(osv.Model):
return res
def _search_starred(self, cr, uid, obj, name, domain, context=None):
- """ Search for messages to read by the current user. Condition is
- inversed because we search unread message on a read column. """
+ """ Search for starred messages by the current user."""
return ['&', ('notification_ids.partner_id.user_ids', 'in', [uid]), ('notification_ids.starred', '=', domain[0][2])]
_columns = {
@@ -153,7 +152,7 @@ class mail_message(osv.Model):
help='Technical field holding the message notifications. Use notified_partner_ids to access notified partners.'),
'subject': fields.char('Subject'),
'date': fields.datetime('Date'),
- 'message_id': fields.char('Message-Id', help='Message unique identifier', select=1, readonly=1),
+ 'message_id': fields.char('Message-Id', help='Message unique identifier', select=1, readonly=1, copy=False),
'body': fields.html('Contents', help='Automatically sanitized HTML contents'),
'to_read': fields.function(_get_to_read, fnct_search=_search_to_read,
type='boolean', string='To read',
@@ -213,8 +212,9 @@ class mail_message(osv.Model):
def download_attachment(self, cr, uid, id_message, attachment_id, context=None):
""" Return the content of linked attachments. """
- message = self.browse(cr, uid, id_message, context=context)
- if attachment_id in [attachment.id for attachment in message.attachment_ids]:
+ # this will fail if you cannot read the message
+ message_values = self.read(cr, uid, [id_message], ['attachment_ids'], context=context)[0]
+ if attachment_id in message_values['attachment_ids']:
attachment = self.pool.get('ir.attachment').browse(cr, SUPERUSER_ID, attachment_id, context=context)
if attachment.datas and attachment.datas_fname:
return {
@@ -227,6 +227,7 @@ class mail_message(osv.Model):
# Notification API
#------------------------------------------------------
+ @api.cr_uid_ids_context
def set_message_read(self, cr, uid, msg_ids, read, create_missing=True, context=None):
""" Set messages as (un)read. Technically, the notifications related
to uid are set to (un)read. If for some msg_ids there are missing
@@ -243,22 +244,23 @@ class mail_message(osv.Model):
user_pid = self.pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=context).partner_id.id
domain = [('partner_id', '=', user_pid), ('message_id', 'in', msg_ids)]
if not create_missing:
- domain += [('read', '=', not read)]
+ domain += [('is_read', '=', not read)]
notif_ids = notification_obj.search(cr, uid, domain, context=context)
# all message have notifications: already set them as (un)read
if len(notif_ids) == len(msg_ids) or not create_missing:
- notification_obj.write(cr, uid, notif_ids, {'read': read}, context=context)
+ notification_obj.write(cr, uid, notif_ids, {'is_read': read}, context=context)
return len(notif_ids)
# some messages do not have notifications: find which one, create notification, update read status
notified_msg_ids = [notification.message_id.id for notification in notification_obj.browse(cr, uid, notif_ids, context=context)]
to_create_msg_ids = list(set(msg_ids) - set(notified_msg_ids))
for msg_id in to_create_msg_ids:
- notification_obj.create(cr, uid, {'partner_id': user_pid, 'read': read, 'message_id': msg_id}, context=context)
- notification_obj.write(cr, uid, notif_ids, {'read': read}, context=context)
+ notification_obj.create(cr, uid, {'partner_id': user_pid, 'is_read': read, 'message_id': msg_id}, context=context)
+ notification_obj.write(cr, uid, notif_ids, {'is_read': read}, context=context)
return len(notif_ids)
+ @api.cr_uid_ids_context
def set_message_starred(self, cr, uid, msg_ids, starred, create_missing=True, context=None):
""" Set messages as (un)starred. Technically, the notifications related
to uid are set to (un)starred.
@@ -276,7 +278,7 @@ class mail_message(osv.Model):
'starred': starred
}
if starred:
- values['read'] = False
+ values['is_read'] = False
notif_ids = notification_obj.search(cr, uid, domain, context=context)
@@ -502,6 +504,7 @@ class mail_message(osv.Model):
return True
+ @api.cr_uid_context
def message_read(self, cr, uid, ids=None, domain=None, message_unload_ids=None,
thread_level=0, context=None, parent_id=False, limit=None):
""" Read messages from mail.message, and get back a list of structured
@@ -671,7 +674,7 @@ class mail_message(osv.Model):
- uid has write or create access on the related document if model, res_id
- otherwise: raise
"""
- def _generate_model_record_ids(msg_val, msg_ids=[]):
+ def _generate_model_record_ids(msg_val, msg_ids):
""" :param model_record_ids: {'model': {'res_id': (msg_id, msg_id)}, ... }
:param message_values: {'msg_id': {'model': .., 'res_id': .., 'author_id': ..}}
"""
@@ -782,8 +785,7 @@ class mail_message(osv.Model):
return message_id
def create(self, cr, uid, values, context=None):
- if context is None:
- context = {}
+ context = dict(context or {})
default_starred = context.pop('default_starred', False)
if 'email_from' not in values: # needed to compute reply_to
@@ -830,13 +832,6 @@ class mail_message(osv.Model):
self.pool.get('ir.attachment').unlink(cr, uid, attachments_to_delete, context=context)
return super(mail_message, self).unlink(cr, uid, ids, context=context)
- def copy(self, cr, uid, id, default=None, context=None):
- """ Overridden to avoid duplicating fields that are unique to each email """
- if default is None:
- default = {}
- default.update(message_id=False, headers=False)
- return super(mail_message, self).copy(cr, uid, id, default=default, context=context)
-
#------------------------------------------------------
# Messaging API
#------------------------------------------------------
@@ -888,5 +883,5 @@ class mail_message(osv.Model):
notification_obj.create(cr, uid, {
'message_id': message.parent_id.id,
'partner_id': partner.id,
- 'read': True,
+ 'is_read': True,
}, context=context)
diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py
index 54f2b8d8f8b..ca040597240 100644
--- a/addons/mail/mail_thread.py
+++ b/addons/mail/mail_thread.py
@@ -39,11 +39,11 @@ import re
from email.message import Message
from urllib import urlencode
-from openerp import tools
+from openerp import api, tools
from openerp import SUPERUSER_ID
from openerp.addons.mail.mail_message import decode
from openerp.osv import fields, osv, orm
-from openerp.osv.orm import browse_record, browse_null
+from openerp.osv.orm import BaseModel
from openerp.tools.safe_eval import safe_eval as eval
from openerp.tools.translate import _
@@ -154,12 +154,12 @@ class mail_thread(osv.AbstractModel):
- message_unread: has uid unread message for the document
- message_summary: html snippet summarizing the Chatter for kanban views """
res = dict((id, dict(message_unread=False, message_unread_count=0, message_summary=' ')) for id in ids)
- user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
+ user_pid = self.pool.get('res.users').read(cr, uid, [uid], ['partner_id'], context=context)[0]['partner_id'][0]
# search for unread messages, directly in SQL to improve performances
cr.execute(""" SELECT m.res_id FROM mail_message m
RIGHT JOIN mail_notification n
- ON (n.message_id = m.id AND n.partner_id = %s AND (n.read = False or n.read IS NULL))
+ ON (n.message_id = m.id AND n.partner_id = %s AND (n.is_read = False or n.is_read IS NULL))
WHERE m.model = %s AND m.res_id in %s""",
(user_pid, self._name, tuple(ids),))
for result in cr.fetchall():
@@ -192,7 +192,7 @@ class mail_thread(osv.AbstractModel):
available, which are followed if any """
res = dict((id, dict(message_subtype_data='')) for id in ids)
if user_pid is None:
- user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
+ user_pid = self.pool.get('res.users').read(cr, uid, [uid], ['partner_id'], context=context)[0]['partner_id'][0]
# find current model subtypes, add them to a dictionary
subtype_obj = self.pool.get('mail.message.subtype')
@@ -232,7 +232,7 @@ class mail_thread(osv.AbstractModel):
fol_obj = self.pool.get('mail.followers')
fol_ids = fol_obj.search(cr, SUPERUSER_ID, [('res_model', '=', self._name), ('res_id', 'in', ids)])
res = dict((id, dict(message_follower_ids=[], message_is_follower=False)) for id in ids)
- user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
+ user_pid = self.pool.get('res.users').read(cr, uid, [uid], ['partner_id'], context=context)[0]['partner_id'][0]
for fol in fol_obj.browse(cr, SUPERUSER_ID, fol_ids):
res[fol.res_id]['message_follower_ids'].append(fol.partner_id.id)
if fol.partner_id.id == user_pid:
@@ -448,10 +448,6 @@ class mail_thread(osv.AbstractModel):
def copy_data(self, cr, uid, id, default=None, context=None):
# avoid tracking multiple temporary changes during copy
context = dict(context or {}, mail_notrack=True)
-
- default = default or {}
- default['message_ids'] = []
- default['message_follower_ids'] = []
return super(mail_thread, self).copy_data(cr, uid, id, default=default, context=context)
#------------------------------------------------------
@@ -621,7 +617,7 @@ class mail_thread(osv.AbstractModel):
# default action is the Inbox action
self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context)
act_model, act_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, *self._get_inbox_action_xml_id(cr, uid, context=context))
- action = self.pool.get(act_model).read(cr, uid, act_id, [])
+ action = self.pool.get(act_model).read(cr, uid, [act_id], [])[0]
params = context.get('params')
msg_id = model = res_id = None
@@ -1059,11 +1055,12 @@ class mail_thread(osv.AbstractModel):
def message_route_process(self, cr, uid, message, message_dict, routes, context=None):
# postpone setting message_dict.partner_ids after message_post, to avoid double notifications
+ context = dict(context or {})
partner_ids = message_dict.pop('partner_ids', [])
thread_id = False
for model, thread_id, custom_values, user_id, alias in routes:
if self._name == 'mail.thread':
- context.update({'thread_model': model})
+ context['thread_model'] = model
if model:
model_pool = self.pool[model]
if not (thread_id and hasattr(model_pool, 'message_update') or hasattr(model_pool, 'message_new')):
@@ -1508,6 +1505,7 @@ class mail_thread(osv.AbstractModel):
m2m_attachment_ids.append((0, 0, data_attach))
return m2m_attachment_ids
+ @api.cr_uid_ids_context
def message_post(self, cr, uid, thread_id, body='', subject=None, type='notification',
subtype=None, parent_id=False, attachments=None, context=None,
content_subtype='html', **kwargs):
@@ -1807,10 +1805,8 @@ class mail_thread(osv.AbstractModel):
record = self.browse(cr, uid, ids[0], context=context)
for updated_field in updated_fields:
field_value = getattr(record, updated_field)
- if isinstance(field_value, browse_record):
+ if isinstance(field_value, BaseModel):
field_value = field_value.id
- elif isinstance(field_value, browse_null):
- field_value = False
values[updated_field] = field_value
# find followers of headers, update structure for new followers
@@ -1870,11 +1866,12 @@ class mail_thread(osv.AbstractModel):
partner_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).partner_id.id
cr.execute('''
UPDATE mail_notification SET
- read=false
+ is_read=false
WHERE
message_id IN (SELECT id from mail_message where res_id=any(%s) and model=%s limit 1) and
partner_id = %s
''', (ids, self._name, partner_id))
+ self.pool.get('mail.notification').invalidate_cache(cr, uid, ['is_read'], context=context)
return True
def message_mark_as_read(self, cr, uid, ids, context=None):
@@ -1882,11 +1879,12 @@ class mail_thread(osv.AbstractModel):
partner_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).partner_id.id
cr.execute('''
UPDATE mail_notification SET
- read=true
+ is_read=true
WHERE
message_id IN (SELECT id FROM mail_message WHERE res_id=ANY(%s) AND model=%s) AND
partner_id = %s
''', (ids, self._name, partner_id))
+ self.pool.get('mail.notification').invalidate_cache(cr, uid, ['is_read'], context=context)
return True
#------------------------------------------------------
diff --git a/addons/mail/res_users.py b/addons/mail/res_users.py
index e218ea85927..a4b4e68942b 100644
--- a/addons/mail/res_users.py
+++ b/addons/mail/res_users.py
@@ -39,7 +39,7 @@ class res_users(osv.Model):
_columns = {
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True,
help="Email address internally associated with this user. Incoming "\
- "emails will appear in the user's notifications."),
+ "emails will appear in the user's notifications.", copy=False),
'display_groups_suggestions': fields.boolean("Display Groups Suggestions"),
}
diff --git a/addons/mail/static/scripts/__init__.py b/addons/mail/static/scripts/__init__.py
deleted file mode 100644
index 3b6a8c7e4b0..00000000000
--- a/addons/mail/static/scripts/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2009-2010 OpenERP SA (<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/>.
-#
-##############################################################################
-
-import openerp_mailgate \ No newline at end of file
diff --git a/addons/mail/static/scripts/openerp_mailgate.py b/addons/mail/static/scripts/openerp_mailgate.py
index 99ebc8f770b..e3dbdf4adc0 100755
--- a/addons/mail/static/scripts/openerp_mailgate.py
+++ b/addons/mail/static/scripts/openerp_mailgate.py
@@ -30,10 +30,10 @@ import optparse
import sys
import xmlrpclib
import smtplib
-from email.MIMEMultipart import MIMEMultipart
-from email.MIMEBase import MIMEBase
-from email.MIMEText import MIMEText
-from email.Utils import COMMASPACE, formatdate
+from email.mime.multipart import MIMEMultipart
+from email.mime.base import MIMEBase
+from email.mime.text import MIMEText
+from email.utils import COMMASPACE, formatdate
from email import Encoders
class DefaultConfig(object):
diff --git a/addons/mail/static/scripts/openerp_mailgate/__init__.py b/addons/mail/static/scripts/openerp_mailgate/__init__.py
deleted file mode 100644
index de2e2bf390d..00000000000
--- a/addons/mail/static/scripts/openerp_mailgate/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2009-2010 OpenERP SA (<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/>.
-#
-##############################################################################
-
-import openerp_mailgate
diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js
index bf83fe6d7c6..bd84dac714d 100644
--- a/addons/mail/static/src/js/mail_followers.js
+++ b/addons/mail/static/src/js/mail_followers.js
@@ -172,8 +172,8 @@ openerp_mail_followers = function(session, mail) {
fetch_generic: function (error, event) {
var self = this;
event.preventDefault();
- return this.ds_users.call('read', [this.session.uid, ['partner_id']]).then(function (results) {
- var pid = results['partner_id'][0];
+ return this.ds_users.call('read', [[this.session.uid], ['partner_id']]).then(function (results) {
+ var pid = results[0]['partner_id'][0];
self.message_is_follower = (_.indexOf(self.value, pid) != -1);
}).then(self.proxy('display_generic'));
},
diff --git a/addons/mail/tests/common.py b/addons/mail/tests/common.py
index d53a8078c96..5a5c28f95d7 100644
--- a/addons/mail/tests/common.py
+++ b/addons/mail/tests/common.py
@@ -24,30 +24,28 @@ from openerp.tests import common
class TestMail(common.TransactionCase):
- def _mock_smtp_gateway(self, *args, **kwargs):
- return args[2]['Message-Id']
-
def _init_mock_build_email(self):
self._build_email_args_list = []
self._build_email_kwargs_list = []
- def _mock_build_email(self, *args, **kwargs):
- """ Mock build_email to be able to test its values. Store them into
- some internal variable for latter processing. """
- self._build_email_args_list.append(args)
- self._build_email_kwargs_list.append(kwargs)
- return self._build_email(*args, **kwargs)
-
def setUp(self):
super(TestMail, self).setUp()
cr, uid = self.cr, self.uid
# Install mock SMTP gateway
+ test = self
+
+ def build_email(self, *args, **kwargs):
+ test._build_email_args_list.append(args)
+ test._build_email_kwargs_list.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._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
+ self.registry('ir.mail_server')._patch_method('build_email', build_email)
+ self.registry('ir.mail_server')._patch_method('send_email', send_email)
# Usefull models
self.ir_model = self.registry('ir.model')
@@ -129,6 +127,6 @@ class TestMail(common.TransactionCase):
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
+ self.registry('ir.mail_server')._revert_method('build_email')
+ self.registry('ir.mail_server')._revert_method('send_email')
super(TestMail, self).tearDown()
diff --git a/addons/mail/tests/test_mail_features.py b/addons/mail/tests/test_mail_features.py
index 2bf7bb91264..fdd87bbcfab 100644
--- a/addons/mail/tests/test_mail_features.py
+++ b/addons/mail/tests/test_mail_features.py
@@ -280,7 +280,7 @@ class test_mail(TestMail):
self.assertNotIn('res_id=%s' % group_pigs.id, url,
'notification email: link based on message should not contain res_id')
- @mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm')
+ @mute_logger('openerp.addons.mail.mail_thread', 'openerp.models')
def test_12_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
@@ -654,7 +654,7 @@ class test_mail(TestMail):
{
'attachment_ids': [(0, 0, _attachments[0]), (0, 0, _attachments[1])]
}, context={
- 'default_composition_mode': 'reply',
+ 'default_composition_mode': 'comment',
'default_res_id': self.group_pigs_id,
'default_parent_id': message.id
})
@@ -772,14 +772,13 @@ class test_mail(TestMail):
def test_30_needaction(self):
""" Tests for mail.message needaction. """
cr, uid, user_admin, user_raoul, group_pigs = self.cr, self.uid, self.user_admin, self.user_raoul, self.group_pigs
- group_pigs_demo = self.mail_group.browse(cr, self.user_raoul_id, self.group_pigs_id)
na_admin_base = self.mail_message._needaction_count(cr, uid, domain=[])
na_demo_base = self.mail_message._needaction_count(cr, user_raoul.id, domain=[])
# Test: number of unread notification = needaction on mail.message
notif_ids = self.mail_notification.search(cr, uid, [
('partner_id', '=', user_admin.partner_id.id),
- ('read', '=', False)
+ ('is_read', '=', False)
])
na_count = self.mail_message._needaction_count(cr, uid, domain=[])
self.assertEqual(len(notif_ids), na_count, 'unread notifications count does not match needaction count')
@@ -787,13 +786,14 @@ class test_mail(TestMail):
# Do: post 2 message on group_pigs as admin, 3 messages as demo user
for dummy in range(2):
group_pigs.message_post(body='My Body', subtype='mt_comment')
+ raoul_pigs = group_pigs.sudo(user_raoul)
for dummy in range(3):
- group_pigs_demo.message_post(body='My Demo Body', subtype='mt_comment')
+ raoul_pigs.message_post(body='My Demo Body', subtype='mt_comment')
# Test: admin has 3 new notifications (from demo), and 3 new needaction
notif_ids = self.mail_notification.search(cr, uid, [
('partner_id', '=', user_admin.partner_id.id),
- ('read', '=', False)
+ ('is_read', '=', False)
])
self.assertEqual(len(notif_ids), na_admin_base + 3, 'Admin should have 3 new unread notifications')
na_admin = self.mail_message._needaction_count(cr, uid, domain=[])
@@ -803,7 +803,7 @@ class test_mail(TestMail):
# Test: demo has 0 new notifications (not a follower, not receiving its own messages), and 0 new needaction
notif_ids = self.mail_notification.search(cr, uid, [
('partner_id', '=', user_raoul.partner_id.id),
- ('read', '=', False)
+ ('is_read', '=', False)
])
self.assertEqual(len(notif_ids), na_demo_base + 0, 'Demo should have 0 new unread notifications')
na_demo = self.mail_message._needaction_count(cr, user_raoul.id, domain=[])
diff --git a/addons/mail/tests/test_mail_gateway.py b/addons/mail/tests/test_mail_gateway.py
index 3fbf3d40405..1b16f151cdf 100644
--- a/addons/mail/tests/test_mail_gateway.py
+++ b/addons/mail/tests/test_mail_gateway.py
@@ -164,7 +164,7 @@ class TestMailgateway(TestMail):
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')
- @mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm')
+ @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
@@ -203,8 +203,8 @@ class TestMailgateway(TestMail):
# 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.perm_read(cr, uid, [frog_group.id], details=False)
- self.assertEqual(res[0].get('create_uid'), uid,
+ 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')
# Test: one message that is the incoming email
self.assertEqual(len(frog_group.message_ids), 1,
@@ -271,8 +271,8 @@ class TestMailgateway(TestMail):
# 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.perm_read(cr, uid, [frog_group.id], details=False)
- self.assertEqual(res[0].get('create_uid'), self.user_raoul_id,
+ 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')
# Test: one message that is the incoming email
self.assertEqual(len(frog_group.message_ids), 1,
@@ -536,7 +536,7 @@ class TestMailgateway(TestMail):
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.osv.orm')
+ @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
diff --git a/addons/mail/tests/test_mail_group.py b/addons/mail/tests/test_mail_group.py
index 34c7f0c00e0..c131ce0bd0b 100644
--- a/addons/mail/tests/test_mail_group.py
+++ b/addons/mail/tests/test_mail_group.py
@@ -27,7 +27,7 @@ from openerp.tools import mute_logger
class TestMailGroup(TestMail):
- @mute_logger('openerp.addons.base.ir.ir_model', 'openerp.osv.orm')
+ @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
diff --git a/addons/mail/tests/test_mail_message.py b/addons/mail/tests/test_mail_message.py
index d4a7ae75df3..40d6786e2c9 100644
--- a/addons/mail/tests/test_mail_message.py
+++ b/addons/mail/tests/test_mail_message.py
@@ -161,7 +161,7 @@ class TestMailMessage(TestMail):
self.assertEqual(mail.reply_to, 'someone@example.com',
'mail_mail: reply_to should equal the rpely_to given to create')
- @mute_logger('openerp.addons.base.ir.ir_model', 'openerp.osv.orm')
+ @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
@@ -196,7 +196,7 @@ class TestMailMessage(TestMail):
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')
- @mute_logger('openerp.addons.base.ir.ir_model', 'openerp.osv.orm')
+ @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
@@ -218,8 +218,8 @@ class TestMailMessage(TestMail):
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
- self.assertRaises(except_orm, self.mail_message.read,
- cr, user_bert_id, message_id)
+ with self.assertRaises(except_orm):
+ 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
@@ -229,11 +229,11 @@ class TestMailMessage(TestMail):
# 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
- self.assertRaises(except_orm, self.mail_message.read,
- cr, self.user_bert_id, message_id)
+ with self.assertRaises(except_orm):
+ self.mail_message.read(cr, self.user_bert_id, message_id)
# Test: Bert downloads attachment, crash because he can't read message
- self.assertRaises(except_orm, self.mail_message.download_attachment,
- cr, user_bert_id, message_id, attachment_id)
+ with self.assertRaises(except_orm):
+ 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
@@ -241,8 +241,8 @@ class TestMailMessage(TestMail):
# 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
- self.assertRaises(except_orm, self.mail_message.read,
- cr, user_bert_id, message_id)
+ with self.assertRaises(except_orm):
+ 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})
# Test: Bert reads the message, ok because linked to a doc he is allowed to read
@@ -250,33 +250,33 @@ class TestMailMessage(TestMail):
# 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
- self.assertRaises(except_orm, self.mail_message.read,
- cr, user_bert_id, message_id)
+ with self.assertRaises(except_orm):
+ self.mail_message.read(cr, user_bert_id, message_id)
# ----------------------------------------
# CASE2: create
# ----------------------------------------
# Do: Bert creates a message on Pigs -> ko, no creation rights
- self.assertRaises(AccessError, self.mail_message.create,
- cr, user_bert_id, {'model': 'mail.group', 'res_id': self.group_pigs_id, 'body': 'Test'})
+ with self.assertRaises(AccessError):
+ self.mail_message.create(cr, user_bert_id, {'model': 'mail.group', 'res_id': self.group_pigs_id, 'body': 'Test'})
# Do: Bert create a message on Jobs -> ko, no creation rights
- self.assertRaises(AccessError, self.mail_message.create,
- cr, user_bert_id, {'model': 'mail.group', 'res_id': self.group_jobs_id, 'body': 'Test'})
+ with self.assertRaises(AccessError):
+ self.mail_message.create(cr, user_bert_id, {'model': 'mail.group', 'res_id': self.group_jobs_id, 'body': 'Test'})
# Do: Bert create a private message -> ko, no creation rights
- self.assertRaises(AccessError, self.mail_message.create,
- cr, user_bert_id, {'body': 'Test'})
+ with self.assertRaises(AccessError):
+ self.mail_message.create(cr, user_bert_id, {'body': 'Test'})
# 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'})
# Do: Raoul creates a message on Priv -> ko, no write access to the related document
- self.assertRaises(except_orm, self.mail_message.create,
- cr, user_raoul_id, {'model': 'mail.group', 'res_id': self.group_priv_id, 'body': 'Test'})
+ with self.assertRaises(except_orm):
+ 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
- self.assertRaises(except_orm, 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):
+ 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})
@@ -335,7 +335,7 @@ class TestMailMessage(TestMail):
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.read, 'mail_notification read failed')
+ self.assertTrue(notif['is_read'], 'mail_notification read failed')
self.assertFalse(msg.to_read, 'mail_message read failed')
# Do: Raoul reads msg
@@ -346,7 +346,7 @@ class TestMailMessage(TestMail):
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.read, 'mail_notification starred failed')
+ self.assertTrue(notif['is_read'], 'mail_notification starred failed')
self.assertFalse(msg_raoul.to_read, 'mail_message starred failed')
# Do: Admin unreads msg
@@ -383,7 +383,7 @@ class TestMailMessage(TestMail):
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.osv.orm')
+ @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
@@ -400,9 +400,9 @@ class TestMailMessage(TestMail):
# ----------------------------------------
# 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'])
+ 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'])['message_ids']
+ 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)
@@ -413,9 +413,8 @@ class TestMailMessage(TestMail):
with self.assertRaises(AccessError):
trigger_read = partner.name
# Do: Bert comments Jobs, ko because no creation right
- self.assertRaises(AccessError,
- self.mail_group.message_post,
- cr, user_bert_id, self.group_jobs_id, body='I love Pigs')
+ 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):
@@ -444,5 +443,5 @@ class TestMailMessage(TestMail):
# 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': 'reply', 'default_parent_id': pigs_msg_id})
+ {'default_composition_mode': 'comment', 'default_parent_id': pigs_msg_id})
mail_compose.send_mail(cr, user_raoul_id, [compose_id])
diff --git a/addons/mail/tests/test_message_read.py b/addons/mail/tests/test_message_read.py
index c02e9a32278..fbf30f2ed22 100644
--- a/addons/mail/tests/test_message_read.py
+++ b/addons/mail/tests/test_message_read.py
@@ -46,7 +46,7 @@ class test_mail_access_rights(TestMail):
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]
# Test: raoul received notifications
- raoul_notification_ids = self.mail_notification.search(cr, user_raoul.id, [('read', '=', False), ('message_id', 'in', msg_ids), ('partner_id', '=', user_raoul.partner_id.id)])
+ 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')
# Test: read some specific ids
diff --git a/addons/mail/update.py b/addons/mail/update.py
index d2873f3a5bf..a76c54ff2da 100644
--- a/addons/mail/update.py
+++ b/addons/mail/update.py
@@ -59,7 +59,7 @@ def get_sys_logs(self, cr, uid):
add_arg = {"timeout":30} if sys.version_info >= (2,6) else {}
arguments = {'arg0': msg, "action": "update",}
- arguments_raw = werkzeug.url_encode(arguments)
+ arguments_raw = werkzeug.urls.url_encode(arguments)
url = config.get("publisher_warranty_url")
diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py
index 0425cd1ee0e..41dc4a9b438 100644
--- a/addons/mail/wizard/mail_compose_message.py
+++ b/addons/mail/wizard/mail_compose_message.py
@@ -196,8 +196,7 @@ class mail_compose_message(osv.TransientModel):
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. """
- if context is None:
- context = {}
+ context = dict(context or {})
# clean the context (hint: mass mailing sets some default values that
# could be wrongly interpreted by mail_mail)