diff --git a/addons/mail/mail_group.py b/addons/mail/mail_group.py index 644718fdfb9..d4c9c565bf3 100644 --- a/addons/mail/mail_group.py +++ b/addons/mail/mail_group.py @@ -25,6 +25,7 @@ from osv import osv from osv import fields from openerp import SUPERUSER_ID + class mail_group(osv.Model): """ A mail_group is a collection of users sharing messages in a discussion group. The group mechanics are based on the followers. """ diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index cfc2992ecde..8c9f45fd724 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -94,10 +94,9 @@ class mail_thread(osv.AbstractModel): def _get_subscription_data(self, cr, uid, ids, name, args, context=None): """ Computes: - - message_is_follower: is uid in the document followers - message_subtype_data: data about document subtypes: which are available, which are followed if any """ - res = dict((id, dict(message_subtype_data='', message_is_follower=False)) for id in ids) + res = dict((id, dict(message_subtype_data='')) for id in ids) user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0] # find current model subtypes, add them to a dictionary @@ -116,7 +115,6 @@ class mail_thread(osv.AbstractModel): ], context=context) for fol in fol_obj.browse(cr, uid, fol_ids, context=context): thread_subtype_dict = res[fol.res_id]['message_subtype_data'] - res[fol.res_id]['message_is_follower'] = True for subtype in fol.subtype_ids: thread_subtype_dict[subtype.name]['followed'] = True res[fol.res_id]['message_subtype_data'] = thread_subtype_dict @@ -139,9 +137,12 @@ class mail_thread(osv.AbstractModel): def _get_followers(self, cr, uid, ids, name, arg, context=None): 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((res_id, []) for 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] for fol in fol_obj.browse(cr, SUPERUSER_ID, fol_ids): - res[fol.res_id].append(fol.partner_id.id) + res[fol.res_id]['message_follower_ids'].append(fol.partner_id.id) + if fol.partner_id.id == user_pid: + res[fol.res_id]['message_is_follower'] = True return res def _set_followers(self, cr, uid, id, name, value, arg, context=None): @@ -195,15 +196,11 @@ class mail_thread(osv.AbstractModel): return res _columns = { - 'message_is_follower': fields.function(_get_subscription_data, - type='boolean', string='Is a Follower', multi='_get_subscription_data,'), - 'message_subtype_data': fields.function(_get_subscription_data, - type='text', string='Subscription data', multi="_get_subscription_data", - help="Holds data about the subtypes. The content of this field "\ - "is a structure holding the current model subtypes, and the "\ - "current document followed subtypes."), + 'message_is_follower': fields.function(_get_followers, + type='boolean', string='Is a Follower', multi='_get_followers,'), 'message_follower_ids': fields.function(_get_followers, fnct_inv=_set_followers, - fnct_search=_search_followers, type='many2many', obj='res.partner', string='Followers'), + fnct_search=_search_followers, type='many2many', + obj='res.partner', string='Followers', multi='_get_followers'), 'message_comment_ids': fields.one2many('mail.message', 'res_id', domain=lambda self: [('model', '=', self._name), ('type', 'in', ('comment', 'email'))], string='Comments and emails', diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 7a4d44b881d..e9df69a27e4 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -1174,6 +1174,7 @@ openerp.mail = function(session) { // update domain var domain = this.options.domain.concat([['model', '=', this.view.model], ['res_id', '=', this.view.datarecord.id]]); // create and render Thread widget + // TDE note: replace message_is_follower by a check in message_follower_ids, as message_is_follower is not used in views anymore var show_header_compose = this.view.is_action_enabled('edit') || (this.getParent().fields.message_is_follower && this.getParent().fields.message_is_follower.get_value()); diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index eff3f904b71..72e941afd8c 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -53,13 +53,12 @@ openerp_mail_followers = function(session, mail) { bind_events: function() { var self = this; - this.$('button.oe_follower') - .on('click', function (event) { - if($(this).hasClass('oe_notfollow')) - self.do_follow(); - else - self.do_unfollow(); - }); + this.$('button.oe_follower').on('click', function (event) { + if($(this).hasClass('oe_notfollow')) + self.do_follow(); + else + self.do_unfollow(); + }); this.$('ul.oe_subtypes input').on('click', self.do_update_subscription); this.$('button.oe_invite').on('click', function (event) { action = { @@ -87,13 +86,13 @@ openerp_mail_followers = function(session, mail) { set_value: function(value_) { this.reinit(); - return this.fetch_followers(value_ || this.get_value()); + return this.fetch_followers(value_ || this.get_value()); }, fetch_followers: function (value_) { this.value = value_ || {}; - this.message_is_follower = (this.getParent().fields.message_is_follower && this.getParent().fields.message_is_follower.get_value()); - if(value_) + this.message_is_follower = this.set_is_follower(value_); + if (value_) return this.ds_follow.call('read', [this.value, ['name', 'user_ids']]) .pipe(this.proxy('display_followers'), this.proxy('display_generic')) .pipe(this.proxy('display_buttons')); @@ -114,7 +113,7 @@ openerp_mail_followers = function(session, mail) { this.$('div.oe_mail_recthread_followers h4').html(content); }, - /** Display the followers, evaluate is_follower directly */ + /** Display the followers */ display_followers: function (records) { var self = this; var node_user_list = this.$('ul.oe_mail_followers_display').empty(); @@ -124,18 +123,16 @@ openerp_mail_followers = function(session, mail) { record.avatar_url = mail.ChatterUtils.get_image(self.session, 'res.partner', 'image_small', record.id); $(session.web.qweb.render('mail.followers.partner', {'record': record})).appendTo(node_user_list); } - self.set_is_follower(records); }, /** Computes whether the current user is in the followers */ set_is_follower: function(value_) { - this.message_is_follower = false; for(var i in value_) { if (value_[i]['user_ids'][0] == this.session.uid) { - this.message_is_follower = true; return true; } } + return false; }, display_buttons: function () { @@ -208,7 +205,6 @@ openerp_mail_followers = function(session, mail) { self.display_subtypes(true); }); } - }, }); diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail.py index a94c4fc2c8a..03779fbc53e 100644 --- a/addons/mail/tests/test_mail.py +++ b/addons/mail/tests/test_mail.py @@ -135,7 +135,9 @@ class test_mail(TestMailMockups): self.res_users = self.registry('res.users') self.res_partner = self.registry('res.partner') - self.user_demo = self.registry('ir.model.data').get_object_reference(self.cr, self.uid, 'base', 'user_demo')[1] + # Test users + self.user_demo_id = self.registry('ir.model.data').get_object_reference(self.cr, self.uid, 'base', 'user_demo')[1] + self.user_admin = self.res_users.browse(self.cr, self.uid, self.uid) # 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 @@ -148,6 +150,7 @@ class test_mail(TestMailMockups): # create a 'pigs' group that will be used through the various tests self.group_pigs_id = self.mail_group.create(self.cr, self.uid, {'name': 'Pigs', 'description': 'Fans of Pigs, unite !'}) + self.group_pigs = self.mail_group.browse(self.cr, self.uid, self.group_pigs_id) def tearDown(self): # Remove mocks @@ -155,6 +158,7 @@ class test_mail(TestMailMockups): super(test_mail, self).tearDown() def test_00_message_process(self): + """ Testing incoming emails processing. """ cr, uid = self.cr, self.uid # Incoming mail creates a new mail_group "frogs" self.assertEqual(self.mail_group.search(cr, uid, [('name', '=', 'frogs')]), []) @@ -193,18 +197,15 @@ class test_mail(TestMailMockups): self.assertEqual(new_mail.body, '\n
\nPlease call me as soon as possible this afternoon!\n\n--\nSylvie\n
\n', 'plaintext mail incorrectly parsed') - def test_10_many2many_reference_field(self): + def test_10_followers_function_field(self): """ Tests designed for the many2many function field 'follower_ids'. We will test to perform writes using the many2many commands 0, 3, 4, 5 and 6. """ - cr, uid = self.cr, self.uid - user_admin = self.res_users.browse(cr, uid, uid) - group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id) + cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs - # Create partner Bert Poilu + # Data: create partner Bert Poilu partner_bert_id = self.res_partner.create(cr, uid, {'name': 'Bert Poilu'}) - - # Create 'disturbing' values in mail.followers: same res_id, other res_model; same res_model, other res_id + # 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'}) self.mail_followers.create(cr, uid, @@ -257,9 +258,7 @@ class test_mail(TestMailMockups): def test_11_message_followers_and_subtypes(self): """ Tests designed for the subscriber API as well as message subtypes """ - cr, uid = self.cr, self.uid - user_admin = self.res_users.browse(cr, uid, uid) - group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id) + cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs # Data: user Raoul user_raoul_id = self.res_users.create(cr, uid, {'name': 'Raoul Grosbedon', 'login': 'raoul'}) user_raoul = self.res_users.browse(cr, uid, user_raoul_id) @@ -281,7 +280,6 @@ class test_mail(TestMailMockups): group_pigs.refresh() # Test: 2 followers (Admin and Raoul) follower_ids = [follower.id for follower in group_pigs.message_follower_ids] - self.assertEqual(len(follower_ids), 2, 'There should be 2 Pigs fans') self.assertEqual(set(follower_ids), set([user_raoul.partner_id.id, user_admin.partner_id.id]), 'Admin and Raoul should be the only 2 Pigs fans') # Test: Raoul follows default subtypes fol_ids = self.mail_followers.search(cr, uid, [('res_model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id), ('partner_id', '=', user_raoul.partner_id.id)]) @@ -308,10 +306,11 @@ class test_mail(TestMailMockups): # ---------------------------------------- group_pigs.refresh() - self.assertEqual(set(group_pigs.message_subtype_data.keys()), set(['comment', 'mt_mg_def', 'mt_all_def', 'mt_mg_nodef', 'mt_all_nodef']), 'mail.group available subtypes incorrect') - self.assertFalse(group_pigs.message_subtype_data['comment']['followed'], 'Admin should not follow comments in pigs') - self.assertTrue(group_pigs.message_subtype_data['mt_mg_nodef']['followed'], 'Admin should follow mt_mg_nodef in pigs') - self.assertTrue(group_pigs.message_subtype_data['mt_all_nodef']['followed'], 'Admin should follow mt_all_nodef in pigs') + subtype_data = group_pigs._get_subscription_data(None, None)[group_pigs.id]['message_subtype_data'] + self.assertEqual(set(subtype_data.keys()), set(['comment', 'mt_mg_def', 'mt_all_def', 'mt_mg_nodef', 'mt_all_nodef']), 'mail.group available subtypes incorrect') + self.assertFalse(subtype_data['comment']['followed'], 'Admin should not follow comments in pigs') + self.assertTrue(subtype_data['mt_mg_nodef']['followed'], 'Admin should follow mt_mg_nodef in pigs') + self.assertTrue(subtype_data['mt_all_nodef']['followed'], 'Admin should follow mt_all_nodef in pigs') def test_20_message_post(self): """ Tests designed for message_post. """ @@ -533,7 +532,7 @@ class test_mail(TestMailMockups): """ Tests for mail.message needaction. """ cr, uid = self.cr, self.uid group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id) - group_pigs_demo = self.mail_group.browse(cr, self.user_demo, self.group_pigs_id) + group_pigs_demo = self.mail_group.browse(cr, self.user_demo_id, self.group_pigs_id) user_admin = self.res_users.browse(cr, uid, uid) # Demo values: check unread notification = needaction on mail.message @@ -569,7 +568,7 @@ class test_mail(TestMailMockups): ]) self.assertEqual(len(notif_ids), na_count, 'posted message count does not match needaction count') - na_count3 = self.mail_message._needaction_count(cr, self.user_demo, domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)]) + na_count3 = self.mail_message._needaction_count(cr, self.user_demo_id, domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)]) self.assertEqual(na_count3-na_count1, 0, 'demo has 0 message: not a follower and do not follow his own messages') na_count2 = self.mail_message._needaction_count(cr, uid, domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)])