diff options
| author | Thibault Delavallée <tde@odoo.com> | 2017-09-19 12:31:47 +0200 |
|---|---|---|
| committer | Thibault Delavallée <tde@odoo.com> | 2017-11-29 10:05:01 +0100 |
| commit | 99ee2f344a6ec884aa924412b12cf14ba184c5a0 (patch) | |
| tree | a949e36314efb6c496286d68623bfb84fa1dae4b /addons/mail/tests | |
| parent | f8118d8c8b872c82e712a2f5218e0b01f7b9cb34 (diff) | |
[IMP] mail: tests: clean and improve mail followers tests
Purpose is to lessen noise and make tests less low-level. Including :
* add test for the various auto subscription cases, notably through
umbrella (like project -> task auto subscription);
* remove low-level tests; there is no need to test the output of add
followers method as it is only an implementation details;
Diffstat (limited to 'addons/mail/tests')
| -rw-r--r-- | addons/mail/tests/test_mail_followers.py | 277 |
1 files changed, 166 insertions, 111 deletions
diff --git a/addons/mail/tests/test_mail_followers.py b/addons/mail/tests/test_mail_followers.py index 1887943de4e..887f9140c2b 100644 --- a/addons/mail/tests/test_mail_followers.py +++ b/addons/mail/tests/test_mail_followers.py @@ -3,142 +3,197 @@ from psycopg2 import IntegrityError -from odoo.addons.mail.tests.common import TestMail +from odoo.addons.mail.tests import common from odoo.tools.misc import mute_logger -class TestMailFollowers(TestMail): - - def setUp(self): - super(TestMailFollowers, self).setUp() - Subtype = self.env['mail.message.subtype'] - self.mt_mg_def = Subtype.create({'name': 'mt_mg_def', 'default': True, 'res_model': 'mail.test'}) - self.mt_cl_def = Subtype.create({'name': 'mt_cl_def', 'default': True, 'res_model': 'crm.lead'}) - self.mt_al_def = Subtype.create({'name': 'mt_al_def', 'default': True, 'res_model': False}) - self.mt_mg_nodef = Subtype.create({'name': 'mt_mg_nodef', 'default': False, 'res_model': 'mail.test'}) - self.mt_al_nodef = Subtype.create({'name': 'mt_al_nodef', 'default': False, 'res_model': False}) - self.default_group_subtypes = Subtype.search([('default', '=', True), '|', ('res_model', '=', 'mail.test'), ('res_model', '=', False)]) - - def test_m2o_command_new(self): - test_channel = self.env['mail.channel'].create({'name': 'Test'}) - groups = self.test_pigs | self.test_public - generic, specific = self.env['mail.followers']._add_follower_command( - 'mail.test', groups.ids, - {self.user_employee.partner_id.id: [self.mt_mg_nodef.id]}, - {test_channel.id: [self.mt_al_nodef.id]}) - self.assertFalse(specific) - self.assertEqual(len(generic), 2) - - items = [it[2] for it in generic] - self.assertEqual({item['res_model'] for item in items}, - {'mail.test'}) - self.assertEqual({item['channel_id'] for item in items if item.get('channel_id')}, - {test_channel.id}) - self.assertEqual({item['partner_id'] for item in items if item.get('partner_id')}, - {self.user_employee.partner_id.id}) - self.assertEqual(set(items[0]['subtype_ids'][0][2] + items[1]['subtype_ids'][0][2]), - {self.mt_mg_nodef.id, self.mt_al_nodef.id}) - - def test_m2o_command_update_selective(self): - test_channel = self.env['mail.channel'].create({'name': 'Test'}) - groups = self.test_pigs | self.test_public - self.env['mail.followers'].create({'partner_id': self.user_employee.partner_id.id, 'res_model': 'mail.test', 'res_id': self.test_pigs.id}) - generic, specific = self.env['mail.followers']._add_follower_command( - 'mail.test', groups.ids, - {self.user_employee.partner_id.id: [self.mt_mg_nodef.id]}, - {test_channel.id: False}, - force=False) - self.assertEqual(len(generic), 1) - self.assertEqual(len(specific), 1) - - self.assertEqual(generic[0][2]['res_model'], 'mail.test') - self.assertEqual(generic[0][2]['channel_id'], test_channel.id) - self.assertEqual(set(generic[0][2]['subtype_ids'][0][2]), set(self.default_group_subtypes.ids)) - - self.assertEqual(list(specific), [self.test_public.id]) - self.assertEqual(specific[self.test_public.id][0][2]['res_model'], 'mail.test') - self.assertEqual(specific[self.test_public.id][0][2]['partner_id'], self.user_employee.partner_id.id) - self.assertEqual(set(specific[self.test_public.id][0][2]['subtype_ids'][0][2]), set([self.mt_mg_nodef.id])) - - def test_message_is_follower(self): - qty_followed_before = len(self.test_pigs.sudo(self.user_employee).search([('message_is_follower', '=', True)])) - self.assertFalse(self.test_pigs.sudo(self.user_employee).message_is_follower) - self.test_pigs.message_subscribe_users(user_ids=[self.user_employee.id]) - qty_followed_after = len(self.test_pigs.sudo(self.user_employee).search([('message_is_follower', '=', True)])) - self.assertTrue(self.test_pigs.sudo(self.user_employee).message_is_follower) - self.assertEqual(qty_followed_before + 1, qty_followed_after) +class BaseFollowersTest(common.BaseFunctionalTest): + + @classmethod + def setUpClass(cls): + super(BaseFollowersTest, cls).setUpClass() + Subtype = cls.env['mail.message.subtype'] + cls.mt_mg_def = Subtype.create({'name': 'mt_mg_def', 'default': True, 'res_model': 'mail.test.simple'}) + cls.mt_cl_def = Subtype.create({'name': 'mt_cl_def', 'default': True, 'res_model': 'mail.test'}) + cls.mt_al_def = Subtype.create({'name': 'mt_al_def', 'default': True, 'res_model': False}) + cls.mt_mg_nodef = Subtype.create({'name': 'mt_mg_nodef', 'default': False, 'res_model': 'mail.test.simple'}) + cls.mt_al_nodef = Subtype.create({'name': 'mt_al_nodef', 'default': False, 'res_model': False}) + cls.mt_mg_def_int = cls.env['mail.message.subtype'].create({'name': 'mt_mg_def', 'default': True, 'res_model': 'mail.test.simple', 'internal': True}) + cls.default_group_subtypes = Subtype.search([('default', '=', True), '|', ('res_model', '=', 'mail.test.simple'), ('res_model', '=', False)]) + cls.default_group_subtypes_portal = Subtype.search([('internal', '=', False), ('default', '=', True), '|', ('res_model', '=', 'mail.test.simple'), ('res_model', '=', False)]) + + def test_field_message_is_follower(self): + test_record = self.test_record.sudo(self.user_employee) + followed_before = test_record.search([('message_is_follower', '=', True)]) + self.assertFalse(test_record.message_is_follower) + test_record.message_subscribe_users(user_ids=[self.user_employee.id]) + followed_after = test_record.search([('message_is_follower', '=', True)]) + self.assertTrue(test_record.message_is_follower) + self.assertEqual(followed_before | test_record, followed_after) + + def test_field_followers(self): + test_record = self.test_record.sudo(self.user_employee) + test_record.message_subscribe(partner_ids=[self.user_employee.partner_id.id, self.user_admin.partner_id.id], channel_ids=[self.channel_listen.id]) + followers = self.env['mail.followers'].search([ + ('res_model', '=', 'mail.test.simple'), + ('res_id', '=', test_record.id)]) + self.assertEqual(followers, test_record.message_follower_ids) + self.assertEqual(test_record.message_partner_ids, self.user_employee.partner_id | self.user_admin.partner_id) + self.assertEqual(test_record.message_channel_ids, self.channel_listen) def test_followers_subtypes_default(self): - self.test_pigs.message_subscribe_users(user_ids=[self.user_employee.id]) - self.assertEqual(self.test_pigs.message_follower_ids.mapped('partner_id'), self.user_employee.partner_id) - self.assertEqual(self.test_pigs.message_follower_ids.mapped('channel_id'), self.env['mail.channel']) + test_record = self.test_record.sudo(self.user_employee) + test_record.message_subscribe(partner_ids=[self.user_employee.partner_id.id]) + self.assertEqual(test_record.message_partner_ids, self.user_employee.partner_id) follower = self.env['mail.followers'].search([ - ('res_model', '=', 'mail.test'), - ('res_id', '=', self.test_pigs.id), + ('res_model', '=', 'mail.test.simple'), + ('res_id', '=', test_record.id), ('partner_id', '=', self.user_employee.partner_id.id)]) - self.assertEqual(len(follower), 1) + self.assertEqual(follower, test_record.message_follower_ids) self.assertEqual(follower.subtype_ids, self.default_group_subtypes) def test_followers_subtypes_default_internal(self): - mt_mg_def_int = self.env['mail.message.subtype'].create({'name': 'mt_mg_def', 'default': True, 'res_model': 'mail.test', 'internal': True}) - self.test_pigs.message_subscribe_users(user_ids=[self.user_employee.id]) - follower = self.env['mail.followers'].search([ - ('res_model', '=', 'mail.test'), - ('res_id', '=', self.test_pigs.id), - ('partner_id', '=', self.user_employee.partner_id.id)]) - self.assertEqual(follower.subtype_ids, self.default_group_subtypes | mt_mg_def_int) + user_portal = self.env['res.users'].with_context(self._quick_create_user_ctx).create({ + 'name': 'Chell Gladys', + 'login': 'chell', + 'email': 'chell@gladys.portal', + 'groups_id': [(6, 0, [self.env.ref('base.group_portal').id])] + }) - self.test_pigs.message_subscribe_users(user_ids=[self.user_portal.id]) + test_record = self.test_record.sudo(self.user_employee) + test_record.message_subscribe(partner_ids=[user_portal.partner_id.id]) + self.assertEqual(test_record.message_partner_ids, user_portal.partner_id) follower = self.env['mail.followers'].search([ - ('res_model', '=', 'mail.test'), - ('res_id', '=', self.test_pigs.id), - ('partner_id', '=', self.user_portal.partner_id.id)]) - self.assertEqual(follower.subtype_ids, self.default_group_subtypes.filtered(lambda subtype: not subtype.internal)) + ('res_model', '=', 'mail.test.simple'), + ('res_id', '=', test_record.id), + ('partner_id', '=', user_portal.partner_id.id)]) + self.assertEqual(follower.subtype_ids, self.default_group_subtypes_portal) def test_followers_subtypes_specified(self): - self.test_pigs.sudo(self.user_employee).message_subscribe_users(subtype_ids=[self.mt_mg_nodef.id]) - self.assertEqual(self.test_pigs.message_follower_ids.mapped('partner_id'), self.user_employee.partner_id) - self.assertEqual(self.test_pigs.message_follower_ids.mapped('channel_id'), self.env['mail.channel']) + test_record = self.test_record.sudo(self.user_employee) + test_record.message_subscribe(partner_ids=[self.user_employee.partner_id.id], subtype_ids=[self.mt_mg_nodef.id]) + self.assertEqual(test_record.message_partner_ids, self.user_employee.partner_id) follower = self.env['mail.followers'].search([ - ('res_model', '=', 'mail.test'), - ('res_id', '=', self.test_pigs.id), + ('res_model', '=', 'mail.test.simple'), + ('res_id', '=', test_record.id), ('partner_id', '=', self.user_employee.partner_id.id)]) - self.assertEqual(len(follower), 1) + self.assertEqual(follower, test_record.message_follower_ids) self.assertEqual(follower.subtype_ids, self.mt_mg_nodef) def test_followers_multiple_subscription(self): - self.test_pigs.sudo(self.user_employee).message_subscribe_users(subtype_ids=[self.mt_mg_nodef.id]) - self.assertEqual(self.test_pigs.message_follower_ids.mapped('partner_id'), self.user_employee.partner_id) - self.assertEqual(self.test_pigs.message_follower_ids.mapped('channel_id'), self.env['mail.channel']) - follower = self.env['mail.followers'].search([ - ('res_model', '=', 'mail.test'), - ('res_id', '=', self.test_pigs.id), - ('partner_id', '=', self.user_employee.partner_id.id)]) - self.assertEqual(len(follower), 1) - self.assertEqual(follower.subtype_ids, self.mt_mg_nodef) + test_record = self.test_record.sudo(self.user_employee) - self.test_pigs.sudo(self.user_employee).message_subscribe_users(subtype_ids=[self.mt_mg_nodef.id, self.mt_al_nodef.id]) - self.assertEqual(self.test_pigs.message_follower_ids.mapped('partner_id'), self.user_employee.partner_id) - self.assertEqual(self.test_pigs.message_follower_ids.mapped('channel_id'), self.env['mail.channel']) - follower = self.env['mail.followers'].search([ - ('res_model', '=', 'mail.test'), - ('res_id', '=', self.test_pigs.id), - ('partner_id', '=', self.user_employee.partner_id.id)]) - self.assertEqual(len(follower), 1) - self.assertEqual(follower.subtype_ids, self.mt_mg_nodef | self.mt_al_nodef) + test_record.message_subscribe(partner_ids=[self.user_admin.partner_id.id], subtype_ids=[self.mt_mg_nodef.id]) + self.assertEqual(test_record.message_partner_ids, self.user_admin.partner_id) + self.assertEqual(test_record.message_channel_ids, self.env['mail.channel']) + self.assertEqual(test_record.message_follower_ids.subtype_ids, self.mt_mg_nodef) - def test_no_DID(self): + test_record.message_subscribe(partner_ids=[self.user_admin.partner_id.id], subtype_ids=[self.mt_mg_nodef.id, self.mt_al_nodef.id]) + self.assertEqual(test_record.message_partner_ids, self.user_admin.partner_id) + self.assertEqual(test_record.message_channel_ids, self.env['mail.channel']) + self.assertEqual(test_record.message_follower_ids.filtered(lambda fol: fol.partner_id == self.user_admin.partner_id).subtype_ids, self.mt_mg_nodef | self.mt_al_nodef) + + def test_followers_no_DID(self): """Test that a follower cannot suffer from dissociative identity disorder. It cannot be both a partner and a channel. """ - test_record = self.env['mail.channel'].create({ - 'name': 'I used to be schizo, but now we are alright.' - }) - test_channel = self.env['mail.channel'].create({'name': 'Follower Channel'}) with self.assertRaises(IntegrityError), mute_logger('odoo.sql_db'): self.env['mail.followers'].create({ - 'res_model': test_record._name, - 'res_id': test_record.id, + 'res_model': self.test_record._name, + 'res_id': self.test_record.id, 'partner_id': self.user_employee.partner_id.id, - 'channel_id': test_channel.id, + 'channel_id': self.channel_listen.id, }) + + +class AdvancedFollowersTest(common.BaseFunctionalTest): + @classmethod + def setUpClass(cls): + super(AdvancedFollowersTest, cls).setUpClass() + + cls.user_portal = cls.env['res.users'].with_context(cls._quick_create_user_ctx).create({ + 'name': 'Chell Gladys', + 'login': 'chell', + 'email': 'chell@gladys.portal', + 'groups_id': [(6, 0, [cls.env.ref('base.group_portal').id])], + }) + + cls.test_track = cls.env['mail.test.track'].sudo(cls.user_employee).create({ + 'name': 'Test', + }) + + Subtype = cls.env['mail.message.subtype'] + cls.sub_nodef = Subtype.create({'name': 'Sub NoDefault', 'default': False, 'res_model': 'mail.test'}) + cls.sub_umb1 = Subtype.create({'name': 'Sub Umbrella1', 'default': False, 'res_model': 'mail.test.track'}) + cls.sub_umb2 = Subtype.create({'name': 'Sub Umbrella2', 'default': False, 'res_model': 'mail.test.track'}) + cls.umb_def = Subtype.create({'name': 'Umbrella Default', 'default': True, 'res_model': 'mail.test'}) + # create subtypes for auto subscription from umbrella to sub records + cls.umb_sub_def = Subtype.create({ + 'name': 'Umbrella Sub1', 'default': True, 'res_model': 'mail.test', + 'parent_id': cls.sub_umb1.id, 'relation_field': 'umbrella_id'}) + cls.umb_sub_nodef = Subtype.create({ + 'name': 'Umbrella Sub2', 'default': False, 'res_model': 'mail.test', + 'parent_id': cls.sub_umb2.id, 'relation_field': 'umbrella_id'}) + + def test_auto_subscribe_create(self): + """ Creator of records are automatically added as followers """ + self.assertEqual(self.test_track.message_partner_ids, self.user_employee.partner_id) + + def test_auto_subscribe_post(self): + """ People posting a message are automatically added as followers """ + self.test_track.sudo(self.user_admin).message_post(body='Coucou hibou', message_type='comment') + self.assertEqual(self.test_track.message_partner_ids, self.user_employee.partner_id | self.user_admin.partner_id) + + def test_auto_subscribe_post_email(self): + """ People posting an email are automatically added as followers """ + self.test_track.sudo(self.user_admin).message_post(body='Coucou hibou', message_type='email') + self.assertEqual(self.test_track.message_partner_ids, self.user_employee.partner_id | self.user_admin.partner_id) + + def test_auto_subscribe_not_on_notification(self): + """ People posting an automatic notification are not subscribed """ + self.test_track.sudo(self.user_admin).message_post(body='Coucou hibou', message_type='notification') + self.assertEqual(self.test_track.message_partner_ids, self.user_employee.partner_id) + + def test_auto_subscribe_responsible(self): + """ Responsibles are tracked and added as followers """ + sub = self.env['mail.test.track'].sudo(self.user_employee).create({ + 'name': 'Test', + 'user_id': self.user_admin.id, + }) + + self.assertEqual(sub.message_partner_ids, (self.user_employee.partner_id | self.user_admin.partner_id)) + + def test_auto_subscribe_defaults(self): + """ Test auto subscription based on an umbrella record. This mimics + the behavior of addons like project and task where subscribing to + some project's subtypes automatically subscribe the follower to its tasks. + + Functional rules applied here + + * subscribing to an umbrella subtype with parent_id / relation_field set + automatically create subscription with matching subtypes + * subscribing to a sub-record as creator applies default subtype values + * portal user should not have access to internal subtypes + """ + umbrella = self.env['mail.test'].with_context(self._quick_create_ctx).create({ + 'name': 'Project-Like', + }) + + umbrella.message_subscribe(partner_ids=[self.user_portal.partner_id.id]) + self.assertEqual(umbrella.message_partner_ids, self.user_portal.partner_id) + + sub1 = self.env['mail.test.track'].sudo(self.user_employee).create({ + 'name': 'Task-Like Test', + 'umbrella_id': umbrella.id, + }) + + all_defaults = self.env['mail.message.subtype'].search([('default', '=', True), '|', ('res_model', '=', 'mail.test.full'), ('res_model', '=', False)]) + external_defaults = all_defaults.filtered(lambda subtype: not subtype.internal) + + self.assertEqual(sub1.message_partner_ids, self.user_portal.partner_id | self.user_employee.partner_id) + self.assertEqual( + sub1.message_follower_ids.filtered(lambda fol: fol.partner_id == self.user_portal.partner_id).subtype_ids, + external_defaults | self.sub_umb1) + self.assertEqual( + sub1.message_follower_ids.filtered(lambda fol: fol.partner_id == self.user_employee.partner_id).subtype_ids, + all_defaults) |
