From ded278b9c20ddf7b9637d53d9b3f519947fb40ff Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 23 Jun 2021 14:15:06 +0000 Subject: [PATCH] [FIX] core: have HttpCase automatically set the base url While HttpCase did set `web.base.url` before starting a browser, in the non-browser test cases (or cases which would mix browser and non-browser) it would not do so. This is an issue when installing the database with one http-port and running tests with an other e.g. after duplicating the database (or even not duplicating it) in order to run multiple test instances concurrently, which requires using different http ports. Tests would then see the base url generated during installation, embedding the port used at installation, and would break weirdly (at best exploding due to not finding any server to bind to, and at worst making request on the wrong instance entirely). Simply updating the base url during setup seems to fix most of the tests. Notes: * Some tests (e.g. survey) don't flush() their create/update before calling `start_tour` or `browser_js`, the implicit flush because of the ICP handled the issue. Perform an explicit flush of base (similar to `url_open`) to ensure they keep working correctly. * `url_join` should handle absolute URIs correctly, it does imply slightly different semantics in case the `base_url` has a non-empty path, but that seems like a very limited risk (and possibly convenient to boot). * `payment` needed a fix because the vagaries of the MRO led to the extra parameter internally used by the thing to be passed to `HttpCase`'s `setUpClass`, which would not expect it. closes odoo/odoo#72645 Signed-off-by: Xavier Morel (xmo) --- addons/payment/tests/http_common.py | 2 +- odoo/tests/common.py | 24 ++++++++++++++---------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/addons/payment/tests/http_common.py b/addons/payment/tests/http_common.py index 8d277bb03d5..f9c60caf001 100644 --- a/addons/payment/tests/http_common.py +++ b/addons/payment/tests/http_common.py @@ -11,7 +11,7 @@ from odoo.tests import HttpCase from odoo.addons.payment.tests.utils import PaymentTestUtils -class PaymentHttpCommon(HttpCase, PaymentTestUtils): +class PaymentHttpCommon(PaymentTestUtils, HttpCase): """ HttpCase common to build and simulate requests going through payment controllers. Only use if you effectively want to test controllers. diff --git a/odoo/tests/common.py b/odoo/tests/common.py index bbe6f58909a..c0040c37000 100644 --- a/odoo/tests/common.py +++ b/odoo/tests/common.py @@ -1365,6 +1365,14 @@ class HttpCase(TransactionCase): cls = type(self) cls._logger = logging.getLogger('%s.%s' % (cls.__module__, cls.__name__)) + @classmethod + def setUpClass(cls): + super().setUpClass() + + ICP = cls.env['ir.config_parameter'] + ICP.set_param('web.base.url', cls.base_url()) + ICP.flush() + def setUp(self): super().setUp() if self.registry_test_mode: @@ -1482,16 +1490,8 @@ class HttpCase(TransactionCase): try: self.authenticate(login, login) - base_url = "http://%s:%s" % (HOST, odoo.tools.config['http_port']) - ICP = self.env['ir.config_parameter'] - ICP.set_param('web.base.url', base_url) - # flush updates to the database before launching the client side, - # otherwise they simply won't be visible - ICP.flush() - if re.match('[a-z]*:', url_path or ''): # about:, http:, ... - url = url_path - else: - url = "%s%s" % (base_url, url_path or '/') + self.env['base'].flush() + url = werkzeug.urls.url_join(self.base_url(), url_path) self._logger.info('Open "%s" in browser', url) if self.browser.screencasts_dir: @@ -1523,6 +1523,10 @@ class HttpCase(TransactionCase): self.browser.clear() self._wait_remaining_requests() + @classmethod + def base_url(cls): + return "http://%s:%s" % (HOST, odoo.tools.config['http_port']) + def start_tour(self, url_path, tour_name, step_delay=None, **kwargs): """Wrapper for `browser_js` to start the given `tour_name` with the optional delay between steps `step_delay`. Other arguments from