Files
odoo_source/addons/website_theme_install/tests/test_views.py
T
Christophe Monniez 8d5da6e4be [IMP] tests: log a warning when HttpCase test in at_install
When loading a page on an existing starting database, registry is not
fully loaded causing potential error when trying to access model
existing in database (views, menitem, ...) since model added in last
loaded module does not exist in registry.

Thus, executing browser js test may lead to errors when executed during
an update on a database with other modules installed.

HTTPCase should be executed post_install to ensure that registry is
fully loaded to avoid this problem.

Since HTTPCase are slower than other test, it is also a good idea to
execute them at the end, in order to prioritize fast fail.

With this commit, a warning is isued if such a test class is tagged to
run at install time.

While at it, remove deprecated at_install and post_install helpers and
remove the deprecated phantom_js alias.

closes odoo/odoo#39462

Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
2019-10-30 12:35:23 +00:00

203 lines
12 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.tests import HttpCase, tagged, TransactionCase
@tagged('post_install', '-at_install')
class TestViews(TransactionCase):
def test_inherit_specific(self):
View = self.env['ir.ui.view']
Website = self.env['website']
website_1 = Website.create({'name': 'Website 1'})
# 1. Simulate COW structure
main_view = View.create({
'name': 'Test Main View',
'type': 'qweb',
'arch': '<body>Arch is not relevant for this test</body>',
'key': '_test.main_view',
}).with_context(load_all_views=True)
# Trigger COW
main_view.with_context(website_id=website_1.id).arch = '<body>specific</body>'
# 2. Simulate a theme install with a child view of `main_view`
test_theme_module = self.env['ir.module.module'].create({'name': 'test_theme'})
self.env['ir.model.data'].create({
'module': 'base',
'name': 'module_test_theme_module',
'model': 'ir.module.module',
'res_id': test_theme_module.id,
})
theme_view = self.env['theme.ir.ui.view'].with_context(install_filename='/testviews').create({
'name': 'Test Child View',
'mode': 'extension',
'inherit_id': 'ir.ui.view,%s' % main_view.id,
'arch': '<xpath expr="//body" position="replace"><span>C</span></xpath>',
'key': 'test_theme.test_child_view',
})
self.env['ir.model.data'].create({
'module': 'test_theme',
'name': 'products',
'model': 'theme.ir.ui.view',
'res_id': theme_view.id,
})
test_theme_module.with_context(load_all_views=True)._theme_load(website_1)
# 3. Ensure everything went correctly
main_views = View.search([('key', '=', '_test.main_view')])
self.assertEqual(len(main_views), 2, "View should have been COWd when writing on its arch in a website context")
specific_main_view = main_views.filtered(lambda v: v.website_id == website_1)
specific_main_view_children = specific_main_view.inherit_children_ids
self.assertEqual(specific_main_view_children.name, 'Test Child View', "Ensure theme.ir.ui.view has been loaded as an ir.ui.view into the website..")
self.assertEqual(specific_main_view_children.website_id, website_1, "..and the website is the correct one.")
@tagged('-at_install', 'post_install')
class Crawler(HttpCase):
def test_multi_website_views_retrieving(self):
View = self.env['ir.ui.view']
Website = self.env['website']
website_1 = Website.create({'name': 'Website 1'})
website_2 = Website.create({'name': 'Website 2'})
main_view = View.create({
'name': 'Products',
'type': 'qweb',
'arch': '<body>Arch is not relevant for this test</body>',
'key': '_website_sale.products',
}).with_context(load_all_views=True)
View.with_context(load_all_views=True).create({
'name': 'Child View W1',
'mode': 'extension',
'inherit_id': main_view.id,
'arch': '<xpath expr="//body" position="replace">It is really not relevant!</xpath>',
'key': '_website_sale.child_view_w1',
'website_id': website_1.id,
'active': False,
'customize_show': True,
})
# Simulate theme view instal + load on website
theme_view = self.env['theme.ir.ui.view'].with_context(install_filename='/testviews').create({
'name': 'Products Theme Kea',
'mode': 'extension',
'inherit_id': main_view,
'arch': '<xpath expr="//p" position="replace"><span>C</span></xpath>',
'key': '_theme_kea_sale.products',
})
view_from_theme_view_on_w2 = View.with_context(load_all_views=True).create({
'name': 'Products Theme Kea',
'mode': 'extension',
'inherit_id': main_view.id,
'arch': '<xpath expr="//body" position="replace">Really really not important for this test</xpath>',
'key': '_theme_kea_sale.products',
'website_id': website_2.id,
'customize_show': True,
})
self.env['ir.model.data'].create({
'module': '_theme_kea_sale',
'name': 'products',
'model': 'theme.ir.ui.view',
'res_id': theme_view.id,
})
# ##################################################### ir.ui.view ###############################################
# id | name | website_id | inherit | key | xml_id |
# ----------------------------------------------------------------------------------------------------------------
# 1 | Products | / | / | _website_sale.products | / |
# 2 | Child View W1 | 1 | 1 | _website_sale.child_view_w1 | / |
# 3 | Products Theme Kea | 2 | 1 | _theme_kea_sale.products | / |
# ################################################# theme.ir.ui.view #############################################
# id | name | inherit | key | xml_id |
# ----------------------------------------------------------------------------------------------------------------
# 1 | Products Theme Kea | 1 | _theme_kea_sale.products | _theme_kea_sale.products |
with self.assertRaises(ValueError):
# It should crash as it should not find a view on website 1 for '_theme_kea_sale.products', !!and certainly not a theme.ir.ui.view!!.
view = View.with_context(website_id=website_1.id)._view_obj('_theme_kea_sale.products')
view = View.with_context(website_id=website_2.id)._view_obj('_theme_kea_sale.products')
self.assertEqual(len(view), 1, "It should find the ir.ui.view with key '_theme_kea_sale.products' on website 2..")
self.assertEqual(view._name, 'ir.ui.view', "..and not a theme.ir.ui.view")
views = View.with_context(website_id=website_1.id).get_related_views('_website_sale.products')
self.assertEqual(len(views), 2, "It should not mix apples and oranges, only ir.ui.view ['_website_sale.products', '_website_sale.child_view_w1'] should be returned")
views = View.with_context(website_id=website_2.id).get_related_views('_website_sale.products')
self.assertEqual(len(views), 2, "It should not mix apples and oranges, only ir.ui.view ['_website_sale.products', '_theme_kea_sale.products'] should be returned")
# Part 2 of the test, it test the same stuff but from a higher level (get_related_views ends up calling _view_obj)
called_theme_view = self.env['theme.ir.ui.view'].with_context(install_filename='/testviews').create({
'name': 'Called View Kea',
'arch': '<div></div>',
'key': '_theme_kea_sale.t_called_view',
})
View.create({
'name': 'Called View Kea',
'type': 'qweb',
'arch': '<div></div>',
'key': '_theme_kea_sale.t_called_view',
'website_id': website_2.id,
}).with_context(load_all_views=True)
self.env['ir.model.data'].create({
'module': '_theme_kea_sale',
'name': 't_called_view',
'model': 'theme.ir.ui.view',
'res_id': called_theme_view.id,
})
view_from_theme_view_on_w2.write({'arch': '<t t-call="_theme_kea_sale.t_called_view"/>'})
# ##################################################### ir.ui.view ###############################################
# id | name | website_id | inherit | key | xml_id |
# ----------------------------------------------------------------------------------------------------------------
# 1 | Products | / | / | _website_sale.products | / |
# 2 | Child View W1 | 1 | 1 | _website_sale.child_view_w1 | / |
# 3 | Products Theme Kea | 2 | 1 | _theme_kea_sale.products | / |
# 4 | Called View Kea | 2 | / | _theme_kea_sale.t_called_view | / |
# ################################################# theme.ir.ui.view #############################################
# id | name | inherit | key | xml_id |
# ----------------------------------------------------------------------------------------------------------------
# 1 | Products Theme Kea | 1 | _theme_kea_sale.products | _theme_kea_sale.products |
# 1 | Called View Kea | / | _theme_kea_sale.t_called_view | _theme_kea_sale.t_called_view |
# Next line should not crash (was mixing apples and oranges - ir.ui.view and theme.ir.ui.view)
views = View.with_context(website_id=website_1.id).get_related_views('_website_sale.products')
self.assertEqual(len(views), 2, "It should not mix apples and oranges, only ir.ui.view ['_website_sale.products', '_website_sale.child_view_w1'] should be returned (2)")
views = View.with_context(website_id=website_2.id).get_related_views('_website_sale.products')
self.assertEqual(len(views), 3, "It should not mix apples and oranges, only ir.ui.view ['_website_sale.products', '_theme_kea_sale.products', '_theme_kea_sale.t_called_view'] should be returned")
# ########################################################
# Test the controller (which is calling get_related_views)
self.authenticate("admin", "admin")
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
# Simulate website 2
url = base_url + '/website/force_website'
json = {'params': {'website_id': website_2.id}}
self.opener.post(url=url, json=json)
# Test controller
url = base_url + '/website/get_switchable_related_views'
json = {'params': {'key': '_website_sale.products'}}
response = self.opener.post(url=url, json=json)
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.json()['result']), 1, "Only '_theme_kea_sale.products' should be returned as it is the only customize_show related view in website 2 context")
self.assertEqual(response.json()['result'][0]['key'], '_theme_kea_sale.products', "Only '_theme_kea_sale.products' should be returned")
# Simulate website 1
url = base_url + '/website/force_website'
json = {'params': {'website_id': website_1.id}}
self.opener.post(url=url, json=json)
# Test controller
url = base_url + '/website/get_switchable_related_views'
json = {'params': {'key': '_website_sale.products'}}
response = self.opener.post(url=url, json=json)
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.json()['result']), 1, "Only '_website_sale.child_view_w1' should be returned as it is the only customize_show related view in website 1 context")
self.assertEqual(response.json()['result'][0]['key'], '_website_sale.child_view_w1', "Only '_website_sale.child_view_w1' should be returned")