# -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. import base64 from werkzeug.urls import url_encode import odoo import odoo.tests from odoo.addons.base.tests.common import HttpCaseWithUserDemo @odoo.tests.tagged('-at_install', 'post_install') class TestUiCustomizeTheme(odoo.tests.HttpCase): def test_01_attachment_website_unlink(self): ''' Some ir.attachment needs to be unlinked when a website is unlink, otherwise some flows will just crash. That's the case when 2 website have their theme color customized. Removing a website will make its customized attachment generic, thus having 2 attachments with the same URL available for other websites, leading to singleton errors (among other). But no all attachment should be deleted, eg we don't want to delete a SO or invoice PDF coming from an ecommerce order. ''' Website = self.env['website'] Page = self.env['website.page'] Attachment = self.env['ir.attachment'] website_default = Website.browse(1) website_test = Website.create({'name': 'Website Test'}) # simulate attachment state when editing 2 theme through customize custom_url = '/_custom/web.assets_frontend/TEST/website/static/src/scss/options/colors/user_theme_color_palette.scss' scss_attachment = Attachment.create({ 'name': custom_url, 'type': 'binary', 'mimetype': 'text/scss', 'datas': '', 'url': custom_url, 'website_id': website_default.id }) scss_attachment.copy({'website_id': website_test.id}) # simulate PDF from ecommerce order # Note: it will only have its website_id flag if the website has a domain # equal to the current URL (fallback or get_current_website()) so_attachment = Attachment.create({ 'name': 'SO036.pdf', 'type': 'binary', 'mimetype': 'application/pdf', 'datas': '', 'website_id': website_test.id }) # avoid sql error on page website_id restrict Page.search([('website_id', '=', website_test.id)]).unlink() website_test.unlink() self.assertEqual(Attachment.search_count([('url', '=', custom_url)]), 1, 'Should not left duplicates when deleting a website') self.assertTrue(so_attachment.exists(), 'Most attachment should not be deleted') self.assertFalse(so_attachment.website_id, 'Website should be removed') @odoo.tests.tagged('-at_install', 'post_install') class TestUiHtmlEditor(HttpCaseWithUserDemo): def test_html_editor_multiple_templates(self): Website = self.env['website'] View = self.env['ir.ui.view'] Page = self.env['website.page'] self.generic_view = View.create({ 'name': 'Generic', 'type': 'qweb', 'arch': '''
content
''', 'key': 'test.generic_view', }) self.generic_page = Page.create({ 'view_id': self.generic_view.id, 'url': '/generic', }) generic_page = Website.viewref('test.generic_view') # Use an empty page layout with oe_structure id for this test oe_structure_layout = '''
''' generic_page.arch = oe_structure_layout oe_structure_layout = generic_page.arch self.start_tour(self.env['website'].get_client_action_url('/generic'), 'html_editor_multiple_templates', login='admin') self.assertEqual(View.search_count([('key', '=', 'test.generic_view')]), 2, "homepage view should have been COW'd") self.assertTrue(generic_page.arch == oe_structure_layout, "Generic homepage view should be untouched") self.assertEqual(len(generic_page.inherit_children_ids.filtered(lambda v: 'oe_structure' in v.name)), 0, "oe_structure view should have been deleted when aboutus was COW") specific_page = Website.with_context(website_id=1).viewref('test.generic_view') self.assertTrue(specific_page.arch != oe_structure_layout, "Specific homepage view should have been changed") self.assertEqual(len(specific_page.inherit_children_ids.filtered(lambda v: 'oe_structure' in v.name)), 1, "oe_structure view should have been created on the specific tree") def test_html_editor_scss(self): self.user_demo.write({ 'groups_id': [(6, 0, [ self.env.ref('base.group_user').id, self.env.ref('website.group_website_designer').id ])] }) self.start_tour(self.env['website'].get_client_action_url('/contactus'), 'test_html_editor_scss', login='admin') self.start_tour(self.env['website'].get_client_action_url('/'), 'test_html_editor_scss_2', login='demo') def media_dialog_undraw(self): self.start_tour("/", 'website_media_dialog_undraw', login='admin') @odoo.tests.tagged('-at_install', 'post_install') class TestUiTranslate(odoo.tests.HttpCase): def test_admin_tour_rte_translator(self): self.env['res.lang'].create({ 'name': 'Parseltongue', 'code': 'pa_GB', 'iso_code': 'pa_GB', 'url_code': 'pa_GB', }) self.start_tour(self.env['website'].get_client_action_url('/'), 'rte_translator', login='admin', timeout=120) def test_translate_menu_name(self): lang_en = self.env.ref('base.lang_en') parseltongue = self.env['res.lang'].create({ 'name': 'Parseltongue', 'code': 'pa_GB', 'iso_code': 'pa_GB', 'url_code': 'pa_GB', }) self.env['res.lang']._activate_lang(parseltongue.code) default_website = self.env.ref('website.default_website') default_website.write({ 'default_lang_id': lang_en.id, 'language_ids': [(6, 0, (lang_en + parseltongue).ids)], }) new_menu = self.env['website.menu'].create({ 'name': 'Menu to edit', 'parent_id': default_website.menu_id.id, 'website_id': default_website.id, 'url': '/englishURL', }) self.start_tour(self.env['website'].get_client_action_url('/'), 'translate_menu_name', login='admin') self.assertNotEqual(new_menu.name, 'value pa-GB', msg="The new menu should not have its value edited, only its translation") self.assertEqual(new_menu.with_context(lang=parseltongue.code).name, 'value pa-GB', msg="The new translation should be set") def test_snippet_translation(self): ResLang = self.env['res.lang'] parseltongue, fake_user_lang = ResLang.create([{ 'name': 'Parseltongue', 'code': 'pa_GB', 'iso_code': 'pa_GB', 'url_code': 'pa_GB', }, { 'name': 'Fake User Lang', 'code': 'fu_GB', 'iso_code': 'fu_GB', 'url_code': 'fu_GB', }]) ResLang._activate_lang(parseltongue.code) ResLang._activate_lang(fake_user_lang.code) self.env.ref('base.user_admin').lang = fake_user_lang.code self.env.ref('website.s_cover').update_field_translations('arch_db', { parseltongue.code: { 'Contact us': 'Contact us in Parseltongue' } }) self.env.ref('web_editor.snippets').update_field_translations('arch_db', { fake_user_lang.code: { 'Save': 'Save in fu_GB', } }) website = self.env['website'].create({ 'name': 'website pa_GB', 'language_ids': [(6, 0, [parseltongue.id])], 'default_lang_id': parseltongue.id, }) website_2 = self.env['website'].create({ 'name': 'website en_US', 'language_ids': [(6, 0, [self.env.ref('base.lang_en').id, parseltongue.id])], 'default_lang_id': parseltongue.id, }) self.start_tour(f"/website/force/{website.id}", 'snippet_translation', login='admin') self.start_tour(f"/website/force/{website_2.id}", 'snippet_translation_changing_lang', login='admin') @odoo.tests.common.tagged('post_install', '-at_install') class TestUi(odoo.tests.HttpCase): def test_01_admin_tour_homepage(self): self.start_tour("/web", 'homepage', login='admin') def test_02_restricted_editor(self): self.restricted_editor = self.env['res.users'].create({ 'name': 'Restricted Editor', 'login': 'restricted', 'password': 'restricted', 'groups_id': [(6, 0, [ self.ref('base.group_user'), self.ref('website.group_website_restricted_editor') ])] }) self.start_tour(self.env['website'].get_client_action_url('/'), 'restricted_editor', login='restricted') def test_04_website_navbar_menu(self): website = self.env['website'].search([], limit=1) self.env['website.menu'].create({ 'name': 'Test Tour Menu', 'url': '/test-tour-menu', 'parent_id': website.menu_id.id, 'sequence': 0, 'website_id': website.id, }) self.start_tour("/", 'website_navbar_menu') def test_05_specific_website_editor(self): asset_bundle_xmlid = 'website.assets_wysiwyg' website_default = self.env['website'].search([], limit=1) new_website = self.env['website'].create({'name': 'New Website'}) code = b"document.body.dataset.hello = 'world';" attach = self.env['ir.attachment'].create({ 'name': 'EditorExtension.js', 'mimetype': 'text/javascript', 'datas': base64.b64encode(code), }) custom_url = '/_custom/web/content/%s/%s' % (attach.id, attach.name) attach.url = custom_url self.env['ir.asset'].create({ 'name': 'EditorExtension', 'bundle': 'website.assets_wysiwyg', 'path': custom_url, 'website_id': new_website.id, }) base_website_bundle = self.env['ir.qweb']._get_asset_bundle(asset_bundle_xmlid, assets_params={'website_id': website_default.id}) self.assertNotIn(custom_url, [f['url'] for f in base_website_bundle.files]) base_website_css_version = base_website_bundle.get_version('css') base_website_js_version = base_website_bundle.get_version('js') new_website_bundle_modified = self.env['ir.qweb']._get_asset_bundle('website.assets_wysiwyg', assets_params={'website_id': new_website.id}) self.assertIn(custom_url, [f['url'] for f in new_website_bundle_modified.files]) self.assertEqual(new_website_bundle_modified.get_version('css'), base_website_css_version) self.assertNotEqual(new_website_bundle_modified.get_version('js'), base_website_js_version, "js version for new website should now have been changed") url_params = url_encode({'path': '/@/'}) self.start_tour(f'/website/force/{website_default.id}?{url_params}', "generic_website_editor", login='admin') self.start_tour(f'/website/force/{new_website.id}?{url_params}', "specific_website_editor", login='admin') def test_06_public_user_editor(self): website_default = self.env['website'].search([], limit=1) self.env['website.page'].search([ ('url', '=', '/'), ('website_id', '=', website_default.id) ], limit=1).arch = """