changeset 6c1469e8c837 in trytond:default
details: https://hg.tryton.org/trytond?cmd=changeset;node=6c1469e8c837
description:
        Validate selection format in Dict schema

        issue7947
        review257131002
diffstat:

 CHANGELOG                        |   1 +
 trytond/ir/message.xml           |   3 +++
 trytond/model/dictschema.py      |  19 ++++++++++++++++++-
 trytond/tests/test_field_dict.py |  15 +++++++++++++++
 4 files changed, 37 insertions(+), 1 deletions(-)

diffs (96 lines):

diff -r f0306c170777 -r 6c1469e8c837 CHANGELOG
--- a/CHANGELOG Thu Mar 21 17:50:39 2019 +0100
+++ b/CHANGELOG Fri Mar 22 11:46:52 2019 +0100
@@ -1,3 +1,4 @@
+* Validate selection format in Dict schema
 * Allow to extend Field's string and help
 * Add console
 * Add Model.__names__ to retrieve model and field names
diff -r f0306c170777 -r 6c1469e8c837 trytond/ir/message.xml
--- a/trytond/ir/message.xml    Thu Mar 21 17:50:39 2019 +0100
+++ b/trytond/ir/message.xml    Fri Mar 22 11:46:52 2019 +0100
@@ -109,6 +109,9 @@
         <record model="ir.message" id="msg_dict_schema_invalid_domain">
             <field name="text">Invalid domain in schema "%(schema)s".</field>
         </record>
+        <record model="ir.message" id="msg_dict_schema_invalid_selection">
+            <field name="text">Invalid selection in schema 
"%(schema)s".</field>
+        </record>
         <record model="ir.message" id="msg_recursion_error">
             <field name="text">Recursion error: Record "%(rec_name)s" with 
parent "%(parent_rec_name)s" was configured as ancestor of itself.</field>
         </record>
diff -r f0306c170777 -r 6c1469e8c837 trytond/model/dictschema.py
--- a/trytond/model/dictschema.py       Thu Mar 21 17:50:39 2019 +0100
+++ b/trytond/model/dictschema.py       Fri Mar 22 11:46:52 2019 +0100
@@ -16,6 +16,10 @@
     pass
 
 
+class SelectionError(ValidationError):
+    pass
+
+
 class DictSchemaMixin(object):
     _rec_name = 'string'
     name = fields.Char('Name', required=True)
@@ -67,6 +71,7 @@
     def validate(cls, schemas):
         super(DictSchemaMixin, cls).validate(schemas)
         cls.check_domain(schemas)
+        cls.check_selection(schemas)
 
     @classmethod
     def check_domain(cls, schemas):
@@ -84,7 +89,19 @@
                     gettext('ir.msg_dict_schema_invalid_domain',
                         schema=schema.rec_name))
 
-    def get_selection_json(self, name):
+    @classmethod
+    def check_selection(cls, schemas):
+        for schema in schemas:
+            if schema.type_ != 'selection':
+                continue
+            try:
+                dict(json.loads(schema.get_selection_json()))
+            except Exception:
+                raise SelectionError(
+                    gettext('ir.msg_dict_schema_invalid_selection',
+                        schema=schema.rec_name))
+
+    def get_selection_json(self, name=None):
         db_selection = self.selection or ''
         selection = [[w.strip() for w in v.split(':', 1)]
             for v in db_selection.splitlines() if v]
diff -r f0306c170777 -r 6c1469e8c837 trytond/tests/test_field_dict.py
--- a/trytond/tests/test_field_dict.py  Thu Mar 21 17:50:39 2019 +0100
+++ b/trytond/tests/test_field_dict.py  Fri Mar 22 11:46:52 2019 +0100
@@ -3,6 +3,7 @@
 import unittest
 
 from trytond import backend
+from trytond.model.dictschema import SelectionError
 from trytond.model.exceptions import RequiredValidationError
 from trytond.pool import Pool
 from trytond.tests.test_tryton import activate_module, with_transaction
@@ -130,6 +131,20 @@
         self.assertDictEqual(dict_.dico, {'type': 'arabic'})
 
     @with_transaction()
+    def test_invalid_selection_schema(self):
+        "Test invalid selection schema"
+        pool = Pool()
+        DictSchema = pool.get('test.dict.schema')
+
+        with self.assertRaises(SelectionError):
+            DictSchema.create([{
+                        'name': 'selection',
+                        'string': "Selection",
+                        'type_': 'selection',
+                        'selection': 'foo',
+                        }])
+
+    @with_transaction()
     @unittest.skipIf(
         backend.name() != 'postgresql', 'jsonb only supported by postgresql')
     def test_create_jsonb(self):

Reply via email to