Files
odoo_source/addons/website_crm/tests/test_website_visitor.py
T
Aurélien Warnon a0d33b1c29 [IMP] website[_event|_crm]: unlink visitors when inactive & enforce linked visitors
PURPOSE

Visitors are useful in terms of marketing analysis but they can bloat the
database really quickly if you have a lot of traffic on your website.
This commit aims to relieve the database by fully deleting inactive visitors.

SPECS

On an active website, you can easily reach hundreds or even thousands of
visitors per day.
While active visitors are useful for marketing purposes, inactive ones were
archived after a period of inactivity (i.e: not connected for X days in a row,
where X is configurable as a parameter and 30 by default).

But archiving visitors is not really useful either.
We don't see any specific cases where you would want to restore some visitors.
That means we are better off unlinking the visitors completely to save database
storage space.

We want to make exceptions and avoid deletion of inactive visitors in some
cases:
- When they are linked to a partner (meaning most likely linked to a
  registered user)
- When they are linked to leads
- When they are registered to events

Several tests were added to ensure that leads matching these conditions are not
unlinked.

We also took this opportunity to enforce the "_link_to_visitor" rules in those
tests to make sure that:
- When visitors are linked, the leads are merged into the main visitor
- When visitors are linked, the event tickets are merged into the main visitor
- When visitors are linked, the wishlisted tracks are merged into the main
  visitor

This is also preliminary work for a commit that will move the push_token of
website.visitors to a separate table.
That will in turn allow us to link the push_tokens within the
"_link_to_visitor" method and delete the linked visitor instead of archiving
it.

LINKS

Task-2410217

Part-of: odoo/odoo#65113
2022-02-17 17:37:40 +00:00

126 lines
4.9 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import datetime, timedelta
from odoo.addons.crm.tests.common import TestCrmCommon
from odoo.addons.website.tests.test_website_visitor import WebsiteVisitorTests
from odoo.tests import tagged
from odoo.tests.common import users
@tagged('website_visitor')
class TestWebsiteVisitor(TestCrmCommon, WebsiteVisitorTests):
def setUp(self):
super(TestWebsiteVisitor, self).setUp()
self.test_partner = self.env['res.partner'].create({
'name': 'Test Customer',
'email': '"Test Customer" <test@test.example.com>',
'country_id': self.env.ref('base.be').id,
'mobile': '+32456001122'
})
@users('user_sales_manager')
def test_compute_email_phone(self):
visitor_sudo = self.env['website.visitor'].sudo().create({
'name': 'Mega Visitor',
})
visitor = visitor_sudo.with_user(self.env.user) # as of 13.0 salesmen cannot create visitors, only read them
customer = self.test_partner.with_user(self.env.user)
self.assertFalse(visitor.email)
self.assertFalse(visitor.mobile)
# partner information copied on visitor -> behaves like related
visitor_sudo.write({'partner_id': self.test_partner.id})
self.assertEqual(visitor.email, customer.email_normalized)
self.assertEqual(visitor.mobile, customer.mobile)
# if reset -> behaves like a related, also reset on visitor
visitor_sudo.write({'partner_id': False})
self.assertFalse(visitor.email)
self.assertFalse(visitor.mobile)
# first lead created -> updates email
lead_1 = self.env['crm.lead'].create({
'name': 'Test Lead 1',
'email_from': 'Rambeau Fort <beaufort@test.example.com',
'visitor_ids': [(4, visitor.id)],
})
self.assertEqual(visitor.email, lead_1.email_normalized)
self.assertFalse(visitor.mobile)
# second lead created -> keep first email but takes mobile as not defined before
lead_2 = self.env['crm.lead'].create({
'name': 'Test Lead 1',
'email_from': 'Martino Brie <brie@test.example.com',
'country_id': self.env.ref('base.be').id,
'mobile': '+32456001122',
'visitor_ids': [(4, visitor.id)],
})
self.assertEqual(visitor.email, lead_1.email_normalized)
self.assertEqual(visitor.mobile, lead_2.mobile)
# partner win on leads
visitor_sudo.write({'partner_id': self.test_partner.id})
self.assertEqual(visitor.email, customer.email_normalized)
self.assertEqual(visitor.mobile, customer.mobile)
# partner updated -> fallback on leads
customer.write({'mobile': False})
self.assertEqual(visitor.email, customer.email_normalized)
self.assertEqual(visitor.mobile, lead_2.mobile)
@tagged('website_visitor')
def test_clean_inactive_visitors_crm(self):
""" Visitors attached to leads should not be deleted even if not connected recently. """
active_visitors = self.env['website.visitor'].create([{
'name': 'Lead Carl',
'lang_id': self.env.ref('base.lang_en').id,
'country_id': self.env.ref('base.be').id,
'website_id': 1,
'last_connection_datetime': datetime.now() - timedelta(days=8),
'lead_ids': [(0, 0, {
'name': 'Lead Carl'
})]
}])
self._test_unlink_old_visitors(self.env['website.visitor'], active_visitors)
@tagged('website_visitor')
def test_link_to_visitor_crm(self):
""" Same as parent's 'test_link_to_visitor' except we also test that leads
are merged into main visitor. """
[main_visitor, linked_visitor] = self.env['website.visitor'].create([
self._prepare_main_visitor_data(),
self._prepare_linked_visitor_data()
])
all_leads = (main_visitor + linked_visitor).lead_ids
linked_visitor._link_to_visitor(main_visitor)
self.assertVisitorDeactivated(linked_visitor, main_visitor)
# leads of both visitors should be merged into main one
self.assertEqual(len(main_visitor.lead_ids), 2)
self.assertEqual(main_visitor.lead_ids, all_leads)
for lead in all_leads:
self.assertEqual(lead.visitor_ids, main_visitor)
def _prepare_main_visitor_data(self):
values = super()._prepare_main_visitor_data()
values.update({
'lead_ids': [(0, 0, {
'name': 'Mitchel Main Lead'
})]
})
return values
def _prepare_linked_visitor_data(self):
values = super()._prepare_linked_visitor_data()
values.update({
'lead_ids': [(0, 0, {
'name': 'Mitchel Secondary Lead'
})]
})
return values