From 3de3a1903a19ed6a8b79e76b46c3761527d0bffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=20De=20Caluw=C3=A9?= Date: Fri, 25 Aug 2023 13:13:18 +0000 Subject: [PATCH] [FIX] web: avoid undefined format in parseDate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The safeConvert function in the useDateTimePicker hook will call parseDate with an undefined format when no format option was provided to the hook. Before this commit, since the options object passed to parseDate still contained the format property, the undefined format will also be passed on to the parseDateTime function. This is problematic, because now the parser will use the default datetime format, and it will fail because of the absence of a time value in the input string. For some input formats, parseDateTime will still yield the correct result using one of its backup parsing methods. However, a wrong result will be returned for date formats containing some textual parts (for example MMM/dd/yyyy). Making sure no undefined format values are passed on in the parseDate function resolves the problem. opw-3478797 closes odoo/odoo#136221 X-original-commit: b04482ed87db05b3fc2523a08ce7ca5818af578b Signed-off-by: Michaël Mattiello (mcm) Signed-off-by: Tom De Caluwé (tdc) --- addons/web/static/src/core/l10n/dates.js | 2 +- .../core/datetime/datetime_input_tests.js | 25 +++++++++++++++++++ .../web/static/tests/core/l10n/dates_tests.js | 15 +++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/core/l10n/dates.js b/addons/web/static/src/core/l10n/dates.js index bdb6fe3ae8c..13809c5205d 100644 --- a/addons/web/static/src/core/l10n/dates.js +++ b/addons/web/static/src/core/l10n/dates.js @@ -379,7 +379,7 @@ export function serializeDateTime(value) { * returned value will always be set at the start of the day) */ export function parseDate(value, options = {}) { - const parsed = parseDateTime(value, { format: localization.dateFormat, ...options }); + const parsed = parseDateTime(value, { ...options, format: options.format || localization.dateFormat }); return parsed && parsed.startOf("day"); } diff --git a/addons/web/static/tests/core/datetime/datetime_input_tests.js b/addons/web/static/tests/core/datetime/datetime_input_tests.js index 4bf2f5c4ddb..5b1252a6932 100644 --- a/addons/web/static/tests/core/datetime/datetime_input_tests.js +++ b/addons/web/static/tests/core/datetime/datetime_input_tests.js @@ -505,4 +505,29 @@ QUnit.module("Components", ({ beforeEach }) => { assert.strictEqual(input.value, "١٥ يوليو, ٢٠٢٠ ١٢:٣٠:٤٣"); }); + + QUnit.test("check datepicker in localization with textual month format", async function (assert) { + assert.expect(3); + let onChangeDate; + + Object.assign(localization, { + dateFormat: 'MMM/dd/yyyy', + timeFormat: 'HH:mm:ss', + dateTimeFormat: 'MMM/dd/yyyy HH:mm:ss', + }); + + const input = await mountInput({ + value: DateTime.fromFormat("09/01/1997", "dd/MM/yyyy"), + type: "date", + onChange: date => onChangeDate = date, + }); + + assert.strictEqual(input.value, "Jan/09/1997"); + + await click(input); + await click(getPickerCell("5").at(0)); + + assert.strictEqual(input.value, "Jan/05/1997"); + assert.strictEqual(onChangeDate.toFormat("dd/MM/yyyy"), "05/01/1997"); + }); }); diff --git a/addons/web/static/tests/core/l10n/dates_tests.js b/addons/web/static/tests/core/l10n/dates_tests.js index 539f50fbfd7..6e2d0b2aaa2 100644 --- a/addons/web/static/tests/core/l10n/dates_tests.js +++ b/addons/web/static/tests/core/l10n/dates_tests.js @@ -464,6 +464,21 @@ QUnit.module("utils", {}, () => { ); }); + QUnit.test("parseDate with textual month notation", async function (assert) { + Object.assign(localization, { + dateFormat: "MMM/dd/yyyy", + }); + assert.strictEqual(parseDate("Jan/05/1997").toISO(), "1997-01-05T00:00:00.000+01:00"); + assert.strictEqual( + parseDate("Jan/05/1997", { format: undefined }).toISO(), + "1997-01-05T00:00:00.000+01:00" + ); + assert.strictEqual( + parseDate("Jan/05/1997", { format: "MMM/dd/yyyy" }).toISO(), + "1997-01-05T00:00:00.000+01:00" + ); + }); + QUnit.test("parseDate (various entries)", async (assert) => { patchDate(2020, 6, 15, 12, 30, 0); patchTimeZone(0);