Skip to content

Commit 8e21d8f

Browse files
committed
[FIX] base_rest*: Translate validation exception
Before this change, the translation method didn't have access to the environement to kwow the target language. We now use the mtranslation method on the env linked to the service to translate the exceptions
1 parent 34648dc commit 8e21d8f

4 files changed

Lines changed: 44 additions & 59 deletions

File tree

base_rest/restapi.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from cerberus import Validator
99

10-
from odoo import _, http
10+
from odoo import http
1111
from odoo.exceptions import UserError, ValidationError
1212

1313
from .tools import ROUTING_DECORATOR_ATTR, cerberus_to_json
@@ -218,13 +218,13 @@ def from_params(self, service, params):
218218
validator = self.get_cerberus_validator(service, "input")
219219
if validator.validate(params):
220220
return validator.document
221-
raise UserError(_("BadRequest %s") % validator.errors)
221+
raise UserError(service.env._("BadRequest %s") % validator.errors)
222222

223223
def to_response(self, service, result):
224224
validator = self.get_cerberus_validator(service, "output")
225225
if validator.validate(result):
226226
return validator.document
227-
raise SystemError(_("Invalid Response %s") % validator.errors)
227+
raise SystemError(service.env._("Invalid Response %s") % validator.errors)
228228

229229
def to_openapi_query_parameters(self, service, spec):
230230
json_schema = self.to_json_schema(service, spec, "input")
@@ -275,7 +275,9 @@ def get_cerberus_validator(self, service, direction):
275275
return schema
276276
if isinstance(schema, dict):
277277
return Validator(schema, purge_unknown=True)
278-
raise Exception(_("Unable to get cerberus schema from %s") % self._schema)
278+
raise Exception(
279+
service.env._("Unable to get cerberus schema from %s") % self._schema
280+
)
279281

