summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorThibault Delavallée <tde@odoo.com>2020-10-05 14:17:28 +0000
committerThibault Delavallée <tde@odoo.com>2020-10-06 14:47:39 +0000
commit950dd491bc4b680e0bcfab83815313e909a3c282 (patch)
treee4fd4941f2dc8c8475b5a1c179aed55de5a0abb2 /addons
parentf21b3c5cff74f935f0f221d1b690f4a4fb44e003 (diff)
[IMP] crm: move and add some test for lead user assign
Purpose of this commit is to * move tests about mass management of leads (mass assignment + mass convert wizards) in its own file to ease writing of tests; * add some performance tests : * performance for assignment; * performance for convert wizard in mass mode; Task ID-2351604 PR #59084
Diffstat (limited to 'addons')
-rw-r--r--addons/crm/tests/__init__.py1
-rw-r--r--addons/crm/tests/common.py22
-rw-r--r--addons/crm/tests/test_crm_activity.py3
-rw-r--r--addons/crm/tests/test_crm_lead_convert.py144
-rw-r--r--addons/crm/tests/test_crm_lead_convert_mass.py212
-rw-r--r--addons/sales_team/tests/common.py18
6 files changed, 250 insertions, 150 deletions
diff --git a/addons/crm/tests/__init__.py b/addons/crm/tests/__init__.py
index e8c18d42468..793d217c703 100644
--- a/addons/crm/tests/__init__.py
+++ b/addons/crm/tests/__init__.py
@@ -3,6 +3,7 @@
from . import test_crm_lead
from . import test_crm_lead_notification
from . import test_crm_lead_convert
+from . import test_crm_lead_convert_mass
from . import test_crm_lead_lost
from . import test_crm_lead_merge
from . import test_crm_activity
diff --git a/addons/crm/tests/common.py b/addons/crm/tests/common.py
index b94acd89b03..f46e1fd265f 100644
--- a/addons/crm/tests/common.py
+++ b/addons/crm/tests/common.py
@@ -6,6 +6,7 @@ from unittest.mock import patch
from odoo.addons.mail.tests.common import MailCase, mail_new_test_user
from odoo.addons.sales_team.tests.common import TestSalesCommon
from odoo.fields import Datetime
+from odoo import tools
INCOMING_EMAIL = """Return-Path: {return_path}
X-Original-To: {to}
@@ -150,7 +151,7 @@ class TestCrmCommon(TestSalesCommon, MailCase):
'zip': '97648',
})
- def _create_leads_batch(self, lead_type='lead', count=10):
+ def _create_leads_batch(self, lead_type='lead', count=10, partner_ids=None, user_ids=None):
""" Helper tool method creating a batch of leads, useful when dealing
with batch processes. Please update me.
@@ -158,14 +159,28 @@ class TestCrmCommon(TestSalesCommon, MailCase):
None (depends on configuration);
"""
types = ['lead', 'opportunity']
- partners = [self.contact_1.id, self.contact_2.id, False]
leads_data = [{
'name': 'TestLead_%02d' % (x),
'type': lead_type if lead_type else types[x % 2],
- 'partner_id': partners[x % 3],
'priority': '%s' % (x % 3),
} for x in range(count)]
+ # customer information
+ if partner_ids:
+ for idx, lead_data in enumerate(leads_data):
+ lead_data['partner_id'] = partner_ids[idx % len(partner_ids)]
+ else:
+ for idx, lead_data in enumerate(leads_data):
+ lead_data['email_from'] = tools.formataddr((
+ 'TestCustomer_%02d' % (idx),
+ 'customer_email_%02d@example.com' % (idx)
+ ))
+
+ # salesteam information
+ if user_ids:
+ for idx, lead_data in enumerate(leads_data):
+ lead_data['user_id'] = user_ids[idx % len(user_ids)]
+
return self.env['crm.lead'].create(leads_data)
def _create_duplicates(self, lead, create_opp=True):
@@ -247,6 +262,7 @@ class TestLeadConvertCommon(TestCrmCommon):
cls.sales_team_convert = cls.env['crm.team'].create({
'name': 'Convert Sales Team',
+ 'sequence': 10,
'alias_name': False,
'use_leads': True,
'use_opportunities': True,
diff --git a/addons/crm/tests/test_crm_activity.py b/addons/crm/tests/test_crm_activity.py
index 6f57b5dbd19..44eb0310492 100644
--- a/addons/crm/tests/test_crm_activity.py
+++ b/addons/crm/tests/test_crm_activity.py
@@ -42,7 +42,7 @@ class TestCrmMailActivity(TestCrmCommon):
# Initialize some batch data
default_order = self.env['crm.lead']._order
self.assertEqual(default_order, "priority desc, id desc") # force updating this test is order changes
- test_leads = self._create_leads_batch(count=10).sorted('id')
+ test_leads = self._create_leads_batch(count=10, partner_ids=[self.contact_1.id, self.contact_2.id, False]).sorted('id')
# assert initial data, ensure we did not break base behavior
for lead in test_leads:
@@ -108,7 +108,6 @@ class TestCrmMailActivity(TestCrmCommon):
search_res = self.env['crm.lead'].search(_domain, limit=None, offset=3, order=_order)
self.assertEqual(expected_leads_desc[3:].ids, search_res.ids)
-
def test_crm_activity_recipients(self):
""" This test case checks
- no internal subtype followed by client
diff --git a/addons/crm/tests/test_crm_lead_convert.py b/addons/crm/tests/test_crm_lead_convert.py
index e830e0888d1..71532306629 100644
--- a/addons/crm/tests/test_crm_lead_convert.py
+++ b/addons/crm/tests/test_crm_lead_convert.py
@@ -406,147 +406,3 @@ class TestLeadConvertBatch(crm_common.TestLeadConvertMassCommon):
self.assertEqual(opp.stage_id, self.stage_gen_1) # did not change
else:
self.assertFalse(True)
-
-
-@tagged('lead_manage')
-class TestLeadConvertMass(crm_common.TestLeadConvertMassCommon):
-
- @classmethod
- def setUpClass(cls):
- super(TestLeadConvertMass, cls).setUpClass()
-
- cls.leads = cls.lead_1 + cls.lead_w_partner + cls.lead_w_email_lost
- cls.assign_users = cls.user_sales_manager + cls.user_sales_leads_convert + cls.user_sales_salesman
-
- @users('user_sales_manager')
- def test_mass_convert_internals(self):
- """ Test internals mass converted in convert mode, without duplicate management """
- # reset some assigned users to test salesmen assign
- (self.lead_w_partner | self.lead_w_email_lost).write({
- 'user_id': False
- })
-
- mass_convert = self.env['crm.lead2opportunity.partner.mass'].with_context({
- 'active_model': 'crm.lead',
- 'active_ids': self.leads.ids,
- 'active_id': self.leads.ids[0]
- }).create({
- 'deduplicate': False,
- 'user_id': self.user_sales_salesman.id,
- 'force_assignment': False,
- })
-
- # default values
- self.assertEqual(mass_convert.name, 'convert')
- self.assertEqual(mass_convert.action, 'each_exist_or_create')
- # depending on options
- self.assertEqual(mass_convert.partner_id, self.env['res.partner'])
- self.assertEqual(mass_convert.deduplicate, False)
- self.assertEqual(mass_convert.user_id, self.user_sales_salesman)
- self.assertEqual(mass_convert.team_id, self.sales_team_convert)
-
- mass_convert.action_mass_convert()
- for lead in self.lead_1 | self.lead_w_partner:
- self.assertEqual(lead.type, 'opportunity')
- if lead == self.lead_w_partner:
- self.assertEqual(lead.user_id, self.env['res.users']) # user_id is bypassed
- self.assertEqual(lead.partner_id, self.contact_1)
- elif lead == self.lead_1:
- self.assertEqual(lead.user_id, self.user_sales_leads) # existing value not forced
- new_partner = lead.partner_id
- self.assertEqual(new_partner.name, 'Amy Wong')
- self.assertEqual(new_partner.email, 'amy.wong@test.example.com')
-
- # test unforced assignation
- mass_convert.write({
- 'user_ids': self.user_sales_salesman.ids,
- })
- mass_convert.action_mass_convert()
- self.assertEqual(self.lead_w_partner.user_id, self.user_sales_salesman)
- self.assertEqual(self.lead_1.user_id, self.user_sales_leads) # existing value not forced
-
- # lost leads are untouched
- self.assertEqual(self.lead_w_email_lost.type, 'lead')
- self.assertFalse(self.lead_w_email_lost.active)
- self.assertFalse(self.lead_w_email_lost.date_conversion)
- # TDE FIXME: partner creation is done even on lost leads because not checked in wizard
- # self.assertEqual(self.lead_w_email_lost.partner_id, self.env['res.partner'])
-
- def test_mass_convert_deduplicate(self):
- """ Test duplicated_lead_ids fields having another behavior in mass convert
- because why not. Its use is: among leads under convert, store those with
- duplicates if deduplicate is set to True. """
- lead_1_dups = self._create_duplicates(self.lead_1, create_opp=False)
- lead_1_final = self.lead_1 # after merge: same but with lower ID
-
- lead_w_partner_dups = self._create_duplicates(self.lead_w_partner, create_opp=False)
- lead_w_partner_final = lead_w_partner_dups[0] # lead_w_partner has no stage -> lower in sort by confidence
- lead_w_partner_dups_partner = lead_w_partner_dups[1] # copy with a partner_id (with the same email)
-
- mass_convert = self.env['crm.lead2opportunity.partner.mass'].with_context({
- 'active_model': 'crm.lead',
- 'active_ids': self.leads.ids,
- }).create({
- 'deduplicate': True,
- })
- self.assertEqual(mass_convert.action, 'each_exist_or_create')
- self.assertEqual(mass_convert.name, 'convert')
- self.assertEqual(mass_convert.lead_tomerge_ids, self.leads)
- self.assertEqual(mass_convert.duplicated_lead_ids, self.lead_1 | self.lead_w_partner)
-
- mass_convert.action_mass_convert()
-
- self.assertEqual(
- (lead_1_dups | lead_w_partner_dups | lead_w_partner_dups_partner).exists(),
- lead_w_partner_final
- )
- for lead in lead_1_final | lead_w_partner_final:
- self.assertTrue(lead.active)
- self.assertEqual(lead.type, 'opportunity')
-
- def test_mass_convert_find_existing(self):
- """ Check that we don't find a wrong partner
- that have similar name during mass conversion
- """
- wrong_partner = self.env['res.partner'].create({
- 'name': 'casa depapel',
- 'street': "wrong street"
- })
-
- lead = self.env['crm.lead'].create({'name': 'Asa Depape'})
- mass_convert = self.env['crm.lead2opportunity.partner.mass'].with_context({
- 'active_model': 'crm.lead',
- 'active_ids': lead.ids,
- 'active_id': lead.ids[0]
- }).create({
- 'deduplicate': False,
- 'action': 'each_exist_or_create',
- 'name': 'convert',
- })
- mass_convert.action_mass_convert()
-
- self.assertNotEqual(lead.partner_id, wrong_partner, "Partner Id should not match the wrong contact")
-
- def test_mass_convert_w_salesmen(self):
- # reset some assigned users to test salesmen assign
- (self.lead_w_partner | self.lead_w_email_lost).write({
- 'user_id': False
- })
-
- mass_convert = self.env['crm.lead2opportunity.partner.mass'].with_context({
- 'active_model': 'crm.lead',
- 'active_ids': self.leads.ids,
- 'active_id': self.leads.ids[0]
- }).create({
- 'deduplicate': False,
- 'user_ids': self.assign_users.ids,
- 'force_assignment': True,
- })
-
- # TDE FIXME: what happens if we mix people from different sales team ? currently nothing, to check
- mass_convert.action_mass_convert()
-
- for idx, lead in enumerate(self.leads - self.lead_w_email_lost):
- self.assertEqual(lead.type, 'opportunity')
- assigned_user = self.assign_users[idx % len(self.assign_users)]
- self.assertEqual(lead.user_id, assigned_user)
diff --git a/addons/crm/tests/test_crm_lead_convert_mass.py b/addons/crm/tests/test_crm_lead_convert_mass.py
new file mode 100644
index 00000000000..05c347301a6
--- /dev/null
+++ b/addons/crm/tests/test_crm_lead_convert_mass.py
@@ -0,0 +1,212 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo.addons.crm.tests import common as crm_common
+from odoo.tests.common import tagged, users
+
+
+@tagged('lead_manage')
+class TestLeadConvertMass(crm_common.TestLeadConvertMassCommon):
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestLeadConvertMass, cls).setUpClass()
+
+ cls.leads = cls.lead_1 + cls.lead_w_partner + cls.lead_w_email_lost
+ cls.assign_users = cls.user_sales_manager + cls.user_sales_leads_convert + cls.user_sales_salesman
+
+ @users('user_sales_manager')
+ def test_assignment_salesmen(self):
+ test_leads = self._create_leads_batch(count=50, user_ids=[False])
+ user_ids = self.assign_users.ids
+ self.assertEqual(test_leads.user_id, self.env['res.users'])
+
+ with self.assertQueryCount(user_sales_manager=0):
+ test_leads = self.env['crm.lead'].browse(test_leads.ids)
+
+ with self.assertQueryCount(user_sales_manager=330):
+ test_leads.handle_salesmen_assignment(user_ids=user_ids, team_id=False)
+
+ self.assertEqual(test_leads.team_id, self.sales_team_convert | self.sales_team_1)
+ self.assertEqual(test_leads[0::3].user_id, self.user_sales_manager)
+ self.assertEqual(test_leads[1::3].user_id, self.user_sales_leads_convert)
+ self.assertEqual(test_leads[2::3].user_id, self.user_sales_salesman)
+
+ @users('user_sales_manager')
+ def test_assignment_salesmen_wteam(self):
+ test_leads = self._create_leads_batch(count=50, user_ids=[False])
+ user_ids = self.assign_users.ids
+ team_id = self.sales_team_convert.id
+ self.assertEqual(test_leads.user_id, self.env['res.users'])
+
+ with self.assertQueryCount(user_sales_manager=0):
+ test_leads = self.env['crm.lead'].browse(test_leads.ids)
+
+ with self.assertQueryCount(user_sales_manager=342):
+ test_leads.handle_salesmen_assignment(user_ids=user_ids, team_id=team_id)
+
+ self.assertEqual(test_leads.team_id, self.sales_team_convert)
+ self.assertEqual(test_leads[0::3].user_id, self.user_sales_manager)
+ self.assertEqual(test_leads[1::3].user_id, self.user_sales_leads_convert)
+ self.assertEqual(test_leads[2::3].user_id, self.user_sales_salesman)
+
+ @users('user_sales_manager')
+ def test_mass_convert_internals(self):
+ """ Test internals mass converted in convert mode, without duplicate management """
+ # reset some assigned users to test salesmen assign
+ (self.lead_w_partner | self.lead_w_email_lost).write({
+ 'user_id': False
+ })
+
+ mass_convert = self.env['crm.lead2opportunity.partner.mass'].with_context({
+ 'active_model': 'crm.lead',
+ 'active_ids': self.leads.ids,
+ 'active_id': self.leads.ids[0]
+ }).create({
+ 'deduplicate': False,
+ 'user_id': self.user_sales_salesman.id,
+ 'force_assignment': False,
+ })
+
+ # default values
+ self.assertEqual(mass_convert.name, 'convert')
+ self.assertEqual(mass_convert.action, 'each_exist_or_create')
+ # depending on options
+ self.assertEqual(mass_convert.partner_id, self.env['res.partner'])
+ self.assertEqual(mass_convert.deduplicate, False)
+ self.assertEqual(mass_convert.user_id, self.user_sales_salesman)
+ self.assertEqual(mass_convert.team_id, self.sales_team_convert)
+
+ mass_convert.action_mass_convert()
+ for lead in self.lead_1 | self.lead_w_partner:
+ self.assertEqual(lead.type, 'opportunity')
+ if lead == self.lead_w_partner:
+ self.assertEqual(lead.user_id, self.env['res.users']) # user_id is bypassed
+ self.assertEqual(lead.partner_id, self.contact_1)
+ elif lead == self.lead_1:
+ self.assertEqual(lead.user_id, self.user_sales_leads) # existing value not forced
+ new_partner = lead.partner_id
+ self.assertEqual(new_partner.name, 'Amy Wong')
+ self.assertEqual(new_partner.email, 'amy.wong@test.example.com')
+
+ # test unforced assignation
+ mass_convert.write({
+ 'user_ids': self.user_sales_salesman.ids,
+ })
+ mass_convert.action_mass_convert()
+ self.assertEqual(self.lead_w_partner.user_id, self.user_sales_salesman)
+ self.assertEqual(self.lead_1.user_id, self.user_sales_leads) # existing value not forced
+
+ # lost leads are untouched
+ self.assertEqual(self.lead_w_email_lost.type, 'lead')
+ self.assertFalse(self.lead_w_email_lost.active)
+ self.assertFalse(self.lead_w_email_lost.date_conversion)
+ # TDE FIXME: partner creation is done even on lost leads because not checked in wizard
+ # self.assertEqual(self.lead_w_email_lost.partner_id, self.env['res.partner'])
+
+ @users('user_sales_manager')
+ def test_mass_convert_deduplicate(self):
+ """ Test duplicated_lead_ids fields having another behavior in mass convert
+ because why not. Its use is: among leads under convert, store those with
+ duplicates if deduplicate is set to True. """
+ lead_1_dups = self._create_duplicates(self.lead_1, create_opp=False)
+ lead_1_final = self.lead_1 # after merge: same but with lower ID
+
+ lead_w_partner_dups = self._create_duplicates(self.lead_w_partner, create_opp=False)
+ lead_w_partner_final = lead_w_partner_dups[0] # lead_w_partner has no stage -> lower in sort by confidence
+ lead_w_partner_dups_partner = lead_w_partner_dups[1] # copy with a partner_id (with the same email)
+
+ mass_convert = self.env['crm.lead2opportunity.partner.mass'].with_context({
+ 'active_model': 'crm.lead',
+ 'active_ids': self.leads.ids,
+ }).create({
+ 'deduplicate': True,
+ })
+ self.assertEqual(mass_convert.action, 'each_exist_or_create')
+ self.assertEqual(mass_convert.name, 'convert')
+ self.assertEqual(mass_convert.lead_tomerge_ids, self.leads)
+ self.assertEqual(mass_convert.duplicated_lead_ids, self.lead_1 | self.lead_w_partner)
+
+ mass_convert.action_mass_convert()
+
+ self.assertEqual(
+ (lead_1_dups | lead_w_partner_dups | lead_w_partner_dups_partner).exists(),
+ lead_w_partner_final
+ )
+ for lead in lead_1_final | lead_w_partner_final:
+ self.assertTrue(lead.active)
+ self.assertEqual(lead.type, 'opportunity')
+
+ @users('user_sales_manager')
+ def test_mass_convert_find_existing(self):
+ """ Check that we don't find a wrong partner
+ that have similar name during mass conversion
+ """
+ wrong_partner = self.env['res.partner'].create({
+ 'name': 'casa depapel',
+ 'street': "wrong street"
+ })
+
+ lead = self.env['crm.lead'].create({'name': 'Asa Depape'})
+ mass_convert = self.env['crm.lead2opportunity.partner.mass'].with_context({
+ 'active_model': 'crm.lead',
+ 'active_ids': lead.ids,
+ 'active_id': lead.ids[0]
+ }).create({
+ 'deduplicate': False,
+ 'action': 'each_exist_or_create',
+ 'name': 'convert',
+ })
+ mass_convert.action_mass_convert()
+
+ self.assertNotEqual(lead.partner_id, wrong_partner, "Partner Id should not match the wrong contact")
+
+ @users('user_sales_manager')
+ def test_mass_convert_performances(self):
+ test_leads = self._create_leads_batch(count=50, user_ids=[False])
+ user_ids = self.assign_users.ids
+
+ with self.assertQueryCount(user_sales_manager=1472):
+ mass_convert = self.env['crm.lead2opportunity.partner.mass'].with_context({
+ 'active_model': 'crm.lead',
+ 'active_ids': test_leads.ids,
+ }).create({
+ 'deduplicate': True,
+ 'user_ids': user_ids,
+ 'force_assignment': True,
+ })
+ mass_convert.action_mass_convert()
+
+ self.assertEqual(set(test_leads.mapped('type')), set(['opportunity']))
+ self.assertEqual(len(test_leads.partner_id), len(test_leads))
+ # TDE FIXME: strange
+ # self.assertEqual(test_leads.team_id, self.sales_team_convert | self.sales_team_1)
+ self.assertEqual(test_leads.team_id, self.sales_team_1)
+ self.assertEqual(test_leads[0::3].user_id, self.user_sales_manager)
+ self.assertEqual(test_leads[1::3].user_id, self.user_sales_leads_convert)
+ self.assertEqual(test_leads[2::3].user_id, self.user_sales_salesman)
+
+ @users('user_sales_manager')
+ def test_mass_convert_w_salesmen(self):
+ # reset some assigned users to test salesmen assign
+ (self.lead_w_partner | self.lead_w_email_lost).write({
+ 'user_id': False
+ })
+
+ mass_convert = self.env['crm.lead2opportunity.partner.mass'].with_context({
+ 'active_model': 'crm.lead',
+ 'active_ids': self.leads.ids,
+ 'active_id': self.leads.ids[0]
+ }).create({
+ 'deduplicate': False,
+ 'user_ids': self.assign_users.ids,
+ 'force_assignment': True,
+ })
+
+ # TDE FIXME: what happens if we mix people from different sales team ? currently nothing, to check
+ mass_convert.action_mass_convert()
+
+ for idx, lead in enumerate(self.leads - self.lead_w_email_lost):
+ self.assertEqual(lead.type, 'opportunity')
+ assigned_user = self.assign_users[idx % len(self.assign_users)]
+ self.assertEqual(lead.user_id, assigned_user)
diff --git a/addons/sales_team/tests/common.py b/addons/sales_team/tests/common.py
index a06f97c02c2..665245d1396 100644
--- a/addons/sales_team/tests/common.py
+++ b/addons/sales_team/tests/common.py
@@ -11,6 +11,21 @@ class TestSalesCommon(SavepointCase):
def setUpClass(cls):
super(TestSalesCommon, cls).setUpClass()
+ # Salesmen organization
+ # ------------------------------------------------------------
+ # Role: M (team member) R (team manager)
+ # SALESMAN---------------sales_team_1
+ # admin------------------M-----------
+ # user_sales_manager-----R-----------
+ # user_sales_leads-------M-----------
+ # user_sales_salesman----/-----------
+
+ # Sales teams organization
+ # ------------------------------------------------------------
+ # SALESTEAM-----------SEQU-----COMPANY
+ # sales_team_1--------5--------False
+ # data----------------9999-----??
+
cls.company_main = cls.env.user.company_id
cls.user_sales_manager = mail_new_test_user(
cls.env, login='user_sales_manager',
@@ -33,6 +48,7 @@ class TestSalesCommon(SavepointCase):
notification_type='inbox',
groups='sales_team.group_sale_salesman',
)
+ cls.user_admin = cls.env.ref('base.user_admin')
cls.env['crm.team'].search([]).write({'sequence': 9999})
cls.sales_team_1 = cls.env['crm.team'].create({
@@ -40,7 +56,7 @@ class TestSalesCommon(SavepointCase):
'sequence': 5,
'company_id': False,
'user_id': cls.user_sales_manager.id,
- 'member_ids': [(4, cls.user_sales_leads.id), (4, cls.env.ref('base.user_admin').id)],
+ 'member_ids': [(4, cls.user_sales_leads.id), (4, cls.user_admin.id)],
})