From 86031d25f1ea6ba979944bb93447ac3ed56ae33c Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa Date: Sun, 22 Dec 2024 19:55:39 -0800 Subject: [PATCH] menu: Implement a helper method to lookup menu items using URL name - This will used to create breadcumbs. Signed-off-by: Sunil Mohan Adapa Reviewed-by: Veiko Aasa --- plinth/menu.py | 12 ++++++++++++ plinth/tests/data/urls.py | 10 ++++++++++ plinth/tests/test_menu.py | 26 ++++++++++++++++++-------- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/plinth/menu.py b/plinth/menu.py index a1d50110d..44150ddff 100644 --- a/plinth/menu.py +++ b/plinth/menu.py @@ -90,6 +90,18 @@ class Menu(app.FollowerComponent): return None + @staticmethod + def get_with_url_name(url_name: str) -> 'Menu': + """Return a menu item with given URL name. + + Raise LookupError of the request item is not found. + """ + for item in Menu._all_menus: + if item.url_name == url_name: + return item + + raise LookupError + main_menu = None diff --git a/plinth/tests/data/urls.py b/plinth/tests/data/urls.py index 88a377dcb..cfa25921c 100644 --- a/plinth/tests/data/urls.py +++ b/plinth/tests/data/urls.py @@ -13,4 +13,14 @@ urlpatterns = [ re_path(r'^sys/$', _test_view, name='system'), re_path(r'^test/(?P\d+)/(?P\d+)/(?P\d+)/$', _test_view, name='test'), + re_path(r'^test1/(?P\d+)/(?P\d+)/(?P\d+)/$', _test_view, + name='test1'), + re_path(r'^test2/(?P\d+)/(?P\d+)/(?P\d+)/$', _test_view, + name='test2'), + re_path(r'^test3/(?P\d+)/(?P\d+)/(?P\d+)/$', _test_view, + name='test3'), + re_path(r'^test4/(?P\d+)/(?P\d+)/(?P\d+)/$', _test_view, + name='test4'), + re_path(r'^test5/(?P\d+)/(?P\d+)/(?P\d+)/$', _test_view, + name='test5'), ] diff --git a/plinth/tests/test_menu.py b/plinth/tests/test_menu.py index 6c6e48997..105fc1ae5 100644 --- a/plinth/tests/test_menu.py +++ b/plinth/tests/test_menu.py @@ -12,7 +12,7 @@ from django.urls import reverse from plinth import menu as menu_module from plinth.menu import Menu -URL_TEMPLATE = '/test/{}/{}/{}/' +URL_TEMPLATE = '/test{}/{}/{}/{}/' # Test helper methods @@ -25,11 +25,11 @@ def build_menu(size=5): for index in range(1, size + 1): kwargs = { - 'component_id': 'menu-test-' + str(index), - 'name': 'Name' + str(index), - 'short_description': 'ShortDescription' + str(index), - 'icon': 'Icon' + str(index), - 'url_name': 'test', + 'component_id': f'menu-test-{index}', + 'name': f'Name{index}', + 'short_description': f'ShortDescription{index}', + 'icon': f'Icon{index}', + 'url_name': f'test{index}', 'url_kwargs': { 'a': index, 'b': index, @@ -134,7 +134,7 @@ def test_active_item(): for index in range(1, 8): request = HttpRequest() - request.path = URL_TEMPLATE.format(index, index, index) + request.path = URL_TEMPLATE.format(index, index, index, index) item = menu.active_item(request) if index <= 5: assert request.path == item.url @@ -145,8 +145,18 @@ def test_active_item(): def test_active_item_when_inside_subpath(): """Verify that the current URL could be a sub-path of a menu item.""" menu = build_menu() - expected_url = URL_TEMPLATE.format(1, 1, 1) + expected_url = URL_TEMPLATE.format(1, 1, 1, 1) request = HttpRequest() request.path = expected_url + 'd/e/f/' item = menu.active_item(request) assert expected_url == item.url + + +def test_get_with_url_name(): + """Verify that menu item can be retrieved from all items.""" + build_menu() + + menu = Menu.get_with_url_name('test5') + assert menu.name == 'Name5' + with pytest.raises(LookupError): + Menu.get_with_url_name('x-non-existent')