Use case: When the server is restarted, the python is updated, but some users may have an ongoing session in a browser tab This may lead to code being unsynchronized and ultimately to some odd bugs. Purpose: When we are in such a case, that is, the assets were recomputed after a update of the code and a restart of the server by the request of another user, notify connected users that assets have changed. Then propose them to reload the page. Known caveats: - This is not a developer's feature. Since assets computing is ORM cached, they have limited opportunities to rebuild. Namely, the feature won't trigger each time the JS has changed, rather, it will when JS has changed AND the cache has been reset somehow (e.g. when the server is restarted). - This not a portal/website feature either, but only in backend. Business clients won't be notified that the JS has changed. - While requests debug=assets do trigger a recomputing of the *components* of bundles, they do not save a bundle This means that the requests that sends the notification cannot be debug=assets. Task 2034462 closes odoo/odoo#39875 Signed-off-by: Mathieu Duckerts-Antoine <Polymorphe57@users.noreply.github.com>
50 lines
1.8 KiB
Python
50 lines
1.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
import odoo.tests
|
|
from odoo.osv import expression
|
|
|
|
|
|
@odoo.tests.tagged('post_install', '-at_install', 'assets_bundle')
|
|
class BusWebTests(odoo.tests.HttpCase):
|
|
|
|
def test_bundle_sends_bus(self):
|
|
"""
|
|
Tests two things:
|
|
- Messages are posted to the bus when assets change
|
|
i.e. their hash has been recomputed and differ from the attachment's
|
|
- The interface deals with those bus messages by displaying one notification
|
|
"""
|
|
db_name = self.env.registry.db_name
|
|
bundle_xml_ids = ('web.assets_common', 'web.assets_backend')
|
|
|
|
domain = []
|
|
for bundle in bundle_xml_ids:
|
|
domain = expression.OR([
|
|
domain,
|
|
[('name', 'ilike', bundle + '%')]
|
|
])
|
|
# start from a clean slate
|
|
self.env['ir.attachment'].search(domain).unlink()
|
|
self.env.registry._clear_cache()
|
|
|
|
sendones = []
|
|
def patched_sendone(self, channel, message):
|
|
"""
|
|
Control API and number of messages posted to the bus
|
|
"""
|
|
sendones.append((channel, message))
|
|
|
|
self.patch(type(self.env['bus.bus']), 'sendone', patched_sendone)
|
|
|
|
self.start_tour('/web', "bundle_changed_notification", login='admin', timeout=180)
|
|
|
|
# One sendone for each asset bundle and for each CSS / JS
|
|
self.assertEqual(len(sendones), 4)
|
|
for sent in sendones:
|
|
channel = sent[0]
|
|
message = sent[1]
|
|
self.assertEqual(channel, (db_name, 'bundle_changed'))
|
|
self.assertEqual(len(message), 2)
|
|
self.assertTrue(message[0] in bundle_xml_ids)
|
|
self.assertTrue(isinstance(message[1], str))
|