diff --git a/addons/test_website/controllers/main.py b/addons/test_website/controllers/main.py index ae45d160b06..cc60ccfd25f 100644 --- a/addons/test_website/controllers/main.py +++ b/addons/test_website/controllers/main.py @@ -1,16 +1,19 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +import json +import werkzeug + from odoo import http from odoo.http import request from odoo.addons.portal.controllers.web import Home -import json +from odoo.exceptions import UserError, ValidationError, AccessError, MissingError, AccessError, AccessDenied class WebsiteTest(Home): - @http.route('/test_view', type='http', auth="public", website=True) - def test_view(self, **kw): + @http.route('/test_view', type='http', auth='public', website=True) + def test_view(self, **kwargs): return request.render('test_website.test_view') @http.route('/ignore_args/converteronly//', type='http', auth="public", website=True) @@ -40,3 +43,55 @@ class WebsiteTest(Home): @http.route('/multi_company_website', type='http', auth="public", website=True) def test_company_context(self): return request.make_response(json.dumps(request.context.get('allowed_company_ids'))) + + @http.route('/test_error_view', type='http', auth='public', website=True) + def test_error_view(self, **kwargs): + return request.render('test_website.test_error_view') + + @http.route('/test_user_error_http', type='http', auth='public', website=True) + def test_user_error_http(self, **kwargs): + raise UserError("This is a user http test") + + @http.route('/test_user_error_json', type='json', auth='public', website=True) + def test_user_error_json(self, **kwargs): + raise UserError("This is a user rpc test") + + @http.route('/test_validation_error_http', type='http', auth='public', website=True) + def test_validation_error_http(self, **kwargs): + raise ValidationError("This is a validation http test") + + @http.route('/test_validation_error_json', type='json', auth='public', website=True) + def test_validation_error_json(self, **kwargs): + raise ValidationError("This is a validation rpc test") + + @http.route('/test_access_error_json', type='json', auth='public', website=True) + def test_access_error_json(self, **kwargs): + raise AccessError("This is an access rpc test") + + @http.route('/test_access_error_http', type='http', auth='public', website=True) + def test_access_error_http(self, **kwargs): + raise AccessError("This is an access http test") + + @http.route('/test_missing_error_json', type='json', auth='public', website=True) + def test_missing_error_json(self, **kwargs): + raise MissingError("This is a missing rpc test") + + @http.route('/test_missing_error_http', type='http', auth='public', website=True) + def test_missing_error_http(self, **kwargs): + raise MissingError("This is a missing http test") + + @http.route('/test_internal_error_json', type='json', auth='public', website=True) + def test_internal_error_json(self, **kwargs): + raise werkzeug.exceptions.InternalServerError() + + @http.route('/test_internal_error_http', type='http', auth='public', website=True) + def test_internal_error_http(self, **kwargs): + raise werkzeug.exceptions.InternalServerError() + + @http.route('/test_access_denied_json', type='json', auth='public', website=True) + def test_denied_error_json(self, **kwargs): + raise AccessDenied("This is an access denied rpc test") + + @http.route('/test_access_denied_http', type='http', auth='public', website=True) + def test_denied_error_http(self, **kwargs): + raise AccessDenied("This is an access denied http test") diff --git a/addons/test_website/data/test_website_data.xml b/addons/test_website/data/test_website_data.xml index 0d829aaab84..05a248190d4 100644 --- a/addons/test_website/data/test_website_data.xml +++ b/addons/test_website/data/test_website_data.xml @@ -30,6 +30,44 @@ + + Test Error View + qweb + test_website.test_error_view + + + + + + + + True /test_page_view diff --git a/addons/test_website/static/src/js/test_error.js b/addons/test_website/static/src/js/test_error.js new file mode 100644 index 00000000000..8a0f909d33f --- /dev/null +++ b/addons/test_website/static/src/js/test_error.js @@ -0,0 +1,30 @@ +odoo.define('website_forum.test_error', function (require) { +'use strict'; + +var publicWidget = require('web.public.widget'); + +publicWidget.registry.testError = publicWidget.Widget.extend({ + selector: '.rpc_error', + events: { + 'click a': '_onRpcErrorClick', + }, + + //---------------------------------------------------------------------- + // Handlers + //---------------------------------------------------------------------- + + /** + * make a rpc call with the href of the DOM element clicked + * @private + * @param {Event} ev + * @returns {Promise} + */ + _onRpcErrorClick: function (ev) { + ev.preventDefault(); + var $link = $(ev.currentTarget); + return this._rpc({ + route: $link.attr('href'), + }); + } +}); +}); diff --git a/addons/test_website/static/tests/tours/error_views.js b/addons/test_website/static/tests/tours/error_views.js new file mode 100644 index 00000000000..a3d9f3fa035 --- /dev/null +++ b/addons/test_website/static/tests/tours/error_views.js @@ -0,0 +1,152 @@ +odoo.define('test_website.error_views', function (require) { +'use strict'; + +var tour = require('web_tour.tour'); + +tour.register('test_error_website', { + test: true, + url: '/test_error_view', +}, +[ + // RPC ERROR + { + content: "trigger rpc user error", + trigger: 'a[href="/test_user_error_json"]', + }, { + content: "rpc user error modal has message", + extra_trigger: 'div.o_dialog_warning.modal-body:contains("This is a user rpc test")', + trigger: 'button.btn.btn-primary', + }, { + content: "trigger rpc access error", + trigger: 'a[href="/test_access_error_json"]', + }, { + content: "rpc access error modal has message", + extra_trigger: 'div.o_dialog_warning.modal-body:contains("This is an access rpc test")', + trigger: 'button.btn.btn-primary', + }, { + content: "trigger validation rpc error", + trigger: 'a[href="/test_validation_error_json"]', + }, { + content: "rpc validation error modal has message", + extra_trigger: 'div.o_dialog_warning.modal-body:contains("This is a validation rpc test")', + trigger: 'button.btn.btn-primary', + }, { + content: "trigger rpc missing error", + trigger: 'a[href="/test_missing_error_json"]', + }, { + content: "rpc missing error modal has message", + extra_trigger: 'div.o_dialog_warning.modal-body:contains("This is a missing rpc test")', + trigger: 'button.btn.btn-primary', + }, { + content: "trigger rpc error 403", + trigger: 'a[href="/test_access_denied_json"]', + }, { + content: "rpc error 403 modal has message", + extra_trigger: 'div.o_dialog_warning.modal-body:contains("This is an access denied rpc test")', + trigger: 'button.btn.btn-primary', + }, { + content: "trigger rpc error 500", + trigger: 'a[href="/test_internal_error_json"]', + }, { + content: "rpc error 500 modal is an ErrorDialog", + extra_trigger: 'div.o_dialog_error.modal-body div.alert.alert-warning', + trigger: 'button.btn.btn-primary[type="button"]', + }, + // HTTP ERROR + { + content: "trigger http user error", + trigger: 'body', + run: function () { + window.location.href = window.location.origin + '/test_user_error_http?debug=0'; + }, + }, { + content: "http user error page has title and message", + extra_trigger: 'h1:contains("Oops! Something went wrong.")', + trigger: 'div.container pre:contains("This is a user http test")', + run: function () { + window.location.href = window.location.origin + '/test_user_error_http?debug=1'; + }, + }, { + content: "http user error page debug has title and message open", + extra_trigger: 'h1:contains("Oops! Something went wrong.")', + trigger: 'div#error_main.collapse.show pre:contains("This is a user http test")', + run: function () {}, + }, { + content: "http user error page debug has traceback closed", + trigger: 'body:has(div#error_traceback.collapse:not(.show) pre#exception_traceback)', + run: function () { + window.location.href = window.location.origin + '/test_validation_error_http?debug=0'; + }, + }, { + content: "http validation error page has title and message", + extra_trigger: 'h1:contains("Oops! Something went wrong.")', + trigger: 'div.container pre:contains("This is a validation http test")', + run: function () { + window.location.href = window.location.origin + '/test_validation_error_http?debug=1'; + }, + }, { + content: "http validation error page debug has title and message open", + extra_trigger: 'h1:contains("Oops! Something went wrong.")', + trigger: 'div#error_main.collapse.show pre:contains("This is a validation http test")', + run: function () {}, + }, { + content: "http validation error page debug has traceback closed", + trigger: 'body:has(div#error_traceback.collapse:not(.show) pre#exception_traceback)', + run: function () { + window.location.href = window.location.origin + '/test_access_error_http?debug=0'; + }, + }, { + content: "http access error page has title and message", + extra_trigger: 'h1:contains("403: Forbidden")', + trigger: 'div.container pre:contains("This is an access http test")', + run: function () { + window.location.href = window.location.origin + '/test_access_error_http?debug=1'; + }, + }, { + content: "http access error page debug has title and message open", + extra_trigger: 'h1:contains("403: Forbidden")', + trigger: 'div#error_main.collapse.show pre:contains("This is an access http test")', + run: function () {}, + }, { + content: "http access error page debug has traceback closed", + trigger: 'body:has(div#error_traceback.collapse:not(.show) pre#exception_traceback)', + run: function () { + window.location.href = window.location.origin + '/test_missing_error_http?debug=0'; + }, + }, { + content: "http missing error page has title and message", + extra_trigger: 'h1:contains("Oops! Something went wrong.")', + trigger: 'div.container pre:contains("This is a missing http test")', + run: function () { + window.location.href = window.location.origin + '/test_missing_error_http?debug=1'; + }, + }, { + content: "http missing error page debug has title and message open", + extra_trigger: 'h1:contains("Oops! Something went wrong.")', + trigger: 'div#error_main.collapse.show pre:contains("This is a missing http test")', + run: function () {}, + }, { + content: "http missing error page debug has traceback closed", + trigger: 'body:has(div#error_traceback.collapse:not(.show) pre#exception_traceback)', + run: function () { + window.location.href = window.location.origin + '/test_karma_error_http?debug=0'; + }, + }, { + content: "http error 403 page has title but no message", + extra_trigger: 'h1:contains("403: Forbidden")', + trigger: 'div#wrap:not(:has(pre:contains("This is an access denied http test"))', //See ir_http.py handle_exception, the exception is replaced so there is no message ! + run: function () { + window.location.href = window.location.origin + '/test_access_denied_http?debug=1'; + }, + }, { + content: "http 403 error page debug has title but no message", + extra_trigger: 'h1:contains("403: Forbidden")', + trigger: 'div#debug_infos:not(:has(#error_main))', + run: function () {}, + }, { + content: "http 403 error page debug has traceback open", + trigger: 'body:has(div#error_traceback.collapse.show pre#exception_traceback)', + run: function () {}, + }, +]); +}); diff --git a/addons/test_website/tests/__init__.py b/addons/test_website/tests/__init__.py index 4bb004cd8f9..8b8ec3e4e44 100644 --- a/addons/test_website/tests/__init__.py +++ b/addons/test_website/tests/__init__.py @@ -3,5 +3,6 @@ from . import test_controller_args from . import test_reset_views +from . import test_error from . import test_views_during_module_operation from . import test_multi_company diff --git a/addons/test_website/tests/test_error.py b/addons/test_website/tests/test_error.py new file mode 100644 index 00000000000..63dad4133f1 --- /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.website.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/views/templates.xml b/addons/test_website/views/templates.xml index 4a6389cf9c7..ee6b500c5ca 100644 --- a/addons/test_website/views/templates.xml +++ b/addons/test_website/views/templates.xml @@ -1,8 +1,15 @@ + +