mirror of
https://github.com/bringout/oca-ocb-test.git
synced 2026-04-20 19:42:10 +02:00
19.0 vanilla
This commit is contained in:
parent
38c6088dcc
commit
d9452d2060
243 changed files with 30797 additions and 10815 deletions
|
|
@ -2,3 +2,5 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_configurator
|
||||
from . import test_controllers
|
||||
from . import test_performance
|
||||
|
|
|
|||
|
|
@ -14,4 +14,4 @@ class TestConfigurator(TestConfiguratorCommon):
|
|||
group_order_template = self.env.ref('sale_management.group_sale_order_template', raise_if_not_found=False)
|
||||
if group_order_template:
|
||||
self.env.ref('base.group_user').write({"implied_ids": [(4, group_order_template.id)]})
|
||||
self.start_tour('/web#action=website.action_website_configuration', 'configurator_flow', login="admin")
|
||||
self.start_tour('/odoo/action-website.action_website_configuration', 'configurator_flow', login="admin")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,151 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from base64 import b64encode
|
||||
|
||||
from odoo import Command, tests
|
||||
from odoo.tools import mute_logger
|
||||
from odoo.tools.json import scriptsafe as json_safe
|
||||
|
||||
from odoo.addons.base.tests.common import HttpCaseWithUserDemo, HttpCaseWithUserPortal
|
||||
|
||||
|
||||
@tests.tagged('-at_install', 'post_install')
|
||||
class TestWebEditorController(HttpCaseWithUserDemo, HttpCaseWithUserPortal):
|
||||
|
||||
def test_modify_image(self):
|
||||
gif_base64 = b"R0lGODdhAQABAIAAAP///////ywAAAAAAQABAAACAkQBADs="
|
||||
attachment = self.env['ir.attachment'].create({
|
||||
'name': 'test.gif',
|
||||
'mimetype': 'image/gif',
|
||||
'datas': gif_base64,
|
||||
'public': True,
|
||||
'res_model': 'ir.ui.view',
|
||||
'res_id': 0,
|
||||
})
|
||||
|
||||
def modify(login, name, expect_fail=False):
|
||||
self.authenticate(login, login)
|
||||
svg = b'<svg viewBox="0 0 400 400"><!-- %s --><image url="data:image/gif;base64,%s" /></svg>' % (name.encode('ascii'), gif_base64)
|
||||
params = {
|
||||
'name': name,
|
||||
'mimetype': 'image/svg+xml',
|
||||
'data': b64encode(svg).decode('ascii'),
|
||||
}
|
||||
if attachment.res_id:
|
||||
params['res_model'] = attachment.res_model
|
||||
params['res_id'] = attachment.res_id
|
||||
response = self.url_open(
|
||||
f'/html_editor/modify_image/{attachment.id}',
|
||||
headers={'Content-Type': 'application/json'},
|
||||
data=json_safe.dumps({
|
||||
"params": params,
|
||||
}),
|
||||
)
|
||||
self.assertEqual(200, response.status_code, "Expect response")
|
||||
if expect_fail:
|
||||
return json_safe.loads(response.content)
|
||||
content = json_safe.loads(response.content)
|
||||
self.assertFalse(content.get('error'), "An error should not happen")
|
||||
url = content.get('result')
|
||||
self.assertTrue(url.partition('?unique=')[0].endswith(name), "Expect name in URL")
|
||||
response = self.url_open(url)
|
||||
self.assertEqual(200, response.status_code, "Expect response")
|
||||
self.assertTrue('image/svg+xml' in response.headers.get('Content-Type'), "Expect SVG mimetype")
|
||||
self.assertEqual(svg, response.content, "Expect unchanged SVG")
|
||||
return True
|
||||
|
||||
# Admin can modify page
|
||||
modify('admin', 'page-admin.gif')
|
||||
|
||||
# Base user cannot modify page
|
||||
self.user_demo.write({
|
||||
'group_ids': [
|
||||
Command.clear(),
|
||||
Command.link(self.env.ref('base.group_user').id),
|
||||
],
|
||||
})
|
||||
with mute_logger('odoo.http'):
|
||||
json = modify('demo', 'page-demofail.gif', True)
|
||||
self.assertFalse(json.get('result'), "Expect no URL when called with insufficient rights")
|
||||
|
||||
# Restricted editor with event right cannot modify page
|
||||
self.user_demo.write({
|
||||
'group_ids': [
|
||||
Command.clear(),
|
||||
Command.link(self.env.ref('base.group_user').id),
|
||||
Command.link(self.env.ref('website.group_website_restricted_editor').id),
|
||||
Command.link(self.env.ref('event.group_event_manager').id),
|
||||
],
|
||||
})
|
||||
with mute_logger('odoo.http'):
|
||||
json = modify('demo', 'page-demofail2.gif', True)
|
||||
self.assertFalse(json.get('result'), "Expect no URL when called with insufficient rights")
|
||||
|
||||
# Website designer can modify page
|
||||
self.user_demo.write({
|
||||
'group_ids': [
|
||||
Command.clear(),
|
||||
Command.link(self.env.ref('base.group_user').id),
|
||||
Command.link(self.env.ref('website.group_website_designer').id),
|
||||
],
|
||||
})
|
||||
modify('demo', 'page-demo.gif')
|
||||
|
||||
# Website designer can modify url attachment (for e.g. unsplash)
|
||||
attachment.url = '/page-logo-unique.gif'
|
||||
modify('demo', 'page-logo-unique.gif')
|
||||
attachment.url = False # Reset previous value
|
||||
|
||||
event = self.env['event.event'].create({'name': 'test event'})
|
||||
attachment.res_model = 'event.event'
|
||||
attachment.res_id = event.id
|
||||
|
||||
# Admin can modify event
|
||||
modify('admin', 'event-admin.gif')
|
||||
|
||||
# Base user cannot modify event
|
||||
self.user_demo.write({
|
||||
'group_ids': [
|
||||
Command.clear(),
|
||||
Command.link(self.env.ref('base.group_user').id),
|
||||
],
|
||||
})
|
||||
with mute_logger('odoo.http'):
|
||||
json = modify('demo', 'event-demofail.gif', True)
|
||||
self.assertFalse(json.get('result'), "Expect no URL when called with insufficient rights")
|
||||
|
||||
# Restricted editor with sales rights cannot modify event
|
||||
self.user_demo.write({
|
||||
'group_ids': [
|
||||
Command.clear(),
|
||||
Command.link(self.env.ref('base.group_user').id),
|
||||
Command.link(self.env.ref('website.group_website_restricted_editor').id),
|
||||
Command.link(self.env.ref('sales_team.group_sale_manager').id),
|
||||
],
|
||||
})
|
||||
with mute_logger('odoo.http'):
|
||||
json = modify('demo', 'event-demofail2.gif', True)
|
||||
self.assertFalse(json.get('result'), "Expect no URL when called with insufficient rights")
|
||||
|
||||
# Restricted editor with event rights can modify event
|
||||
self.user_demo.write({
|
||||
'group_ids': [
|
||||
Command.clear(),
|
||||
Command.link(self.env.ref('base.group_user').id),
|
||||
Command.link(self.env.ref('website.group_website_restricted_editor').id),
|
||||
Command.link(self.env.ref('event.group_event_manager').id),
|
||||
],
|
||||
})
|
||||
modify('demo', 'event-demo.gif')
|
||||
|
||||
# Website designer cannot modify event
|
||||
self.user_demo.write({
|
||||
'group_ids': [
|
||||
Command.clear(),
|
||||
Command.link(self.env.ref('base.group_user').id),
|
||||
Command.link(self.env.ref('website.group_website_designer').id),
|
||||
],
|
||||
})
|
||||
with mute_logger('odoo.http'):
|
||||
json = modify('demo', 'event-demofail3.gif', True)
|
||||
self.assertFalse(json.get('result'), "Expect no URL when called with insufficient rights")
|
||||
|
|
@ -0,0 +1,382 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import base64
|
||||
import io
|
||||
import re
|
||||
from PIL import Image
|
||||
from unittest.mock import patch
|
||||
import odoo
|
||||
from odoo.fields import Command
|
||||
from odoo.tests import tagged
|
||||
from odoo.addons.website.tests.test_performance import TestWebsitePerformanceCommon
|
||||
from odoo.addons.website_sale.tests.common import WebsiteSaleCommon
|
||||
from odoo.addons.website_sale.tests.test_website_sale_pricelist import TestWebsitePriceList
|
||||
|
||||
|
||||
class TestWebsiteAllPerformance(TestWebsitePerformanceCommon, TestWebsitePriceList, WebsiteSaleCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
|
||||
# Attachment needed for the replacement of images
|
||||
cls.env['ir.attachment'].create({
|
||||
'public': True,
|
||||
'name': 's_default_image.jpg',
|
||||
'type': 'url',
|
||||
'url': f'{cls.base_url()}/web/image/website.s_banner_default_image.jpg',
|
||||
})
|
||||
|
||||
cats = cls.env['product.public.category'].create([{
|
||||
'name': 'Level 0',
|
||||
}, {
|
||||
'name': 'Level 1',
|
||||
}, {
|
||||
'name': 'Level 2',
|
||||
}])
|
||||
cats[2].parent_id = cats[1].id
|
||||
cats[1].parent_id = cats[0].id
|
||||
|
||||
# First image (blue) for the template.
|
||||
color_blue = '#4169E1'
|
||||
name_blue = 'Royal Blue'
|
||||
# Red for the variant.
|
||||
color_red = '#CD5C5C'
|
||||
name_red = 'Indian Red'
|
||||
|
||||
# Create the color attribute.
|
||||
cls.product_attribute = cls.env['product.attribute'].create({
|
||||
'name': 'Beautiful Color',
|
||||
'display_type': 'color',
|
||||
})
|
||||
|
||||
# create the color attribute values
|
||||
cls.attr_values = cls.env['product.attribute.value'].create([{
|
||||
'name': name_blue,
|
||||
'attribute_id': cls.product_attribute.id,
|
||||
'html_color': color_blue,
|
||||
'sequence': 1,
|
||||
}, {
|
||||
'name': name_red,
|
||||
'attribute_id': cls.product_attribute.id,
|
||||
'html_color': color_red,
|
||||
'sequence': 2,
|
||||
},
|
||||
])
|
||||
|
||||
# first image (blue) for the template
|
||||
f = io.BytesIO()
|
||||
Image.new('RGB', (1920, 1080), '#4169E1').save(f, 'JPEG')
|
||||
f.seek(0)
|
||||
blue_image = base64.b64encode(f.read())
|
||||
|
||||
# second image (red) for the variant 1
|
||||
f = io.BytesIO()
|
||||
Image.new('RGB', (800, 500), '#FF69E1').save(f, 'JPEG')
|
||||
f.seek(0)
|
||||
red_image = base64.b64encode(f.read())
|
||||
|
||||
cls.productA = cls.env['product.product'].create({
|
||||
'name': 'Product A',
|
||||
'list_price': 100,
|
||||
'sale_ok': True,
|
||||
'website_published': True,
|
||||
'website_sequence': 1,
|
||||
'public_categ_ids': [Command.link(cats[2].id)],
|
||||
})
|
||||
|
||||
cls.productB = cls.env['product.product'].create({
|
||||
'name': 'Product B',
|
||||
'list_price': 100,
|
||||
'sale_ok': True,
|
||||
'website_published': True,
|
||||
'image_1920': red_image,
|
||||
'website_sequence': -10,
|
||||
})
|
||||
|
||||
cls.templateC = cls.env['product.template'].create({
|
||||
'name': 'Test Remove Image',
|
||||
'image_1920': blue_image,
|
||||
'website_sequence': -10,
|
||||
'public_categ_ids': [Command.link(cats[1].id)],
|
||||
})
|
||||
cls.productC = cls.templateC.product_variant_ids[0]
|
||||
cls.productC.write({
|
||||
'name': 'Product C',
|
||||
'list_price': 100,
|
||||
'sale_ok': True,
|
||||
'website_published': True,
|
||||
})
|
||||
cls.product_images = cls.env['product.image'].with_context(default_product_tmpl_id=cls.productC.product_tmpl_id.id).create([{
|
||||
'name': 'Template image',
|
||||
'image_1920': blue_image,
|
||||
}, {
|
||||
'name': 'Variant image',
|
||||
'image_1920': red_image,
|
||||
'product_variant_id': cls.productC.id,
|
||||
}])
|
||||
|
||||
for i in range(20):
|
||||
template = cls.env['product.template'].create({
|
||||
'name': f'Product test {i}',
|
||||
'list_price': 100,
|
||||
'sale_ok': True,
|
||||
'image_1920': red_image,
|
||||
'website_sequence': -9,
|
||||
'attribute_line_ids': [
|
||||
Command.create({
|
||||
'attribute_id': cls.product_attribute.id,
|
||||
'value_ids': [Command.set(cls.product_attribute.value_ids.ids)],
|
||||
}),
|
||||
],
|
||||
})
|
||||
variant = template.product_variant_ids[0]
|
||||
if i % 5:
|
||||
variant.website_published = True
|
||||
if i % 4:
|
||||
variant.website_sequence = -7
|
||||
|
||||
images = [{
|
||||
'name': 'Template image',
|
||||
'image_1920': blue_image,
|
||||
}]
|
||||
if i % 2:
|
||||
images.append({
|
||||
'name': 'Variant image',
|
||||
'image_1920': red_image,
|
||||
'product_variant_id': variant.id,
|
||||
})
|
||||
cls.env['product.image'].create(images)
|
||||
|
||||
fpos = cls.env["account.fiscal.position"].create({
|
||||
'name': 'Fiscal Position BE',
|
||||
'country_id': cls.env.ref('base.be').id,
|
||||
'auto_apply': True,
|
||||
'sequence': -1,
|
||||
})
|
||||
usd = cls.env.ref('base.USD')
|
||||
cls.env['product.pricelist'].create({
|
||||
'name': 'Custom pricelist (TEST)',
|
||||
'currency_id': usd.id,
|
||||
'sequence': -1,
|
||||
'item_ids': [(0, 0, {
|
||||
'base': 'list_price',
|
||||
'applied_on': '1_product',
|
||||
'product_tmpl_id': cls.templateC.id,
|
||||
'price_discount': 20,
|
||||
'min_quantity': 2,
|
||||
'compute_price': 'formula',
|
||||
})],
|
||||
})
|
||||
tax_group = cls.env['account.tax.group'].create({'name': 'Test 6%'})
|
||||
cls.env['account.tax'].create({
|
||||
'name': "Test 6%",
|
||||
'fiscal_position_ids': fpos,
|
||||
'amount': 6,
|
||||
'price_include_override': 'tax_included',
|
||||
'type_tax_use': 'sale',
|
||||
'amount_type': 'percent',
|
||||
'country_id': cls.env.ref('base.us').id,
|
||||
'tax_group_id': tax_group.id,
|
||||
})
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.session = None
|
||||
self.env['website'].search([]).channel_id = False
|
||||
|
||||
def _get_cart_quantity(self):
|
||||
return int(re.search(
|
||||
r'my_cart_quantity.*?>([0-9.]+)</sup>',
|
||||
self.url_open(self.page.url).text
|
||||
).group(1))
|
||||
|
||||
def test_website_user_id_public_user(self):
|
||||
origin_serve_page = odoo.addons.website.models.ir_http.IrHttp._serve_page
|
||||
|
||||
def _serve_page():
|
||||
request = odoo.http.request
|
||||
self.assertTrue(request.env['website'].search([]).user_id._is_public(), 'The public user of the website is not public!')
|
||||
self.assertTrue(request.env.user._is_public(), 'The visitor should not be logged')
|
||||
return origin_serve_page()
|
||||
|
||||
with patch('odoo.addons.website.models.ir_http.IrHttp._serve_page', wraps=_serve_page) as mocked:
|
||||
self.url_open(self.page.url)
|
||||
mocked.assert_called_once()
|
||||
|
||||
def test_perf_sql_queries_page(self):
|
||||
self.set_registry_readonly_mode(True)
|
||||
self.page.track = False
|
||||
|
||||
# self.url_open('/web/set_profiling?profile=1&execution_context_qweb=1')
|
||||
|
||||
self.assertEqual(self._get_cart_quantity(), 0)
|
||||
|
||||
origin_allow_to_use_cache = odoo.addons.website.models.website_page.WebsitePage._allow_to_use_cache
|
||||
|
||||
def _allow_to_use_cache(request):
|
||||
can_use = origin_allow_to_use_cache(request.env['website.page'], request)
|
||||
self.assertTrue(can_use, 'The homepage should be cached for the public user')
|
||||
|
||||
with patch('odoo.addons.website.models.website_page.WebsitePage._allow_to_use_cache', wraps=_allow_to_use_cache) as mocked:
|
||||
self.url_open(self.page.url)
|
||||
mocked.assert_called_once()
|
||||
|
||||
select_tables_perf = {
|
||||
# website queries
|
||||
'orm_signaling_registry': 1,
|
||||
'ir_attachment': 1,
|
||||
# website_livechat _post_process_response_from_cache queries
|
||||
'website': 1,
|
||||
# website_crm_iap_reveal _serve_page queries
|
||||
'website_visitor': 1,
|
||||
}
|
||||
expected_query_count = sum(select_tables_perf.values())
|
||||
self._check_url_hot_query(self.page.url, expected_query_count, select_tables_perf, {})
|
||||
|
||||
self.url_open('/shop/cart/add', json={
|
||||
"id": 0,
|
||||
"jsonrpc": "2.0",
|
||||
"method": "call",
|
||||
"params": {
|
||||
"product_template_id": self.productC.product_tmpl_id.id,
|
||||
"product_id": self.productC.id,
|
||||
"quantity": 1,
|
||||
"uom_id": 1,
|
||||
"product_custom_attribute_values": [],
|
||||
"no_variant_attribute_value_ids": [],
|
||||
"linked_products": []
|
||||
}
|
||||
})
|
||||
self.assertEqual(self._get_cart_quantity(), 1)
|
||||
select_tables_perf = {
|
||||
# website queries
|
||||
'orm_signaling_registry': 1,
|
||||
'ir_attachment': 1,
|
||||
# website_livechat _post_process_response_from_cache queries
|
||||
'website': 1,
|
||||
# website_crm_iap_reveal _serve_page queries
|
||||
'website_visitor': 1,
|
||||
}
|
||||
expected_query_count = sum(select_tables_perf.values())
|
||||
self._check_url_hot_query(self.page.url, expected_query_count, select_tables_perf, {})
|
||||
|
||||
self.url_open('/shop/cart/update', json={
|
||||
"id": 0,
|
||||
"jsonrpc": "2.0",
|
||||
"method": "call",
|
||||
"params": {
|
||||
"line_id": self.env['sale.order'].search([], limit=1).order_line.id,
|
||||
"product_id": self.productC.id,
|
||||
"quantity": 0
|
||||
}
|
||||
})
|
||||
|
||||
self.assertEqual(self._get_cart_quantity(), 0)
|
||||
select_tables_perf = {
|
||||
# website queries
|
||||
'orm_signaling_registry': 1,
|
||||
'ir_attachment': 1,
|
||||
# website_livechat _post_process_response_from_cache queries
|
||||
'website': 1,
|
||||
# website_crm_iap_reveal _serve_page queries
|
||||
'website_visitor': 1,
|
||||
}
|
||||
expected_query_count = sum(select_tables_perf.values())
|
||||
self._check_url_hot_query(self.page.url, expected_query_count, select_tables_perf, {})
|
||||
|
||||
def _get_queries_shop(self):
|
||||
html = self.url_open('/shop').text
|
||||
self.assertIn(f'<img src="/web/image/product.product/{self.productC.id}/', html)
|
||||
self.assertIn(f'<img src="/web/image/product.template/{self.productA.product_tmpl_id.id}/', html)
|
||||
self.assertIn(f'<img src="/web/image/product.image/{self.product_images.ids[1]}/', html)
|
||||
|
||||
query_count = 51 # To increase this number you must ask the permission to al
|
||||
queries = {
|
||||
'orm_signaling_registry': 1,
|
||||
'website': 2,
|
||||
'res_company': 2,
|
||||
'product_pricelist': 4,
|
||||
'product_template': 5,
|
||||
'product_tag': 1,
|
||||
'product_public_category': 6,
|
||||
'product_product': 1,
|
||||
'product_template_attribute_line': 3,
|
||||
'res_users': 1,
|
||||
'res_partner': 2,
|
||||
'product_category': 1,
|
||||
'product_pricelist_item': 2,
|
||||
'account_tax': 1,
|
||||
'res_currency': 1,
|
||||
'account_account_tag': 1,
|
||||
'product_ribbon': 1,
|
||||
'product_attribute_value': 3,
|
||||
'product_attribute': 1,
|
||||
'ir_attachment': 4,
|
||||
'product_image': 3,
|
||||
'product_template_attribute_value': 1,
|
||||
'ir_ui_view': 2,
|
||||
'website_menu': 1,
|
||||
'website_page': 1,
|
||||
}
|
||||
|
||||
addons = tuple(self.env.registry._init_modules) + (self.env.context.get('install_module'),)
|
||||
if 'website_helpdesk' in addons:
|
||||
query_count += 1
|
||||
queries['helpdesk_team'] = 1
|
||||
if 'website_sale_subscription' in addons:
|
||||
query_count += 1
|
||||
queries['product_product'] += 1
|
||||
|
||||
tax = self.env.ref('account.1_sale_tax_template', raise_if_not_found=False)
|
||||
if tax and tax.name == '15%':
|
||||
query_count += 2
|
||||
queries['account_tax_repartition_line'] = 2
|
||||
|
||||
if self._has_demo_data():
|
||||
query_count += 5
|
||||
queries['product_template'] += 1
|
||||
queries['product_product'] += 2
|
||||
queries['ir_attachment'] += 1
|
||||
queries['product_ribbon'] += 1
|
||||
else:
|
||||
query_count += 3
|
||||
queries['product_template_attribute_value'] += 3
|
||||
|
||||
# To increase the query count you must ask the permission to al
|
||||
return query_count, queries
|
||||
|
||||
def _has_demo_data(self):
|
||||
return bool(self.env['ir.module.module'].search_count([('demo', '=', True)]))
|
||||
|
||||
def test_perf_sql_queries_shop(self):
|
||||
# To increase the query count you must ask the permission to al
|
||||
query_count, queries = self._get_queries_shop()
|
||||
|
||||
if self._has_demo_data():
|
||||
query_count += 5
|
||||
queries['account_tax'] += 1
|
||||
queries['account_account_tag'] += 2
|
||||
queries['product_template_attribute_value'] += 2
|
||||
|
||||
self.assertEqual(sum(queries.values()), query_count, 'Please learn to count.')
|
||||
self._check_url_hot_query('/shop', query_count, queries)
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestWebsiteAllPerformanceShop(TestWebsiteAllPerformance):
|
||||
|
||||
def test_perf_sql_queries_shop(self):
|
||||
# To increase the query count you must ask the permission to al
|
||||
query_count, queries = self._get_queries_shop()
|
||||
|
||||
query_count += 3
|
||||
queries['account_tax'] += 1
|
||||
queries['account_account_tag'] += 2
|
||||
|
||||
if self._has_demo_data():
|
||||
query_count += 2
|
||||
queries['product_template_attribute_value'] += 2
|
||||
|
||||
self.assertEqual(sum(queries.values()), query_count, 'Please learn to count.')
|
||||
self._check_url_hot_query('/shop', query_count, queries)
|
||||
Loading…
Add table
Add a link
Reference in a new issue