[FIX] web: correctly set current_company_id in BasicModel

This commit fix a bug introduced in #66551 where a mismatch has been done between
session.user_context.allowed_company_ids and session.user_companies.allowed_companies.

This commit also adds the following tests:

- a JS test in order to prevent future unwanted issues regarding multi company
  in BasicModel.
- a Python test in order to ensure that session_info['user_companies'] is not
  involuntarily changed.

closes odoo/odoo#68025

Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
This commit is contained in:
Laurent Stukkens (LTU)
2021-03-19 11:29:51 +00:00
parent 49429f986a
commit 68d6427a2a
4 changed files with 130 additions and 1 deletions
@@ -3711,7 +3711,7 @@ var BasicModel = AbstractModel.extend({
// in general, the actual "company_id" field of the form should be used for m2o domains, not this fallback
let current_company_id;
if (session.user_context.allowed_company_ids) {
current_company_id = Object.keys(session.user_context.allowed_company_ids)[0];
current_company_id = session.user_context.allowed_company_ids[0];
} else {
current_company_id = session.user_companies ?
session.user_companies.current_company :
@@ -4,6 +4,7 @@ odoo.define('web.basic_model_tests', function (require) {
var BasicModel = require('web.BasicModel');
var FormView = require('web.FormView');
var testUtils = require('web.test_utils');
const session = require('web.session');
var createModel = testUtils.createModel;
var createView = testUtils.createView;
@@ -2530,4 +2531,73 @@ odoo.define('web.basic_model_tests', function (require) {
assert.equal(model.getActiveField(record), 'active', 'should have returned "active" field name');
});
});
QUnit.module('Multi Company', function (hooks) {
let sessionUserCompaniesBackup;
let sessionUserContextBackup;
hooks.before(function (assert) {
// Backups session parts that this testing module will alter in order to restore it at the end.
sessionUserCompaniesBackup = 'user_companies' in session && session.user_companies || false;
sessionUserContextBackup = 'user_context' in session && session.user_context || false;
session.user_companies = {
current_company: 3,
allowed_companies: {
1: {
id: 1,
name: 'Company 1',
},
2: {
id: 2,
name: 'Company 2',
},
3: {
id: 3,
name: 'Company 3',
},
},
};
session.user_context = {
allowed_company_ids: [1, 2],
};
});
hooks.after(function (assert) {
if (sessionUserCompaniesBackup !== false) {
session.user_companies = sessionUserCompaniesBackup || { };
} else {
delete session.user_companies;
}
if (sessionUserContextBackup !== false) {
session.user_context = sessionUserContextBackup || { };
} else {
delete session.user_context;
}
});
QUnit.test('basic_model _getEvalContext returns a correct current_company_id', async function(assert) {
assert.expect(3);
const model = await createModel({
Model: BasicModel,
data: this.data,
});
let context = model._getEvalContext({ });
assert.strictEqual(
context.current_company_id,
session.user_context.allowed_company_ids[0],
'basic_model _getEvalContext returns the first entry in session.user_context.allowed_company_ids array');
session.user_context.allowed_company_ids = [2, 1];
context = model._getEvalContext({ });
assert.strictEqual(
context.current_company_id,
session.user_context.allowed_company_ids[0],
'basic_model _getEvalContext returns the first entry in session.user_context.allowed_company_ids array');
delete session.user_context.allowed_company_ids;
context = model._getEvalContext({ });
assert.strictEqual(
context.current_company_id,
session.user_companies.current_company,
'basic_model _getEvalContext returns session.user_companies.current_company when session.user_context.allowed_company_ids is not set');
});
});
});
+1
View File
@@ -7,3 +7,4 @@ from . import test_menu
from . import test_serving_base
from . import test_click_everywhere
from . import test_base_document_layout
from . import test_session_info
+58
View File
@@ -0,0 +1,58 @@
# -*- encoding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import json
from uuid import uuid4
from odoo import Command
from odoo.tests import common
class TestSessionInfo(common.HttpCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.company_a = cls.env['res.company'].create({'name': "A"})
cls.company_b = cls.env['res.company'].create({'name': "B"})
cls.company_c = cls.env['res.company'].create({'name': "C"})
cls.companies = [cls.company_a, cls.company_b, cls.company_c]
cls.user_password = "info"
cls.user = common.new_test_user(
cls.env,
"session",
email="session@in.fo",
password=cls.user_password,
tz="UTC")
cls.user.write({
'company_id': cls.company_a.id,
'company_ids': [Command.set([company.id for company in cls.companies])],
})
cls.payload = json.dumps(dict(jsonrpc="2.0", method="call", id=str(uuid4())))
cls.headers = {
"Content-Type": "application/json",
}
def test_session_info(self):
""" Checks that the session_info['user_companies'] structure correspond to what is expected """
self.authenticate(self.user.login, self.user_password)
response = self.url_open("/web/session/get_session_info", data=self.payload, headers=self.headers)
self.assertEqual(response.status_code, 200)
data = response.json()
result = data["result"]
expected_allowed_companies = {
str(company.id): {
'id': company.id,
'name': company.name,
} for company in self.companies
}
expected_user_companies = {
'current_company': self.company_a.id,
'allowed_companies': expected_allowed_companies,
}
self.assertEqual(
result['user_companies'],
expected_user_companies,
"The session_info['user_companies'] does not have the expected structure")