diff --git a/addons/test_html_field_history/__init__.py b/addons/test_html_field_history/__init__.py new file mode 100644 index 00000000000..dc5e6b693d1 --- /dev/null +++ b/addons/test_html_field_history/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import models diff --git a/addons/test_html_field_history/__manifest__.py b/addons/test_html_field_history/__manifest__.py new file mode 100644 index 00000000000..c87e7f03eb0 --- /dev/null +++ b/addons/test_html_field_history/__manifest__.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +{ + 'name': 'Test - html_field_history', + 'version': '1.0', + 'category': 'Hidden', + 'depends': ['web_editor'], + 'data': [ + 'security/ir.model.access.csv', + ], + 'license': 'LGPL-3', +} diff --git a/addons/test_html_field_history/models/__init__.py b/addons/test_html_field_history/models/__init__.py new file mode 100644 index 00000000000..a3b6f86312f --- /dev/null +++ b/addons/test_html_field_history/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import model_html_field_history_test diff --git a/addons/test_html_field_history/models/model_html_field_history_test.py b/addons/test_html_field_history/models/model_html_field_history_test.py new file mode 100644 index 00000000000..266347fab4f --- /dev/null +++ b/addons/test_html_field_history/models/model_html_field_history_test.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ModelHtmlFieldHistoryTest(models.Model): + _description = "Test html_field_history Model" + _name = "html.field.history.test" + _inherit = ["html.field.history.mixin"] + + def _get_versioned_fields(self): + return [ + ModelHtmlFieldHistoryTest.versioned_field_1.name, + ModelHtmlFieldHistoryTest.versioned_field_2.name, + ] + + versioned_field_1 = fields.Html(string="vf1") + versioned_field_2 = fields.Html(string="vf2", sanitize=False) diff --git a/addons/test_html_field_history/security/ir.model.access.csv b/addons/test_html_field_history/security/ir.model.access.csv new file mode 100644 index 00000000000..e45ce3bc479 --- /dev/null +++ b/addons/test_html_field_history/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_resource_test_all,resource.test.all,model_html_field_history_test,base.group_user,1,1,1,1 diff --git a/addons/test_html_field_history/tests/__init__.py b/addons/test_html_field_history/tests/__init__.py new file mode 100644 index 00000000000..e32480285d2 --- /dev/null +++ b/addons/test_html_field_history/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_model diff --git a/addons/test_html_field_history/tests/test_model.py b/addons/test_html_field_history/tests/test_model.py new file mode 100644 index 00000000000..7228fbe4c72 --- /dev/null +++ b/addons/test_html_field_history/tests/test_model.py @@ -0,0 +1,101 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.tests.common import TransactionCase, tagged +from odoo.exceptions import ValidationError + + +@tagged("-at_install", "post_install") +class TestModel(TransactionCase): + def setUp(self): + self.env["html.field.history.test"].search([]).unlink() + super().setUp() + + def test_html_field_history_write(self): + rec1 = self.env["html.field.history.test"].create( + { + "versioned_field_1": "mock content", + } + ) + self.assertFalse( + rec1.html_field_history, + "Record creation should not generate revisions", + ) + self.assertFalse( + rec1.html_field_history_metadata, + "We should never have metadata without revisions", + ) + + rec1.write( + { + "versioned_field_1": "mock content 2", + } + ) + self.assertEqual(len(rec1.html_field_history["versioned_field_1"]), 1) + self.assertEqual(len(rec1.html_field_history_metadata["versioned_field_1"]), 1) + self.assertFalse(rec1.html_field_history["versioned_field_2"]) + self.assertFalse(rec1.html_field_history_metadata["versioned_field_2"]) + + rec1.write( + { + "versioned_field_1": "mock content 3", + } + ) + rec1.write( + { + "versioned_field_1": None, + } + ) + self.assertEqual(len(rec1.html_field_history["versioned_field_1"]), 3) + rec1.unlink() + + rec2 = self.env["html.field.history.test"].create( + { + "versioned_field_2": "mock content", + } + ) + self.assertFalse( + rec2.html_field_history, + "Record creation should not generate revisions", + ) + self.assertFalse( + rec2.html_field_history_metadata, + "We should never have metadata without revisions", + ) + + with self.assertRaises( + ValidationError, + msg="We should not be able to versioned a field that is not declared as sanitize=True", + ): + rec2.write( + { + "versioned_field_2": "mock content 2", + } + ) + + rec2.unlink() + + def test_html_field_history_revision_are_sanitized(self): + rec1 = self.env["html.field.history.test"].create( + { + "versioned_field_1": "mock content", + } + ) + self.assertFalse( + rec1.html_field_history, + "Record creation should not generate revisions", + ) + # Attempt to write unsecure HTML inside sanitized html field + rec1.write({"versioned_field_1": 'scam