diff --git a/addons/website/tests/test_qweb.py b/addons/website/tests/test_qweb.py index 9cc199291a98e23727bff95c8f0ae76b4269b746..7343b3910df4e53ac4b9da540a7446e96523f790 100644 --- a/addons/website/tests/test_qweb.py +++ b/addons/website/tests/test_qweb.py @@ -3,7 +3,7 @@ import re -from odoo import tools +from odoo import http, tools from odoo.addons.website.tools import MockRequest from odoo.modules.module import get_module_resource from odoo.tests.common import TransactionCase @@ -139,15 +139,12 @@ class TestQwebProcessAtt(TransactionCase): self._test_att('/my-page', {'href': '/fr/my-page'}) def test_process_att_url_crap(self): - with MockRequest(self.env, website=self.website) as request: + with MockRequest(self.env, website=self.website): + match = http.root.get_db_router.return_value.bind.return_value.match # #{fragment} is stripped from URL when testing route self._test_att('/x#y?z', {'href': '/x#y?z'}) - self.assertEqual( - request.httprequest.app._log_call[-1], - (('/x',), {'method': 'POST', 'query_args': None}) - ) + match.assert_called_with('/x', method='POST', query_args=None) + + match.reset_calls() self._test_att('/x?y#z', {'href': '/x?y#z'}) - self.assertEqual( - request.httprequest.app._log_call[-1], - (('/x',), {'method': 'POST', 'query_args': 'y'}) - ) + match.assert_called_with('/x', method='POST', query_args='y') diff --git a/addons/website/tools.py b/addons/website/tools.py index fa1eee4f47395b7a2215d7e296c2d4ec0fb20616..6930f8a5e68b276885f64d9c1bebb95b5e43977b 100644 --- a/addons/website/tools.py +++ b/addons/website/tools.py @@ -1,11 +1,13 @@ # -*- encoding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. - -import odoo +import contextlib import re +from unittest.mock import Mock, MagicMock, patch + import werkzeug -from odoo.tools import DotDict +import odoo +from odoo.tools.misc import DotDict def get_video_embed_code(video_url): @@ -55,71 +57,58 @@ def get_video_embed_code(video_url): return '<iframe class="embed-responsive-item" src="%s" allowFullScreen="true" frameborder="0"></iframe>' % embedUrl -class MockObject(object): - _log_call = [] - - def __init__(self, *args, **kwargs): - self.__dict__ = kwargs - - def __call__(self, *args, **kwargs): - self._log_call.append((args, kwargs)) - return self - - def __getitem__(self, index): - return self - - def werkzeugRaiseNotFound(*args, **kwargs): raise werkzeug.exceptions.NotFound() -class MockRequest(object): - """ Class with context manager mocking odoo.http.request for tests """ - def __init__(self, env, **kw): - app = MockObject(routing={ +@contextlib.contextmanager +def MockRequest( + env, *, routing=True, multilang=True, + context=None, + cookies=None, country_code=None, website=None, sale_order_id=None +): + router = MagicMock() + match = router.return_value.bind.return_value.match + if routing: + match.return_value[0].routing = { 'type': 'http', 'website': True, - 'multilang': kw.get('multilang', True), - }) - app.get_db_router = app.bind = app.match = app - if not kw.get('routing', True): - app.match = werkzeugRaiseNotFound - - lang = kw.get('lang') - if not lang: - lang_code = kw.get('context', {}).get('lang', env.context.get('lang', 'en_US')) - lang = env['res.lang']._lang_get(lang_code) - - context = kw.get('context', {}) - context.setdefault('lang', lang_code) - - self.request = DotDict({ - 'context': context, - 'db': None, - 'env': env, - 'httprequest': { - 'path': '/hello/', - 'app': app, - 'environ': { - 'REMOTE_ADDR': '127.0.0.1', - }, - 'cookies': kw.get('cookies', {}), - }, - 'lang': lang, - 'redirect': werkzeug.utils.redirect, - 'session': { - 'geoip': { - 'country_code': kw.get('country_code'), - }, - 'debug': False, - 'sale_order_id': kw.get('sale_order_id'), - }, - 'website': kw.get('website'), - }) - - def __enter__(self): - odoo.http._request_stack.push(self.request) - return self.request - - def __exit__(self, exc_type, exc_value, traceback): - odoo.http._request_stack.pop() + 'multilang': multilang + } + else: + match.side_effect = werkzeugRaiseNotFound + + if context is None: + context = {} + lang_code = context.get('lang', env.context.get('lang', 'en_US')) + context.setdefault('lang', lang_code) + + request = Mock( + context=context, + db=None, + endpoint=match.return_value[0] if routing else None, + env=env, + httprequest=Mock( + host='localhost', + path='/hello/', + app=odoo.http.root, + environ={'REMOTE_ADDR': '127.0.0.1'}, + cookies=cookies or {}, + referrer='', + ), + lang=env['res.lang']._lang_get(lang_code), + redirect=werkzeug.utils.redirect, + session=DotDict( + geoip={'country_code': country_code}, + debug=False, + sale_order_id=sale_order_id, + ), + website=website + ) + + with contextlib.ExitStack() as s: + odoo.http._request_stack.push(request) + s.callback(odoo.http._request_stack.pop) + s.enter_context(patch('odoo.http.root.get_db_router', router)) + + yield request