# -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. from unittest.mock import patch from werkzeug import urls from odoo.addons.test_mass_mailing.tests.common import MassMailingCase from odoo.addons.base.models.ir_config_parameter import IrConfigParameter from odoo.tests.common import TransactionCase, users from odoo.tools import mute_logger class TestMassMail(MassMailingCase): def setUp(self): """ In this setup we prepare 20 blacklist entries. We therefore add 20 recipients compared to first test in order to have comparable results. """ super(TestMassMail, self).setUp() values = [{ 'name': 'Recipient %s' % x, 'email_from': 'Recipient ' % x, } for x in range(0, 6)] self.mm_recs = self.env['mass.mail.test.bl'].create(values) self.env['mail.blacklist'].create({ 'email': 'rec.2@example.com' }) self.test_medium = self.env['utm.medium'].create({'name': 'TestMedium'}) @users('marketing') @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') def test_link_tracker(self): _url = 'https://www.example.com/foo/bar?baz=qux' mailing = self.env['mail.mass_mailing'].create({ 'name': 'TestMailing', 'subject': 'Test', 'medium_id': self.test_medium.id, 'body_html': '

Hello ${object.name}Unsubscribe

' % _url, 'reply_to_mode': 'email', 'mailing_model_id': self.ref('test_mass_mailing.model_mass_mail_test_bl'), 'mailing_domain': [('id', 'in', self.mm_recs.ids)], }) mailing.send_mail() # basic test emails are sent self.assertEqual(mailing.sent, 5) self.assertEqual(mailing.delivered, 5) # link trackers links = self.env['link.tracker'].sudo().search([('mass_mailing_id', '=', mailing.id)]) self.assertEqual(len(links), 1) self.assertEqual(links.mapped('url'), [_url]) # check UTMS are correctly set on redirect URL redirect_url = urls.url_parse(links.redirected_url) redirect_params = redirect_url.decode_query().to_dict(flat=True) self.assertEqual(redirect_url.scheme, 'https') self.assertEqual(redirect_url.decode_netloc(), 'www.example.com') self.assertEqual(redirect_url.path, '/foo/bar') self.assertEqual(redirect_params, { 'utm_source': mailing.name, 'utm_medium': self.test_medium.name, 'baz': 'qux', }) class TestAccessRights(TransactionCase): def test_01_mass_mail_blacklist(self): mass_mailing_contacts = self.env['mail.mass_mailing.contact'] mass_mailing = self.env['mail.mass_mailing'] mail_blacklist = self.env['mail.blacklist'] # create mailing contact record self.mailing_contact_1 = mass_mailing_contacts.create({'name': 'test email 1', 'email': 'test1@email.com'}) self.mailing_contact_2 = mass_mailing_contacts.create({'name': 'test email 2', 'email': 'test2@email.com'}) self.mailing_contact_3 = mass_mailing_contacts.create({'name': 'test email 3', 'email': 'test3@email.com'}) self.mailing_contact_4 = mass_mailing_contacts.create({'name': 'test email 4', 'email': 'test4@email.com'}) self.mailing_contact_5 = mass_mailing_contacts.create({'name': 'test email 5', 'email': 'test5@email.com'}) # create blacklist record mail_blacklist.create({'email': self.mailing_contact_3.email}) mail_blacklist.create({'email': self.mailing_contact_4.email}) # create mass mailing record self.mass_mailing = mass_mailing.create({ 'name': 'test', 'subject': 'Blacklisted', 'mailing_domain': [('id', 'in', [self.mailing_contact_1.id, self.mailing_contact_2.id, self.mailing_contact_3.id, self.mailing_contact_4.id, self.mailing_contact_5.id])], 'body_html': 'This is mass mail marketing demo'}) self.mass_mailing.put_in_queue() res_ids = self.mass_mailing.get_remaining_recipients() composer_values = { 'body': self.mass_mailing.convert_links()[self.mass_mailing.id], 'subject': self.mass_mailing.name, 'model': self.mass_mailing.mailing_model_real, 'email_from': self.mass_mailing.email_from, 'composition_mode': 'mass_mail', 'mass_mailing_id': self.mass_mailing.id, 'mailing_list_ids': [(4, l.id) for l in self.mass_mailing.contact_list_ids], } composer = self.env['mail.compose.message'].with_context(active_ids=res_ids, mass_mailing_seen_list=self.mass_mailing._get_seen_list()).create( composer_values) composer.send_mail() self.assertEqual(self.mass_mailing.ignored, 2, 'blacklist ignored email number incorrect, should be equals to 2') def test_02_mass_mail_simple_opt_out(self): mass_mailing_contacts = self.env['mail.mass_mailing.contact'] mass_mailing_lists = self.env['mail.mass_mailing.list'] mass_mailing_optout = self.env['mail.mass_mailing.list_contact_rel'] mass_mailing = self.env['mail.mass_mailing'] # create mailing contact record mailing_contact_1 = mass_mailing_contacts.create({'name': 'test email 1', 'email': 'test1@email.com'}) mailing_contact_2 = mass_mailing_contacts.create({'name': 'test email 2', 'email': 'test2@email.com'}) # create mailing list record mailing_list_1 = mass_mailing_lists.create({ 'name': 'A', 'contact_ids': [ (4, mailing_contact_1.id), (4, mailing_contact_2.id) ] }) # Set Opt out mass_mailing_optout.search([('contact_id', '=', mailing_contact_1.id), ('list_id', '=', mailing_list_1.id)]).write({ 'opt_out': True, }) # create mass mailing record self.mass_mailing = mass_mailing.create({ 'name': 'One', 'subject': 'One', 'mailing_model_id': self.env['ir.model']._get(mass_mailing_contacts).id, 'body_html': 'This is mass mail marketing demo'}) self.mass_mailing.contact_list_ids = [mailing_list_1.id] self.mass_mailing.put_in_queue() composer_values = { 'body': self.mass_mailing.convert_links()[self.mass_mailing.id], 'subject': self.mass_mailing.name, 'model': self.mass_mailing.mailing_model_real, 'email_from': self.mass_mailing.email_from, 'composition_mode': 'mass_mail', 'mass_mailing_id': self.mass_mailing.id, 'mailing_list_ids': [(4, l.id) for l in self.mass_mailing.contact_list_ids], } composer = self.env['mail.compose.message'].with_context( active_ids=[mailing_contact_1.id, mailing_contact_2.id], mass_mailing_seen_list=self.mass_mailing._get_seen_list(), mass_mailing_opt_out_list=self.mass_mailing._get_opt_out_list()).create(composer_values) composer.send_mail() self.assertEqual(self.mass_mailing.ignored, 1, 'Opt Out ignored email number incorrect, should be equals to 1') def test_03_mass_mail_multi_opt_out(self): mass_mailing_contacts = self.env['mail.mass_mailing.contact'] mass_mailing_lists = self.env['mail.mass_mailing.list'] mass_mailing_optout = self.env['mail.mass_mailing.list_contact_rel'] mass_mailing = self.env['mail.mass_mailing'] # create mailing contact record mailing_contact_1 = mass_mailing_contacts.create({'name': 'test email 1', 'email': 'test1@email.com'}) mailing_contact_2 = mass_mailing_contacts.create({'name': 'test email 2', 'email': 'test2@email.com'}) # create mailing list record mailing_list_1 = mass_mailing_lists.create({ 'name': 'A', 'contact_ids': [ (4, mailing_contact_1.id), (4, mailing_contact_2.id) ] }) mailing_list_2 = mass_mailing_lists.create({ 'name': 'B', 'contact_ids': [ (4, mailing_contact_1.id), (4, mailing_contact_2.id) ] }) # Set Opt out mass_mailing_optout.search([('contact_id', '=', mailing_contact_1.id), ('list_id', '=', mailing_list_1.id)]).write({ 'opt_out': True, }) # create mass mailing record self.mass_mailing = mass_mailing.create({ 'name': 'One', 'subject': 'One', 'mailing_model_id': self.env['ir.model']._get(mass_mailing_contacts).id, 'body_html': 'This is mass mail marketing demo'}) self.mass_mailing.contact_list_ids = [mailing_list_1.id, mailing_list_2.id] self.mass_mailing.put_in_queue() composer_values = { 'body': self.mass_mailing.convert_links()[self.mass_mailing.id], 'subject': self.mass_mailing.name, 'model': self.mass_mailing.mailing_model_real, 'email_from': self.mass_mailing.email_from, 'composition_mode': 'mass_mail', 'mass_mailing_id': self.mass_mailing.id, 'mailing_list_ids': [(4, l.id) for l in self.mass_mailing.contact_list_ids], } composer = self.env['mail.compose.message'].with_context( active_ids=[mailing_contact_1.id, mailing_contact_2.id], mass_mailing_seen_list=self.mass_mailing._get_seen_list(), mass_mailing_opt_out_list=self.mass_mailing._get_opt_out_list()).create(composer_values) composer.send_mail() # if user is opt_out on One list but not on another, send the mail anyway self.assertEqual(self.mass_mailing.ignored, 0, 'Opt Out ignored email number incorrect, should be equals to 0') def test_04_mass_mail_multi_users_different_opt_out(self): mass_mailing_contacts = self.env['mail.mass_mailing.contact'] mass_mailing_lists = self.env['mail.mass_mailing.list'] mass_mailing_optout = self.env['mail.mass_mailing.list_contact_rel'] mass_mailing = self.env['mail.mass_mailing'] # create mailing contact record mailing_contact_1 = mass_mailing_contacts.create({'name': 'test email (A)', 'email': 'test@email.com'}) mailing_contact_2 = mass_mailing_contacts.create({'name': 'test email (B)', 'email': 'test@email.com'}) # create mailing list record mailing_list_1 = mass_mailing_lists.create({ 'name': 'A', 'contact_ids': [ (4, mailing_contact_1.id), (4, mailing_contact_2.id) ] }) # Set Opt out mass_mailing_optout.search([('contact_id', '=', mailing_contact_1.id), ('list_id', '=', mailing_list_1.id)]).write({ 'opt_out': True, }) # create mass mailing record self.mass_mailing = mass_mailing.create({ 'name': 'One', 'subject': 'One', 'mailing_model_id': self.env['ir.model']._get(mass_mailing_contacts).id, 'body_html': 'This is mass mail marketing demo'}) self.mass_mailing.contact_list_ids = [mailing_list_1.id] self.mass_mailing.put_in_queue() composer_values = { 'body': self.mass_mailing.convert_links()[self.mass_mailing.id], 'subject': self.mass_mailing.name, 'model': self.mass_mailing.mailing_model_real, 'email_from': self.mass_mailing.email_from, 'composition_mode': 'mass_mail', 'mass_mailing_id': self.mass_mailing.id, 'mailing_list_ids': [(4, l.id) for l in self.mass_mailing.contact_list_ids], } composer = self.env['mail.compose.message'].with_context( active_ids=[mailing_contact_1.id, mailing_contact_2.id], mass_mailing_seen_list=self.mass_mailing._get_seen_list(), mass_mailing_opt_out_list=self.mass_mailing._get_opt_out_list()).create(composer_values) composer.send_mail() # if user A is opt_out on One list but user B is not opt_out on same list, # send the mail anyway to the opt-in contact. Ignore (as normal behaviour) opted-out contact. self.assertEqual(self.mass_mailing.ignored, 1, 'Opt Out ignored email number incorrect, should be equals to 1') class TestOnResPartner(TransactionCase): def test_mass_mail_on_res_partner(self): partners = self.env['res.partner'] mass_mailing = self.env['mail.mass_mailing'] # create mailing contact record partner_a = partners.create({ 'name': 'test email 1', 'email': 'test1@email.com', }) partner_b = partners.create({ 'name': 'test email 2', 'email': 'test2@email.com', }) # Set Blacklist self.blacklist_contact_entry = self.env['mail.blacklist'].create({ 'email': 'Test2@email.com', }) # create mass mailing record self.mass_mailing = mass_mailing.create({ 'name': 'One', 'subject': 'One', 'mailing_domain': [('id', 'in', [partner_a.id, partner_b.id])], 'body_html': 'This is mass mail marketing demo'}) self.mass_mailing.mailing_model_real = 'res.partner' self.mass_mailing.put_in_queue() res_ids = self.mass_mailing.get_remaining_recipients() composer_values = { 'body': self.mass_mailing.convert_links()[self.mass_mailing.id], 'subject': self.mass_mailing.name, 'model': self.mass_mailing.mailing_model_real, 'email_from': self.mass_mailing.email_from, 'composition_mode': 'mass_mail', 'mass_mailing_id': self.mass_mailing.id, 'mailing_list_ids': [(4, l.id) for l in self.mass_mailing.contact_list_ids], } composer = self.env['mail.compose.message'].with_context( active_ids=res_ids, mass_mailing_seen_list=self.mass_mailing._get_seen_list()).create(composer_values) composer.send_mail() # if user is opt_out on One list but not on another, send the mail anyway self.assertEqual(self.mass_mailing.ignored, 1, 'Blacklisted ignored email number incorrect, should be equals to 1')