From eb0ea8efbe932c140302e9f8da33a839bcd73146 Mon Sep 17 00:00:00 2001 From: Antoine Guenet Date: Fri, 28 Dec 2018 17:59:35 +0000 Subject: [ADD] web_editor,*: Tests for new structure of web editor The refactoring also had to be done in order to create a set of unit tests. Each behavior can be tested, including the behaviors performed as a consequence of keyboard interactions (for instance: Enter, Tab...). This commit also contains some changes to test_utils that were necessary given the new structure of the wysiwyg editor. Co-authored-by: Gorash --- addons/web_editor/static/tests/test_utils.js | 674 +++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 addons/web_editor/static/tests/test_utils.js (limited to 'addons/web_editor/static/tests/test_utils.js') diff --git a/addons/web_editor/static/tests/test_utils.js b/addons/web_editor/static/tests/test_utils.js new file mode 100644 index 00000000000..ff740e52f36 --- /dev/null +++ b/addons/web_editor/static/tests/test_utils.js @@ -0,0 +1,674 @@ +odoo.define('web_editor.test_utils', function (require) { +"use strict"; + +var ajax = require('web.ajax'); +var testUtils = require('web.test_utils'); +var Widget = require('web.Widget'); +var Wysiwyg = require('web_editor.wysiwyg'); +var options = require('web_editor.snippets.options'); + + +/** + * Options with animation and edition for test. + */ +options.registry.option_test = options.Class.extend({ + cleanForSave: function () { + this.$target.addClass('cleanForSave'); + }, + onBuilt: function () { + this.$target.addClass('built'); + }, + onBlur: function () { + this.$target.removeClass('focus'); + }, + onClone: function () { + this.$target.addClass('clone'); + this.$target.removeClass('focus'); + }, + onFocus: function () { + this.$target.addClass('focus'); + }, + onMove: function () { + this.$target.addClass('move'); + }, + onRemove: function () { + this.$target.closest('.note-editable').addClass('snippet_has_removed'); + }, +}); + + +/** + * Constructor WysiwygTest why editable and unbreakable node used in test. + */ +var WysiwygTest = Wysiwyg.extend({ + _parentToDestroyForTest: null, + /** + * Override 'destroy' of discuss so that it calls 'destroy' on the parent. + * + * @override + */ + destroy: function () { + unpatch(); + this._super(); + this.$target.remove(); + this._parentToDestroyForTest.destroy(); + }, + /** + * @override + */ + isUnbreakableNode: function (node) { + var Node = (node.tagName ? node : node.parentNode); + return (!this.options.useOnlyTestUnbreakable && this._super(node)) || + !this.isEditableNode(node) || + Node.tagName === "UNBREAKABLE" || + (Node.className + '').indexOf('unbreakable') !== -1; + }, + /** + * @override + */ + isEditableNode: function (node) { + if (!$(node).closest(this.$el).length) { + return false; + } + while (node) { + if (node.tagName === "EDITABLE") { + return true; + } + if (node.tagName === "NOTEDITABLE") { + return false; + } + if ((node.className + '').indexOf('editable') !== -1) { + return true; + } + if (this.$el[0] === node) { + return true; + } + node = node.parentNode; + } + return false; + }, +}); + + +function patch() { + testUtils.mock.patch(ajax, { + loadAsset: function (xmlId) { + if (xmlId === 'template.assets') { + return $.when({ + cssLibs: [], + cssContents: ['body {background-color: red;}'] + }); + } + if (xmlId === 'template.assets_all_style') { + return $.when({ + cssLibs: $('head link[href]:not([type="image/x-icon"])').map(function () { + return $(this).attr('href'); + }).get(), + cssContents: ['body {background-color: red;}'] + }); + } + throw 'Wrong template'; + }, + }); +} + +function unpatch() { + testUtils.mock.unpatch(ajax); +} + +/** + * @param {object} data + * @returns {object} + */ +function wysiwygData(data) { + return _.defaults({}, data, { + 'ir.ui.view': { + fields: { + display_name: { + string: "Displayed name", + type: "char", + }, + }, + records: [], + read_template: function (args) { + if (args[0] === 'web_editor.colorpicker') { + return '' + + '' + + '
' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '
' + + '
' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '
' + + '
' + + '
' + + '
'; + } + }, + render_template: function (args) { + if (args[0] === 'web_editor.snippets') { + return '

Add blocks

' + + '
' + + '
' + + '
' + + ' First Panel' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '

Title

' + + '

Content

' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + ' ' + + '
' + + ' Background Image' + + '
' + + '
' + + ' ' + + '
'; + } + }, + }, + 'ir.attachment': { + fields: { + display_name: { + string: "display_name", + type: 'char', + }, + datas_fname: { + string: "datas_fname", + type: 'char', + }, + mimetype: { + string: "mimetype", + type: 'char', + }, + checksum: { + string: "checksum", + type: 'char', + }, + url: { + string: "url", + type: 'char', + }, + type: { + string: "type", + type: 'char', + }, + res_id: { + string: "res_id", + type: 'integer', + }, + res_model: { + string: "res_model", + type: 'char', + }, + access_token: { + string: "access_token", + type: 'char', + }, + }, + records: [{ + id: 1, + public: true, + name: 'image', + datas_fname: 'image.png', + mimetype: 'image/png', + checksum: false, + url: '/web_editor/static/src/img/transparent.png', + type: 'url', + res_id: 0, + res_model: false, + access_token: false + }], + generate_access_token: function () { + return; + }, + }, + }); +} + +/** + * Create the wysiwyg instance for test (contains patch, usefull ir.ui.view, snippets). + * + * @param {object} params + */ +function createWysiwyg(params) { + patch(); + params.data = wysiwygData(params.data); + + var parent = new Widget(); + testUtils.mock.addMockEnvironment(parent, params); + + var wysiwygOptions = _.extend({}, params.wysiwygOptions, { + recordInfo: { + context: {}, + res_model: 'module.test', + res_id: 1, + }, + useOnlyTestUnbreakable: params.useOnlyTestUnbreakable, + }); + + var wysiwyg = new WysiwygTest(parent, wysiwygOptions); + wysiwyg._parentToDestroyForTest = parent; + + var $textarea = $('