odoo.define('web_editor.test_utils', function (require) { "use strict"; var ajax = require('web.ajax'); var MockServer = require('web.MockServer'); var testUtils = require('web.test_utils'); var Widget = require('web.Widget'); var Wysiwyg = require('web_editor.wysiwyg'); var options = require('web_editor.snippets.options'); MockServer.include({ //-------------------------------------------------------------------------- // Private //-------------------------------------------------------------------------- /** * @override * @private * @returns {Promise} */ _performRpc: function (route, args) { if (args.model === "ir.ui.view") { if (args.method === 'read_template' && args.args[0] === "web_editor.colorpicker") { var template = '' + '' + '
' + ' ' + ' ' + ' ' + ' ' + ' ' + '
' + '
' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + '
' + '
' + '
' + '
'; return Promise.resolve(template); } if (args.method === 'render_template' && args.args[0] === "web_editor.snippets") { var template = '

Add blocks

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

Title

' + '

Content

' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + ' ' + '
' + ' Background Image' + '
' + '
' + ' ' + '
'; return Promise.resolve(template); } } return this._super.apply(this, arguments); }, }); /** * 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 Promise.resolve({ cssLibs: [], cssContents: ['body {background-color: red;}'] }); } if (xmlId === 'template.assets_all_style') { return Promise.resolve({ cssLibs: $('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 = $('