diff options
| -rw-r--r-- | addons/hr/tests/__init__.py | 1 | ||||
| -rw-r--r-- | addons/hr/tests/test_multi_company.py | 35 | ||||
| -rw-r--r-- | addons/test_website/controllers/main.py | 4 | ||||
| -rw-r--r-- | addons/test_website/tests/__init__.py | 1 | ||||
| -rw-r--r-- | addons/test_website/tests/test_multi_company.py | 16 | ||||
| -rw-r--r-- | addons/web/static/src/js/widgets/switch_company_menu.js | 33 | ||||
| -rw-r--r-- | addons/web/static/src/xml/base.xml | 8 | ||||
| -rw-r--r-- | addons/web/static/tests/widgets/company_switcher_tests.js | 169 | ||||
| -rw-r--r-- | addons/web/views/webclient_templates.xml | 1 |
9 files changed, 248 insertions, 20 deletions
diff --git a/addons/hr/tests/__init__.py b/addons/hr/tests/__init__.py index 27d9c2fbb81..c46b7cc336f 100644 --- a/addons/hr/tests/__init__.py +++ b/addons/hr/tests/__init__.py @@ -5,3 +5,4 @@ from . import test_hr_employee from . import test_channel from . import test_hr_flow from . import test_self_user_access +from . import test_multi_company diff --git a/addons/hr/tests/test_multi_company.py b/addons/hr/tests/test_multi_company.py new file mode 100644 index 00000000000..bbe26f9b365 --- /dev/null +++ b/addons/hr/tests/test_multi_company.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.tests import Form +from odoo.addons.hr.tests.common import TestHrCommon +from odoo.addons.base.models.qweb import QWebException + + +class TestMultiCompany(TestHrCommon): + + def setUp(self): + super().setUp() + self.company_1 = self.env['res.company'].create({'name': 'Opoo'}) + self.company_2 = self.env['res.company'].create({'name': 'Otoo'}) + self.employees = self.env['hr.employee'].create([ + {'name': 'Bidule', 'company_id': self.company_1.id}, + {'name': 'Machin', 'company_id': self.company_2.id}, + ]) + self.res_users_hr_officer.company_ids = [ + (4, self.company_1.id), + (4, self.company_2.id), + ] + + def test_multi_company_report(self): + content, content_type = self.env.ref('hr.hr_employee_print_badge').sudo(self.res_users_hr_officer).with_context( + allowed_company_ids=[self.company_1.id, self.company_2.id] + ).render_qweb_pdf(res_ids=self.employees.ids) + self.assertIn(b'Bidule', content) + self.assertIn(b'Machin', content) + + def test_single_company_report(self): + with self.assertRaises(QWebException): # CacheMiss followed by AccessError + content, content_type = self.env.ref('hr.hr_employee_print_badge').sudo(self.res_users_hr_officer).with_context( + allowed_company_ids=[self.company_1.id] + ).render_qweb_pdf(res_ids=self.employees.ids) diff --git a/addons/test_website/controllers/main.py b/addons/test_website/controllers/main.py index 259072c81ff..ae45d160b06 100644 --- a/addons/test_website/controllers/main.py +++ b/addons/test_website/controllers/main.py @@ -36,3 +36,7 @@ class WebsiteTest(Home): @http.route('/ignore_args/converter/<string:a>/nokw', type='http', auth="public", website=True) def test_ignore_args_converter_nokw(self, a, b='youhou'): return request.make_response(json.dumps(dict(a=a, b=b))) + + @http.route('/multi_company_website', type='http', auth="public", website=True) + def test_company_context(self): + return request.make_response(json.dumps(request.context.get('allowed_company_ids'))) diff --git a/addons/test_website/tests/__init__.py b/addons/test_website/tests/__init__.py index 40d4ece53e7..4bb004cd8f9 100644 --- a/addons/test_website/tests/__init__.py +++ b/addons/test_website/tests/__init__.py @@ -4,3 +4,4 @@ from . import test_controller_args from . import test_reset_views from . import test_views_during_module_operation +from . import test_multi_company diff --git a/addons/test_website/tests/test_multi_company.py b/addons/test_website/tests/test_multi_company.py new file mode 100644 index 00000000000..8c9c6859959 --- /dev/null +++ b/addons/test_website/tests/test_multi_company.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.tests.common import HttpCase, tagged + + +@tagged('post_install', '-at_install') +class TestMultiCompany(HttpCase): + + def test_company_in_context(self): + """ Test website company is set in context """ + website = self.env['website'].browse(1) + company = self.env['res.company'].create({'name': "Adaa"}) + website.company_id = company + response = self.url_open('/multi_company_website') + self.assertEqual(response.json()[0], company.id) diff --git a/addons/web/static/src/js/widgets/switch_company_menu.js b/addons/web/static/src/js/widgets/switch_company_menu.js index 62e2a27f3d0..75bc918768b 100644 --- a/addons/web/static/src/js/widgets/switch_company_menu.js +++ b/addons/web/static/src/js/widgets/switch_company_menu.js @@ -25,21 +25,25 @@ var SwitchCompanyMenu = Widget.extend({ * @override */ init: function () { - var self = this; this._super.apply(this, arguments); this.isMobile = config.device.isMobile; this._onSwitchCompanyClick = _.debounce(this._onSwitchCompanyClick, 1500, true); - this.allowed_company_ids = String(session.user_context.allowed_company_ids).split(','); - this.user_companies = session.user_companies.allowed_companies; + }, - var hash = $.bbq.getState() - if (!hash.cids || hash.cids === undefined) { - hash.cids = String(session.user_companies.current_company[0]); - } - this.current_company = parseInt(hash.cids.split(',')[0]); + /** + * @override + */ + willStart: function () { + var self = this; + this.allowed_company_ids = String(session.user_context.allowed_company_ids) + .split(',') + .map(function (id) {return parseInt(id);}); + this.user_companies = session.user_companies.allowed_companies; + this.current_company = this.allowed_company_ids[0]; this.current_company_name = _.find(session.user_companies.allowed_companies, function (company) { return company[0] === self.current_company; })[1]; + return this._super.apply(this, arguments); }, //-------------------------------------------------------------------------- @@ -52,11 +56,10 @@ var SwitchCompanyMenu = Widget.extend({ */ _onSwitchCompanyClick: function (ev) { ev.stopPropagation(); - var dropdownItem = $(ev.currentTarget).parent() - var dropdownMenu = dropdownItem.parent() + var dropdownItem = $(ev.currentTarget).parent(); + var dropdownMenu = dropdownItem.parent(); var companyID = dropdownItem.data('company-id'); - var hash = $.bbq.getState() - var allowed_company_ids = _.map(hash.cids.split(','), function(company_id) {return parseInt(company_id);}); + var allowed_company_ids = this.allowed_company_ids; if (dropdownItem.find('.fa-square-o').length) { // 1 enabled company: Stay in single company mode if (this.allowed_company_ids.length === 1) { @@ -81,11 +84,9 @@ var SwitchCompanyMenu = Widget.extend({ */ _onToggleCompanyClick: function (ev) { ev.stopPropagation(); - var dropdownItem = $(ev.currentTarget).parent() - var dropdownMenu = dropdownItem.parent() + var dropdownItem = $(ev.currentTarget).parent(); var companyID = dropdownItem.data('company-id'); - var hash = $.bbq.getState() - var allowed_company_ids = _.map(hash.cids.split(','), function(company_id) {return parseInt(company_id);}); + var allowed_company_ids = this.allowed_company_ids; var current_company_id = allowed_company_ids[0]; if (dropdownItem.find('.fa-square-o').length) { allowed_company_ids.push(companyID); diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index e34d017b1a4..878a9cfaef5 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -1469,21 +1469,21 @@ <div role="menuitem" href="#" class="dropdown-item d-flex py-0 px-0" data-menu="company" t-att-data-company-id="company[0]"> <div class="ml-auto pl-3 pr-3 border border-top-0 border-left-0 border-bottom-0 toggle_company o_py"> <span style="height: 2rem;"> - <t t-if="widget.allowed_company_ids.includes(company[0].toString())"> + <t t-if="widget.allowed_company_ids.includes(company[0])"> <i class="fa fa-fw fa-check-square pt-2"></i> </t> - <t t-if="!widget.allowed_company_ids.includes(company[0].toString())"> + <t t-if="!widget.allowed_company_ids.includes(company[0])"> <i class="fa fa-fw fa-square-o pt-2"></i> </t> </span> </div> <div class="d-flex flex-grow-1 align-items-center py-0 log_into pl-3 o_py" t-att-style="company[0] === widget.current_company ? 'background-color: lightgrey;' : ''"> - <t t-if="widget.allowed_company_ids.includes(company[0].toString())"> + <t t-if="widget.allowed_company_ids.includes(company[0])"> <span class='mr-3 company_label'> <t t-esc="company[1]"/> </span> </t> - <t t-if="!widget.allowed_company_ids.includes(company[0].toString())"> + <t t-if="!widget.allowed_company_ids.includes(company[0])"> <span class='mr-3 company_label text-muted'> <t t-esc="company[1]"/> </span> diff --git a/addons/web/static/tests/widgets/company_switcher_tests.js b/addons/web/static/tests/widgets/company_switcher_tests.js new file mode 100644 index 00000000000..6b3ead230ca --- /dev/null +++ b/addons/web/static/tests/widgets/company_switcher_tests.js @@ -0,0 +1,169 @@ +odoo.define('web.SwitchCompanyMenu_tests', function (require) { +"use strict"; + +var SwitchCompanyMenu = require('web.SwitchCompanyMenu'); +var testUtils = require('web.test_utils'); + + +async function createSwitchCompanyMenu(params) { + params = params || {}; + var target = params.debug ? document.body : $('#qunit-fixture'); + var menu = new SwitchCompanyMenu(); + testUtils.mock.addMockEnvironment(menu, params); + await menu.appendTo(target) + return menu +} + + +async function initMockCompanyMenu(assert, params) { + var menu = await createSwitchCompanyMenu({ + session: { + ...params.session, + setCompanies: function (mainCompanyId, companyIds) { + assert.equal(mainCompanyId, params.assertMainCompany[0], params.assertMainCompany[1]); + assert.equal(_.intersection(companyIds, params.asserCompanies[0]).length, params.asserCompanies[0].length, params.asserCompanies[1]); + }, + } + }) + await testUtils.dom.click(menu.$('.dropdown-toggle')); // open company switcher dropdown + return menu +} + +async function testSwitchCompany(assert, params) { + assert.expect(2); + var menu = await initMockCompanyMenu(assert, params); + await testUtils.dom.click(menu.$(`div[data-company-id=${params.company}] div.log_into`)); + menu.destroy(); +} + +async function testToggleCompany(assert, params) { + assert.expect(2); + var menu = await initMockCompanyMenu(assert, params); + await testUtils.dom.click(menu.$(`div[data-company-id=${params.company}] div.toggle_company`)); + menu.destroy(); +} + +QUnit.module('widgets', { + beforeEach: async function () { + this.session_mock_multi = { + user_companies: { + current_company: [1, "Company 1"], + allowed_companies: [[1, "Company 1"], [2, "Company 2"], [3, "Company 3"]], + }, + user_context: { allowed_company_ids: [1, 3] }, + }, + this.session_mock_single = { + user_companies: { + current_company: [1, "Company 1"], + allowed_companies: [[1, "Company 1"], [2, "Company 2"], [3, "Company 3"]], + }, + user_context: { allowed_company_ids: [1] }, + } + }, + +}, function () { + + QUnit.module('SwitchCompanyMenu', {}, function () { + + QUnit.test("Company switcher basic rendering", async function (assert) { + assert.expect(6); + var menu = await createSwitchCompanyMenu({ session: this.session_mock_multi }); + assert.equal(menu.$('.company_label:contains(Company 1)').length, 1, "it should display Company 1") + assert.equal(menu.$('.company_label:contains(Company 2)').length, 1, "it should display Company 2") + assert.equal(menu.$('.company_label:contains(Company 3)').length, 1, "it should display Company 3") + + assert.equal(menu.$('div[data-company-id=1] .fa-check-square').length, 1, "Company 1 should be checked") + assert.equal(menu.$('div[data-company-id=2] .fa-square-o').length, 1, "Company 2 should not be checked") + assert.equal(menu.$('div[data-company-id=3] .fa-check-square').length, 1, "Company 3 should be checked") + menu.destroy(); + }); + }); + + QUnit.module('SwitchCompanyMenu', {}, function () { + + QUnit.test("Toggle new company in multiple company mode", async function (assert) { + /** + * [x] **Company 1** [x] **Company 1** + * toggle->[ ] Company 2 ====> [x] Company 2 + * [x] Company 3 [x] Company 3 + */ + await testToggleCompany(assert, { + company: 2, + session: this.session_mock_multi, + assertMainCompany: [1, "Main company should not have changed"], + asserCompanies: [[1, 2, 3], "All companies should be activated"], + }); + }); + + QUnit.test("Toggle active company in mutliple company mode", async function (assert) { + /** + * [x] **Company 1** [x] **Company 1** + * [ ] Company 2 ====> [ ] Company 2 + * toggle->[x] Company 3 [ ] Company 3 + */ + await testToggleCompany(assert, { + company: 3, + session: this.session_mock_multi, + assertMainCompany: [1, "Main company should not have changed"], + asserCompanies: [[1], "Companies 3 should be unactivated"], + }); + }); + + QUnit.test("Switch main company in mutliple company mode", async function (assert) { + /** + * [x] **Company 1** [x] Company 1 + * [ ] Company 2 ====> [ ] Company 2 + * switch->[x] Company 3 [x] **Company 3** + */ + await testSwitchCompany(assert, { + company: 3, + session: this.session_mock_multi, + assertMainCompany: [3, "Main company should switch to Company 3"], + asserCompanies: [[1, 3], "Companies 1 and 3 should still be active"], + }); + }); + + QUnit.test("Switch new company in mutliple company mode", async function (assert) { + /** + * [x] **Company 1** [x] Company 1 + * switch->[ ] Company 2 ====> [x] **Company 2** + * [x] Company 3 [x] Company 3 + */ + await testSwitchCompany(assert, { + company: 2, + session: this.session_mock_multi, + assertMainCompany: [2, "Company 2 should become the main company"], + asserCompanies: [[1, 2, 3], "Companies 1 and 3 should still be active"], + }); + }); + + QUnit.test("Switch main company in single company mode", async function (assert) { + /** + * [x] **Company 1** [ ] Company 1 + * [ ] Company 2 ====> [ ] Company 2 + * switch->[ ] Company 3 [x] **Company 3** + */ + await testSwitchCompany(assert, { + company: 3, + session: this.session_mock_single, + assertMainCompany: [3, "Main company should switch to Company 3"], + asserCompanies: [[3], "Companies 1 should no longer be active"], + }); + }); + + QUnit.test("Toggle new company in single company mode", async function (assert) { + /** + * [x] **Company 1** [ ] **Company 1** + * [ ] Company 2 ====> [ ] Company 2 + * toggle->[ ] Company 3 [x] Company 3 + */ + await testToggleCompany(assert, { + company: 3, + session: this.session_mock_single, + assertMainCompany: [1, "Company 1 should still be the main company"], + asserCompanies: [[1, 3], "Company 3 should be activated"], + }); + }); + }); +}); +}); diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml index 6494eda9622..ed504c9050e 100644 --- a/addons/web/views/webclient_templates.xml +++ b/addons/web/views/webclient_templates.xml @@ -689,6 +689,7 @@ <script type="text/javascript" src="/web/static/tests/chrome/user_menu_tests.js"></script> <script type="text/javascript" src="/web/static/tests/chrome/systray_tests.js"></script> + <script type="text/javascript" src="/web/static/tests/widgets/company_switcher_tests.js"/> <script type="text/javascript" src="/web/static/tests/widgets/data_export_tests.js"/> <script type="text/javascript" src="/web/static/tests/widgets/domain_selector_tests.js"/> <script type="text/javascript" src="/web/static/tests/widgets/model_field_selector_tests.js"/> |
