diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py index bc16076272e..6c91a3b1633 100644 --- a/addons/base/controllers/main.py +++ b/addons/base/controllers/main.py @@ -118,6 +118,16 @@ class Menu(openerpweb.Controller): @openerpweb.jsonrequest def load(self, req): + return {'data': self.do_load(req)} + + def do_load(self, req): + """ Loads all menu items (all applications and their sub-menus). + + :param req: A request object, with an OpenERP session attribute + :type req: < session -> OpenERPSession > + :return: the menu root + :rtype: dict('children': menu_nodes) + """ Menus = req.session.model('ir.ui.menu') # menus are loaded fully unlike a regular tree view, cause there are # less than 512 items @@ -132,14 +142,15 @@ class Menu(openerpweb.Controller): if not menu_item['parent_id']: continue parent = menu_item['parent_id'][0] if parent in menu_items_map: - menu_items_map[parent].set_default('children', []).append(menu_item) + menu_items_map[parent].setdefault( + 'children', []).append(menu_item) # sort by sequence a tree using parent_id for menu_item in menu_items: - menu_item.set_default('children', []).sort( + menu_item.setdefault('children', []).sort( key=lambda x:x["sequence"]) - return {'data': menu_root} + return menu_root @openerpweb.jsonrequest def action(self, req, menu_id): diff --git a/addons/base/tests/__init__.py b/addons/base/tests/__init__.py new file mode 100644 index 00000000000..40a96afc6ff --- /dev/null +++ b/addons/base/tests/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- diff --git a/addons/base/tests/test_menu.py b/addons/base/tests/test_menu.py new file mode 100644 index 00000000000..1d1e49b6c97 --- /dev/null +++ b/addons/base/tests/test_menu.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +import mock +import unittest2 +import base.controllers.main +import openerpweb.openerpweb + +class Placeholder(object): + def __init__(self, **kwargs): + for k, v in kwargs.iteritems(): + setattr(self, k, v) + +class LoadTest(unittest2.TestCase): + def setUp(self): + self.menu = base.controllers.main.Menu() + self.menus_mock = mock.Mock() + self.request = Placeholder( + session=openerpweb.openerpweb.OpenERPSession( + model_factory=lambda _session, _name: self.menus_mock)) + + def tearDown(self): + del self.request + del self.menus_mock + del self.menu + + def test_empty(self): + self.menus_mock.search = mock.Mock(return_value=[]) + self.menus_mock.read = mock.Mock(return_value=[]) + + root = self.menu.do_load(self.request) + + self.menus_mock.search.assert_called_with([]) + self.menus_mock.read.assert_called_with( + [], ['name', 'sequence', 'parent_id']) + + self.assertListEqual( + root['children'], + []) + + def test_applications_sort(self): + self.menus_mock.search = mock.Mock(return_value=[1, 2, 3]) + self.menus_mock.read = mock.Mock(return_value=[ + {'id': 2, 'sequence': 3, 'parent_id': [False, '']}, + {'id': 3, 'sequence': 2, 'parent_id': [False, '']}, + {'id': 1, 'sequence': 1, 'parent_id': [False, '']}, + ]) + + root = self.menu.do_load(self.request) + + self.menus_mock.read.assert_called_with( + [1, 2, 3], ['name', 'sequence', 'parent_id']) + + self.assertEqual( + root['children'], + [{ + 'id': 1, 'sequence': 1, + 'parent_id': [False, ''], 'children': [] + }, { + 'id': 3, 'sequence': 2, + 'parent_id': [False, ''], 'children': [] + }, { + 'id': 2, 'sequence': 3, + 'parent_id': [False, ''], 'children': [] + }]) + + def test_deep(self): + self.menus_mock.search = mock.Mock(return_value=[1, 2, 3, 4]) + self.menus_mock.read = mock.Mock(return_value=[ + {'id': 1, 'sequence': 1, 'parent_id': [False, '']}, + {'id': 2, 'sequence': 2, 'parent_id': [1, '']}, + {'id': 3, 'sequence': 1, 'parent_id': [2, '']}, + {'id': 4, 'sequence': 2, 'parent_id': [2, '']}, + ]) + + root = self.menu.do_load(self.request) + + self.assertEqual( + root['children'], + [{ + 'id': 1, + 'sequence': 1, + 'parent_id': [False, ''], + 'children': [{ + 'id': 2, + 'sequence': 2, + 'parent_id': [1, ''], + 'children': [{ + 'id': 3, + 'sequence': 1, + 'parent_id': [2, ''], + 'children': [] + }, { + 'id': 4, + 'sequence': 2, + 'parent_id': [2, ''], + 'children': [] + }] + }] + }] + ) diff --git a/openerpweb/openerpweb.py b/openerpweb/openerpweb.py index 404616273fb..f966501f72c 100644 --- a/openerpweb/openerpweb.py +++ b/openerpweb/openerpweb.py @@ -39,13 +39,15 @@ class OpenERPModel(object): class OpenERPSession(object): - def __init__(self, server='127.0.0.1', port=8069): + def __init__(self, server='127.0.0.1', port=8069, + model_factory=OpenERPModel): self._server = server self._port = port self._db = False self._uid = False self._login = False self._password = False + self.model_factory = model_factory def proxy(self, service): s = xmlrpctimeout.TimeoutServerProxy('http://%s:%s/xmlrpc/%s' % (self._server, self._port, service), timeout=5) @@ -69,7 +71,7 @@ class OpenERPSession(object): return r def model(self, model): - return OpenERPModel(self, model) + return self.model_factory(self, model) #---------------------------------------------------------- # OpenERP Web RequestHandler