1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
|
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import datetime, timedelta
from odoo.addons.mass_mailing.tests.common import MassMailCommon
from odoo.tests import Form, users, tagged
from odoo.tools import mute_logger
from odoo import fields
@tagged('post_install', '-at_install')
class TestMailingABTesting(MassMailCommon):
def setUp(self):
super().setUp()
self.mailing_list = self._create_mailing_list_of_x_contacts(150)
self.ab_testing_mailing_1 = self.env['mailing.mailing'].create({
'subject': 'A/B Testing V1',
'contact_list_ids': self.mailing_list.ids,
'ab_testing_enabled': True,
'ab_testing_pc': 10,
'ab_testing_schedule_datetime': datetime.now(),
})
self.ab_testing_mailing_2 = self.ab_testing_mailing_1.copy({
'subject': 'A/B Testing V2',
'ab_testing_pc': 20,
})
self.ab_testing_campaign = self.ab_testing_mailing_1.campaign_id
self.ab_testing_mailing_ids = self.ab_testing_mailing_1 + self.ab_testing_mailing_2
self.env.flush_all()
self.env.invalidate_all()
@mute_logger('odoo.addons.mail.models.mail_mail')
@users('user_marketing')
def test_mailing_ab_testing_auto_flow(self):
with self.mock_mail_gateway():
self.ab_testing_mailing_ids.action_send_mail()
self.assertEqual(self.ab_testing_mailing_1.state, 'done')
self.assertEqual(self.ab_testing_mailing_2.state, 'done')
self.assertEqual(self.ab_testing_mailing_1.opened_ratio, 0)
self.assertEqual(self.ab_testing_mailing_2.opened_ratio, 0)
total_trace_ids = self.ab_testing_mailing_ids.mailing_trace_ids
unique_recipients_used = set(map(lambda mail: mail.res_id, total_trace_ids.mail_mail_id))
self.assertEqual(len(self.ab_testing_mailing_1.mailing_trace_ids), 15)
self.assertEqual(len(self.ab_testing_mailing_2.mailing_trace_ids), 30)
self.assertEqual(len(unique_recipients_used), 45)
self.ab_testing_mailing_1.mailing_trace_ids[:10].set_opened()
self.ab_testing_mailing_2.mailing_trace_ids[:15].set_opened()
self.ab_testing_mailing_ids.invalidate_recordset()
self.assertEqual(self.ab_testing_mailing_1.opened_ratio, 66.67)
self.assertEqual(self.ab_testing_mailing_2.opened_ratio, 50)
with self.mock_mail_gateway():
self.ab_testing_mailing_2.action_send_winner_mailing()
self.ab_testing_mailing_ids.invalidate_recordset()
winner_mailing = self.ab_testing_campaign.mailing_mail_ids.filtered(lambda mailing: mailing.ab_testing_pc == 100)
self.assertEqual(winner_mailing.subject, 'A/B Testing V1')
@mute_logger('odoo.addons.mail.models.mail_mail')
@users('user_marketing')
def test_mailing_ab_testing_auto_flow_cron(self):
self.ab_testing_mailing_1.write({
'ab_testing_schedule_datetime': datetime.now() + timedelta(days=-1),
})
with self.mock_mail_gateway():
self.ab_testing_mailing_ids.action_send_mail()
self.assertEqual(self.ab_testing_mailing_1.state, 'done')
self.assertEqual(self.ab_testing_mailing_2.state, 'done')
self.assertEqual(self.ab_testing_mailing_1.opened_ratio, 0)
self.assertEqual(self.ab_testing_mailing_2.opened_ratio, 0)
total_trace_ids = self.ab_testing_mailing_ids.mailing_trace_ids
unique_recipients_used = set(map(lambda mail: mail.res_id, total_trace_ids.mail_mail_id))
self.assertEqual(len(self.ab_testing_mailing_1.mailing_trace_ids), 15)
self.assertEqual(len(self.ab_testing_mailing_2.mailing_trace_ids), 30)
self.assertEqual(len(unique_recipients_used), 45)
self.ab_testing_mailing_1.mailing_trace_ids[:10].set_opened()
self.ab_testing_mailing_2.mailing_trace_ids[:15].set_opened()
self.ab_testing_mailing_ids.invalidate_recordset()
self.assertEqual(self.ab_testing_mailing_1.opened_ratio, 66.67)
self.assertEqual(self.ab_testing_mailing_2.opened_ratio, 50)
with self.mock_mail_gateway():
self.env.ref('mass_mailing.ir_cron_mass_mailing_ab_testing').sudo().method_direct_trigger()
self.ab_testing_mailing_ids.invalidate_recordset()
winner_mailing = self.ab_testing_campaign.mailing_mail_ids.filtered(lambda mailing: mailing.ab_testing_pc == 100)
self.assertEqual(winner_mailing.subject, 'A/B Testing V1')
@users('user_marketing')
def test_mailing_ab_testing_campaign(self):
schedule_datetime = datetime.now() + timedelta(days=30)
ab_mailing = self.env['mailing.mailing'].create({
'subject': 'A/B Testing V1',
'contact_list_ids': self.mailing_list.ids,
'ab_testing_enabled': True,
'ab_testing_winner_selection': 'manual',
'ab_testing_schedule_datetime': schedule_datetime,
})
ab_mailing.invalidate_recordset()
# Check if the campaign is correctly created and the values set on the mailing are still the same
self.assertTrue(ab_mailing.campaign_id, "A campaign id is present for the A/B test mailing")
self.assertEqual(ab_mailing.ab_testing_winner_selection, 'manual', "The selection winner has been propagated correctly")
self.assertEqual(ab_mailing.ab_testing_schedule_datetime, schedule_datetime, "The schedule date has been propagated correctly")
# Check that while enabling the A/B testing, if campaign is already set, new one should not be created
created_mailing_campaign = ab_mailing.campaign_id
ab_mailing.ab_testing_enabled = False
ab_mailing.ab_testing_enabled = True
self.assertEqual(ab_mailing.campaign_id, created_mailing_campaign, "No new campaign should have been created")
# Check that while enabling the A/B testing, if user manually selects a campaign, it should be saved
# rather than being replaced with the automatically created one
ab_mailing.write({'ab_testing_enabled': False, 'campaign_id': False})
ab_mailing.write({'ab_testing_enabled': True, 'campaign_id': created_mailing_campaign})
self.assertEqual(ab_mailing.campaign_id, created_mailing_campaign, "No new campaign should have been created")
ab_mailing_2 = self.env['mailing.mailing'].create({
'subject': 'A/B Testing V2',
'contact_list_ids': self.mailing_list.ids,
})
ab_mailing_2.invalidate_recordset()
ab_mailing_2.ab_testing_enabled = True
# Check if the campaign is correctly created with default values
self.assertTrue(ab_mailing.campaign_id, "A campaign id is present for the A/B test mailing")
self.assertTrue(ab_mailing.ab_testing_winner_selection, "The selection winner has been set to default value")
self.assertTrue(ab_mailing.ab_testing_schedule_datetime, "The schedule date has been set to default value")
@users('user_marketing')
def test_mailing_ab_testing_compare(self):
# compare version feature should returns all mailings of the same
# campaign having a/b testing enabled.
compare_version = self.ab_testing_mailing_1.action_compare_versions()
self.assertEqual(
self.env['mailing.mailing'].search(compare_version.get('domain')),
self.ab_testing_mailing_1 + self.ab_testing_mailing_2
)
@mute_logger('odoo.addons.mail.models.mail_mail')
@users('user_marketing')
def test_mailing_ab_testing_manual_flow(self):
self.ab_testing_mailing_1.write({
'ab_testing_winner_selection': 'manual',
})
with self.mock_mail_gateway():
self.ab_testing_mailing_ids.action_send_mail()
self.assertEqual(self.ab_testing_mailing_1.state, 'done')
self.assertEqual(self.ab_testing_mailing_2.state, 'done')
self.assertEqual(self.ab_testing_mailing_1.opened_ratio, 0)
self.assertEqual(self.ab_testing_mailing_2.opened_ratio, 0)
total_trace_ids = self.ab_testing_mailing_ids.mailing_trace_ids
unique_recipients_used = set(map(lambda mail: mail.res_id, total_trace_ids.mail_mail_id))
self.assertEqual(len(self.ab_testing_mailing_1.mailing_trace_ids), 15)
self.assertEqual(len(self.ab_testing_mailing_2.mailing_trace_ids), 30)
self.assertEqual(len(unique_recipients_used), 45)
self.ab_testing_mailing_1.mailing_trace_ids[:10].set_opened()
self.ab_testing_mailing_2.mailing_trace_ids[:15].set_opened()
self.ab_testing_mailing_ids.invalidate_recordset()
self.assertEqual(self.ab_testing_mailing_1.opened_ratio, 66.67)
self.assertEqual(self.ab_testing_mailing_2.opened_ratio, 50)
with self.mock_mail_gateway():
self.ab_testing_mailing_2.action_send_winner_mailing()
self.ab_testing_mailing_ids.invalidate_recordset()
winner_mailing = self.ab_testing_campaign.mailing_mail_ids.filtered(lambda mailing: mailing.ab_testing_pc == 100)
self.assertEqual(winner_mailing.subject, 'A/B Testing V2')
@mute_logger('odoo.addons.mail.models.mail_mail')
@users('user_marketing')
def test_mailing_ab_testing_minimum_participants(self):
""" Test that it should send minimum one mail(if possible) when ab_testing_pc is too small compared to the amount of targeted records."""
mailing_list = self._create_mailing_list_of_x_contacts(10)
ab_testing = self.env['mailing.mailing'].create({
'subject': 'A/B Testing SMS V1',
'contact_list_ids': mailing_list.ids,
'ab_testing_enabled': True,
'ab_testing_pc': 2,
'ab_testing_schedule_datetime': datetime.now(),
'mailing_type': 'mail',
'campaign_id': self.ab_testing_campaign.id,
})
with self.mock_mail_gateway():
ab_testing.action_send_mail()
self.assertEqual(ab_testing.state, 'done')
self.assertEqual(len(self._mails), 1)
def test_mailing_ab_testing_duplicate_date(self):
""" Test that "Send final on" date value should be copied in new mass_mailing """
ab_testing_mail_1 = Form(self.ab_testing_mailing_1)
ab_testing_mail_1.ab_testing_schedule_datetime = datetime.now() + timedelta(days=10)
action = ab_testing_mail_1.save().action_duplicate()
ab_testing_mailing_2 = self.env[action['res_model']].browse(action['res_id'])
self.assertEqual(fields.Datetime.to_string(ab_testing_mailing_2.ab_testing_schedule_datetime), ab_testing_mail_1.ab_testing_schedule_datetime)
|