diff --git a/addons/web/static/tests/helpers/test_utils.js b/addons/web/static/tests/helpers/test_utils.js index 7ba73115c84..759962e444c 100644 --- a/addons/web/static/tests/helpers/test_utils.js +++ b/addons/web/static/tests/helpers/test_utils.js @@ -16,6 +16,7 @@ var session = require('web.session'); var testUtilsCreate = require('web.test_utils_create'); var testUtilsDom = require('web.test_utils_dom'); var testUtilsFields = require('web.test_utils_fields'); +var testUtilsFile = require('web.test_utils_file'); var testUtilsForm = require('web.test_utils_form'); var testUtilsGraph = require('web.test_utils_graph'); var testUtilsKanban = require('web.test_utils_kanban'); @@ -98,6 +99,11 @@ return $.when( editSelect: testUtilsFields.editSelect, editAndTrigger: testUtilsFields.editAndTrigger, }, + file: { + createFile: testUtilsFile.createFile, + dragoverFile: testUtilsFile.dragoverFile, + dropFile: testUtilsFile.dropFile, + }, createActionManager: testUtilsCreate.createActionManager, createDebugManager: testUtilsCreate.createDebugManager, diff --git a/addons/web/static/tests/helpers/test_utils_file.js b/addons/web/static/tests/helpers/test_utils_file.js new file mode 100644 index 00000000000..64e044e3180 --- /dev/null +++ b/addons/web/static/tests/helpers/test_utils_file.js @@ -0,0 +1,113 @@ +odoo.define('web.test_utils_file', function () { +"use strict"; + +/** + * FILE Test Utils + * + * This module defines various utility functions to help simulate events with + * files, such as drag-and-drop. + * + * Note that all methods defined in this module are exported in the main + * testUtils file. + */ + + +//------------------------------------------------------------------------------ +// Private functions +//------------------------------------------------------------------------------ + +/** + * Create a fake object 'dataTransfer', linked to a file, which is passed to + * drag and drop events. + * + * @param {Object} file + * @returns {Object} + */ +function _createFakeDataTransfer(file) { + return { + dropEffect: 'all', + effectAllowed: 'all', + files: [file], + getData: function () { + return file; + }, + items: [], + types: ['Files'], + }; +} + +//------------------------------------------------------------------------------ +// Public functions +//------------------------------------------------------------------------------ + +/** + * Create a file object, which can be used for drag-and-drop. + * + * @param {Object} data + * @param {string} data.name + * @param {string} data.content + * @param {string} data.contentType + * @returns {$.Promise} resolved with file created + */ +function createFile(data) { + var def = $.Deferred(); + var requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; + if (!requestFileSystem) { + throw new Error('FileSystem API is not supported'); + } + requestFileSystem(window.TEMPORARY, 1024 * 1024, function (fileSystem) { + fileSystem.root.getFile(data.name, { create: true }, function (fileEntry) { + fileEntry.createWriter(function (fileWriter) { + fileWriter.onwriteend = function (e) { + fileSystem.root.getFile(data.name, {}, function (fileEntry) { + fileEntry.file(function (file) { + def.resolve(file); + }); + }); + }; + fileWriter.write(new Blob([ data.content ], { type: data.contentType })); + }); + }); + }); + return def; +} + +/** + * Drag a file over a DOM element + * + * @param {$.Element} $el + * @param {Object} file must have been created beforehand (@see createFile) + */ +function dragoverFile($el, file) { + var ev = new Event('dragover', { bubbles: true }); + Object.defineProperty(ev, 'dataTransfer', { + value: _createFakeDataTransfer(file), + }); + $el[0].dispatchEvent(ev); +} + +/** + * Drop a file on a DOM element. + * + * @param {$.Element} $el + * @param {Object} file must have been created beforehand (@see createFile) + */ +function dropFile($el, file) { + var ev = new Event('drop', { bubbles: true, }); + Object.defineProperty(ev, 'dataTransfer', { + value: _createFakeDataTransfer(file), + }); + $el[0].dispatchEvent(ev); +} + +//------------------------------------------------------------------------------ +// Exposed API +//------------------------------------------------------------------------------ + +return { + createFile: createFile, + dragoverFile: dragoverFile, + dropFile: dropFile, +}; + +}); diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml index e7729ab9fad..fa0ecce61e6 100644 --- a/addons/web/views/webclient_templates.xml +++ b/addons/web/views/webclient_templates.xml @@ -495,6 +495,7 @@ +