Prior to this commit, adding an anchor using auto-complete would not properly prefix the url with the URL of the current page. Steps to reproduce: - Create a page (e.g. /test), add blocks and create an anchor (e.g. - Save the page - Click on "Edit Menu" in "Pages" - Add a new menu entry - Type '#' in the URL field and select the anchor - Save => The menu entry is wrongly set as it does not contain the original page's URL inside the `href` attribute. This means that clicking on the menu from any other place will not properly redirect to the anchor on the /test page On top of that, editing a menu entry that was previously linked to a page would change the URL of the page with an anchor, making it impossible to access the page anymore until you change the URL back in the page manager. Steps to reproduce: - Create a new page (e.g. test) - Add a new menu entry that has this page as its URL - Save the new menu entry (close the dialogs) - Re-open the Menu dialog and edit the newly created menu entry - In the URL field, replace it with the page + an anchor (e.g. /test#anchor) - Save => The page's URL is now /test#anchor and is no longer accessible The is due to the `save` method of the `website.menu` model not containing code to properly manage adding an anchor to the menu. This commit fixes that. opw-3067750 closes odoo/odoo#108502 X-original-commit: 192bf08da191e6fad27dd2913be0801817256a3a Signed-off-by: Romain Derie (rde) <rde@odoo.com>
188 lines
8.0 KiB
Python
188 lines
8.0 KiB
Python
# coding: utf-8
|
|
|
|
import json
|
|
|
|
from odoo.tests import common
|
|
|
|
|
|
class TestMenu(common.TransactionCase):
|
|
def setUp(self):
|
|
super(TestMenu, self).setUp()
|
|
self.nb_website = self.env['website'].search_count([])
|
|
|
|
def test_01_menu_got_duplicated(self):
|
|
Menu = self.env['website.menu']
|
|
total_menu_items = Menu.search_count([])
|
|
|
|
self.menu_root = Menu.create({
|
|
'name': 'Root',
|
|
})
|
|
|
|
self.menu_child = Menu.create({
|
|
'name': 'Child',
|
|
'parent_id': self.menu_root.id,
|
|
})
|
|
|
|
self.assertEqual(total_menu_items + self.nb_website * 2, Menu.search_count([]), "Creating a menu without a website_id should create this menu for every website_id")
|
|
|
|
def test_02_menu_count(self):
|
|
Menu = self.env['website.menu']
|
|
total_menu_items = Menu.search_count([])
|
|
|
|
top_menu = self.env['website'].get_current_website().menu_id
|
|
data = [
|
|
{
|
|
'id': 'new-1',
|
|
'parent_id': top_menu.id,
|
|
'name': 'New Menu Specific 1',
|
|
'url': '/new-specific-1',
|
|
'is_mega_menu': False,
|
|
},
|
|
{
|
|
'id': 'new-2',
|
|
'parent_id': top_menu.id,
|
|
'name': 'New Menu Specific 2',
|
|
'url': '/new-specific-2',
|
|
'is_mega_menu': False,
|
|
}
|
|
]
|
|
Menu.save(1, {'data': data, 'to_delete': []})
|
|
|
|
self.assertEqual(total_menu_items + 2, Menu.search_count([]), "Creating 2 new menus should create only 2 menus records")
|
|
|
|
def test_03_default_menu_for_new_website(self):
|
|
Website = self.env['website']
|
|
Menu = self.env['website.menu']
|
|
total_menu_items = Menu.search_count([])
|
|
|
|
# Simulating website.menu created on module install (blog, shop, forum..) that will be created on default menu tree
|
|
default_menu = self.env.ref('website.main_menu')
|
|
Menu.create({
|
|
'name': 'Sub Default Menu',
|
|
'parent_id': default_menu.id,
|
|
})
|
|
self.assertEqual(total_menu_items + 1 + self.nb_website, Menu.search_count([]), "Creating a default child menu should create it as such and copy it on every website")
|
|
|
|
# Ensure new website got a top menu
|
|
total_menus = Menu.search_count([])
|
|
Website.create({'name': 'new website'})
|
|
self.assertEqual(total_menus + 4, Menu.search_count([]), "New website's bootstraping should have duplicate default menu tree (Top/Home/Contactus/Sub Default Menu)")
|
|
|
|
def test_04_specific_menu_translation(self):
|
|
IrModuleModule = self.env['ir.module.module']
|
|
Menu = self.env['website.menu']
|
|
existing_menus = Menu.search([])
|
|
|
|
default_menu = self.env.ref('website.main_menu')
|
|
template_menu = Menu.create({
|
|
'parent_id': default_menu.id,
|
|
'name': 'Menu in english',
|
|
'url': 'turlututu',
|
|
})
|
|
new_menus = Menu.search([]) - existing_menus
|
|
specific1, specific2 = new_menus.with_context(lang='fr_FR') - template_menu
|
|
|
|
# create fr_FR translation for template menu
|
|
self.env.ref('base.lang_fr').active = True
|
|
template_menu.with_context(lang='fr_FR').name = 'Menu en français'
|
|
self.assertEqual(specific1.name, 'Menu in english',
|
|
'Translating template menu does not translate specific menu')
|
|
|
|
# have different translation for specific website
|
|
specific1.name = 'Menu in french'
|
|
|
|
# loading translation add missing specific translation
|
|
IrModuleModule._load_module_terms(['website'], ['fr_FR'])
|
|
Menu.invalidate_model(['name'])
|
|
self.assertEqual(specific1.name, 'Menu in french',
|
|
'Load translation without overwriting keep existing translation')
|
|
self.assertEqual(specific2.name, 'Menu en français',
|
|
'Load translation add missing translation from template menu')
|
|
|
|
# loading translation with overwrite sync all translations from menu template
|
|
IrModuleModule._load_module_terms(['website'], ['fr_FR'], overwrite=True)
|
|
Menu.invalidate_model(['name'])
|
|
self.assertEqual(specific1.name, 'Menu en français',
|
|
'Load translation with overwriting update existing menu from template')
|
|
|
|
def test_05_default_menu_unlink(self):
|
|
Menu = self.env['website.menu']
|
|
total_menu_items = Menu.search_count([])
|
|
|
|
default_menu = self.env.ref('website.main_menu')
|
|
default_menu.child_id[0].unlink()
|
|
self.assertEqual(total_menu_items - 1 - self.nb_website, Menu.search_count([]), "Deleting a default menu item should delete its 'copies' (same URL) from website's menu trees. In this case, the default child menu and its copies on website 1 and website 2")
|
|
|
|
|
|
class TestMenuHttp(common.HttpCase):
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.page_url = '/page_specific'
|
|
self.page = self.env['website.page'].create({
|
|
'url': self.page_url,
|
|
'website_id': 1,
|
|
# ir.ui.view properties
|
|
'name': 'Base',
|
|
'type': 'qweb',
|
|
'arch': '<div>Specific View</div>',
|
|
'key': 'test.specific_view',
|
|
})
|
|
self.menu = self.env['website.menu'].create({
|
|
'name': 'Page Specific menu',
|
|
'page_id': self.page.id,
|
|
'url': self.page_url,
|
|
'website_id': 1,
|
|
})
|
|
|
|
def simulate_rpc_save_menu(self, data, to_delete=None):
|
|
self.authenticate("admin", "admin")
|
|
# `Menu.save(1, {'data': [data], 'to_delete': []})` would have been
|
|
# ideal but need a full frontend context to generate routing maps,
|
|
# router and registry, even MockRequest is not enough
|
|
self.url_open('/web/dataset/call_kw', data=json.dumps({
|
|
"params": {
|
|
'model': 'website.menu',
|
|
'method': 'save',
|
|
'args': [1, {'data': [data], 'to_delete': to_delete or []}],
|
|
'kwargs': {},
|
|
},
|
|
}), headers={"Content-Type": "application/json", "Referer": self.page.get_base_url() + self.page_url})
|
|
|
|
def test_01_menu_page_m2o(self):
|
|
# Ensure that the M2o relation tested later in the test is properly set.
|
|
self.assertTrue(self.menu.page_id, "M2o should have been set by the setup")
|
|
# Edit the menu URL to a 'reserved' URL
|
|
data = {
|
|
'id': self.menu.id,
|
|
'parent_id': self.menu.parent_id.id,
|
|
'name': self.menu.name,
|
|
'url': '/website/info',
|
|
}
|
|
self.simulate_rpc_save_menu(data)
|
|
|
|
self.assertFalse(self.menu.page_id, "M2o should have been unset as this is a reserved URL.")
|
|
self.assertEqual(self.menu.url, '/website/info', "Menu URL should have changed.")
|
|
self.assertEqual(self.page.url, self.page_url, "Page's URL shouldn't have changed.")
|
|
|
|
# 3. Edit the menu URL back to the page URL
|
|
data['url'] = self.page_url
|
|
self.env['website.menu'].save(1, {'data': [data], 'to_delete': []})
|
|
self.assertEqual(self.menu.page_id, self.page,
|
|
"M2o should have been set back, as there was a page found with the new URL set on the menu.")
|
|
self.assertTrue(self.page.url == self.menu.url == self.page_url)
|
|
|
|
def test_02_menu_anchors(self):
|
|
# Ensure that the M2o relation tested later in the test is properly set.
|
|
self.assertTrue(self.menu.page_id, "M2o should have been set by the setup")
|
|
# Edit the menu URL to an anchor
|
|
data = {
|
|
'id': self.menu.id,
|
|
'parent_id': self.menu.parent_id.id,
|
|
'name': self.menu.name,
|
|
'url': '#anchor',
|
|
}
|
|
self.simulate_rpc_save_menu(data)
|
|
self.assertFalse(self.menu.page_id, "M2o should have been unset as this is an anchor URL.")
|
|
self.assertEqual(self.menu.url, self.page_url + '#anchor', "Page URL should have been properly prefixed with the referer url")
|
|
self.assertEqual(self.page.url, self.page_url, "Page URL should not have changed")
|