summaryrefslogtreecommitdiff
path: root/addons/test_website
diff options
context:
space:
mode:
Diffstat (limited to 'addons/test_website')
-rw-r--r--addons/test_website/__init__.py4
-rw-r--r--addons/test_website/__manifest__.py24
-rw-r--r--addons/test_website/controllers/__init__.py4
-rw-r--r--addons/test_website/controllers/main.py13
-rw-r--r--addons/test_website/data/test_website_data.xml54
-rw-r--r--addons/test_website/static/src/js/reset_views.test.js103
-rw-r--r--addons/test_website/tests/__init__.py4
-rw-r--r--addons/test_website/tests/test_reset_views.py102
-rw-r--r--addons/test_website/views/templates.xml8
9 files changed, 316 insertions, 0 deletions
diff --git a/addons/test_website/__init__.py b/addons/test_website/__init__.py
new file mode 100644
index 00000000000..273ede25ea3
--- /dev/null
+++ b/addons/test_website/__init__.py
@@ -0,0 +1,4 @@
+# -*- encoding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import controllers
diff --git a/addons/test_website/__manifest__.py b/addons/test_website/__manifest__.py
new file mode 100644
index 00000000000..557722971d4
--- /dev/null
+++ b/addons/test_website/__manifest__.py
@@ -0,0 +1,24 @@
+# -*- encoding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+{
+ 'name': 'Website Test',
+ 'version': '1.0',
+ 'category': 'Hidden',
+ 'sequence': 9876,
+ 'summary': 'Website Test, mainly for module install/uninstall tests',
+ 'description': """This module contains tests related to website. Those are
+contained in a separate module as we are testing module install/uninstall/upgrade
+and we don't want to reload the website module every time, including it's possible
+dependencies. Neither we want to add in website module some routes, views and
+models which only purpose is to run tests.""",
+ 'depends': [
+ 'website',
+ ],
+ 'data': [
+ 'views/templates.xml',
+ 'data/test_website_data.xml',
+ ],
+ 'installable': True,
+ 'application': False,
+}
diff --git a/addons/test_website/controllers/__init__.py b/addons/test_website/controllers/__init__.py
new file mode 100644
index 00000000000..5d4b25db9c0
--- /dev/null
+++ b/addons/test_website/controllers/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import main
diff --git a/addons/test_website/controllers/main.py b/addons/test_website/controllers/main.py
new file mode 100644
index 00000000000..fad797d6984
--- /dev/null
+++ b/addons/test_website/controllers/main.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import http
+from odoo.http import request
+from odoo.addons.portal.controllers.web import Home
+
+
+class WebsiteTest(Home):
+
+ @http.route('/test_view', type='http', auth="public", website=True)
+ def test_view(self, **kw):
+ return request.render('test_website.test_view')
diff --git a/addons/test_website/data/test_website_data.xml b/addons/test_website/data/test_website_data.xml
new file mode 100644
index 00000000000..df827d542a3
--- /dev/null
+++ b/addons/test_website/data/test_website_data.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <data noupdate="1">
+ <record id="test_view" model="ir.ui.view">
+ <field name="name">Test View</field>
+ <field name="type">qweb</field>
+ <field name="key">test_website.test_view</field>
+ <field name="arch" type="xml">
+ <t name="Test View" priority="29" t-name="test_website.test_view">
+ <t t-call="website.layout">
+ <p>Test View</p>
+ <p>placeholder</p>
+ </t>
+ </t>
+ </field>
+ </record>
+ <record id="test_page_view" model="ir.ui.view">
+ <field name="name">Test Page View</field>
+ <field name="type">qweb</field>
+ <field name="key">test_website.test_page_view</field>
+ <field name="arch" type="xml">
+ <t name="Test Page View" priority="29" t-name="test_website.test_page_view">
+ <t t-call="website.layout">
+ <div id="oe_structure_test_website_page" class="oe_structure oe_empty"/>
+ <p>Test Page View</p>
+ <p>placeholder</p>
+ </t>
+ </t>
+ </field>
+ </record>
+ <record id="test_page" model="website.page">
+ <field name="website_published">True</field>
+ <field name="url">/test_page_view</field>
+ <field name="view_id" ref="test_page_view"/>
+ </record>
+ <record id="test_view_to_be_t_called" model="ir.ui.view">
+ <field name="name">Test View To Be t-called</field>
+ <field name="type">qweb</field>
+ <field name="key">test_website.test_view_to_be_t_called</field>
+ <field name="arch" type="xml">
+ <t name="Test View To Be t-called" priority="29" t-name="test_website.test_view_to_be_t_called">
+ <p>Test View To Be t-called</p>
+ <p>placeholder</p>
+ </t>
+ </field>
+ </record>
+ <template id="test_view_child_broken" inherit_id="test_website.test_view" active="False">
+ <xpath expr="//p[last()]" position="replace">
+ <p>Test View Child Broken</p>
+ <p>placeholder</p>
+ </xpath>
+ </template>
+ </data>
+</odoo>
diff --git a/addons/test_website/static/src/js/reset_views.test.js b/addons/test_website/static/src/js/reset_views.test.js
new file mode 100644
index 00000000000..957cda6d594
--- /dev/null
+++ b/addons/test_website/static/src/js/reset_views.test.js
@@ -0,0 +1,103 @@
+odoo.define('test_website.reset_views', function (require) {
+'use strict';
+
+var tour = require("web_tour.tour");
+var base = require("web_editor.base");
+
+tour.register('test_reset_page_view_complete_flow_part1', {
+ test: true,
+ url: '/test_page_view',
+ wait_for: base.ready()
+},
+ [
+ // 1. Edit the page through Edit Mode, it will COW the view
+ {
+ content: "enter edit mode",
+ trigger: "a[data-action=edit]"
+ },
+ {
+ content: "drop a snippet",
+ trigger: "#oe_snippets .oe_snippet:has(.s_cover) .oe_snippet_thumbnail",
+ // id starting by 'oe_structure..' will actually create an inherited view
+ run: "drag_and_drop #oe_structure_test_website_page",
+ },
+ {
+ content: "save the page",
+ extra_trigger: '#oe_structure_test_website_page .s_cover',
+ trigger: "#web_editor-top-edit button[data-action=save]",
+ },
+ // 2. Edit that COW'd view in the HTML editor to break it.
+ {
+ content: "open customize menu",
+ extra_trigger: "body:not(.editor_enable)",
+ trigger: '#customize-menu > a',
+ },
+ {
+ content: "open html editor",
+ trigger: '#html_editor',
+ },
+ {
+ content: "add a broken t-field in page DOM",
+ trigger: 'div.ace_line .ace_xml:contains("placeholder")',
+ run: function () {
+ ace.edit('ace-view-editor').getSession().insert({row: 4, column: 1}, '<t t-field="not.exist"/>\n');
+ },
+ },
+ {
+ content: "save the html editor",
+ extra_trigger: '.ace_content:contains("not.exist")',
+ trigger: ".o_ace_view_editor button[data-action=save]",
+ }
+
+ // 3. Reset the broken view
+ ]
+);
+
+tour.register('test_reset_page_view_complete_flow_part2', {
+ test: true,
+ url: '/test_page_view',
+ wait_for: base.ready()
+},
+ [
+ {
+ content: "check that the view got fixed",
+ trigger: 'p:containsExact("Test Page View")',
+ run: function () {}, // it's a check
+ },
+ {
+ content: "check that the inherited COW view is still there (created during edit mode)",
+ trigger: '#oe_structure_test_website_page .s_cover',
+ run: function () {}, // it's a check
+ },
+ //4. Now break the inherited view created when dropping a snippet
+ {
+ content: "open customize menu",
+ trigger: '#customize-menu > a',
+ },
+ {
+ content: "open html editor",
+ trigger: '#html_editor',
+ },
+ {
+ content: "select oe_structure view",
+ trigger: '#ace-view-list',
+ run: function () {
+ var viewId = $('#ace-view-list option:contains("oe_structure")').val();
+ $('#ace-view-list').val(viewId).trigger('change');
+ },
+ },
+ {
+ content: "add a broken t-field in page DOM",
+ trigger: 'div.ace_line .ace_xml:contains("oe_structure_test_website_page")',
+ run: function () {
+ ace.edit('ace-view-editor').getSession().insert({row: 4, column: 1}, '<t t-field="not.exist"/>\n');
+ },
+ },
+ {
+ content: "save the html editor",
+ trigger: ".o_ace_view_editor button[data-action=save]",
+ }
+ ]
+);
+
+});
diff --git a/addons/test_website/tests/__init__.py b/addons/test_website/tests/__init__.py
new file mode 100644
index 00000000000..4c32d5f1959
--- /dev/null
+++ b/addons/test_website/tests/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import test_reset_views
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 00000000000..047b1abe3cd
--- /dev/null
+++ b/addons/test_website/tests/test_reset_views.py
@@ -0,0 +1,102 @@
+# 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='<p>placeholder</p>', to='<p t-field="not.exist"/>'):
+ view.arch = view.arch.replace(fr, to)
+
+
+@odoo.tests.common.tagged('post_install', '-at_install')
+class TestWebsiteResetViews(odoo.tests.HttpCase):
+ def do_test(self, name):
+ self.browser_js(
+ "/",
+ "odoo.__DEBUG__.services['web_tour.tour'].run('%s')" % name,
+ "odoo.__DEBUG__.services['web_tour.tour'].tours.%s.ready" % name,
+ login="admin"
+ )
+
+ def fix_it(self, page):
+ self.authenticate("admin", "admin")
+ resp = self.url_open(page)
+ self.assertEqual(resp.status_code, 500, "Waiting 500")
+ self.assertTrue('<button id="reset_templates_button"' in resp.text)
+ data = {'templates': [self.find_template(resp)], 'redirect': page}
+ resp = self.url_open('/website/reset_templates', data)
+ self.assertEqual(resp.status_code, 200, "Waiting 200")
+
+ def find_template(self, response):
+ find = re.search(r'<input.*type="checkbox".*name="templates".*value="([0-9]+)?"', response.text)
+ return find and find.group(1)
+
+ def setUp(self):
+ super(TestWebsiteResetViews, self).setUp()
+ self.Website = self.env['website']
+ self.View = self.env['ir.ui.view']
+ self.test_view = self.Website.viewref('test_website.test_view')
+
+ @mute_logger('odoo.addons.website.models.ir_http')
+ def test_01_reset_specific_page_view(self):
+ self.test_page_view = self.Website.viewref('test_website.test_page_view')
+ total_views = self.View.search_count([('type', '=', 'qweb')])
+ # Trigger COW then break the QWEB XML on it
+ break_view(self.test_page_view.with_context(website_id=1))
+ self.assertEqual(total_views + 1, self.View.search_count([('type', '=', 'qweb')]), "Missing COW view")
+ self.fix_it('/test_page_view')
+
+ @mute_logger('odoo.addons.website.models.ir_http')
+ def test_02_reset_specific_view_controller(self):
+ total_views = self.View.search_count([('type', '=', 'qweb')])
+ # Trigger COW then break the QWEB XML on it
+ break_view(self.test_view.with_context(website_id=1))
+ self.assertEqual(total_views + 1, self.View.search_count([('type', '=', 'qweb')]), "Missing COW view")
+ self.fix_it('/test_view')
+
+ @mute_logger('odoo.addons.website.models.ir_http')
+ def test_03_reset_specific_view_controller_t_called(self):
+ self.test_view_to_be_t_called = self.Website.viewref('test_website.test_view_to_be_t_called')
+
+ total_views = self.View.search_count([('type', '=', 'qweb')])
+ # Trigger COW then break the QWEB XML on it
+ break_view(self.test_view_to_be_t_called.with_context(website_id=1))
+ break_view(self.test_view, to='<t t-call="test_website.test_view_to_be_t_called"/>')
+ self.assertEqual(total_views + 1, self.View.search_count([('type', '=', 'qweb')]), "Missing COW view")
+ self.fix_it('/test_view')
+
+ @mute_logger('odoo.addons.website.models.ir_http')
+ def test_04_reset_specific_view_controller_inherit(self):
+ self.test_view_child_broken = self.Website.viewref('test_website.test_view_child_broken')
+
+ # Activate and break the inherited view
+ self.test_view_child_broken.active = True
+ break_view(self.test_view_child_broken.with_context(website_id=1, load_all_views=True))
+
+ self.fix_it('/test_view')
+
+ # This test work in real life, but not in test mode since we cannot rollback savepoint.
+ # @mute_logger('odoo.addons.website.models.ir_http', 'odoo.addons.website.models.ir_ui_view')
+ # def test_05_reset_specific_view_controller_broken_request(self):
+ # total_views = self.View.search_count([('type', '=', 'qweb')])
+ # # Trigger COW then break the QWEB XML on it
+ # break_view(self.test_view.with_context(website_id=1), to='<t t-esc="request.env[\'website\'].browse(\'a\').name" />')
+ # self.assertEqual(total_views + 1, self.View.search_count([('type', '=', 'qweb')]), "Missing COW view (1)")
+ # self.fix_it('/test_view')
+
+ # also mute ir.ui.view as `get_view_id()` will raise "Could not find view object with xml_id 'not.exist'""
+ @mute_logger('odoo.addons.website.models.ir_http', 'odoo.addons.website.models.ir_ui_view')
+ def test_06_reset_specific_view_controller_inexisting_template(self):
+ total_views = self.View.search_count([('type', '=', 'qweb')])
+ # Trigger COW then break the QWEB XML on it
+ break_view(self.test_view.with_context(website_id=1), to='<t t-call="not.exist"/>')
+ self.assertEqual(total_views + 1, self.View.search_count([('type', '=', 'qweb')]), "Missing COW view (2)")
+ self.fix_it('/test_view')
+
+ @mute_logger('odoo.addons.website.models.ir_http')
+ def test_07_reset_page_view_complete_flow(self):
+ self.do_test('test_reset_page_view_complete_flow_part1')
+ self.fix_it('/test_page_view')
+ self.do_test('test_reset_page_view_complete_flow_part2')
+ self.fix_it('/test_page_view')
diff --git a/addons/test_website/views/templates.xml b/addons/test_website/views/templates.xml
new file mode 100644
index 00000000000..2ce171bac30
--- /dev/null
+++ b/addons/test_website/views/templates.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <template id="assets_frontend" inherit_id="website.assets_frontend">
+ <xpath expr="script[last()]" position="after">
+ <script type="text/javascript" src="/test_website/static/src/js/reset_views.test.js"></script>
+ </xpath>
+ </template>
+</odoo>