From 3751379f1e9a4c215fb6eb898b4ccc67659b9ace Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 10 May 2022 21:51:50 +0700 Subject: initial commit 2 --- addons/test_website/tests/__init__.py | 13 ++ addons/test_website/tests/test_controller_args.py | 31 ++++ addons/test_website/tests/test_custom_snippet.py | 13 ++ addons/test_website/tests/test_error.py | 10 ++ addons/test_website/tests/test_is_multilang.py | 71 +++++++++ addons/test_website/tests/test_multi_company.py | 16 ++ addons/test_website/tests/test_performance.py | 10 ++ addons/test_website/tests/test_redirect.py | 162 +++++++++++++++++++++ addons/test_website/tests/test_reset_views.py | 111 ++++++++++++++ addons/test_website/tests/test_session.py | 9 ++ .../tests/test_views_during_module_operation.py | 83 +++++++++++ 11 files changed, 529 insertions(+) create mode 100644 addons/test_website/tests/__init__.py create mode 100644 addons/test_website/tests/test_controller_args.py create mode 100644 addons/test_website/tests/test_custom_snippet.py create mode 100644 addons/test_website/tests/test_error.py create mode 100644 addons/test_website/tests/test_is_multilang.py create mode 100644 addons/test_website/tests/test_multi_company.py create mode 100644 addons/test_website/tests/test_performance.py create mode 100644 addons/test_website/tests/test_redirect.py create mode 100644 addons/test_website/tests/test_reset_views.py create mode 100644 addons/test_website/tests/test_session.py create mode 100644 addons/test_website/tests/test_views_during_module_operation.py (limited to 'addons/test_website/tests') diff --git a/addons/test_website/tests/__init__.py b/addons/test_website/tests/__init__.py new file mode 100644 index 00000000..38da4577 --- /dev/null +++ b/addons/test_website/tests/__init__.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import test_controller_args +from . import test_custom_snippet +from . import test_error +from . import test_is_multilang +from . import test_multi_company +from . import test_performance +from . import test_redirect +from . import test_reset_views +from . import test_session +from . import test_views_during_module_operation diff --git a/addons/test_website/tests/test_controller_args.py b/addons/test_website/tests/test_controller_args.py new file mode 100644 index 00000000..fc21c22a --- /dev/null +++ b/addons/test_website/tests/test_controller_args.py @@ -0,0 +1,31 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +import odoo.tests + + +@odoo.tests.common.tagged('post_install', '-at_install') +class TestWebsiteControllerArgs(odoo.tests.HttpCase): + + def test_crawl_args(self): + req = self.url_open('/ignore_args/converter/valueA/?b=valueB&c=valueC') + self.assertEqual(req.status_code, 200) + self.assertEqual(req.json(), {'a': 'valueA', 'b': 'valueB', 'kw': {'c': 'valueC'}}) + + req = self.url_open('/ignore_args/converter/valueA/nokw?b=valueB&c=valueC') + self.assertEqual(req.status_code, 200) + self.assertEqual(req.json(), {'a': 'valueA', 'b': 'valueB'}) + + req = self.url_open('/ignore_args/converteronly/valueA/?b=valueB&c=valueC') + self.assertEqual(req.status_code, 200) + self.assertEqual(req.json(), {'a': 'valueA', 'kw': None}) + + req = self.url_open('/ignore_args/none?a=valueA&b=valueB') + self.assertEqual(req.status_code, 200) + self.assertEqual(req.json(), {'a': None, 'kw': None}) + + req = self.url_open('/ignore_args/a?a=valueA&b=valueB') + self.assertEqual(req.status_code, 200) + self.assertEqual(req.json(), {'a': 'valueA', 'kw': None}) + + req = self.url_open('/ignore_args/kw?a=valueA&b=valueB') + self.assertEqual(req.status_code, 200) + self.assertEqual(req.json(), {'a': 'valueA', 'kw': {'b': 'valueB'}}) diff --git a/addons/test_website/tests/test_custom_snippet.py b/addons/test_website/tests/test_custom_snippet.py new file mode 100644 index 00000000..c79ed227 --- /dev/null +++ b/addons/test_website/tests/test_custom_snippet.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import odoo.tests +from odoo.tools import mute_logger + + +@odoo.tests.common.tagged('post_install', '-at_install') +class TestCustomSnippet(odoo.tests.HttpCase): + + @mute_logger('odoo.addons.http_routing.models.ir_http', 'odoo.http') + def test_01_run_tour(self): + self.start_tour("/", 'test_custom_snippet', login="admin") diff --git a/addons/test_website/tests/test_error.py b/addons/test_website/tests/test_error.py new file mode 100644 index 00000000..f4c9334e --- /dev/null +++ b/addons/test_website/tests/test_error.py @@ -0,0 +1,10 @@ +import odoo.tests +from odoo.tools import mute_logger + + +@odoo.tests.common.tagged('post_install', '-at_install') +class TestWebsiteError(odoo.tests.HttpCase): + + @mute_logger('odoo.addons.http_routing.models.ir_http', 'odoo.http') + def test_01_run_test(self): + self.start_tour("/test_error_view", 'test_error_website') diff --git a/addons/test_website/tests/test_is_multilang.py b/addons/test_website/tests/test_is_multilang.py new file mode 100644 index 00000000..1c7d6180 --- /dev/null +++ b/addons/test_website/tests/test_is_multilang.py @@ -0,0 +1,71 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +import odoo.tests +import lxml + + +@odoo.tests.common.tagged('post_install', '-at_install') +class TestIsMultiLang(odoo.tests.HttpCase): + + def test_01_is_multilang_url(self): + website = self.env['website'].search([], limit=1) + fr = self.env.ref('base.lang_fr').sudo() + en = self.env.ref('base.lang_en').sudo() + + fr.active = True + fr_prefix = "/" + fr.iso_code + + website.default_lang_id = en + website.language_ids = en + fr + + for data in [None, {'post': True}]: # GET / POST + body = lxml.html.fromstring(self.url_open('/fr/multi_url', data=data).content) + + self.assertEqual(fr_prefix + '/get', body.find('./a[@id="get"]').get('href')) + self.assertEqual(fr_prefix + '/post', body.find('./form[@id="post"]').get('action')) + self.assertEqual(fr_prefix + '/get_post', body.find('./a[@id="get_post"]').get('href')) + self.assertEqual('/get_post_nomultilang', body.find('./a[@id="get_post_nomultilang"]').get('href')) + + def test_02_url_lang_code_underscore(self): + website = self.env['website'].browse(1) + it = self.env.ref('base.lang_it').sudo() + en = self.env.ref('base.lang_en').sudo() + be = self.env.ref('base.lang_fr_BE').sudo() + country1 = self.env['res.country'].create({'name': "My Super Country"}) + + it.active = True + be.active = True + website.domain = 'http://127.0.0.1:8069' # for _is_canonical_url + website.default_lang_id = en + website.language_ids = en + it + be + params = { + 'src': country1.name, + 'value': country1.name + ' Italia', + 'type': 'model', + 'name': 'res.country,name', + 'res_id': country1.id, + 'lang': it.code, + 'state': 'translated', + } + self.env['ir.translation'].create(params) + params.update({ + 'value': country1.name + ' Belgium', + 'lang': be.code, + }) + self.env['ir.translation'].create(params) + r = self.url_open('/test_lang_url/%s' % country1.id) + self.assertEqual(r.status_code, 200) + self.assertTrue(r.url.endswith('/test_lang_url/my-super-country-%s' % country1.id)) + + r = self.url_open('/%s/test_lang_url/%s' % (it.url_code, country1.id)) + self.assertEqual(r.status_code, 200) + self.assertTrue(r.url.endswith('/%s/test_lang_url/my-super-country-italia-%s' % (it.url_code, country1.id))) + + body = lxml.html.fromstring(r.content) + # Note: this test is indirectly testing the `ref=canonical` tag is correctly set, + # as it is required in order for `rel=alternate` tags to be inserted in the DOM + it_href = body.find('./head/link[@rel="alternate"][@hreflang="it"]').get('href') + fr_href = body.find('./head/link[@rel="alternate"][@hreflang="fr"]').get('href') + en_href = body.find('./head/link[@rel="alternate"][@hreflang="en"]').get('href') + self.assertTrue(it_href.endswith('/%s/test_lang_url/my-super-country-italia-%s' % (it.url_code, country1.id))) + self.assertTrue(fr_href.endswith('/%s/test_lang_url/my-super-country-belgium-%s' % (be.url_code, country1.id))) + self.assertTrue(en_href.endswith('/test_lang_url/my-super-country-%s' % country1.id)) diff --git a/addons/test_website/tests/test_multi_company.py b/addons/test_website/tests/test_multi_company.py new file mode 100644 index 00000000..1395466a --- /dev/null +++ b/addons/test_website/tests/test_multi_company.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.tests.common import HttpCase, tagged + + +@tagged('post_install', '-at_install') +class TestMultiCompany(HttpCase): + + def test_company_in_context(self): + """ Test website company is set in context """ + website = self.env.ref('website.default_website') + company = self.env['res.company'].create({'name': "Adaa"}) + website.company_id = company + response = self.url_open('/multi_company_website') + self.assertEqual(response.json()[0], company.id) diff --git a/addons/test_website/tests/test_performance.py b/addons/test_website/tests/test_performance.py new file mode 100644 index 00000000..cd06dfda --- /dev/null +++ b/addons/test_website/tests/test_performance.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.addons.website.tests.test_performance import UtilPerf + + +class TestPerformance(UtilPerf): + def test_10_perf_sql_website_controller_minimalist(self): + url = '/empty_controller_test' + self.assertEqual(self._get_url_hot_query(url), 3) diff --git a/addons/test_website/tests/test_redirect.py b/addons/test_website/tests/test_redirect.py new file mode 100644 index 00000000..38eebcde --- /dev/null +++ b/addons/test_website/tests/test_redirect.py @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +import odoo +from odoo.tests import HttpCase, tagged +from odoo.tests.common import HOST +from odoo.tools import mute_logger +from odoo.addons.http_routing.models.ir_http import slug + +from unittest.mock import patch + + +@tagged('-at_install', 'post_install') +class TestRedirect(HttpCase): + + def setUp(self): + super(TestRedirect, self).setUp() + + self.user_portal = self.env['res.users'].with_context({'no_reset_password': True}).create({ + 'name': 'Test Website Portal User', + 'login': 'portal_user', + 'password': 'portal_user', + 'email': 'portal_user@mail.com', + 'groups_id': [(6, 0, [self.env.ref('base.group_portal').id])] + }) + + self.base_url = "http://%s:%s" % (HOST, odoo.tools.config['http_port']) + + def test_01_redirect_308_model_converter(self): + + self.env['website.rewrite'].create({ + 'name': 'Test Website Redirect', + 'redirect_type': '308', + 'url_from': '/test_website/country/', + 'url_to': '/redirected/country/', + }) + country_ad = self.env.ref('base.ad') + + """ Ensure 308 redirect with model converter works fine, including: + - Correct & working redirect as public user + - Correct & working redirect as logged in user + - Correct replace of url_for() URLs in DOM + """ + url = '/test_website/country/' + slug(country_ad) + redirect_url = url.replace('test_website', 'redirected') + + # [Public User] Open the original url and check redirect OK + r = self.url_open(url) + self.assertEqual(r.status_code, 200) + self.assertTrue(r.url.endswith(redirect_url), "Ensure URL got redirected") + self.assertTrue(country_ad.name in r.text, "Ensure the controller returned the expected value") + self.assertTrue(redirect_url in r.text, "Ensure the url_for has replaced the href URL in the DOM") + + # [Logged In User] Open the original url and check redirect OK + self.authenticate("portal_user", "portal_user") + r = self.url_open(url) + self.assertEqual(r.status_code, 200) + self.assertTrue(r.url.endswith(redirect_url), "Ensure URL got redirected (2)") + self.assertTrue('Logged In' in r.text, "Ensure logged in") + self.assertTrue(country_ad.name in r.text, "Ensure the controller returned the expected value (2)") + self.assertTrue(redirect_url in r.text, "Ensure the url_for has replaced the href URL in the DOM") + + @mute_logger('odoo.addons.http_routing.models.ir_http') # mute 403 warning + def test_02_redirect_308_RequestUID(self): + self.env['website.rewrite'].create({ + 'name': 'Test Website Redirect', + 'redirect_type': '308', + 'url_from': '/test_website/200/', + 'url_to': '/test_website/308/', + }) + + rec_published = self.env['test.model'].create({'name': 'name', 'website_published': True}) + rec_unpublished = self.env['test.model'].create({'name': 'name', 'website_published': False}) + + WebsiteHttp = odoo.addons.website.models.ir_http.Http + + def _get_error_html(env, code, value): + return str(code).split('_')[-1], "CUSTOM %s" % code + + with patch.object(WebsiteHttp, '_get_error_html', _get_error_html): + # Patch will avoid to display real 404 page and regenerate assets each time and unlink old one. + # And it allow to be sur that exception id handled by handle_exception and return a "managed error" page. + + # published + resp = self.url_open("/test_website/200/name-%s" % rec_published.id, allow_redirects=False) + self.assertEqual(resp.status_code, 308) + self.assertEqual(resp.headers.get('Location'), self.base_url + "/test_website/308/name-%s" % rec_published.id) + + resp = self.url_open("/test_website/308/name-%s" % rec_published.id, allow_redirects=False) + self.assertEqual(resp.status_code, 200) + + resp = self.url_open("/test_website/200/xx-%s" % rec_published.id, allow_redirects=False) + self.assertEqual(resp.status_code, 308) + self.assertEqual(resp.headers.get('Location'), self.base_url + "/test_website/308/xx-%s" % rec_published.id) + + resp = self.url_open("/test_website/308/xx-%s" % rec_published.id, allow_redirects=False) + self.assertEqual(resp.status_code, 301) + self.assertEqual(resp.headers.get('Location'), self.base_url + "/test_website/308/name-%s" % rec_published.id) + + resp = self.url_open("/test_website/200/xx-%s" % rec_published.id, allow_redirects=True) + self.assertEqual(resp.status_code, 200) + self.assertEqual(resp.url, self.base_url + "/test_website/308/name-%s" % rec_published.id) + + # unexisting + resp = self.url_open("/test_website/200/name-100", allow_redirects=False) + self.assertEqual(resp.status_code, 308) + self.assertEqual(resp.headers.get('Location'), self.base_url + "/test_website/308/name-100") + + resp = self.url_open("/test_website/308/name-100", allow_redirects=False) + self.assertEqual(resp.status_code, 404) + self.assertEqual(resp.text, "CUSTOM 404") + + resp = self.url_open("/test_website/200/xx-100", allow_redirects=False) + self.assertEqual(resp.status_code, 308) + self.assertEqual(resp.headers.get('Location'), self.base_url + "/test_website/308/xx-100") + + resp = self.url_open("/test_website/308/xx-100", allow_redirects=False) + self.assertEqual(resp.status_code, 404) + self.assertEqual(resp.text, "CUSTOM 404") + + # unpublish + resp = self.url_open("/test_website/200/name-%s" % rec_unpublished.id, allow_redirects=False) + self.assertEqual(resp.status_code, 308) + self.assertEqual(resp.headers.get('Location'), self.base_url + "/test_website/308/name-%s" % rec_unpublished.id) + + resp = self.url_open("/test_website/308/name-%s" % rec_unpublished.id, allow_redirects=False) + self.assertEqual(resp.status_code, 403) + self.assertEqual(resp.text, "CUSTOM 403") + + resp = self.url_open("/test_website/200/xx-%s" % rec_unpublished.id, allow_redirects=False) + self.assertEqual(resp.status_code, 308) + self.assertEqual(resp.headers.get('Location'), self.base_url + "/test_website/308/xx-%s" % rec_unpublished.id) + + resp = self.url_open("/test_website/308/xx-%s" % rec_unpublished.id, allow_redirects=False) + self.assertEqual(resp.status_code, 403) + self.assertEqual(resp.text, "CUSTOM 403") + + # with seo_name as slug + rec_published.seo_name = "seo_name" + rec_unpublished.seo_name = "seo_name" + + resp = self.url_open("/test_website/200/seo-name-%s" % rec_published.id, allow_redirects=False) + self.assertEqual(resp.status_code, 308) + self.assertEqual(resp.headers.get('Location'), self.base_url + "/test_website/308/seo-name-%s" % rec_published.id) + + resp = self.url_open("/test_website/308/seo-name-%s" % rec_published.id, allow_redirects=False) + self.assertEqual(resp.status_code, 200) + + resp = self.url_open("/test_website/200/xx-%s" % rec_unpublished.id, allow_redirects=False) + self.assertEqual(resp.status_code, 308) + self.assertEqual(resp.headers.get('Location'), self.base_url + "/test_website/308/xx-%s" % rec_unpublished.id) + + resp = self.url_open("/test_website/308/xx-%s" % rec_unpublished.id, allow_redirects=False) + self.assertEqual(resp.status_code, 403) + self.assertEqual(resp.text, "CUSTOM 403") + + resp = self.url_open("/test_website/200/xx-100", allow_redirects=False) + self.assertEqual(resp.status_code, 308) + self.assertEqual(resp.headers.get('Location'), self.base_url + "/test_website/308/xx-100") + + resp = self.url_open("/test_website/308/xx-100", allow_redirects=False) + self.assertEqual(resp.status_code, 404) + self.assertEqual(resp.text, "CUSTOM 404") diff --git a/addons/test_website/tests/test_reset_views.py b/addons/test_website/tests/test_reset_views.py new file mode 100644 index 00000000..a11e8282 --- /dev/null +++ b/addons/test_website/tests/test_reset_views.py @@ -0,0 +1,111 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +import re + +import odoo.tests +from odoo.tools import mute_logger + + +def break_view(view, fr='

placeholder

', to='

'): + view.arch = view.arch.replace(fr, to) + + +@odoo.tests.common.tagged('post_install', '-at_install') +class TestWebsiteResetViews(odoo.tests.HttpCase): + + def fix_it(self, page, mode='soft'): + self.authenticate("admin", "admin") + resp = self.url_open(page) + self.assertEqual(resp.status_code, 500, "Waiting 500") + self.assertTrue('