/** @odoo-module **/ import { makeFakeLocalizationService } from "@web/../tests/helpers/mock_services"; import { click, clickCreate, clickDiscard, clickSave, editInput, getFixture, patchDate, patchTimeZone, patchWithCleanup, triggerEvent, triggerEvents, triggerScroll, } from "@web/../tests/helpers/utils"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; import { strftimeToLuxonFormat } from "@web/core/l10n/dates"; import { registry } from "@web/core/registry"; let serverData; let target; QUnit.module("Fields", (hooks) => { hooks.beforeEach(() => { target = getFixture(); serverData = { models: { partner: { fields: { date: { string: "A date", type: "date", searchable: true }, datetime: { string: "A datetime", type: "datetime", searchable: true }, display_name: { string: "Displayed name", type: "char", searchable: true }, foo: { string: "Foo", type: "char", default: "My little Foo Value", searchable: true, trim: true, }, }, records: [ { id: 1, date: "2017-02-03", datetime: "2017-02-08 10:00:00", display_name: "first record", foo: "yop", }, { id: 2, display_name: "second record", foo: "blip", }, { id: 4, display_name: "aaa", foo: "abc", }, { id: 3, foo: "gnap" }, { id: 5, foo: "blop" }, ], }, }, }; setupViewRegistries(); }); QUnit.module("DateField"); QUnit.test("DateField: toggle datepicker", async function (assert) { await makeView({ type: "form", resModel: "partner", serverData, arch: `
`, }); assert.containsNone( document.body, ".bootstrap-datetimepicker-widget", "datepicker should be closed initially" ); await click(target, ".o_datepicker .o_datepicker_input"); assert.containsOnce( document.body, ".bootstrap-datetimepicker-widget", "datepicker should be opened" ); // focus another field await click(target, ".o_field_widget[name='foo'] input"); assert.containsNone( document.body, ".bootstrap-datetimepicker-widget", "datepicker should close itself when the user clicks outside" ); }); QUnit.test("DateField: toggle datepicker far in the future", async function (assert) { serverData.models.partner.records = [ { id: 1, date: "9999-12-30", foo: "yop", }, ]; await makeView({ type: "form", resModel: "partner", resId: 1, serverData, arch: `
`, }); assert.containsNone( document.body, ".bootstrap-datetimepicker-widget", "datepicker should be closed initially" ); await click(target, ".o_datepicker .o_datepicker_input"); assert.containsOnce( document.body, ".bootstrap-datetimepicker-widget", "datepicker should be opened" ); // focus another field await click(target, ".o_field_widget[name='foo'] input"); assert.containsNone( document.body, ".bootstrap-datetimepicker-widget", "datepicker should close itself when the user clicks outside" ); }); QUnit.test("date field is empty if no date is set", async function (assert) { await makeView({ type: "form", resModel: "partner", resId: 4, serverData, arch: '
', }); assert.containsOnce( target, ".o_field_widget .o_datepicker_input", "should have one input in the form view" ); assert.strictEqual( target.querySelector(".o_field_widget input").value, "", "and it should be empty" ); }); QUnit.test( "DateField: set an invalid date when the field is already set", async function (assert) { await makeView({ type: "form", resModel: "partner", resId: 1, serverData, arch: '
', }); const input = target.querySelector(".o_field_widget[name='date'] input"); assert.strictEqual(input.value, "02/03/2017"); input.value = "mmmh"; await triggerEvent(input, null, "change"); assert.strictEqual(input.value, "02/03/2017", "should have reset the original value"); } ); QUnit.test( "DateField: set an invalid date when the field is not set yet", async function (assert) { await makeView({ type: "form", resModel: "partner", resId: 4, serverData, arch: '
', }); const input = target.querySelector(".o_field_widget[name='date'] input"); assert.strictEqual(input.value, ""); input.value = "mmmh"; await triggerEvent(input, null, "change"); assert.strictEqual(input.value, "", "The date field should be empty"); } ); QUnit.test("DateField value should not set on first click", async function (assert) { await makeView({ type: "form", resModel: "partner", resId: 4, serverData, arch: '
', }); await click(target, ".o_datepicker .o_datepicker_input"); // open datepicker and select a date assert.strictEqual( target.querySelector(".o_field_widget[name='date'] input").value, "", "date field's input should be empty on first click" ); await click(document.body, ".day[data-day*='/22/']"); // re-open datepicker await click(target, ".o_datepicker .o_datepicker_input"); assert.strictEqual( document.body.querySelector(".day.active").textContent, "22", "datepicker should be highlight with 22nd day of month" ); }); QUnit.test("DateField in form view (with positive time zone offset)", async function (assert) { assert.expect(7); patchTimeZone(120); // Should be ignored by date fields await makeView({ type: "form", resModel: "partner", resId: 1, serverData, arch: '
', mockRPC(route, { args }) { if (route === "/web/dataset/call_kw/partner/write") { assert.strictEqual( args[1].date, "2017-02-22", "the correct value should be saved" ); } }, }); assert.strictEqual( target.querySelector(".o_datepicker_input").value, "02/03/2017", "the date should be correct in edit mode" ); // open datepicker and select another value await click(target, ".o_datepicker_input"); assert.containsOnce( document.body, ".bootstrap-datetimepicker-widget", "datepicker should be opened" ); assert.containsOnce( document.body, ".day.active[data-day='02/03/2017']", "datepicker should be highlight February 3" ); await click( document.body.querySelectorAll(".bootstrap-datetimepicker-widget .picker-switch")[0] ); await click( document.body.querySelectorAll(".bootstrap-datetimepicker-widget .picker-switch")[1] ); await click(document.body.querySelectorAll(".bootstrap-datetimepicker-widget .year")[8]); await click(document.body.querySelectorAll(".bootstrap-datetimepicker-widget .month")[1]); await click(document.body.querySelector(".day[data-day*='/22/']")); assert.containsNone( document.body, ".bootstrap-datetimepicker-widget", "datepicker should be closed" ); assert.strictEqual( target.querySelector(".o_datepicker_input").value, "02/22/2017", "the selected date should be displayed in the input" ); // save await clickSave(target); assert.strictEqual( target.querySelector(".o_field_date input").value, "02/22/2017", "the selected date should be displayed after saving" ); }); QUnit.test("DateField in form view (with negative time zone offset)", async function (assert) { patchTimeZone(-120); // Should be ignored by date fields await makeView({ type: "form", resModel: "partner", resId: 1, serverData, arch: '
', }); assert.strictEqual( target.querySelector(".o_datepicker_input").value, "02/03/2017", "the date should be correct in edit mode" ); }); QUnit.test("DateField dropdown disappears on scroll", async function (assert) { await makeView({ type: "form", resModel: "partner", resId: 1, serverData, arch: `
`, }); await click(target, ".o_datepicker .o_datepicker_input"); assert.containsOnce( document.body, ".bootstrap-datetimepicker-widget", "datepicker should be opened" ); await triggerScroll(target, { top: 50 }); assert.containsNone( document.body, ".bootstrap-datetimepicker-widget", "datepicker should be closed" ); }); QUnit.test("DateField with label opens datepicker on click", async function (assert) { await makeView({ type: "form", resModel: "partner", resId: 1, serverData, arch: `