mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-05-20 10:34:30 +00:00
menu: Avoid reversing URL during Menu component construction
This allows app initialization to happen without Django being configured. Tests: - Update unit tests. - Visit /app, /system and /help pages. All the icons are listed properly. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
fa48fafa6b
commit
00e42a42b9
@ -1,6 +1,6 @@
|
|||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
|
|
||||||
from plinth import app
|
from plinth import app
|
||||||
|
|
||||||
@ -8,7 +8,7 @@ from plinth import app
|
|||||||
class Menu(app.FollowerComponent):
|
class Menu(app.FollowerComponent):
|
||||||
"""Component to manage a single menu item."""
|
"""Component to manage a single menu item."""
|
||||||
|
|
||||||
_all_menus = {}
|
_all_menus = set()
|
||||||
|
|
||||||
def __init__(self, component_id, name=None, short_description=None,
|
def __init__(self, component_id, name=None, short_description=None,
|
||||||
icon=None, url_name=None, url_args=None, url_kwargs=None,
|
icon=None, url_name=None, url_args=None, url_kwargs=None,
|
||||||
@ -57,21 +57,22 @@ class Menu(app.FollowerComponent):
|
|||||||
self.url = url
|
self.url = url
|
||||||
self.order = order
|
self.order = order
|
||||||
self.advanced = advanced
|
self.advanced = advanced
|
||||||
self.items = []
|
|
||||||
|
|
||||||
# Add self to parent menu item
|
self.url_name = url_name
|
||||||
if parent_url_name:
|
self.url_args = url_args
|
||||||
parent_menu = self.get(parent_url_name)
|
self.url_kwargs = url_kwargs
|
||||||
parent_menu.items.append(self)
|
self.parent_url_name = parent_url_name
|
||||||
|
|
||||||
# Add self to global list of menu items
|
# Add self to global list of menu items.
|
||||||
self._all_menus[url] = self
|
self._all_menus.add(self)
|
||||||
|
|
||||||
@classmethod
|
@property
|
||||||
def get(cls, urlname, url_args=None, url_kwargs=None):
|
def items(self):
|
||||||
"""Return a menu item with given URL name."""
|
"""Return the list of children for this menu item."""
|
||||||
url = reverse(urlname, args=url_args, kwargs=url_kwargs)
|
return [
|
||||||
return cls._all_menus[url]
|
item for item in self._all_menus
|
||||||
|
if item.parent_url_name == self.url_name
|
||||||
|
]
|
||||||
|
|
||||||
def sorted_items(self):
|
def sorted_items(self):
|
||||||
"""Return menu items in sorted order according to current locale."""
|
"""Return menu items in sorted order according to current locale."""
|
||||||
|
|||||||
@ -47,20 +47,20 @@ def build_menu(size=5):
|
|||||||
@pytest.fixture(name='empty_menus', autouse=True)
|
@pytest.fixture(name='empty_menus', autouse=True)
|
||||||
def fixture_empty_menus():
|
def fixture_empty_menus():
|
||||||
"""Remove all menu entries before starting a test."""
|
"""Remove all menu entries before starting a test."""
|
||||||
Menu._all_menus = {}
|
Menu._all_menus = set()
|
||||||
|
|
||||||
|
|
||||||
def test_init():
|
def test_init(rf):
|
||||||
"""Verify that main_menu and essential items are created."""
|
"""Verify that main_menu and essential items are created."""
|
||||||
menu_module.init()
|
menu_module.init()
|
||||||
main_menu = menu_module.main_menu
|
main_menu = menu_module.main_menu
|
||||||
assert isinstance(main_menu, Menu)
|
assert isinstance(main_menu, Menu)
|
||||||
|
|
||||||
apps_menu = main_menu.get('apps')
|
apps_menu = main_menu.active_item(rf.get('/apps/foo/'))
|
||||||
assert apps_menu.icon == 'fa-download'
|
assert apps_menu.icon == 'fa-download'
|
||||||
assert str(apps_menu.url) == '/apps/'
|
assert str(apps_menu.url) == '/apps/'
|
||||||
|
|
||||||
system_menu = main_menu.get('system')
|
system_menu = main_menu.active_item(rf.get('/sys/bar/'))
|
||||||
assert system_menu.icon == 'fa-cog'
|
assert system_menu.icon == 'fa-cog'
|
||||||
assert str(system_menu.url) == '/sys/'
|
assert str(system_menu.url) == '/sys/'
|
||||||
|
|
||||||
@ -95,6 +95,7 @@ def test_menu_creation_with_arguments():
|
|||||||
expected_icon, url_name, url_kwargs=url_kwargs,
|
expected_icon, url_name, url_kwargs=url_kwargs,
|
||||||
parent_url_name='index', order=expected_order, advanced=True)
|
parent_url_name='index', order=expected_order, advanced=True)
|
||||||
|
|
||||||
|
assert menu.parent_url_name == 'index'
|
||||||
assert len(parent_menu.items) == 1
|
assert len(parent_menu.items) == 1
|
||||||
assert parent_menu.items[0] == menu
|
assert parent_menu.items[0] == menu
|
||||||
assert expected_name == menu.name
|
assert expected_name == menu.name
|
||||||
@ -103,46 +104,12 @@ def test_menu_creation_with_arguments():
|
|||||||
assert expected_url == menu.url
|
assert expected_url == menu.url
|
||||||
assert expected_order == menu.order
|
assert expected_order == menu.order
|
||||||
assert menu.advanced
|
assert menu.advanced
|
||||||
|
assert url_name == menu.url_name
|
||||||
|
assert menu.url_args is None
|
||||||
|
assert url_kwargs == menu.url_kwargs
|
||||||
assert not menu.items
|
assert not menu.items
|
||||||
|
|
||||||
|
|
||||||
def test_get():
|
|
||||||
"""Verify that a menu item can be correctly retrieved."""
|
|
||||||
expected_name = 'Name2'
|
|
||||||
expected_short_description = 'ShortDescription2'
|
|
||||||
expected_icon = 'Icon2'
|
|
||||||
expected_url = 'index'
|
|
||||||
url_name = 'index'
|
|
||||||
reversed_url = reverse(url_name)
|
|
||||||
expected_order = 2
|
|
||||||
menu = Menu('menu-test', expected_name, expected_short_description,
|
|
||||||
expected_icon, url_name, order=expected_order, advanced=True)
|
|
||||||
actual_item = menu.get(expected_url)
|
|
||||||
|
|
||||||
assert actual_item is not None
|
|
||||||
assert expected_name == actual_item.name
|
|
||||||
assert expected_short_description == actual_item.short_description
|
|
||||||
assert expected_icon == actual_item.icon
|
|
||||||
assert reversed_url == actual_item.url
|
|
||||||
assert expected_order == actual_item.order
|
|
||||||
assert actual_item.advanced
|
|
||||||
assert not actual_item.items
|
|
||||||
|
|
||||||
|
|
||||||
def test_get_with_item_not_found():
|
|
||||||
"""Verify that a KeyError is raised if a menu item is not found."""
|
|
||||||
expected_name = 'Name3'
|
|
||||||
expected_short_description = 'ShortDescription3'
|
|
||||||
expected_icon = 'Icon3'
|
|
||||||
url_name = 'index'
|
|
||||||
expected_order = 3
|
|
||||||
menu = Menu('menu-test', expected_name, expected_short_description,
|
|
||||||
expected_icon, url_name, order=expected_order)
|
|
||||||
|
|
||||||
with pytest.raises(KeyError):
|
|
||||||
menu.get('apps')
|
|
||||||
|
|
||||||
|
|
||||||
def test_sort_items():
|
def test_sort_items():
|
||||||
"""Verify that menu items are sorted correctly."""
|
"""Verify that menu items are sorted correctly."""
|
||||||
size = 1000
|
size = 1000
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user