280282
def to_json_schema(self, service, spec, direction):
281283
schema = self.get_cerberus_validator(service, direction).schema
@@ -321,7 +323,7 @@ def _do_validate(self, service, data, direction):
321323
for idx, p in enumerate(data):
322324
if not validator.validate(p):
323325
raise ExceptionClass(
324-
_(
326+
service.env._(
325327
"BadRequest item %(idx)s :%(errors)s",
326328
idx=idx,
327329
errors=validator.errors,
@@ -330,7 +332,7 @@ def _do_validate(self, service, data, direction):
330332
values.append(validator.document)
331333
if self._min_items is not None and len(values) < self._min_items:
332334
raise ExceptionClass(
333-
_(
335+
service.env._(
334336
"BadRequest: Not enough items in the list (%(current)s "
335337
"< %(expected)s)",
336338
current=len(values),
@@ -339,7 +341,7 @@ def _do_validate(self, service, data, direction):
339341
)
340342
if self._max_items is not None and len(values) > self._max_items:
341343
raise ExceptionClass(
342-
_(
344+
service.env._(
343345
"BadRequest: Too many items in the list (%(current)s "
344346
"> %(expected)s)",
345347
current=len(values),
@@ -367,7 +369,7 @@ def __init__(self, parts):
367369
:param parts: list of RestMethodParam
368370
"""
369371
if not isinstance(parts, dict):
370-
raise ValidationError(_("You must provide a dict of RestMethodParam"))
372+
raise RuntimeError("You must provide a dict of RestMethodParam")
371373
self._parts = parts
372374

373375
def to_openapi_properties(self, service, spec, direction):
@@ -410,7 +412,7 @@ def from_params(self, service, params):
410412
) # multipart ony sends its parts as string
411413
except json.JSONDecodeError as error:
412414
raise ValidationError(
413-
_(f"{key}'s JSON content is malformed: {error}")
415+
service.env._(f"{key}'s JSON content is malformed: {error}")
414416
) from error
415417
param = part.from_params(service, json_param)
416418
params[key] = param

base_rest/tests/test_cerberus_list_validator.py

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
# Copyright 2020 ACSONE SA/NV
22
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
33

4-
import logging
54
import unittest
65

76
from cerberus import Validator
87

98
from odoo.exceptions import UserError
10-
from odoo.tests.common import BaseCase, MetaCase
9+
from odoo.tests.common import TransactionCase
1110

1211
from ..components.cerberus_validator import BaseRestCerberusValidator
1312
from ..restapi import CerberusListValidator
1413

1514

16-
class TestCerberusListValidator(BaseCase, MetaCase("DummyCase", (object,), {})):
15+
class TestCerberusListValidator(TransactionCase):
1716
"""Test all the methods that must be implemented by CerberusListValidator to
1817
be a valid RestMethodParam"""
1918

@@ -47,18 +46,8 @@ def setUpClass(cls):
4746
schema=cls.nested_schema
4847
)
4948
cls.maxDiff = None
50-
51-
def setUp(self):
52-
super().setUp()
53-
# mute logger
54-
loggers = ["odoo.tools.translate"]
55-
for logger in loggers:
56-
logging.getLogger(logger).addFilter(self)
57-
58-
@self.addCleanup
59-
def un_mute_logger():
60-
for logger_ in loggers:
61-
logging.getLogger(logger_).removeFilter(self)
49+
cls.mock_service = unittest.mock.Mock()
50+
cls.mock_service.env = cls.env
6251

6352
def filter(self, record):
6453
# required to mute logger
@@ -203,15 +192,18 @@ def test_from_params_validation(self):
203192
# minItems / maxItems
204193
with self.assertRaises(UserError):
205194
# minItems = 1
206-
self.simple_schema_list_validator.from_params(None, params=[])
195+
self.simple_schema_list_validator.from_params(self.mock_service, params=[])
207196
with self.assertRaises(UserError):
208197
# maxItems = 2
209198
self.simple_schema_list_validator.from_params(
210-
None, params=[{"name": "test"}, {"name": "test"}, {"name": "test"}]
199+
self.mock_service,
200+
params=[{"name": "test"}, {"name": "test"}, {"name": "test"}],
211201
)
212202
with self.assertRaises(UserError):
213203
# name required
214-
self.simple_schema_list_validator.from_params(None, params=[{}])
204+
self.simple_schema_list_validator.from_params(
205+
self.mock_service, params=[{}]
206+
)
215207

216208
def test_to_response_ignore_unknown(self):
217209
result = [{"name": "test", "unknown": True}]
@@ -223,15 +215,18 @@ def test_to_response_validation(self):
223215
# as a programmatic error not a user error
224216
with self.assertRaises(SystemError):
225217
# minItems = 1
226-
self.simple_schema_list_validator.to_response(None, result=[])
218+
self.simple_schema_list_validator.to_response(self.mock_service, result=[])
227219
with self.assertRaises(SystemError):
228220
# maxItems = 2
229221
self.simple_schema_list_validator.to_response(
230-
None, result=[{"name": "test"}, {"name": "test"}, {"name": "test"}]
222+
self.mock_service,
223+
result=[{"name": "test"}, {"name": "test"}, {"name": "test"}],
231224
)
232225
with self.assertRaises(SystemError):
233226
# name required
234-
self.simple_schema_list_validator.to_response(None, result=[{}])
227+
self.simple_schema_list_validator.to_response(
228+
self.mock_service, result=[{}]
229+
)
235230

236231
def test_schema_lookup_from_string(self):
237232
class MyService:

base_rest/tests/test_cerberus_validator.py

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
# Copyright 2020 ACSONE SA/NV
22
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
33

4-
import logging
54
import unittest
65

76
from cerberus import Validator
87

98
from odoo.exceptions import UserError
10-
from odoo.tests.common import BaseCase, MetaCase
9+
from odoo.tests.common import TransactionCase
1110

1211
from ..components.cerberus_validator import BaseRestCerberusValidator
1312
from ..restapi import CerberusValidator
1413
from ..tools import cerberus_to_json
1514

1615

17-
class TestCerberusValidator(BaseCase, MetaCase("DummyCase", (object,), {})):
16+
class TestCerberusValidator(TransactionCase):
1817
"""Test all the methods that must be implemented by CerberusValidator to
1918
be a valid RestMethodParam"""
2019

@@ -50,22 +49,8 @@ def setUpClass(cls):
5049
cls.nested_schema_cerberus_validator = CerberusValidator(
5150
schema=cls.nested_schema
5251
)
53-
54-
def setUp(self):
55-
super().setUp()
56-
# mute logger
57-
loggers = ["odoo.tools.translate"]
58-
for logger in loggers:
59-
logging.getLogger(logger).addFilter(self)
60-
61-
@self.addCleanup
62-
def un_mute_logger():
63-
for logger_ in loggers:
64-
logging.getLogger(logger_).removeFilter(self)
65-
66-
def filter(self, record):
67-
# required to mute logger
68-
return 0
52+
cls.mock_service = unittest.mock.Mock()
53+
cls.mock_service.env = cls.env
6954

7055
def test_to_openapi_responses(self):
7156
res = self.simple_schema_cerberus_validator.to_openapi_responses(None, None)
@@ -271,7 +256,9 @@ def test_from_params_ignore_unknown(self):
271256
def test_from_params_validation(self):
272257
# name is required
273258
with self.assertRaises(UserError):
274-
self.simple_schema_cerberus_validator.from_params(None, params={})
259+
self.simple_schema_cerberus_validator.from_params(
260+
self.mock_service, params={}
261+
)
275262

276263
def test_to_response_add_default(self):
277264
result = {"name": "test"}
@@ -288,7 +275,9 @@ def test_to_response_validation(self):
288275
# If a response is not conform to the expected schema it's considered
289276
# as a programmatic error not a user error
290277
with self.assertRaises(SystemError):
291-
self.simple_schema_cerberus_validator.to_response(None, result={})
278+
self.simple_schema_cerberus_validator.to_response(
279+
self.mock_service, result={}
280+
)
292281

293282
def test_schema_lookup_from_string(self):
294283
class MyService:

base_rest_pydantic/restapi.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
33
import json
44

5-
from odoo import _
65
from odoo.exceptions import UserError
76

87
from odoo.addons.base_rest import restapi
@@ -41,7 +40,7 @@ def from_params(self, service, params):
4140
try:
4241
return self._model_cls(**params)
4342
except ValidationError as ve:
44-
raise UserError(_("BadRequest %s") % ve.json(indent=0)) from ve
43+
raise UserError(service.env._("BadRequest %s") % ve.json(indent=0)) from ve
4544

4645
def to_response(self, service, result):
4746
# do we really need to validate the instance????
@@ -58,7 +57,7 @@ def to_response(self, service, result):
5857
try:
5958
self._model_cls.model_validate_json(to_validate_jsonified)
6059
except ValidationError as validation_error:
61-
raise SystemError(_("Invalid Response")) from validation_error
60+
raise SystemError(service.env._("Invalid Response")) from validation_error
6261
return json_dict
6362

6463
def to_openapi_query_parameters(self, servic, spec):
@@ -154,14 +153,14 @@ def __init__(
154153
self._unique_items = unique_items
155154

156155
def from_params(self, service, params):
157-
self._do_validate(params, "input")
156+
self._do_validate(service, params, "input")
158157
return [
159158
super(PydanticModelList, self).from_params(service, param)
160159
for param in params
161160
]
162161

163162
def to_response(self, service, result):
164-
self._do_validate(result, "output")
163+
self._do_validate(service, result, "output")
165164
return [
166165
super(PydanticModelList, self).to_response(service=service, result=r)
167166
for r in result
@@ -170,11 +169,11 @@ def to_response(self, service, result):
170169
def to_openapi_query_parameters(self, service, spec):
171170
raise NotImplementedError("List are not (?yet?) supported as query paramters")
172171

173-
def _do_validate(self, values, direction):
172+
def _do_validate(self, service, values, direction):
174173
ExceptionClass = UserError if direction == "input" else SystemError
175174
if self._min_items is not None and len(values) < self._min_items:
176175
raise ExceptionClass(
177-
_(
176+
service.env._(
178177
(
179178
"BadRequest: Not enough items in the list (%(current)s < "
180179
"%(expected)s)"
@@ -185,7 +184,7 @@ def _do_validate(self, values, direction):
185184
)
186185
if self._max_items is not None and len(values) > self._max_items:
187186
raise ExceptionClass(
188-
_(
187+
service.env._(
189188
(
190189
"BadRequest: Too many items in the list (%(current)s > "
191190
"%(expected)s)"

0 commit comments

Comments
 (0)