summaryrefslogtreecommitdiff
path: root/addons/crm/tests
diff options
context:
space:
mode:
authorJérome Maes <jem@openerp.com>2016-06-20 10:32:07 +0200
committerJérome Maes <jem@openerp.com>2016-07-04 17:28:04 +0200
commitf3c1eceae76d442e43e213a0db3a681bd1d79e6f (patch)
treee7bb099a73add9c40e6b55bcc9e944298f288b76 /addons/crm/tests
parentaa44700dccdc2618e0b8bc94252789264104047c (diff)
[MIG] crm : convert yml tests into testcase python
Convert from yml file into python test cases. Tests are group according to the scope (crm.lead operation, messaging, business, ...)
Diffstat (limited to 'addons/crm/tests')
-rw-r--r--addons/crm/tests/__init__.py2
-rw-r--r--addons/crm/tests/common.py32
-rw-r--r--addons/crm/tests/customer_request.eml30
-rw-r--r--addons/crm/tests/test_crm_lead.py180
-rw-r--r--addons/crm/tests/test_lead2opportunity.py156
-rw-r--r--addons/crm/tests/test_new_lead_notification.py1
6 files changed, 398 insertions, 3 deletions
diff --git a/addons/crm/tests/__init__.py b/addons/crm/tests/__init__.py
index 69d299aea81..b6e7a816642 100644
--- a/addons/crm/tests/__init__.py
+++ b/addons/crm/tests/__init__.py
@@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-
+import test_crm_lead
import test_new_lead_notification
+import test_lead2opportunity
diff --git a/addons/crm/tests/common.py b/addons/crm/tests/common.py
index b59be71bada..7a04e27ddb9 100644
--- a/addons/crm/tests/common.py
+++ b/addons/crm/tests/common.py
@@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from openerp.addons.mail.tests.common import TestMail
-
+from odoo.tests.common import TransactionCase
+from odoo.addons.mail.tests.common import TestMail
class TestCrm(TestMail):
@@ -19,9 +20,34 @@ class TestCrm(TestMail):
'login': 'riton',
'alias_name': 'riton',
'email': 'riton.salesman_all@example.com',
- 'groups_id': [(6, 0, [user_group_employee.id, user_group_salesman_all.id])]})
+ 'groups_id': [(6, 0, [user_group_employee.id, user_group_salesman_all.id])]
+ })
cls.sales_team_1 = cls.env['crm.team'].create({
'name': 'Test Sales Team',
'alias_name': 'test_sales_team',
})
+
+
+class TestCrmCases(TransactionCase):
+
+ def setUp(self):
+ super(TestCrmCases, self).setUp()
+
+ # Create a user as 'Crm Salesmanager' and added the `sales manager` group
+ self.crm_salemanager = self.env['res.users'].create({
+ 'company_id': self.env.ref("base.main_company").id,
+ 'name': "Crm Sales manager",
+ 'login': "csm",
+ 'email': "crmmanager@yourcompany.com",
+ 'groups_id': [(6, 0, [self.ref('sales_team.group_sale_manager')])]
+ })
+
+ # Create a user as 'Crm Salesman' and added few groups
+ self.crm_salesman = self.env['res.users'].create({
+ 'company_id': self.env.ref("base.main_company").id,
+ 'name': "Crm Salesman",
+ 'login': "csu",
+ 'email': "crmuser@yourcompany.com",
+ 'groups_id': [(6, 0, [self.env.ref('sales_team.group_sale_salesman_all_leads').id, self.env.ref('base.group_partner_manager').id])]
+ })
diff --git a/addons/crm/tests/customer_request.eml b/addons/crm/tests/customer_request.eml
new file mode 100644
index 00000000000..2c6c5e8110d
--- /dev/null
+++ b/addons/crm/tests/customer_request.eml
@@ -0,0 +1,30 @@
+Return-Path: <info@customer.com>
+X-Original-To: info@customer.com
+Delivered-To: sales@my.com
+Received: by mail.my.com (Postfix, from userid xxx)
+ id 822ECBFB67; Mon, 24 Oct 2011 07:36:51 +0200 (CEST)
+X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.my.com
+X-Spam-Level:
+X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED autolearn=ham
+ version=3.3.1
+Received: from [192.168.1.146]
+ (Authenticated sender: info@mail.customer.com)
+ by mail.customer.com (Postfix) with ESMTPSA id 07A30BFAB4
+ for <sales@my.com>; Mon, 24 Oct 2011 07:36:50 +0200 (CEST)
+Message-ID: <4EA4F95D.904@customer.com>
+Date: Mon, 24 Oct 2011 11:06:29 +0530
+From: Mr. John Right <info@customer.com>
+User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.14) Gecko/20110223 Lightning/1.0b2 Thunderbird/3.1.8
+MIME-Version: 1.0
+To: sales@my.com
+Subject: Fournir votre devis avec le meilleur prix.
+Content-Type: text/plain; charset=ISO-8859-1; format=flowed
+Content-Transfer-Encoding: 8bit
+
+Bonjour l'équipe de vente,
+
+Je veux acheter vos produits et services.
+
+S'il vous plaît fournir votre cotation avec le meilleur prix.
+
+Merci
diff --git a/addons/crm/tests/test_crm_lead.py b/addons/crm/tests/test_crm_lead.py
new file mode 100644
index 00000000000..7ff20c4ab5e
--- /dev/null
+++ b/addons/crm/tests/test_crm_lead.py
@@ -0,0 +1,180 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from .common import TestCrmCases
+from odoo.modules.module import get_module_resource
+
+
+class TestCRMLead(TestCrmCases):
+
+ def test_crm_lead_cancel(self):
+ # I set a new sale team giving access rights of salesman.
+ team = self.env['crm.team'].sudo(self.crm_salemanager.id).create({'name': "Phone Marketing"})
+ lead = self.env.ref('crm.crm_case_1')
+ lead.sudo(self.crm_salemanager.id).write({'team_id': team.id})
+ # Salesmananger check unqualified lead
+ self.assertEqual(lead.stage_id.sequence, 1, 'Lead is in new stage')
+
+ def test_crm_lead_copy(self):
+ # I make duplicate the Lead
+ self.env.ref('crm.crm_case_4').copy()
+
+ def test_crm_lead_unlink(self):
+ # Only Sales manager Unlink the Lead so test with Manager's access rights
+ self.env.ref('crm.crm_case_4').sudo(self.crm_salemanager.id).unlink()
+
+ def test_find_stage(self):
+ # I create a new lead
+ lead = self.env['crm.lead'].create({
+ 'type': "lead",
+ 'name': "Test lead new",
+ 'partner_id': self.env.ref("base.res_partner_1").id,
+ 'description': "This is the description of the test new lead.",
+ 'team_id': self.env.ref("sales_team.team_sales_department").id
+ })
+ # I change type from lead to opportunity
+ lead.convert_opportunity(self.env.ref("base.res_partner_2").id)
+ # I check default stage of opportunity
+ self.assertLessEqual(lead.stage_id.sequence, 1, "Default stage of lead is incorrect!")
+
+ # Now I change the stage of opportunity to won.
+ lead.action_set_won()
+ # I check stage of opp should won, after change stage.
+ stage_id = lead._stage_find(domain=[('probability', '=', 100.0)])
+ self.assertEqual(stage_id, lead.stage_id, "Stage of opportunity is incorrect!")
+
+ def test_crm_lead_message(self):
+ # Give the access rights of Salesman to communicate with customer
+ # Customer interested in our product, so he sends request by email to get more details.
+ # Mail script will fetch his request from mail server. Then I process that mail after read EML file.
+ request_file = open(get_module_resource('crm', 'tests', 'customer_request.eml'), 'rb')
+ request_message = request_file.read()
+ self.env['mail.thread'].sudo(self.crm_salesman).message_process('crm.lead', request_message)
+
+ # After getting the mail, I check details of new lead of that customer
+ lead = self.env['crm.lead'].sudo(self.crm_salesman).search([('email_from', '=', 'Mr. John Right <info@customer.com>')], limit=1)
+ self.assertTrue(lead.ids, 'Fail to create merge opportunity wizard')
+ self.assertFalse(lead.partner_id, 'Customer should be a new one')
+ self.assertEqual(lead.name, 'Fournir votre devis avec le meilleur prix.', 'Subject does not match')
+
+ # I reply his request with welcome message.
+ # TODO revert mail.mail to mail.compose.message (conversion to customer should be automatic).
+ lead = self.env['crm.lead'].search([('email_from', '=', 'Mr. John Right <info@customer.com>')], limit=1)
+ mail = self.env['mail.compose.message'].with_context(active_model='crm.lead', active_id=lead.id).create({
+ 'body': "Merci de votre intérêt pour notre produit, nous vous contacterons bientôt. Bien à vous",
+ 'email_from': 'sales@mycompany.com'
+ })
+ try:
+ mail.send_mail()
+ except:
+ pass
+
+ # Now, I convert him into customer and put him into regular customer list
+ lead = self.env['crm.lead'].search([('email_from', '=', 'Mr. John Right <info@customer.com>')], limit=1)
+ lead.handle_partner_assignation()
+
+ def test_crm_lead_merge(self):
+ # During a mixed merge (involving leads and opps), data should be handled a certain way following their type (m2o, m2m, text, ...) Start by creating two leads and an opp and giving the rights of Sales manager.
+ default_stage_id = self.ref("crm.stage_lead1")
+ LeadSalesmanager = self.env['crm.lead'].sudo(self.crm_salemanager.id)
+
+ # TEST CASE 1
+ test_crm_opp_01 = LeadSalesmanager.create({
+ 'type': 'opportunity',
+ 'name': 'Test opportunity 1',
+ 'partner_id': self.env.ref("base.res_partner_3").id,
+ 'stage_id': default_stage_id,
+ 'description': 'This is the description of the test opp 1.'
+ })
+
+ test_crm_lead_01 = LeadSalesmanager.create({
+ 'type': 'lead',
+ 'name': 'Test lead first',
+ 'partner_id': self.env.ref("base.res_partner_1").id,
+ 'stage_id': default_stage_id,
+ 'description': 'This is the description of the test lead first.'
+ })
+
+ test_crm_lead_02 = LeadSalesmanager.create({
+ 'type': 'lead',
+ 'name': 'Test lead second',
+ 'partner_id': self.env.ref("base.res_partner_1").id,
+ 'stage_id': default_stage_id,
+ 'description': 'This is the description of the test lead second.'
+ })
+
+ lead_ids = [test_crm_opp_01.id, test_crm_lead_01.id, test_crm_lead_02.id]
+ additionnal_context = {'active_model': 'crm.lead', 'active_ids': lead_ids, 'active_id': lead_ids[0]}
+
+ # I create a merge wizard and merge the leads and opp together in the first item of the list.
+ merge_opp_wizard_01 = self.env['crm.merge.opportunity'].sudo(self.crm_salemanager.id).with_context(**additionnal_context).create({})
+ merge_opp_wizard_01.action_merge()
+
+ # I check for the resulting merged opp (based on name and partner)
+ merged_lead = self.env['crm.lead'].search([('name', '=', 'Test opportunity 1'), ('partner_id', '=', self.env.ref("base.res_partner_3").id)], limit=1)
+ self.assertTrue(merged_lead, 'Fail to create merge opportunity wizard')
+ self.assertEqual(merged_lead.description, 'This is the description of the test opp 1.\n\nThis is the description of the test lead first.\n\nThis is the description of the test lead second.', 'Description mismatch: when merging leads/opps with different text values, these values should get concatenated and separated with line returns')
+ self.assertEqual(merged_lead.type, 'opportunity', 'Type mismatch: when at least one opp in involved in the merge, the result should be a new opp (instead of %s)' % merged_lead.type)
+
+ # The other (tailing) leads/opps shouldn't exist anymore
+ self.assertFalse(test_crm_lead_01.exists(), 'This tailing lead (id %s) should not exist anymore' % test_crm_lead_02.id)
+ self.assertFalse(test_crm_lead_02.exists(), 'This tailing opp (id %s) should not exist anymore' % test_crm_opp_01.id)
+
+ # TEST CASE 2
+ # I want to test leads merge. Start by creating two leads (with the same partner)
+ test_crm_lead_03 = LeadSalesmanager.create({
+ 'type': 'lead',
+ 'name': 'Test lead 3',
+ 'partner_id': self.env.ref("base.res_partner_1").id,
+ 'stage_id': default_stage_id
+ })
+
+ test_crm_lead_04 = LeadSalesmanager.create({
+ 'type': 'lead',
+ 'name': 'Test lead 4',
+ 'partner_id': self.env.ref("base.res_partner_1").id,
+ 'stage_id': default_stage_id
+ })
+
+ lead_ids = [test_crm_lead_03.id, test_crm_lead_04.id]
+ additionnal_context = {'active_model': 'crm.lead', 'active_ids': lead_ids, 'active_id': lead_ids[0]}
+
+ # I create a merge wizard and merge the leads together.
+ merge_opp_wizard_02 = self.env['crm.merge.opportunity'].sudo(self.crm_salemanager.id).with_context(**additionnal_context).create({})
+ merge_opp_wizard_02.action_merge()
+
+ # I check for the resulting merged lead (based on name and partner)
+ merged_lead = self.env['crm.lead'].search([('name', '=', 'Test lead 3'), ('partner_id', '=', self.env.ref("base.res_partner_1").id)], limit=1)
+ self.assertTrue(merged_lead, 'Fail to create merge opportunity wizard')
+ self.assertEqual(merged_lead.partner_id.id, self.env.ref("base.res_partner_1").id, 'Partner mismatch')
+ self.assertEqual(merged_lead.type, 'lead', 'Type mismatch: when leads get merged together, the result should be a new lead (instead of %s)' % merged_lead.type)
+ self.assertFalse(test_crm_lead_04.exists(), 'This tailing lead (id %s) should not exist anymore' % test_crm_lead_04.id)
+
+ # TEST CASE 3
+ # I want to test opps merge. Start by creating two opportunities (with the same partner).
+ test_crm_opp_02 = LeadSalesmanager.create({
+ 'type': 'opportunity',
+ 'name': 'Test opportunity 2',
+ 'partner_id': self.env.ref("base.res_partner_3").id,
+ 'stage_id': default_stage_id
+ })
+
+ test_crm_opp_03 = LeadSalesmanager.create({
+ 'type': 'opportunity',
+ 'name': 'Test opportunity 3',
+ 'partner_id': self.env.ref("base.res_partner_3").id,
+ 'stage_id': default_stage_id
+ })
+
+ opportunity_ids = [test_crm_opp_02.id, test_crm_opp_03.id]
+ additionnal_context = {'active_model': 'crm.lead', 'active_ids': opportunity_ids, 'active_id': opportunity_ids[0]}
+
+ # I create a merge wizard and merge the opps together.
+ merge_opp_wizard_03 = self.env['crm.merge.opportunity'].sudo(self.crm_salemanager.id).with_context(**additionnal_context).create({})
+ merge_opp_wizard_03.action_merge()
+
+ merged_opportunity = self.env['crm.lead'].search([('name', '=', 'Test opportunity 2'), ('partner_id', '=', self.env.ref("base.res_partner_3").id)], limit=1)
+ self.assertTrue(merged_opportunity, 'Fail to create merge opportunity wizard')
+ self.assertEqual(merged_opportunity.partner_id.id, self.env.ref("base.res_partner_3").id, 'Partner mismatch')
+ self.assertEqual(merged_opportunity.type, 'opportunity', 'Type mismatch: when opps get merged together, the result should be a new opp (instead of %s)' % merged_opportunity.type)
+ self.assertFalse(test_crm_opp_03.exists(), 'This tailing opp (id %s) should not exist anymore' % test_crm_opp_03.id)
diff --git a/addons/crm/tests/test_lead2opportunity.py b/addons/crm/tests/test_lead2opportunity.py
new file mode 100644
index 00000000000..d69e58e7fb9
--- /dev/null
+++ b/addons/crm/tests/test_lead2opportunity.py
@@ -0,0 +1,156 @@
+# -*- coding: utf-8 -*-
+
+from .common import TestCrmCases
+
+
+class TestLead2opportunity2win(TestCrmCases):
+
+ def test_lead2opportunity2win(self):
+ """ Tests for Test Lead 2 opportunity 2 win """
+ CrmLead2OpportunityPartnerMass = self.env['crm.lead2opportunity.partner.mass']
+ CalendarAttendee = self.env['calendar.attendee']
+ default_stage_id = self.ref("crm.stage_lead1")
+
+ crm_case_2 = self.env.ref('crm.crm_case_2')
+ crm_case_3 = self.env.ref('crm.crm_case_3')
+ crm_case_13 = self.env.ref('crm.crm_case_13')
+
+ # In order to test the conversion of a lead into a opportunity,
+ # I set lead to open stage.
+ crm_case_3.write({'stage_id': default_stage_id})
+
+ # I check if the lead stage is "Open".
+ self.assertEqual(crm_case_3.stage_id.sequence, 1, 'Lead stage is Open')
+
+ # Giving access rights of salesman to convert the lead into opportunity.
+ # I convert lead into opportunity for exiting customer.
+ crm_case_3.sudo(self.crm_salemanager.id).convert_opportunity(self.env.ref("base.res_partner_2").id)
+
+ # I check details of converted opportunity.
+ self.assertEqual(crm_case_3.type, 'opportunity', 'Lead is not converted to opportunity!')
+ self.assertEqual(crm_case_3.partner_id.id, self.env.ref("base.res_partner_2").id, 'Partner mismatch!')
+ self.assertEqual(crm_case_3.stage_id.id, default_stage_id, 'Stage of opportunity is incorrect!')
+
+ # Now I schedule meeting with customer.
+ crm_case_3.action_schedule_meeting()
+
+ # After communicated with customer, I put some notes with contract details.
+ crm_case_3.message_post(subject='Test note', body='Détails envoyés par le client sur ​​le FAX pour la qualité')
+
+ # I convert mass lead into opportunity customer.
+ mass = CrmLead2OpportunityPartnerMass.with_context({'active_model': 'crm.lead', 'active_ids': [crm_case_13.id, crm_case_2.id], 'active_id': crm_case_13.id}).create({
+ 'user_ids': [(6, 0, self.env.ref('base.user_root').ids)],
+ 'team_id': self.env.ref("sales_team.team_sales_department").id
+ })
+ mass.sudo(self.crm_salemanager.id).mass_convert()
+
+ # Now I check first lead converted on opportunity.
+ self.assertEqual(crm_case_13.name, "Plan to buy 60 keyboards and mouses", "Opportunity name not correct")
+ self.assertEqual(crm_case_13.type, 'opportunity', "Lead is not converted to opportunity!")
+ expected_partner = "Will McEncroe"
+ self.assertEqual(crm_case_13.partner_id.name, expected_partner, "Partner mismatch! %s vs %s" % (crm_case_13.partner_id.name, expected_partner))
+ self.assertEqual(crm_case_13.stage_id.id, default_stage_id, "Stage of probability is incorrect!")
+
+ # Then check for second lead converted on opportunity.
+ self.assertEqual(crm_case_2.name, "Interest in Your New Software", "Opportunity name not correct")
+ self.assertEqual(crm_case_2.type, "opportunity", "Lead is not converted to opportunity!")
+ self.assertEqual(crm_case_2.stage_id.id, default_stage_id, "Stage of probability is incorrect!")
+
+ # I loose the second opportunity
+ crm_case_2.case_mark_lost()
+
+ # I check details of the opportunity after the loose
+ self.assertEqual(crm_case_2.probability, 0.0, "Revenue probability should be 0.0!")
+
+ # I confirm review needs meeting.
+ self.env.ref('calendar.calendar_event_4').with_context({'active_model': 'calendar.event'}).write({'state': 'open'})
+
+ # I invite a user for meeting.
+ CalendarAttendee.create({'partner_id': self.ref('base.partner_root'), 'email': 'user@meeting.com'}).do_accept()
+
+ def test_lead2opportunity_assign_salesmen(self):
+ """ Tests for Test Lead2opportunity Assign Salesmen """
+ CrmLead2OpportunityPartnerMass = self.env['crm.lead2opportunity.partner.mass']
+ LeadSaleman = self.env['crm.lead'].sudo(self.crm_salesman.id)
+ default_stage_id = self.ref("crm.stage_lead1")
+
+ # During a lead to opp conversion, salesmen should be assigned to leads following the round-robin method. Start by creating 4 salesmen (A to D) and 6 leads (1 to 6).
+ test_res_user_01 = self.env['res.users'].create({
+ 'name': 'Test user A',
+ 'login': 'tua@example.com',
+ 'new_password': 'tua'
+ })
+ test_res_user_02 = self.env['res.users'].create({
+ 'name': 'Test user B',
+ 'login': 'tub@example.com',
+ 'new_password': 'tub'
+ })
+ test_res_user_03 = self.env['res.users'].create({
+ 'name': 'Test user C',
+ 'login': 'tuc@example.com',
+ 'new_password': 'tuc'
+ })
+ test_res_user_04 = self.env['res.users'].create({
+ 'name': 'Test user D',
+ 'login': 'tud@example.com',
+ 'new_password': 'tud'
+ })
+
+ # Salesman also creates lead so giving access rights of salesman.
+ test_crm_lead_01 = LeadSaleman.create({
+ 'type': 'lead',
+ 'name': 'Test lead 1',
+ 'email_from': 'Raoul Grosbedon <raoul@grosbedon.fr>',
+ 'stage_id': default_stage_id
+ })
+ test_crm_lead_02 = LeadSaleman.create({
+ 'type': 'lead',
+ 'name': 'Test lead 2',
+ 'email_from': 'Raoul Grosbedon <raoul@grosbedon.fr>',
+ 'stage_id': default_stage_id
+ })
+ test_crm_lead_03 = LeadSaleman.create({
+ 'type': 'lead',
+ 'name': 'Test lead 3',
+ 'email_from': 'Raoul Grosbedon <raoul@grosbedon.fr>',
+ 'stage_id': default_stage_id
+ })
+ test_crm_lead_04 = LeadSaleman.create({
+ 'type': 'lead',
+ 'name': 'Test lead 4',
+ 'email_from': 'Fabrice Lepoilu',
+ 'stage_id': default_stage_id
+ })
+ test_crm_lead_05 = LeadSaleman.create({
+ 'type': 'lead',
+ 'name': 'Test lead 5',
+ 'email_from': 'Fabrice Lepoilu',
+ 'stage_id': default_stage_id
+ })
+ test_crm_lead_06 = LeadSaleman.create({
+ 'type': 'lead',
+ 'name': 'Test lead 6',
+ 'email_from': 'Agrolait SuperSeed SA',
+ 'stage_id': default_stage_id
+ })
+
+ lead_ids = [test_crm_lead_01.id, test_crm_lead_02.id, test_crm_lead_03.id, test_crm_lead_04.id, test_crm_lead_05.id, test_crm_lead_06.id]
+ salesmen_ids = [test_res_user_01.id, test_res_user_02.id, test_res_user_03.id, test_res_user_04.id]
+
+ # Salesman create a mass convert wizard and convert all the leads.
+ additionnal_context = {'active_model': 'crm.lead', 'active_ids': lead_ids, 'active_id': test_crm_lead_01.id}
+ mass = CrmLead2OpportunityPartnerMass.sudo(self.crm_salesman.id).with_context(**additionnal_context).create({
+ 'user_ids': [(6, 0, salesmen_ids)],
+ 'team_id': self.env.ref("sales_team.team_sales_department").id,
+ 'deduplicate': False,
+ 'force_assignation': True
+ })
+ mass.sudo(self.crm_salesman.id).mass_convert()
+
+ # The leads should now be opps with a salesman and a salesteam. Also, salesmen should have been assigned following a round-robin method.
+ opps = self.env['crm.lead'].sudo(self.crm_salesman.id).browse(lead_ids)
+ i = 0
+ for opp in opps:
+ self.assertEqual(opp.type, 'opportunity', 'Type mismatch: this should be an opp, not a lead')
+ self.assertEqual(opp.user_id.id, salesmen_ids[i], 'Salesman mismatch: expected salesman %r, got %r' % (salesmen_ids[i], opp.user_id.id))
+ i = i + 1 if (i < len(salesmen_ids) - 1) else 0
diff --git a/addons/crm/tests/test_new_lead_notification.py b/addons/crm/tests/test_new_lead_notification.py
index 36c28767acb..819a3e70a2a 100644
--- a/addons/crm/tests/test_new_lead_notification.py
+++ b/addons/crm/tests/test_new_lead_notification.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
from .common import TestCrm