# Copyright 2016 Jairo Llopis # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import mock from odoo.tests.common import HttpCase from werkzeug import urls class UICase(HttpCase): _tour_run = "odoo.__DEBUG__.services['web_tour.tour'].run('%s')" _tour_ready = "odoo.__DEBUG__.services['web_tour.tour'].tours.%s.ready" def extract_url(self, mail, *args, **kwargs): url = mail._get_unsubscribe_url(self.email) self.assertTrue(urls.url_parse(url).decode_query().get('token')) self.assertTrue(url.startswith(self.domain)) self.url = url.replace(self.domain, "", 1) return True def setUp(self): super(UICase, self).setUp() self.email = "test.contact@example.com" self.mail_postprocess_patch = mock.patch( "odoo.addons.mass_mailing.models.mail_mail.MailMail." "_postprocess_sent_message", autospec=True, side_effect=self.extract_url, ) self.domain = self.env["ir.config_parameter"].get_param('web.base.url') List = self.lists = self.env["mail.mass_mailing.list"] for n in range(4): self.lists += List.create({"name": "test list %d" % n}) self.contact = self.env["mail.mass_mailing.contact"].create({ "name": "test contact", "email": self.email, "list_ids": [(6, False, self.lists.ids)], }) self.mailing = self.env["mail.mass_mailing"].create({ "name": "test mailing %d" % n, "mailing_model_id": self.env.ref( 'mass_mailing.model_mail_mass_mailing_list').id, "contact_list_ids": [ (6, 0, [self.lists[0].id, self.lists[3].id]) ], "reply_to_mode": "thread", }) self.mailing._onchange_model_and_list() # HACK https://github.com/odoo/odoo/pull/14429 self.mailing.body_html = """
This link should get the unsubscription URL
""" def tearDown(self): del self.email, self.lists, self.contact, self.mailing, self.url super(UICase, self).tearDown() def test_contact_unsubscription(self): """Test a mass mailing contact that wants to unsubscribe.""" # This list we are unsubscribing from, should appear always in UI self.lists[0].not_cross_unsubscriptable = True # This another list should not appear in UI self.lists[2].not_cross_unsubscriptable = True # This another list should not appear in UI, even if it is one of # the lists of the mailing self.lists[3].is_public = False # Extract the unsubscription link from the message body with self.mail_postprocess_patch: self.mailing.send_mail() tour = "mass_mailing_custom_unsubscribe_tour_contact" self.browser_js( url_path=self.url, code=self._tour_run % tour, ready=self._tour_ready % tour, login='demo') # Check results from running tour self.assertFalse(self.lists[0].subscription_contact_ids.opt_out) self.assertTrue(self.lists[1].subscription_contact_ids.opt_out) self.assertFalse(self.lists[2].subscription_contact_ids.opt_out) cnt = self.contact common_domain = [ ("mass_mailing_id", "=", self.mailing.id), ("email", "=", self.email), ("unsubscriber_id", "=", "%s,%d" % (cnt._name, cnt.id)), ] # first unsubscription reason = "mass_mailing_custom_unsubscribe.reason_other" unsubscription_1 = self.env["mail.unsubscription"].search( common_domain + [ ("action", "=", "unsubscription"), ("details", "=", "I want to unsubscribe because I want. " "Period."), ("reason_id", "=", self.env.ref(reason).id), ] ) # second unsubscription reason = "mass_mailing_custom_unsubscribe.reason_not_interested" unsubscription_2 = self.env["mail.unsubscription"].search( common_domain + [ ("action", "=", "unsubscription"), ("reason_id", "=", self.env.ref(reason).id), ] ) # re-subscription from self.lists[3] unsubscription_3 = self.env["mail.unsubscription"].search( common_domain + [ ("action", "=", "subscription"), ] ) # unsubscriptions above are all unsubscriptions saved during the # tour and they are all the existing unsubscriptions self.assertEqual( unsubscription_1 | unsubscription_2 | unsubscription_3, self.env["mail.unsubscription"].search([]) ) self.assertEqual(3, len(self.env["mail.unsubscription"].search([]))) def test_partner_unsubscription(self): """Test a partner that wants to unsubscribe.""" # Change mailing to be sent to partner partner_id = self.env["res.partner"].name_create( "Demo Partner <%s>" % self.email)[0] self.mailing.mailing_model_id = self.env.ref( "base.model_res_partner") self.mailing.mailing_domain = repr([ ('is_blacklisted', '=', False), ('id', '=', partner_id), ]) # Extract the unsubscription link from the message body with self.mail_postprocess_patch: self.mailing.send_mail() tour = "mass_mailing_custom_unsubscribe_tour_partner" self.phantom_js( url_path=self.url, code=self._tour_run % tour, ready=self._tour_ready % tour, login='demo') # Check results from running tour partner = self.env["res.partner"].browse(partner_id) self.assertTrue(partner.is_blacklisted) reason_xid = "mass_mailing_custom_unsubscribe.reason_not_interested" unsubscriptions = self.env["mail.unsubscription"].search([ ("action", "=", 'blacklist_add'), ("mass_mailing_id", "=", self.mailing.id), ("email", "=", self.email), ("unsubscriber_id", "=", "res.partner,%d" % partner_id), ("details", "=", False), ("reason_id", "=", self.env.ref(reason_xid).id), ]) self.assertEqual(1, len(unsubscriptions))