From 1ee7bf5f20f23abea8b7f3730d8317d69bb1ecfd Mon Sep 17 00:00:00 2001 From: luvi Date: Fri, 10 Mar 2023 09:47:49 +0000 Subject: [PATCH] [FIX] web: trigger onUpload when same file used in FileInput This commit fixes the behavior of the FileInput component. Since the html element of type input doesn't trigger its onChange when a file with the same name is given twice to the input, we must first clear the input value, which will cause the input to handle the file even if the input already contains this file. Even if that seems unnecessary, this is an easy way to fix issues in the base_import action were data are not send back to the server when re-uploading the same file to let the server process the data. A test has been added to assert that the onUpload is effectively called twice when uploading a file, even if it's the same exact file. closes odoo/odoo#114978 X-original-commit: d4a23c521d0e15f893d74e3530bc68ef19641f48 Signed-off-by: Julien Mougenot (jum) Signed-off-by: Luca Vitali --- .../static/src/core/file_input/file_input.js | 3 +++ .../web/static/tests/core/file_input_tests.js | 24 ++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/core/file_input/file_input.js b/addons/web/static/src/core/file_input/file_input.js index b089a2b4a0d..cc18401c73c 100644 --- a/addons/web/static/src/core/file_input/file_input.js +++ b/addons/web/static/src/core/file_input/file_input.js @@ -73,6 +73,9 @@ export class FileInput extends Component { const parsedFileData = await this.uploadFiles(this.httpParams); // When calling onUpload, also pass the files to allow to get data like their names this.props.onUpload(parsedFileData, this.fileInputRef.el ? this.fileInputRef.el.files : []); + // Because the input would not trigger this method if the same file name is uploaded, + // we must clear the value after handling the upload + this.fileInputRef.el.value = null; } /** diff --git a/addons/web/static/tests/core/file_input_tests.js b/addons/web/static/tests/core/file_input_tests.js index 4d50bd9caa1..a784adecaa4 100644 --- a/addons/web/static/tests/core/file_input_tests.js +++ b/addons/web/static/tests/core/file_input_tests.js @@ -1,7 +1,7 @@ /** @odoo-module **/ import { makeTestEnv } from "@web/../tests/helpers/mock_env"; -import { getFixture, mount, patchWithCleanup, triggerEvent } from "@web/../tests/helpers/utils"; +import { editInput, getFixture, mount, patchWithCleanup, triggerEvent } from "@web/../tests/helpers/utils"; import { FileInput } from "@web/core/file_input/file_input"; import { registry } from "@web/core/registry"; @@ -116,4 +116,26 @@ QUnit.module("Components", ({ beforeEach }) => { assert.isNotVisible(target.querySelector(".o_file_input")); }); + + QUnit.test("uploading the same file twice triggers the onChange twice", async (assert) => { + await createFileInput({ + props: { + onUpload(files) { + assert.step( + files[0].name + ); + }, + }, + mockPost: (route, params) => { + return JSON.stringify([{name: params.ufile[0].name}]); + }, + }); + + const file = new File(["test"], "fake_file.txt", { type: "text/plain" }); + await editInput(target, ".o_file_input input", file); + assert.verifySteps(["fake_file.txt"], "file has been initially uploaded"); + + await editInput(target, ".o_file_input input", file); + assert.verifySteps(["fake_file.txt"], "file has been uploaded a second time"); + }); });