1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
# SPDX-License-Identifier: AGPL-3.0-or-later
"""
Test module for menus.
"""
import random
import pytest
from django.http import HttpRequest
from django.urls import reverse
from plinth import menu as menu_module
from plinth.menu import Menu
URL_TEMPLATE = '/test{}/{}/{}/{}/'
# Test helper methods
def build_menu(size=5):
"""Build a menu with the specified number of items."""
random.seed()
menu = Menu('menu-index', url_name='index')
for index in range(1, size + 1):
kwargs = {
'component_id': f'menu-test-{index}',
'name': f'Name{index}',
'icon': f'Icon{index}',
'tags': ['tag1', 'tag2'],
'url_name': f'test{index}',
'url_kwargs': {
'a': index,
'b': index,
'c': index
},
'parent_url_name': 'index',
'order': random.randint(0, 1000),
}
Menu(**kwargs)
return menu
@pytest.fixture(name='empty_menus', autouse=True)
def fixture_empty_menus():
"""Remove all menu entries before starting a test."""
Menu._all_menus = set()
def test_init(rf):
"""Verify that main_menu and essential items are created."""
menu_module.init()
main_menu = menu_module.main_menu
assert isinstance(main_menu, Menu)
apps_menu = main_menu.active_item(rf.get('/apps/foo/'))
assert apps_menu.icon == 'fa-download'
assert str(apps_menu.url) == '/apps/'
system_menu = main_menu.active_item(rf.get('/sys/bar/'))
assert system_menu.icon == 'fa-cog'
assert str(system_menu.url) == '/sys/'
def test_menu_creation_without_arguments():
"""Verify the Menu state without initialization parameters."""
with pytest.raises(ValueError):
Menu('menu-test')
menu = Menu('menu-index', url_name='index')
assert menu.component_id == 'menu-index'
assert menu.name is None
assert menu.icon is None
assert menu.tags is None
assert menu.url == '/'
assert menu.order == 50
assert not menu.advanced
assert not menu.items
def test_menu_creation_with_arguments():
"""Verify the Menu state with initialization parameters."""
expected_name = 'Name'
expected_icon = 'Icon'
expected_tags = ['tag1', 'tag2']
url_name = 'test'
url_kwargs = {'a': 1, 'b': 2, 'c': 3}
expected_url = reverse(url_name, kwargs=url_kwargs)
expected_order = 42
parent_menu = Menu('menu-index', url_name='index')
menu = Menu('menu-test', expected_name, expected_icon, expected_tags,
url_name, url_kwargs=url_kwargs, parent_url_name='index',
order=expected_order, advanced=True)
assert menu.parent_url_name == 'index'
assert len(parent_menu.items) == 1
assert parent_menu.items[0] == menu
assert expected_name == menu.name
assert expected_icon == menu.icon
assert expected_tags == menu.tags
assert expected_url == menu.url
assert expected_order == menu.order
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
def test_sort_items():
"""Verify that menu items are sorted correctly."""
size = 1000
menu = build_menu(size)
for index in range(0, 200):
menu.items[index].order = 100
# Verify that the order of every item is equal to or greater
# than the order of the item preceding it and if the order is
# the same, the names are considered.
items = menu.sorted_items()
for index in range(1, size):
assert items[index].order >= items[index - 1].order
if items[index].order == items[index - 1].order:
assert items[index].name >= items[index - 1].name
def test_active_item():
"""Verify that an active menu item can be correctly retrieved."""
menu = build_menu()
for index in range(1, 8):
request = HttpRequest()
request.path = URL_TEMPLATE.format(index, index, index, index)
item = menu.active_item(request)
if index <= 5:
assert request.path == item.url
else:
assert item is None
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, 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')
|