19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-09 09:30:27 +01:00
parent d1963a3c3a
commit 2d3ee4855a
7430 changed files with 2687981 additions and 2965473 deletions

View file

@ -19,6 +19,7 @@ from . import test_web_search_read
from . import test_domain
from . import test_translate
from . import test_web_redirect
from . import test_res_users_settings
from . import test_res_users
from . import test_webmanifest
from . import test_ir_qweb

View file

@ -14,6 +14,18 @@ _logger = logging.getLogger(__name__)
@odoo.tests.tagged('click_all', 'post_install', '-at_install', '-standard')
class TestMenusAdmin(odoo.tests.HttpCase):
allow_end_on_form = True
@classmethod
def _request_handler(cls, s: Session, r: PreparedRequest, /, **kw):
# mock odoofin requests
if 'proxy/v1/get_dashboard_institutions' in r.url:
r = Response()
r.status_code = 200
r.json = lambda: {'result': {}}
return r
return super()._request_handler(s, r, **kw)
def test_01_click_everywhere_as_admin(self):
if 'tour_enabled' in self.env['res.users']._fields:
self.env.ref('base.user_admin').tour_enabled = False

View file

@ -287,3 +287,18 @@ class TestIrModel(TransactionCase):
"Should have the monetary field in the created ir.model")
self.assertEqual(monetary_field.currency_field, "x_good_currency",
"The currency field in monetary should have x_good_currency as name")
def test_invalid_field_domain(self):
"""Ensure assigning an invalid domain raises ValidationError."""
field_ripeness_id = self.env['ir.model.fields']._get('x_bananas', 'x_ripeness_id')
valid_domain = "[('x_name', '=', 'Green')]"
invalid_domain = "[('x_name', '=', Green)]" # Green without quotes
field_ripeness_id.domain = valid_domain
with self.assertRaises(ValidationError) as error:
field_ripeness_id.domain = invalid_domain
self.assertIn('An error occurred while evaluating the domain', str(error.exception))
self.assertEqual(field_ripeness_id.domain, valid_domain)

View file

