| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | # -*- coding: utf-8; -*- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from unittest import TestCase | 
					
						
							|  |  |  | from unittest.mock import patch, MagicMock | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from wuttaweb import menus as mod | 
					
						
							| 
									
										
										
										
											2025-01-06 16:47:48 -06:00
										 |  |  | from wuttaweb.testing import WebTestCase | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-14 21:20:00 -05:00
										 |  |  | class TestMenuHandler(WebTestCase): | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def setUp(self): | 
					
						
							| 
									
										
										
										
											2024-08-14 21:20:00 -05:00
										 |  |  |         self.setup_web() | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |         self.handler = mod.MenuHandler(self.config) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_make_admin_menu(self): | 
					
						
							| 
									
										
										
										
											2024-12-03 21:32:46 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # no people entry by default | 
					
						
							|  |  |  |         menu = self.handler.make_admin_menu(self.request) | 
					
						
							|  |  |  |         self.assertIsInstance(menu, dict) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         routes = [item.get("route") for item in menu["items"]] | 
					
						
							|  |  |  |         self.assertNotIn("people", routes) | 
					
						
							| 
									
										
										
										
											2024-12-03 21:32:46 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # but we can request it | 
					
						
							|  |  |  |         menu = self.handler.make_admin_menu(self.request, include_people=True) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         routes = [item.get("route") for item in menu["items"]] | 
					
						
							|  |  |  |         self.assertIn("people", routes) | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_make_menus(self): | 
					
						
							|  |  |  |         menus = self.handler.make_menus(self.request) | 
					
						
							|  |  |  |         self.assertIsInstance(menus, list) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_is_allowed(self): | 
					
						
							| 
									
										
										
										
											2024-08-14 21:20:00 -05:00
										 |  |  |         model = self.app.model | 
					
						
							|  |  |  |         auth = self.app.get_auth_handler() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # user with perms | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         barney = model.User(username="barney") | 
					
						
							| 
									
										
										
										
											2024-08-14 21:20:00 -05:00
										 |  |  |         self.session.add(barney) | 
					
						
							|  |  |  |         blokes = model.Role(name="Blokes") | 
					
						
							|  |  |  |         self.session.add(blokes) | 
					
						
							|  |  |  |         barney.roles.append(blokes) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         auth.grant_permission(blokes, "appinfo.list") | 
					
						
							| 
									
										
										
										
											2024-08-14 21:20:00 -05:00
										 |  |  |         self.request.user = barney | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # perm not granted to user | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         item = {"perm": "appinfo.configure"} | 
					
						
							| 
									
										
										
										
											2024-08-14 21:20:00 -05:00
										 |  |  |         self.assertFalse(self.handler._is_allowed(self.request, item)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # perm *is* granted to user | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         item = {"perm": "appinfo.list"} | 
					
						
							| 
									
										
										
										
											2024-08-14 21:20:00 -05:00
										 |  |  |         self.assertTrue(self.handler._is_allowed(self.request, item)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # perm not required | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |         item = {} | 
					
						
							|  |  |  |         self.assertTrue(self.handler._is_allowed(self.request, item)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_mark_allowed(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def make_menus(): | 
					
						
							|  |  |  |             return [ | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                     "type": "menu", | 
					
						
							|  |  |  |                     "items": [ | 
					
						
							|  |  |  |                         {"title": "Foo", "url": "#"}, | 
					
						
							|  |  |  |                         {"title": "Bar", "url": "#"}, | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                     ], | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         mock_is_allowed = MagicMock() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(self.handler, "_is_allowed", new=mock_is_allowed): | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # all should be allowed | 
					
						
							|  |  |  |             mock_is_allowed.return_value = True | 
					
						
							|  |  |  |             menus = make_menus() | 
					
						
							|  |  |  |             self.handler._mark_allowed(self.request, menus) | 
					
						
							|  |  |  |             menu = menus[0] | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertTrue(menu["allowed"]) | 
					
						
							|  |  |  |             foo, bar = menu["items"] | 
					
						
							|  |  |  |             self.assertTrue(foo["allowed"]) | 
					
						
							|  |  |  |             self.assertTrue(bar["allowed"]) | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # none should be allowed | 
					
						
							|  |  |  |             mock_is_allowed.return_value = False | 
					
						
							|  |  |  |             menus = make_menus() | 
					
						
							|  |  |  |             self.handler._mark_allowed(self.request, menus) | 
					
						
							|  |  |  |             menu = menus[0] | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertFalse(menu["allowed"]) | 
					
						
							|  |  |  |             foo, bar = menu["items"] | 
					
						
							|  |  |  |             self.assertFalse(foo["allowed"]) | 
					
						
							|  |  |  |             self.assertFalse(bar["allowed"]) | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_mark_allowed_submenu(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def make_menus(): | 
					
						
							|  |  |  |             return [ | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                     "type": "menu", | 
					
						
							|  |  |  |                     "items": [ | 
					
						
							|  |  |  |                         {"title": "Foo", "url": "#"}, | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                         { | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                             "type": "menu", | 
					
						
							|  |  |  |                             "items": [ | 
					
						
							|  |  |  |                                 {"title": "Bar", "url": "#"}, | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                             ], | 
					
						
							|  |  |  |                         }, | 
					
						
							|  |  |  |                     ], | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         mock_is_allowed = MagicMock() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(self.handler, "_is_allowed", new=mock_is_allowed): | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # all should be allowed | 
					
						
							|  |  |  |             mock_is_allowed.return_value = True | 
					
						
							|  |  |  |             menus = make_menus() | 
					
						
							|  |  |  |             self.handler._mark_allowed(self.request, menus) | 
					
						
							|  |  |  |             menu = menus[0] | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertTrue(menu["allowed"]) | 
					
						
							|  |  |  |             foo, submenu = menu["items"] | 
					
						
							|  |  |  |             self.assertTrue(foo["allowed"]) | 
					
						
							|  |  |  |             self.assertTrue(submenu["allowed"]) | 
					
						
							|  |  |  |             subitem = submenu["items"][0] | 
					
						
							|  |  |  |             self.assertTrue(subitem["allowed"]) | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # none should be allowed | 
					
						
							|  |  |  |             mock_is_allowed.return_value = False | 
					
						
							|  |  |  |             menus = make_menus() | 
					
						
							|  |  |  |             self.handler._mark_allowed(self.request, menus) | 
					
						
							|  |  |  |             menu = menus[0] | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertFalse(menu["allowed"]) | 
					
						
							|  |  |  |             foo, submenu = menu["items"] | 
					
						
							|  |  |  |             self.assertFalse(foo["allowed"]) | 
					
						
							|  |  |  |             self.assertFalse(submenu["allowed"]) | 
					
						
							|  |  |  |             subitem = submenu["items"][0] | 
					
						
							|  |  |  |             self.assertFalse(subitem["allowed"]) | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_make_menu_key(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(self.handler._make_menu_key("foo"), "foo") | 
					
						
							|  |  |  |         self.assertEqual(self.handler._make_menu_key("FooBar"), "foobar") | 
					
						
							|  |  |  |         self.assertEqual(self.handler._make_menu_key("Foo - $#Bar"), "foobar") | 
					
						
							|  |  |  |         self.assertEqual(self.handler._make_menu_key("Foo__Bar"), "foo__bar") | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_make_menu_entry_item(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         item = {"title": "Foo", "url": "#"} | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |         entry = self.handler._make_menu_entry(self.request, item) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(entry["type"], "item") | 
					
						
							|  |  |  |         self.assertEqual(entry["title"], "Foo") | 
					
						
							|  |  |  |         self.assertEqual(entry["url"], "#") | 
					
						
							|  |  |  |         self.assertTrue(entry["is_link"]) | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_make_menu_entry_item_with_no_url(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         item = {"title": "Foo"} | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |         entry = self.handler._make_menu_entry(self.request, item) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(entry["type"], "item") | 
					
						
							|  |  |  |         self.assertEqual(entry["title"], "Foo") | 
					
						
							|  |  |  |         self.assertNotIn("url", entry) | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |         # nb. still sets is_link = True; basically it's <a> with no href | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertTrue(entry["is_link"]) | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_make_menu_entry_item_with_known_route(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         item = {"title": "Foo", "route": "home"} | 
					
						
							|  |  |  |         with patch.object(self.request, "route_url", return_value="/something"): | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |             entry = self.handler._make_menu_entry(self.request, item) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertEqual(entry["type"], "item") | 
					
						
							|  |  |  |             self.assertEqual(entry["url"], "/something") | 
					
						
							|  |  |  |             self.assertTrue(entry["is_link"]) | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_make_menu_entry_item_with_unknown_route(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         item = {"title": "Foo", "route": "home"} | 
					
						
							|  |  |  |         with patch.object(self.request, "route_url", side_effect=KeyError): | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |             entry = self.handler._make_menu_entry(self.request, item) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertEqual(entry["type"], "item") | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |             # nb. fake url is used, based on (bad) route name | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertEqual(entry["url"], "home") | 
					
						
							|  |  |  |             self.assertTrue(entry["is_link"]) | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_make_menu_entry_sep(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         item = {"type": "sep"} | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |         entry = self.handler._make_menu_entry(self.request, item) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(entry["type"], "sep") | 
					
						
							|  |  |  |         self.assertTrue(entry["is_sep"]) | 
					
						
							|  |  |  |         self.assertFalse(entry["is_menu"]) | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-14 10:47:14 -05:00
										 |  |  |     def test_make_raw_menus(self): | 
					
						
							|  |  |  |         # minimal test to ensure it calls the other method | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(self.handler, "make_menus") as make_menus: | 
					
						
							|  |  |  |             self.handler._make_raw_menus(self.request, foo="bar") | 
					
						
							|  |  |  |             make_menus.assert_called_once_with(self.request, foo="bar") | 
					
						
							| 
									
										
										
										
											2024-07-14 10:47:14 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |     def test_do_make_menus_prune_unallowed_item(self): | 
					
						
							|  |  |  |         test_menus = [ | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                 "title": "First Menu", | 
					
						
							|  |  |  |                 "type": "menu", | 
					
						
							|  |  |  |                 "items": [ | 
					
						
							|  |  |  |                     {"title": "Foo", "url": "#"}, | 
					
						
							|  |  |  |                     {"title": "Bar", "url": "#"}, | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                 ], | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def is_allowed(request, item): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             if item.get("title") == "Bar": | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                 return False | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(self.handler, "make_menus", return_value=test_menus): | 
					
						
							|  |  |  |             with patch.object(self.handler, "_is_allowed", side_effect=is_allowed): | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                 menus = self.handler.do_make_menus(self.request) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # Foo remains but Bar is pruned | 
					
						
							|  |  |  |                 menu = menus[0] | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                 self.assertEqual(len(menu["items"]), 1) | 
					
						
							|  |  |  |                 item = menu["items"][0] | 
					
						
							|  |  |  |                 self.assertEqual(item["title"], "Foo") | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_do_make_menus_prune_unallowed_menu(self): | 
					
						
							|  |  |  |         test_menus = [ | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                 "title": "First Menu", | 
					
						
							|  |  |  |                 "type": "menu", | 
					
						
							|  |  |  |                 "items": [ | 
					
						
							|  |  |  |                     {"title": "Foo", "url": "#"}, | 
					
						
							|  |  |  |                     {"title": "Bar", "url": "#"}, | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                 ], | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                 "title": "Second Menu", | 
					
						
							|  |  |  |                 "type": "menu", | 
					
						
							|  |  |  |                 "items": [ | 
					
						
							|  |  |  |                     {"title": "Baz", "url": "#"}, | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                 ], | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def is_allowed(request, item): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             if item.get("title") == "Baz": | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                 return True | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(self.handler, "make_menus", return_value=test_menus): | 
					
						
							|  |  |  |             with patch.object(self.handler, "_is_allowed", side_effect=is_allowed): | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                 menus = self.handler.do_make_menus(self.request) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # Second/Baz remains but First/Foo/Bar are pruned | 
					
						
							|  |  |  |                 self.assertEqual(len(menus), 1) | 
					
						
							|  |  |  |                 menu = menus[0] | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                 self.assertEqual(menu["title"], "Second Menu") | 
					
						
							|  |  |  |                 self.assertEqual(len(menu["items"]), 1) | 
					
						
							|  |  |  |                 item = menu["items"][0] | 
					
						
							|  |  |  |                 self.assertEqual(item["title"], "Baz") | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_do_make_menus_with_top_link(self): | 
					
						
							|  |  |  |         test_menus = [ | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                 "title": "First Menu", | 
					
						
							|  |  |  |                 "type": "menu", | 
					
						
							|  |  |  |                 "items": [ | 
					
						
							|  |  |  |                     {"title": "Foo", "url": "#"}, | 
					
						
							|  |  |  |                     {"title": "Bar", "url": "#"}, | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                 ], | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                 "title": "Second Link", | 
					
						
							|  |  |  |                 "type": "link", | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |             }, | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(self.handler, "make_menus", return_value=test_menus): | 
					
						
							|  |  |  |             with patch.object(self.handler, "_is_allowed", return_value=True): | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                 menus = self.handler.do_make_menus(self.request) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # ensure top link remains | 
					
						
							|  |  |  |                 self.assertEqual(len(menus), 2) | 
					
						
							|  |  |  |                 menu = menus[1] | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                 self.assertEqual(menu["title"], "Second Link") | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_do_make_menus_with_trailing_sep(self): | 
					
						
							|  |  |  |         test_menus = [ | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                 "title": "First Menu", | 
					
						
							|  |  |  |                 "type": "menu", | 
					
						
							|  |  |  |                 "items": [ | 
					
						
							|  |  |  |                     {"title": "Foo", "url": "#"}, | 
					
						
							|  |  |  |                     {"title": "Bar", "url": "#"}, | 
					
						
							|  |  |  |                     {"type": "sep"}, | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                 ], | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(self.handler, "make_menus", return_value=test_menus): | 
					
						
							|  |  |  |             with patch.object(self.handler, "_is_allowed", return_value=True): | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                 menus = self.handler.do_make_menus(self.request) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # ensure trailing sep was pruned | 
					
						
							|  |  |  |                 menu = menus[0] | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                 self.assertEqual(len(menu["items"]), 2) | 
					
						
							|  |  |  |                 foo, bar = menu["items"] | 
					
						
							|  |  |  |                 self.assertEqual(foo["title"], "Foo") | 
					
						
							|  |  |  |                 self.assertEqual(bar["title"], "Bar") | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_do_make_menus_with_submenu(self): | 
					
						
							|  |  |  |         test_menus = [ | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                 "title": "First Menu", | 
					
						
							|  |  |  |                 "type": "menu", | 
					
						
							|  |  |  |                 "items": [ | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                     { | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                         "title": "First Submenu", | 
					
						
							|  |  |  |                         "type": "menu", | 
					
						
							|  |  |  |                         "items": [ | 
					
						
							|  |  |  |                             {"title": "Foo", "url": "#"}, | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                         ], | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                     { | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                         "title": "Second Submenu", | 
					
						
							|  |  |  |                         "type": "menu", | 
					
						
							|  |  |  |                         "items": [ | 
					
						
							|  |  |  |                             {"title": "Bar", "url": "#"}, | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                         ], | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                 ], | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def is_allowed(request, item): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             if item.get("title") == "Bar": | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                 return False | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(self.handler, "make_menus", return_value=test_menus): | 
					
						
							|  |  |  |             with patch.object(self.handler, "_is_allowed", side_effect=is_allowed): | 
					
						
							| 
									
										
										
										
											2024-07-13 20:03:44 -05:00
										 |  |  |                 menus = self.handler.do_make_menus(self.request) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # first submenu remains, second is pruned | 
					
						
							|  |  |  |                 menu = menus[0] | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                 self.assertEqual(len(menu["items"]), 1) | 
					
						
							|  |  |  |                 submenu = menu["items"][0] | 
					
						
							|  |  |  |                 self.assertEqual(submenu["type"], "submenu") | 
					
						
							|  |  |  |                 self.assertEqual(submenu["title"], "First Submenu") | 
					
						
							|  |  |  |                 self.assertEqual(len(submenu["items"]), 1) | 
					
						
							|  |  |  |                 item = submenu["items"][0] | 
					
						
							|  |  |  |                 self.assertEqual(item["title"], "Foo") |