From 5a7e6d02474cefa590d36484470c20c3fe176d45 Mon Sep 17 00:00:00 2001 From: Romain Derie Date: Mon, 31 May 2021 08:59:25 +0000 Subject: [PATCH] [IMP] website: add tests - redirect 301 in case if trailing slash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit add tests to ensure every dispatch flows redirect to a 301 if the requested URL has a trailing slash. It also ensures the URL params are not lost in the process. - Basic controller: `/my/?a=b` - Website Pages: `/my-page/?a=b` - Basic controller with language: `/fr_BE/my/?a=b` - Website Pages with language: `/fr_BE/my-page/?a=b` - Homepage with language (special case/controller): `/fr_BE/?a=b` opw-2505818 opw-2513575 closes odoo/odoo#71065 Community: https://github.com/odoo/odoo/pull/71065 Enterprise: https://github.com/odoo/enterprise/pull/18615 Related: odoo/enterprise#18615 Signed-off-by: Jérémy Kersten (jke) --- addons/website/tests/test_lang_url.py | 51 +++++++++++++++++++++++++++ odoo/tests/common.py | 4 ++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/addons/website/tests/test_lang_url.py b/addons/website/tests/test_lang_url.py index 51153ade50a..bd021fd66a9 100644 --- a/addons/website/tests/test_lang_url.py +++ b/addons/website/tests/test_lang_url.py @@ -1,9 +1,11 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +import odoo from odoo.addons.http_routing.models.ir_http import url_lang from odoo.addons.website.tools import MockRequest from odoo.tests import HttpCase, tagged +from odoo.tests.common import HOST @tagged('-at_install', 'post_install') @@ -60,3 +62,52 @@ class TestLangUrl(HttpCase): r = self.url_open(url) self.assertEqual(r.status_code, 200) self.assertTrue('lang="fr-FR"' in r.text, "Ensure contactus did not soft crash + loaded in correct lang") + + +@tagged('-at_install', 'post_install') +class TestControllerRedirect(TestLangUrl): + def setUp(self): + self.page = self.env['website.page'].create({ + 'name': 'Test View', + 'type': 'qweb', + 'arch': '''Test View Page''', + 'key': 'test.test_view', + 'url': '/page_1', + 'is_published': True, + }) + super().setUp() + + def test_01_controller_redirect(self): + """ Trailing slash URLs should be redirected to non-slash URLs (unless + the controller explicitly specifies a trailing slash in the route). + """ + + def assertUrlRedirect(url, expected_url, msg="", code=301): + if expected_url.startswith('/'): + expected_url = "http://%s:%s%s" % (HOST, odoo.tools.config['http_port'], expected_url) + if not msg: + msg = 'Url <%s> differ from <%s>.' % (url, expected_url) + + r = self.url_open(url, head=True) + self.assertEqual(r.status_code, code) + self.assertEqual(r.headers.get('Location'), expected_url, msg) + + self.authenticate('admin', 'admin') + + # Controllers + assertUrlRedirect('/my/', '/my', "Check for basic controller.") + assertUrlRedirect('/my/?a=b', '/my?a=b', "Check for basic controller + URL params.") + # website.page + assertUrlRedirect('/page_1/', '/page_1', "Check for website.page.") + assertUrlRedirect('/page_1/?a=b', '/page_1?a=b', "Check for website.page + URL params.") + + # == Same with language == + # Controllers + assertUrlRedirect('/fr/my/', '/fr/my', "Check for basic controller with language in URL.") + assertUrlRedirect('/fr/my/?a=b', '/fr/my?a=b', "Check for basic controller with language in URL + URL params.") + # Homepage (which is a controller) + assertUrlRedirect('/fr/', '/fr', "Check for homepage + language.") + assertUrlRedirect('/fr/?a=b', '/fr?a=b', "Check for homepage + language + URL params") + # website.page + assertUrlRedirect('/fr/page_1/', '/fr/page_1', "Check for website.page with language in URL.") + assertUrlRedirect('/fr/page_1/?a=b', '/fr/page_1?a=b', "Check for website.page with language in URL + URL params.") diff --git a/odoo/tests/common.py b/odoo/tests/common.py index 74e27421a97..bbe6f58909a 100644 --- a/odoo/tests/common.py +++ b/odoo/tests/common.py @@ -1386,10 +1386,12 @@ class HttpCase(TransactionCase): cls.browser.stop() cls.browser = None - def url_open(self, url, data=None, files=None, timeout=10, headers=None, allow_redirects=True): + def url_open(self, url, data=None, files=None, timeout=10, headers=None, allow_redirects=True, head=False): self.env['base'].flush() if url.startswith('/'): url = "http://%s:%s%s" % (HOST, odoo.tools.config['http_port'], url) + if head: + return self.opener.head(url, data=data, files=files, timeout=timeout, headers=headers, allow_redirects=False) if data or files: return self.opener.post(url, data=data, files=files, timeout=timeout, headers=headers, allow_redirects=allow_redirects) return self.opener.get(url, timeout=timeout, headers=headers, allow_redirects=allow_redirects)