@ -33,8 +33,8 @@ class TestPerfSessionInfo(common.HttpCase):
self.env.registry.clear_all_caches()
# cold ormcache:
# - Only web: 43
# - All modules: 121
with self.assertQueryCount(121):
# - All modules: 122
with self.assertQueryCount(122):
self.url_open(
"/web/session/get_session_info",
data=json.dumps({'jsonrpc': "2.0", 'method': "call", 'id': str(uuid4())}),

View file

@ -1,5 +1,6 @@
import io
import json
from http import HTTPStatus
from lxml import etree
from zipfile import ZipFile
@ -48,3 +49,17 @@ class TestPivotExport(HttpCase):
self.assertEqual(xml_data['B1'], '500')
self.assertEqual(xml_data['A2'], '0')
self.assertEqual(xml_data['B2'], '42')
def test_export_xlsx_with_empty_data(self):
""" Test the export_xlsx method of the pivot controller without jdata """
self.authenticate('admin', 'admin')
response = self.url_open(
'/web/pivot/export_xlsx',
data={
'data': json.dumps({}),
'csrf_token': http.Request.csrf_token(self),
},
)
self.assertEqual(response.status_code, HTTPStatus.UNPROCESSABLE_ENTITY)
self.assertIn('No data to export', response.text)

View file

@ -0,0 +1,107 @@
from odoo.exceptions import ValidationError
from odoo.tests import TransactionCase
class TestResUsersSettings(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.user = cls.env['res.users'].create({
'name': 'Jean',
'login': 'jean@mail.com',
'password': 'jean@mail.com',
})
cls.user_settings = cls.env['res.users.settings']._find_or_create_for_user(cls.user)
cls.window_action = cls.env['ir.actions.act_window'].create({
'name': 'Test Action',
'res_model': 'res.users',
})
def test_fields_validity_embedded_action_settings(self):
'''
Test that the embedded actions fields 'embedded_actions_order' and 'embedded_actions_visibility' are valid
and raise ValidationError when necessary.
'''
embedded_action_settings_data = {
'user_setting_id': self.user_settings.id,
'action_id': self.window_action.id,
'res_model': 'res.users',
'res_id': self.user.id,
'embedded_visibility': True,
}
# Invalid case: duplicated ids
embedded_action_settings_data.update({
'embedded_actions_order': '1,2,1',
'embedded_actions_visibility': '3,3,4',
})
with self.assertRaises(ValidationError, msg='The ids in embedded_actions_order must not be duplicated'):
self.env['res.users.settings.embedded.action'].create(embedded_action_settings_data)
# Invalid case: non-integer ids or non-false values
embedded_action_settings_data.update({
'embedded_actions_order': '1,2,true',
'embedded_actions_visibility': '3,4,false,abc',
})
with self.assertRaises(ValidationError, msg='The ids in embedded_actions_order must only be integers or "false"'):
self.env['res.users.settings.embedded.action'].create(embedded_action_settings_data)
def test_set_and_get_embedded_action_settings(self):
'''
Test setting and getting embedded action settings.
'''
settings_vals = {
'embedded_actions_order': [False, 1, 2, 3],
'embedded_actions_visibility': [2, False, 3],
'embedded_visibility': True,
}
self.user_settings.set_embedded_actions_setting(
action_id=self.window_action.id,
res_id=self.user.id,
vals={
**settings_vals,
'res_model': 'res.users',
},
)
# Check if the setting is correctly created
embedded_actions_config = self.user_settings.embedded_actions_config_ids
self.assertEqual(len(embedded_actions_config), 1, 'There should be one embedded action setting created.')
self.assertEqual(embedded_actions_config.action_id, self.window_action, 'The action should match the one set.')
self.assertEqual(embedded_actions_config.res_id, self.user.id, 'The res_id should match the one set.')
self.assertEqual(embedded_actions_config.res_model, 'res.users', 'The res_model should match the one set.')
self.assertEqual(embedded_actions_config.embedded_actions_order, 'false,1,2,3', 'The embedded actions order should match the one set.')
self.assertEqual(embedded_actions_config.embedded_actions_visibility, '2,false,3', 'The embedded actions visibility should match the one set.')
self.assertEqual(embedded_actions_config.embedded_visibility, True, 'The embedded visibility should be True.')
# Check if the settings are correctly formatted from the getter
embedded_settings = self.user_settings.get_embedded_actions_settings()
expected_settings = {
f'{self.window_action.id}+{self.user.id}': settings_vals,
}
self.assertEqual(embedded_settings, expected_settings, 'The settings should be correctly formatted with the given values.')
# Edit the settings
new_settings_vals = {
'embedded_actions_order': [3, 1, False, 2],
'embedded_actions_visibility': [1, 3],
'embedded_visibility': False,
}
self.user_settings.set_embedded_actions_setting(
action_id=self.window_action.id,
res_id=self.user.id,
vals=new_settings_vals,
)
# Check if the setting is correctly updated
embedded_actions_config = self.user_settings.embedded_actions_config_ids
self.assertEqual(len(embedded_actions_config), 1, 'There should still be one embedded action setting after update.')
self.assertEqual(embedded_actions_config.action_id, self.window_action, 'The action should remain the same after update.')
self.assertEqual(embedded_actions_config.res_id, self.user.id, 'The res_id should remain the same after update.')
self.assertEqual(embedded_actions_config.res_model, 'res.users', 'The res_model should remain the same after update.')
self.assertEqual(embedded_actions_config.embedded_actions_order, '3,1,false,2', 'The embedded actions order should be updated.')
self.assertEqual(embedded_actions_config.embedded_actions_visibility, '1,3', 'The embedded actions visibility should be updated.')
self.assertEqual(embedded_actions_config.embedded_visibility, False, 'The embedded visibility should be updated to False.')
# Check if the settings are correctly formatted after the update
embedded_settings = self.user_settings.get_embedded_actions_settings()
expected_settings = {
f'{self.window_action.id}+{self.user.id}': new_settings_vals,
}
self.assertEqual(embedded_settings, expected_settings, 'The settings should be correctly formatted after the update with the new values.')

View file

@ -15,8 +15,10 @@ class TestSessionInfo(common.HttpCase):
cls.company_b = cls.env['res.company'].create({'name': "B"})
cls.company_c = cls.env['res.company'].create({'name': "C"})
cls.company_b_branch = cls.env['res.company'].create({'name': "B Branch", 'parent_id': cls.company_b.id})
cls.allowed_companies = cls.company_a + cls.company_b_branch + cls.company_c
cls.disallowed_ancestor_companies = cls.company_b
cls.company_c_branch = cls.env['res.company'].create({'name': "C Branch", 'parent_id': cls.company_c.id})
cls.company_c_branch_branch = cls.env['res.company'].create({'name': "C Branch Branch", 'parent_id': cls.company_c_branch.id})
cls.allowed_companies = cls.company_a + cls.company_b_branch + cls.company_c + cls.company_c_branch_branch
cls.disallowed_ancestor_companies = cls.company_b + cls.company_c_branch
cls.user_password = "info"
cls.user = common.new_test_user(