The generation inside the rendering has some drawbacks: - `commit_assetsbundle` is needed for reports rendering because the template rendering may generate some assets that will be accessed by another transaction before the transaction is committed. But this solution is not ideal since the transaction is committed in the middle of the request - when the first rendered page is a 404, the assets are not committed and the page is broken. - when starting, deleting an attachment can create a concurrent update error and the request is retried. This will occur once per attachment and for all worker trying to access the same resource. The whole transaction is rollbacked, even the previously created assets bundle. - The cold page load is a slower since there is more work to do. - Implementing a readonly request is difficult because it could be transformed to read write and re-executed if the assets bundle does not exist. Generating assets when needed solves those issues. The concurrency when deleting an assets could still occur but only once per bundle, and in a smaller transaction. This could be solved with a lock now that we have more control on the transaction. The commit_assetsbundle can be removed and 404 page should have a correct layout. The cold page load could be a little faster because the assets bundle can be generated in parallel requests instead of sequentially when rendering the page. Part-of: odoo/odoo#131353
80 lines
3.2 KiB
Python
80 lines
3.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from lxml import etree
|
|
import re
|
|
|
|
from odoo import tools
|
|
from odoo.addons.base.tests.common import TransactionCaseWithUserDemo
|
|
|
|
|
|
class TestQweb(TransactionCaseWithUserDemo):
|
|
def _load(self, module, filepath):
|
|
tools.convert_file(
|
|
self.env, module,
|
|
filepath,
|
|
{}, 'init', False, 'test'
|
|
)
|
|
|
|
def test_qweb_cdn(self):
|
|
self._load('test_website', 'tests/template_qweb_test.xml')
|
|
|
|
website = self.env.ref('website.default_website')
|
|
website.write({
|
|
"cdn_activated": True,
|
|
"cdn_url": "http://test.cdn"
|
|
})
|
|
|
|
demo = self.env['res.users'].search([('login', '=', 'demo')])[0]
|
|
demo.write({"signature": '''<span class="toto">
|
|
span<span class="fa"></span><img src="/web/image/1"/>
|
|
</span>'''})
|
|
|
|
demo_env = self.env(user=demo)
|
|
|
|
html = demo_env['ir.qweb']._render('test_website.test_template', {"user": demo}, website_id=website.id)
|
|
asset_bundle_xmlid = 'test_website.test_bundle'
|
|
qweb = self.env['ir.qweb']
|
|
bundle = qweb._get_asset_bundle(asset_bundle_xmlid, css=True, js=True, assets_params={'website_id': website.id})
|
|
|
|
asset_version_js = bundle.get_version('js')
|
|
asset_version_css = bundle.get_version('css')
|
|
css_url, js_url = bundle.get_links()[-2:]
|
|
|
|
html = html.strip()
|
|
html = re.sub(r'\?unique=[^"]+', '', html).encode('utf8')
|
|
|
|
format_data = {
|
|
"css": css_url,
|
|
"js": js_url,
|
|
"user_id": demo.id,
|
|
"filename": "Marc%20Demo",
|
|
"alt": "Marc Demo",
|
|
"asset_xmlid": asset_bundle_xmlid,
|
|
"asset_version_css": asset_version_css,
|
|
"asset_version_js": asset_version_js,
|
|
}
|
|
self.assertHTMLEqual(html, ("""<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<link type="text/css" rel="stylesheet" href="http://test.external.link/style1.css"/>
|
|
<link type="text/css" rel="stylesheet" href="http://test.external.link/style2.css"/>
|
|
<link type="text/css" rel="stylesheet" href="http://test.cdn%(css)s"/>
|
|
<meta/>
|
|
<script type="text/javascript" src="http://test.external.link/javascript1.js"></script>
|
|
<script type="text/javascript" src="http://test.external.link/javascript2.js"></script>
|
|
<script type="text/javascript" src="http://test.cdn%(js)s" onerror="__odooAssetError=1"></script>
|
|
</head>
|
|
<body>
|
|
<img src="http://test.external.link/img.png" loading="lazy"/>
|
|
<img src="http://test.cdn/test_website/static/img.png" loading="lazy"/>
|
|
<a href="http://test.external.link/link">x</a>
|
|
<a href="http://test.cdn/web/content/local_link">x</a>
|
|
<span style="background-image: url('http://test.cdn/web/image/2')">xxx</span>
|
|
<div widget="html"><span class="toto">
|
|
span<span class="fa"></span><img src="http://test.cdn/web/image/1" loading="lazy">
|
|
</span></div>
|
|
<div widget="image"><img src="http://test.cdn/web/image/res.users/%(user_id)s/avatar_1920/%(filename)s" class="img img-fluid" alt="%(alt)s" loading="lazy"/></div>
|
|
</body>
|
|
</html>""" % format_data).encode('utf8'))
|