diff --git a/openerp/addons/base/ir/ir_ui_view.py b/openerp/addons/base/ir/ir_ui_view.py index d3b090c45d4..7601c4f44fc 100644 --- a/openerp/addons/base/ir/ir_ui_view.py +++ b/openerp/addons/base/ir/ir_ui_view.py @@ -24,6 +24,7 @@ from lxml import etree from tools import graph from tools.safe_eval import safe_eval as eval import tools +from tools.view_validation import valid_view import os import logging @@ -53,14 +54,11 @@ class view(osv.osv): result = dict((r.id, etree.fromstring(r.arch.encode('utf8')).tag) for r in records) return result - def _set_type_field(self, cr, uid, ids, name, value, args, context=None): - print "ignoring", value - _columns = { 'name': fields.char('View Name',size=64, required=True), 'model': fields.char('Object', size=64, required=True, select=True), 'priority': fields.integer('Sequence', required=True), - 'type': fields.function(_type_field, fnct_inv=_set_type_field, type='selection', selection=[ + 'type': fields.function(_type_field, type='selection', selection=[ ('tree','Tree'), ('form','Form'), ('mdx','mdx'), @@ -85,6 +83,11 @@ class view(osv.osv): # Holds the RNG schema _relaxng_validator = None + def create(self, cr, uid, values, context=None): + if 'type' in values: + _logger.warning("Setting the `type` field is deprecated in the `ir.ui.view` model.") + return super(osv.osv, self).create(cr, uid, values, context) + def _relaxng(self): if not self._relaxng_validator: frng = tools.file_open(os.path.join('base','rng','view.rng')) @@ -132,6 +135,8 @@ class view(osv.osv): for error in validator.error_log: _logger.error(tools.ustr(error)) return False + if not valid_view(view_arch): + return False return True _constraints = [ diff --git a/openerp/tests/__init__.py b/openerp/tests/__init__.py index 5fccb07a082..fb4b937208e 100644 --- a/openerp/tests/__init__.py +++ b/openerp/tests/__init__.py @@ -11,6 +11,7 @@ See the :ref:`test-framework` section in the :ref:`features` list. import test_expression import test_ir_sequence import test_orm +import test_view_validation fast_suite = [ test_ir_sequence, @@ -19,6 +20,7 @@ fast_suite = [ checks = [ test_expression, test_orm, + test_view_validation, ] # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/tests/test_view_validation.py b/openerp/tests/test_view_validation.py new file mode 100644 index 00000000000..1773556d8ea --- /dev/null +++ b/openerp/tests/test_view_validation.py @@ -0,0 +1,44 @@ +# This test can be run stand-alone with something like: +# > PYTHONPATH=. python2 openerp/tests/test_view_validation.py + +from lxml import etree +from StringIO import StringIO +import unittest2 + +import openerp +from openerp.tools.view_validation import valid_page_in_book, valid_view + +invalid_page = etree.parse(StringIO('''\ +
+ +
+ + +
+
+
+''')).getroot() + +valid_page = etree.parse(StringIO('''\ +
+ +
+ + +
+
+
+''')).getroot() + +class test_view_validation(unittest2.TestCase): + """ Test the view validation code (but not the views themselves). """ + + def test_page_validation(self): + assert not valid_page_in_book(invalid_page) + assert valid_page_in_book(valid_page) + + assert not valid_view(invalid_page) + assert valid_view(valid_page) + +if __name__ == '__main__': + unittest2.main() diff --git a/openerp/tools/view_validation.py b/openerp/tools/view_validation.py new file mode 100644 index 00000000000..0f1609b8376 --- /dev/null +++ b/openerp/tools/view_validation.py @@ -0,0 +1,12 @@ +""" View validation code (using assertions, not the RNG schema). """ + +def valid_page_in_book(arch): + """A `page` node must be below a `book` node.""" + return not arch.xpath('//page[not(ancestor::notebook)]') + +def valid_view(arch): + if arch.tag == 'form': + for pred in [valid_page_in_book]: + if not pred(arch): + return False + return True