[MERGE] forward porting fixes from saas-3
[odoo/odoo.git] / addons / email_template / tests / test_mail.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Business Applications
5 #    Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 ##############################################################################
21
22 import base64
23 from openerp.addons.mail.tests.common import TestMail
24 from openerp.tools import mute_logger
25
26
27 class test_message_compose(TestMail):
28
29     def setUp(self):
30         super(test_message_compose, self).setUp()
31
32         # create a 'pigs' and 'bird' groups that will be used through the various tests
33         self.group_bird_id = self.mail_group.create(self.cr, self.uid,
34             {'name': 'Bird', 'description': 'I am angry !'})
35
36     def test_00_message_compose_wizard(self):
37         """ Tests designed for the mail.compose.message wizard updated by email_template. """
38         cr, uid = self.cr, self.uid
39         mail_compose = self.registry('mail.compose.message')
40         self.res_users.write(cr, uid, [uid], {'signature': 'Admin', 'email': 'a@a.a'})
41         user_admin = self.res_users.browse(cr, uid, uid)
42         p_a_id = user_admin.partner_id.id
43         group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
44         group_bird = self.mail_group.browse(cr, uid, self.group_bird_id)
45
46         # Mail data
47         _subject1 = 'Pigs'
48         _subject2 = 'Bird'
49         _body_html1 = 'Fans of Pigs, unite !'
50         _body_html2 = 'I am angry !'
51         _attachments = [
52             {'name': 'First', 'datas_fname': 'first.txt', 'datas': base64.b64encode('My first attachment'), 'res_model': 'res.partner', 'res_id': self.partner_admin_id},
53             {'name': 'Second', 'datas_fname': 'second.txt', 'datas': base64.b64encode('My second attachment'), 'res_model': 'res.partner', 'res_id': self.partner_admin_id},
54             ]
55         _attachments_test = [('first.txt', 'My first attachment'), ('second.txt', 'My second attachment')]
56
57         # Create template on mail.group, with attachments
58         group_model_id = self.registry('ir.model').search(cr, uid, [('model', '=', 'mail.group')])[0]
59         email_template = self.registry('email.template')
60         email_template_id = email_template.create(cr, uid, {
61             'model_id': group_model_id,
62             'name': 'Pigs Template',
63             'subject': '${object.name}',
64             'body_html': '${object.description}',
65             'user_signature': True,
66             'attachment_ids': [(0, 0, _attachments[0]), (0, 0, _attachments[1])],
67             'email_to': 'b@b.b, c@c.c',
68             'email_cc': 'd@d.d'
69             })
70
71         # ----------------------------------------
72         # CASE1: comment and save as template
73         # ----------------------------------------
74
75         # 1. Comment on pigs
76         compose_id = mail_compose.create(cr, uid,
77             {'subject': 'Forget me subject', 'body': '<p>Dummy body</p>', 'post': True},
78             {'default_composition_mode': 'comment',
79                 'default_model': 'mail.group',
80                 'default_res_id': self.group_pigs_id,
81                 'active_ids': [self.group_pigs_id, self.group_bird_id]})
82         compose = mail_compose.browse(cr, uid, compose_id)
83
84         # 2. Save current composition form as a template
85         mail_compose.save_as_template(cr, uid, [compose_id], context={'default_model': 'mail.group'})
86         # Test: email_template subject, body_html, model
87         last_template_id = email_template.search(cr, uid, [('model', '=', 'mail.group'), ('subject', '=', 'Forget me subject')], limit=1)[0]
88         self.assertTrue(last_template_id, 'email_template not found for model mail.group, subject Forget me subject')
89         last_template = email_template.browse(cr, uid, last_template_id)
90         self.assertEqual(last_template.body_html, '<p>Dummy body</p>', 'email_template incorrect body_html')
91
92         # ----------------------------------------
93         # CASE2: comment with template, save as template
94         # ----------------------------------------
95
96         # 1. Comment on pigs
97         context = {
98             'default_composition_mode': 'comment',
99             'default_model': 'mail.group',
100             'default_res_id': self.group_pigs_id,
101             'default_use_template': False,
102             'default_template_id': email_template_id,
103             'active_ids': [self.group_pigs_id, self.group_bird_id]
104         }
105         compose_id = mail_compose.create(cr, uid, {'subject': 'Forget me subject', 'body': 'Dummy body', 'post': True}, context)
106         compose = mail_compose.browse(cr, uid, compose_id, context)
107         onchange_res = compose.onchange_template_id(email_template_id, 'comment', 'mail.group', self.group_pigs_id)['value']
108         onchange_res['partner_ids'] = [(4, partner_id) for partner_id in onchange_res.pop('partner_ids', [])]
109         onchange_res['attachment_ids'] = [(4, attachment_id) for attachment_id in onchange_res.pop('attachment_ids', [])]
110         compose.write(onchange_res)
111         compose.refresh()
112
113         message_pids = [partner.id for partner in compose.partner_ids]
114         partner_ids = self.res_partner.search(cr, uid, [('email', 'in', ['b@b.b', 'c@c.c', 'd@d.d'])])
115         # Test: mail.compose.message: subject, body, partner_ids
116         self.assertEqual(compose.subject, _subject1, 'mail.compose.message subject incorrect')
117         self.assertIn(_body_html1, compose.body, 'mail.compose.message body incorrect')
118         self.assertEqual(set(message_pids), set(partner_ids), 'mail.compose.message partner_ids incorrect')
119         # Test: mail.compose.message: attachments (owner has not been modified)
120         for attach in compose.attachment_ids:
121             self.assertEqual(attach.res_model, 'res.partner', 'mail.compose.message attachment res_model through templat was overriden')
122             self.assertEqual(attach.res_id, self.partner_admin_id, 'mail.compose.message attachment res_id incorrect')
123             self.assertIn((attach.datas_fname, base64.b64decode(attach.datas)), _attachments_test,
124                 'mail.message attachment name / data incorrect')
125         # Test: mail.message: attachments
126         mail_compose.send_mail(cr, uid, [compose_id])
127         group_pigs.refresh()
128         message_pigs = group_pigs.message_ids[0]
129         for attach in message_pigs.attachment_ids:
130             self.assertEqual(attach.res_model, 'mail.group', 'mail.compose.message attachment res_model through templat was overriden')
131             self.assertEqual(attach.res_id, self.group_pigs_id, 'mail.compose.message attachment res_id incorrect')
132             self.assertIn((attach.datas_fname, base64.b64decode(attach.datas)), _attachments_test,
133                 'mail.message attachment name / data incorrect')
134
135         # ----------------------------------------
136         # CASE3: mass_mail with template
137         # ----------------------------------------
138
139         # 1. Mass_mail on pigs and bird, with a default_partner_ids set to check he is correctly added
140         context = {
141             'default_composition_mode': 'mass_mail',
142             'default_notify': True,
143             'default_model': 'mail.group',
144             'default_res_id': self.group_pigs_id,
145             'default_template_id': email_template_id,
146             'default_partner_ids': [p_a_id],
147             'active_ids': [self.group_pigs_id, self.group_bird_id]
148         }
149         compose_id = mail_compose.create(cr, uid, {'subject': 'Forget me subject', 'body': 'Dummy body', 'post': True}, context)
150         compose = mail_compose.browse(cr, uid, compose_id, context)
151         onchange_res = compose.onchange_template_id(email_template_id, 'mass_mail', 'mail.group', self.group_pigs_id)['value']
152         onchange_res['partner_ids'] = [(4, partner_id) for partner_id in onchange_res.pop('partner_ids', [])]
153         onchange_res['attachment_ids'] = [(4, attachment_id) for attachment_id in onchange_res.pop('attachment_ids', [])]
154         compose.write(onchange_res)
155         compose.refresh()
156
157         message_pids = [partner.id for partner in compose.partner_ids]
158         partner_ids = [p_a_id]
159         self.assertEqual(compose.subject, '${object.name}', 'mail.compose.message subject incorrect')
160         self.assertEqual(compose.body, '<p>${object.description}</p>', 'mail.compose.message body incorrect')
161         self.assertEqual(set(message_pids), set(partner_ids), 'mail.compose.message partner_ids incorrect')
162
163         # 2. Post the comment, get created message
164         mail_compose.send_mail(cr, uid, [compose_id],  {'default_res_id': -1, 'active_ids': [self.group_pigs_id, self.group_bird_id]})
165         group_pigs.refresh()
166         group_bird.refresh()
167         message_pigs = group_pigs.message_ids[0]
168         message_bird = group_bird.message_ids[0]
169         # Test: subject, body
170         self.assertEqual(message_pigs.subject, _subject1, 'mail.message subject on Pigs incorrect')
171         self.assertEqual(message_bird.subject, _subject2, 'mail.message subject on Bird incorrect')
172         self.assertIn(_body_html1, message_pigs.body, 'mail.message body on Pigs incorrect')
173         self.assertIn(_body_html2, message_bird.body, 'mail.message body on Bird incorrect')
174         # Test: partner_ids: p_a_id (default) + 3 newly created partners
175         message_pigs_pids = [partner.id for partner in message_pigs.notified_partner_ids]
176         message_bird_pids = [partner.id for partner in message_bird.notified_partner_ids]
177         partner_ids = self.res_partner.search(cr, uid, [('email', 'in', ['b@b.b', 'c@c.c', 'd@d.d'])])
178         partner_ids.append(p_a_id)
179         self.assertEqual(set(message_pigs_pids), set(partner_ids), 'mail.message on pigs incorrect number of notified_partner_ids')
180         self.assertEqual(set(message_bird_pids), set(partner_ids), 'mail.message on bird notified_partner_ids incorrect')
181
182         # ----------------------------------------
183         # CASE4: test newly introduced partner_to field
184         # ----------------------------------------
185
186         # get already-created partners back
187         p_b_id = self.res_partner.search(cr, uid, [('email', '=', 'b@b.b')])[0]
188         p_c_id = self.res_partner.search(cr, uid, [('email', '=', 'c@c.c')])[0]
189         p_d_id = self.res_partner.search(cr, uid, [('email', '=', 'd@d.d')])[0]
190         # modify template: use partner_to, use template and email address in email_to to test all features together
191         user_model_id = self.registry('ir.model').search(cr, uid, [('model', '=', 'res.users')])[0]
192         email_template.write(cr, uid, [email_template_id], {
193             'model_id': user_model_id,
194             'body_html': '${object.login}',
195             'email_to': '${object.email}, c@c',
196             'partner_to': '%i,%i' % (p_b_id, p_c_id),
197             'email_cc': 'd@d',
198             })
199         # patner by email + partner by id (no double)
200         send_to = [p_a_id, p_b_id, p_c_id, p_d_id]
201         # Generate messsage with default email and partner on template
202         mail_value = mail_compose.generate_email_for_composer(cr, uid, email_template_id, uid)
203         self.assertEqual(set(mail_value['partner_ids']), set(send_to), 'mail.message partner_ids list created by template is incorrect')
204
205     @mute_logger('openerp.osv.orm', 'openerp.osv.orm')
206     def test_10_email_templating(self):
207         """ Tests designed for the mail.compose.message wizard updated by email_template. """
208         cr, uid, context = self.cr, self.uid, {}
209
210         # create the email.template on mail.group model
211         group_model_id = self.registry('ir.model').search(cr, uid, [('model', '=', 'mail.group')])[0]
212         email_template = self.registry('email.template')
213         email_template_id = email_template.create(cr, uid, {
214             'model_id': group_model_id,
215             'name': 'Pigs Template',
216             'email_from': 'Raoul Grosbedon <raoul@example.com>',
217             'subject': '${object.name}',
218             'body_html': '${object.description}',
219             'user_signature': True,
220             'email_to': 'b@b.b, c@c.c',
221             'email_cc': 'd@d.d',
222             'partner_to': '${user.partner_id.id},%s,%s,-1' % (self.user_raoul.partner_id.id, self.user_bert.partner_id.id)
223         })
224
225         # not force send: email_recipients is not taken into account
226         msg_id = email_template.send_mail(cr, uid, email_template_id, self.group_pigs_id, context=context)
227         mail = self.mail_mail.browse(cr, uid, msg_id, context=context)
228         self.assertEqual(mail.subject, 'Pigs', 'email_template: send_mail: wrong subject')
229         self.assertEqual(mail.email_to, 'b@b.b, c@c.c', 'email_template: send_mail: wrong email_to')
230         self.assertEqual(mail.email_cc, 'd@d.d', 'email_template: send_mail: wrong email_cc')
231         self.assertEqual(
232             set([partner.id for partner in mail.recipient_ids]),
233             set((self.partner_admin_id, self.user_raoul.partner_id.id, self.user_bert.partner_id.id)),
234             'email_template: send_mail: wrong management of partner_to')
235
236         # force send: take email_recipients into account
237         email_template.send_mail(cr, uid, email_template_id, self.group_pigs_id, force_send=True, context=context)
238         sent_emails = self._build_email_kwargs_list
239         email_to_lst = [
240             ['b@b.b', 'c@c.c'], ['"Followers of Pigs" <admin@yourcompany.example.com>'],
241             ['"Followers of Pigs" <raoul@raoul.fr>'], ['"Followers of Pigs" <bert@bert.fr>']]
242         self.assertEqual(len(sent_emails), 4, 'email_template: send_mail: 3 valid email recipients + email_to -> should send 4 emails')
243         for email in sent_emails:
244             self.assertIn(email['email_to'], email_to_lst, 'email_template: send_mail: wrong email_recipients')