diff options
Diffstat (limited to 'addons/project/tests/test_multicompany.py')
| -rw-r--r-- | addons/project/tests/test_multicompany.py | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/addons/project/tests/test_multicompany.py b/addons/project/tests/test_multicompany.py new file mode 100644 index 00000000..5fc6b018 --- /dev/null +++ b/addons/project/tests/test_multicompany.py @@ -0,0 +1,292 @@ +# -*- coding: utf-8 -*- + +from contextlib import contextmanager + +from odoo.tests.common import SavepointCase, Form +from odoo.exceptions import AccessError, UserError + + +class TestMultiCompanyCommon(SavepointCase): + + @classmethod + def setUpMultiCompany(cls): + + # create companies + cls.company_a = cls.env['res.company'].create({ + 'name': 'Company A' + }) + cls.company_b = cls.env['res.company'].create({ + 'name': 'Company B' + }) + + # shared customers + cls.partner_1 = cls.env['res.partner'].create({ + 'name': 'Valid Lelitre', + 'email': 'valid.lelitre@agrolait.com', + 'company_id': False, + }) + cls.partner_2 = cls.env['res.partner'].create({ + 'name': 'Valid Poilvache', + 'email': 'valid.other@gmail.com', + 'company_id': False, + }) + + # users to use through the various tests + user_group_employee = cls.env.ref('base.group_user') + Users = cls.env['res.users'].with_context({'no_reset_password': True}) + + cls.user_employee_company_a = Users.create({ + 'name': 'Employee Company A', + 'login': 'employee-a', + 'email': 'employee@companya.com', + 'company_id': cls.company_a.id, + 'company_ids': [(6, 0, [cls.company_a.id])], + 'groups_id': [(6, 0, [user_group_employee.id])] + }) + cls.user_manager_company_a = Users.create({ + 'name': 'Manager Company A', + 'login': 'manager-a', + 'email': 'manager@companya.com', + 'company_id': cls.company_a.id, + 'company_ids': [(6, 0, [cls.company_a.id])], + 'groups_id': [(6, 0, [user_group_employee.id])] + }) + cls.user_employee_company_b = Users.create({ + 'name': 'Employee Company B', + 'login': 'employee-b', + 'email': 'employee@companyb.com', + 'company_id': cls.company_b.id, + 'company_ids': [(6, 0, [cls.company_b.id])], + 'groups_id': [(6, 0, [user_group_employee.id])] + }) + cls.user_manager_company_b = Users.create({ + 'name': 'Manager Company B', + 'login': 'manager-b', + 'email': 'manager@companyb.com', + 'company_id': cls.company_b.id, + 'company_ids': [(6, 0, [cls.company_b.id])], + 'groups_id': [(6, 0, [user_group_employee.id])] + }) + + @contextmanager + def sudo(self, login): + old_uid = self.uid + try: + user = self.env['res.users'].sudo().search([('login', '=', login)]) + # switch user + self.uid = user.id + self.env = self.env(user=self.uid) + yield + finally: + # back + self.uid = old_uid + self.env = self.env(user=self.uid) + + @contextmanager + def allow_companies(self, company_ids): + """ The current user will be allowed in each given companies (like he can sees all of them in the company switcher and they are all checked) """ + old_allow_company_ids = self.env.user.company_ids.ids + current_user = self.env.user + try: + current_user.write({'company_ids': company_ids}) + context = dict(self.env.context, allowed_company_ids=company_ids) + self.env = self.env(user=current_user, context=context) + yield + finally: + # back + current_user.write({'company_ids': old_allow_company_ids}) + context = dict(self.env.context, allowed_company_ids=old_allow_company_ids) + self.env = self.env(user=current_user, context=context) + + @contextmanager + def switch_company(self, company): + """ Change the company in which the current user is logged """ + old_companies = self.env.context.get('allowed_company_ids', []) + try: + # switch company in context + new_companies = list(old_companies) + if company.id not in new_companies: + new_companies = [company.id] + new_companies + else: + new_companies.insert(0, new_companies.pop(new_companies.index(company.id))) + context = dict(self.env.context, allowed_company_ids=new_companies) + self.env = self.env(context=context) + yield + finally: + # back + context = dict(self.env.context, allowed_company_ids=old_companies) + self.env = self.env(context=context) + + +class TestMultiCompanyProject(TestMultiCompanyCommon): + + @classmethod + def setUpClass(cls): + super(TestMultiCompanyProject, cls).setUpClass() + + cls.setUpMultiCompany() + + user_group_project_user = cls.env.ref('project.group_project_user') + user_group_project_manager = cls.env.ref('project.group_project_manager') + + # setup users + cls.user_employee_company_a.write({ + 'groups_id': [(4, user_group_project_user.id)] + }) + cls.user_manager_company_a.write({ + 'groups_id': [(4, user_group_project_manager.id)] + }) + cls.user_employee_company_b.write({ + 'groups_id': [(4, user_group_project_user.id)] + }) + cls.user_manager_company_b.write({ + 'groups_id': [(4, user_group_project_manager.id)] + }) + + # create project in both companies + Project = cls.env['project.project'].with_context({'mail_create_nolog': True, 'tracking_disable': True}) + cls.project_company_a = Project.create({ + 'name': 'Project Company A', + 'alias_name': 'project+companya', + 'partner_id': cls.partner_1.id, + 'company_id': cls.company_a.id, + 'type_ids': [ + (0, 0, { + 'name': 'New', + 'sequence': 1, + }), + (0, 0, { + 'name': 'Won', + 'sequence': 10, + }) + ] + }) + cls.project_company_b = Project.create({ + 'name': 'Project Company B', + 'alias_name': 'project+companyb', + 'partner_id': cls.partner_1.id, + 'company_id': cls.company_b.id, + 'type_ids': [ + (0, 0, { + 'name': 'New', + 'sequence': 1, + }), + (0, 0, { + 'name': 'Won', + 'sequence': 10, + }) + ] + }) + # already-existing tasks in company A and B + Task = cls.env['project.task'].with_context({'mail_create_nolog': True, 'tracking_disable': True}) + cls.task_1 = Task.create({ + 'name': 'Task 1 in Project A', + 'user_id': cls.user_employee_company_a.id, + 'project_id': cls.project_company_a.id + }) + cls.task_2 = Task.create({ + 'name': 'Task 2 in Project B', + 'user_id': cls.user_employee_company_b.id, + 'project_id': cls.project_company_b.id + }) + + def test_create_project(self): + """ Check project creation in multiple companies """ + with self.sudo('manager-a'): + project = self.env['project.project'].with_context({'tracking_disable': True}).create({ + 'name': 'Project Company A', + 'partner_id': self.partner_1.id, + }) + self.assertEqual(project.company_id, self.env.user.company_id, "A newly created project should be in the current user company") + + with self.switch_company(self.company_b): + with self.assertRaises(AccessError, msg="Manager can not create project in a company in which he is not allowed"): + project = self.env['project.project'].with_context({'tracking_disable': True}).create({ + 'name': 'Project Company B', + 'partner_id': self.partner_1.id, + 'company_id': self.company_b.id + }) + + # when allowed in other company, can create a project in another company (different from the one in which you are logged) + with self.allow_companies([self.company_a.id, self.company_b.id]): + project = self.env['project.project'].with_context({'tracking_disable': True}).create({ + 'name': 'Project Company B', + 'partner_id': self.partner_1.id, + 'company_id': self.company_b.id + }) + + def test_generate_analytic_account(self): + """ Check the analytic account generation, company propagation """ + with self.sudo('manager-b'): + with self.allow_companies([self.company_a.id, self.company_b.id]): + self.project_company_a._create_analytic_account() + + self.assertEqual(self.project_company_a.company_id, self.project_company_a.analytic_account_id.company_id, "The analytic account created from a project should be in the same company") + + def test_create_task(self): + with self.sudo('employee-a'): + # create task, set project; the onchange will set the correct company + with Form(self.env['project.task'].with_context({'tracking_disable': True})) as task_form: + task_form.name = 'Test Task in company A' + task_form.project_id = self.project_company_a + task = task_form.save() + + self.assertEqual(task.company_id, self.project_company_a.company_id, "The company of the task should be the one from its project.") + + def test_move_task(self): + with self.sudo('employee-a'): + with self.allow_companies([self.company_a.id, self.company_b.id]): + with Form(self.task_1) as task_form: + task_form.project_id = self.project_company_b + task = task_form.save() + + self.assertEqual(task.company_id, self.company_b, "The company of the task should be the one from its project.") + + with Form(self.task_1) as task_form: + task_form.project_id = self.project_company_a + task = task_form.save() + + self.assertEqual(task.company_id, self.company_a, "Moving a task should change its company.") + + def test_create_subtask(self): + with self.sudo('employee-a'): + with self.allow_companies([self.company_a.id, self.company_b.id]): + # create subtask, set parent; the onchange will set the correct company and subtask project + with Form(self.env['project.task'].with_context({'tracking_disable': True})) as task_form: + task_form.name = 'Test Subtask in company B' + task_form.parent_id = self.task_1 + task_form.project_id = self.project_company_b + + task = task_form.save() + + self.assertEqual(task.company_id, self.project_company_b.company_id, "The company of the subtask should be the one from its project, and not from its parent.") + + # set parent on existing orphan task; the onchange will set the correct company and subtask project + self.task_2.write({'project_id': False}) + with Form(self.task_2) as task_form: + task_form.name = 'Test Task 2 becomes child of Task 1 (other company)' + task_form.parent_id = self.task_1 + task = task_form.save() + + self.assertEqual(task.company_id, task.project_id.company_id, "The company of the orphan subtask should be the one from its project.") + + def test_cross_subtask_project(self): + # set up default subtask project + self.project_company_a.write({'allow_subtasks': True, 'subtask_project_id': self.project_company_b.id}) + + with self.sudo('employee-a'): + with self.allow_companies([self.company_a.id, self.company_b.id]): + with Form(self.env['project.task'].with_context({'tracking_disable': True})) as task_form: + task_form.name = 'Test Subtask in company B' + task_form.parent_id = self.task_1 + + task = task_form.save() + + self.assertEqual(task.project_id, self.task_1.project_id.subtask_project_id, "The default project of a subtask should be the default subtask project of the project from the mother task") + self.assertEqual(task.company_id, task.project_id.subtask_project_id.company_id, "The company of the orphan subtask should be the one from its project.") + self.assertEqual(self.task_1.child_ids.ids, [task.id]) + + with self.sudo('employee-a'): + with self.assertRaises(AccessError): + with Form(task) as task_form: + task_form.name = "Testing changing name in a company I can not read/write" |
