diff --git a/trytond/model/modelsql.py b/trytond/model/modelsql.py index 8721cda5eb..f5320e3530 100644 --- a/trytond/model/modelsql.py +++ b/trytond/model/modelsql.py @@ -347,7 +347,7 @@ class ModelSQL(ModelStorage): if field.required and \ not hasattr(field, 'set') and \ field_name not in ('create_uid', 'create_date'): - if not values.get(field_name): + if values.get(field_name) is None: cls.raise_user_error('required_field', error_args=cls._get_error_args( field_name)) diff --git a/trytond/test/__init__.py b/trytond/test/__init__.py index b6378c528f..75d50d1076 100644 --- a/trytond/test/__init__.py +++ b/trytond/test/__init__.py @@ -89,6 +89,7 @@ def register(): ModelInheritsSubSubModel, ModelInheritsSubSubSubModel, ModelInheritsOverriddenFieldModel, + ModelSQLRequiredField, MPTT, ImportDataBoolean, ImportDataInteger, diff --git a/trytond/test/model.py b/trytond/test/model.py index 24d2bd2380..ff5a006cad 100644 --- a/trytond/test/model.py +++ b/trytond/test/model.py @@ -5,7 +5,7 @@ from trytond.model import ModelSingleton, ModelSQL, fields __all__ = [ 'Singleton', 'URLObject', 'ModelInherits', 'ModelInheritsSubModel', 'ModelInheritsSubSubModel', 'ModelInheritsSubSubSubModel', - 'ModelInheritsOverriddenFieldModel', + 'ModelInheritsOverriddenFieldModel', 'ModelSQLRequiredField' ] @@ -70,3 +70,11 @@ class ModelInheritsOverriddenFieldModel(ModelSQL): subfield = fields.Integer('Overridden field') parent_model = fields.Many2One('test.subsubmodel', 'Parent model', required=True) + + +class ModelSQLRequiredField(ModelSQL): + 'model with a required field' + __name__ = 'test.modelsql' + + integer = fields.Integer(string="integer", required=True) + desc = fields.Char(string="desc", required=True) diff --git a/trytond/tests/test_modelsql.py b/trytond/tests/test_modelsql.py new file mode 100644 index 0000000000..55c526b384 --- /dev/null +++ b/trytond/tests/test_modelsql.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# This file is part of Tryton. The COPYRIGHT file at the top level of this +# repository contains the full copyright notices and license terms. + +import unittest + +from trytond.config import CONFIG +from trytond.exceptions import UserError +from trytond.transaction import Transaction +from trytond.tests.test_tryton import POOL, DB_NAME, USER, CONTEXT, \ + install_module + +class ModelSQLTestCase(unittest.TestCase): + ''' + Test ModelSQL + ''' + + def setUp(self): + install_module('test') + self.modelsql = POOL.get('test.modelsql') + + # SQLite not concerned because tryton don't set "NOT NULL" constraint: + # 'ALTER TABLE' don't support NOT NULL constraint without default value + @unittest.skipIf(CONFIG['db_type'] not in ('postgresql', 'mysql'), + 'postgresql or mysql needed') + def test0010required_field_missing(self): + ''' + Test error message when a required field is missing. + ''' + fields = { + 'desc': '', + 'integer': 0, + } + for key, value in fields.iteritems(): + with Transaction().start(DB_NAME, USER, context=CONTEXT): + try: + self.modelsql.create({key: value}) + except UserError, err: + # message must not quote key + msg = "'%s' not missing but quoted in error: '%s'" % (key, + err.message) + self.assertTrue(key not in err.message, msg) + continue + self.fail('UserError should be caught') + +def suite(): + return unittest.TestLoader().loadTestsFromTestCase(ModelSQLTestCase) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite()) diff --git a/trytond/tests/test_tryton.py b/trytond/tests/test_tryton.py index 6a95bb04a7..4fc11769c9 100644 --- a/trytond/tests/test_tryton.py +++ b/trytond/tests/test_tryton.py @@ -255,6 +255,8 @@ def all_suite(): suite_.addTests(test_wizard.suite()) import trytond.tests.test_model_inherits as test_inherits suite_.addTests(test_inherits.suite()) + import trytond.tests.test_modelsql as test_modelsql + suite_.addTests(test_modelsql.suite()) return suite_