UNPKG

devextreme

Version:

JavaScript/TypeScript Component Suite for Responsive Web Development

1,048 lines (1,047 loc) • 144 kB
/** * DevExtreme (esm/__internal/scheduler/appointment_popup/appointment_popup.integration.test.js) * Version: 25.2.7 * Build date: Tue May 05 2026 * * Copyright (c) 2012 - 2026 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ import { afterEach, beforeEach, describe, expect, it, jest } from "@jest/globals"; import dateLocalization from "../../../common/core/localization/date"; import { CustomStore } from "../../../common/data/custom_store"; import $ from "../../../core/renderer"; import { loadMessages, locale } from "../../../localization"; import { toMilliseconds } from "../../utils/toMilliseconds"; import fx from "../../../common/core/animation/fx"; import { createScheduler } from "../__tests__/__mock__/create_scheduler"; import { setupSchedulerTestEnvironment } from "../__tests__/__mock__/m_mock_scheduler"; import { DEFAULT_SCHEDULER_OPTIONS } from "../utils/options/constants"; const CLASSES = { icon: "dx-scheduler-form-icon", hidden: "dx-hidden", scheduler: "dx-scheduler", mainGroupHidden: "dx-scheduler-form-main-group-hidden", recurrenceGroupHidden: "dx-scheduler-form-recurrence-group-hidden" }; const recurringAppointment = { text: "recurring-app", startDate: new Date(2017, 4, 1, 9, 30), endDate: new Date(2017, 4, 1, 11), recurrenceRule: "FREQ=DAILY;COUNT=5" }; const commonAppointment = { text: "common-app", startDate: new Date(2017, 4, 9, 9, 30), endDate: new Date(2017, 4, 9, 11) }; const disabledAppointment = { text: "disabled-app", startDate: new Date(2017, 4, 22, 9, 30), endDate: new Date(2017, 4, 22, 11, 30), disabled: true }; const allDayAppointment = { text: "all-day-app", startDate: new Date(2017, 4, 1), endDate: new Date(2017, 4, 1), allDay: true }; const getDefaultConfig = () => ({ dataSource: [], views: ["month"], currentView: "month", currentDate: new Date(2017, 4, 25), firstDayOfWeek: 1, startDayHour: 9, height: 600, width: 600 }); describe("Appointment Form", () => { beforeEach(() => { fx.off = true; setupSchedulerTestEnvironment({ height: 600 }) }); afterEach(() => { const $scheduler = $(document.querySelector(`.${CLASSES.scheduler}`)); $scheduler.dxScheduler("dispose"); document.body.innerHTML = ""; fx.off = false; jest.useRealTimers() }); describe("Changes saving/canceling", () => { it("should update appointment on save button click", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { dataSource: [Object.assign({}, commonAppointment)] })); const dataSource = scheduler.getDataSource(); const item = dataSource.items()[0]; scheduler.showAppointmentPopup(item); POM.popup.setInputValue("subjectEditor", "New Subject"); POM.popup.saveButton.click(); expect(dataSource.items()[0]).toMatchObject(Object.assign({}, commonAppointment, { text: "New Subject" })) }); it("should not update appointment on cancel button click", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { dataSource: [Object.assign({}, commonAppointment)] })); const dataSource = scheduler.getDataSource(); const item = dataSource.items()[0]; scheduler.showAppointmentPopup(item); POM.popup.setInputValue("subjectEditor", "New Subject"); POM.popup.cancelButton.click(); expect(dataSource.items()[0]).toMatchObject(commonAppointment) }); it("should update recurring appointment on save button click in recurrence form", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { dataSource: [Object.assign({}, recurringAppointment)] })); const dataSource = scheduler.getDataSource(); const item = dataSource.items()[0]; scheduler.showAppointmentPopup(item); POM.popup.editSeriesButton.click(); POM.popup.setInputValue("subjectEditor", "New Subject"); POM.popup.recurrenceSettingsButton.click(); POM.popup.saveButton.click(); expect(dataSource.items()[0]).toMatchObject(Object.assign({}, recurringAppointment, { text: "New Subject" })) }); it("should not update recurring appointment on cancel button click in recurrence form", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { dataSource: [Object.assign({}, recurringAppointment)] })); const dataSource = scheduler.getDataSource(); const item = dataSource.items()[0]; scheduler.showAppointmentPopup(item); POM.popup.editSeriesButton.click(); POM.popup.setInputValue("subjectEditor", "New Subject"); POM.popup.recurrenceSettingsButton.click(); POM.popup.cancelButton.click(); expect(dataSource.items()[0]).toMatchObject(recurringAppointment) }); it("should update appointment recurrence rule changes on save button click", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { dataSource: [Object.assign({}, commonAppointment)] })); const dataSource = scheduler.getDataSource(); const item = dataSource.items()[0]; scheduler.showAppointmentPopup(item); POM.popup.selectRepeatValue("daily"); POM.popup.saveButton.click(); expect(dataSource.items()[0]).toMatchObject(Object.assign({}, commonAppointment, { recurrenceRule: "FREQ=DAILY" })) }); it("should not update appointment recurrence rule changes on cancel button click", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { dataSource: [Object.assign({}, commonAppointment)] })); const dataSource = scheduler.getDataSource(); const item = dataSource.items()[0]; scheduler.showAppointmentPopup(item); POM.popup.selectRepeatValue("daily"); POM.popup.cancelButton.click(); expect(dataSource.items()[0]).toMatchObject(commonAppointment) }); it("should not update recurrence rule on save button click if recurrence rule was not changed", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { dataSource: [Object.assign({}, recurringAppointment)] })); const dataSource = scheduler.getDataSource(); const item = dataSource.items()[0]; scheduler.showAppointmentPopup(item); POM.popup.editSeriesButton.click(); POM.popup.saveButton.click(); expect(dataSource.items()[0]).toMatchObject(recurringAppointment) }); it("should update recurrence rule on save button click if repeat editor value was set to never", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { dataSource: [Object.assign({}, recurringAppointment)] })); const dataSource = scheduler.getDataSource(); const item = dataSource.items()[0]; scheduler.showAppointmentPopup(item); POM.popup.editSeriesButton.click(); POM.popup.selectRepeatValue("never"); POM.popup.saveButton.click(); expect(dataSource.items()[0]).toMatchObject(Object.assign({}, recurringAppointment, { recurrenceRule: "" })) }); it("should update appointment when data source is a custom store", async () => { const appointment = Object.assign({}, commonAppointment, { id: 0 }); const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { dataSource: { store: { type: "array", key: "id", data: [appointment] } } })); scheduler.showAppointmentPopup(appointment); POM.popup.setInputValue("subjectEditor", "Updated subject"); scheduler.hideAppointmentPopup(true); const items = scheduler.getDataSource().items(); expect(items).toHaveLength(1); expect(items[0]).toMatchObject(Object.assign({}, appointment, { text: "Updated subject" })) }); it("should create appointment when data source is a custom store", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { dataSource: { store: { type: "array", key: "id", data: [] } } })); scheduler.showAppointmentPopup(); POM.popup.setInputValue("subjectEditor", "New subject"); POM.popup.setInputValue("startDateEditor", new Date(2017, 4, 25, 9, 0)); POM.popup.setInputValue("startTimeEditor", new Date(2017, 4, 25, 9, 0)); POM.popup.setInputValue("endDateEditor", new Date(2017, 4, 25, 10, 0)); POM.popup.setInputValue("endTimeEditor", new Date(2017, 4, 25, 10, 0)); POM.popup.setInputValue("descriptionEditor", "New appointment description"); scheduler.hideAppointmentPopup(true); const items = scheduler.getDataSource().items(); expect(items).toHaveLength(1); expect(items[0]).toMatchObject({ text: "New subject", startDate: new Date(2017, 4, 25, 9, 0), endDate: new Date(2017, 4, 25, 10, 0), description: "New appointment description" }) }); it("should update resource value on save button click", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { dataSource: [{ text: "Resource test app", startDate: new Date(2017, 4, 9, 9, 30), endDate: new Date(2017, 4, 9, 11), roomId: 1 }], resources: [{ fieldExpr: "roomId", dataSource: [{ text: "Room 1", id: 1, color: "#00af2c" }, { text: "Room 2", id: 2, color: "#56ca85" }, { text: "Room 3", id: 3, color: "#8ecd3c" }] }] })); const dataSource = scheduler.getDataSource(); const item = dataSource.items()[0]; scheduler.showAppointmentPopup(item); POM.popup.setInputValue("roomId", 2); POM.popup.saveButton.click(); expect(dataSource.items()[0].roomId).toBe(2) }); it("should create separate appointment when saving single appointment from series", async () => { const appointment = { text: "recurring-app", startDate: "2017-05-01T09:30:00.000Z", endDate: "2017-05-01T11:00:00.000Z", recurrenceRule: "FREQ=DAILY;COUNT=5" }; const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { dataSource: [Object.assign({}, appointment)] })); const dataSource = scheduler.getDataSource(); POM.openPopupByDblClick("recurring-app"); POM.popup.editAppointmentButton.click(); POM.popup.setInputValue("subjectEditor", "single appointment"); scheduler.hideAppointmentPopup(true); expect(dataSource.items()).toHaveLength(2); expect(dataSource.items()[0]).toEqual(Object.assign({}, appointment, { recurrenceException: "20170501T093000Z" })); expect(dataSource.items()[1]).toEqual(Object.assign({}, appointment, { text: "single appointment", recurrenceRule: "", allDay: false })) }) }); describe("Validation", () => { it.each(["startDateEditor", "startTimeEditor", "endDateEditor", "endTimeEditor"])("should not close popup on save button click when %s is empty", async editorName => { const { scheduler: scheduler, POM: POM } = await createScheduler(getDefaultConfig()); scheduler.showAppointmentPopup(Object.assign({}, commonAppointment)); POM.popup.setInputValue(editorName, null); POM.popup.saveButton.click(); expect(POM.isPopupVisible()).toBe(true) }); it.each(["startTimeEditor", "endDateEditor", "endTimeEditor"])("should not close popup on save button click in recurrence form when %s editor is empty", async editorName => { const { scheduler: scheduler, POM: POM } = await createScheduler(getDefaultConfig()); scheduler.showAppointmentPopup(Object.assign({}, commonAppointment)); POM.popup.setInputValue(editorName, null); POM.popup.selectRepeatValue("daily"); POM.popup.saveButton.click(); expect(POM.isPopupVisible()).toBe(true) }); it("should close popup on save button click in recurrence form when startEditor editor is empty", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(getDefaultConfig()); scheduler.showAppointmentPopup(Object.assign({}, commonAppointment)); POM.popup.setInputValue("startDateEditor", null); POM.popup.selectRepeatValue("daily"); expect(POM.popup.getInputValue("recurrenceStartDateEditor")).toBe("5/9/2017"); POM.popup.saveButton.click(); expect(POM.isPopupVisible()).toBe(false) }) }); describe("State", () => { it("should create a new form instance on each popup opening", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(getDefaultConfig()); scheduler.showAppointmentPopup(commonAppointment); const firstFormInstance = POM.popup.dxForm; POM.popup.cancelButton.click(); scheduler.showAppointmentPopup(commonAppointment); const secondFormInstance = POM.popup.dxForm; expect(secondFormInstance).not.toBe(firstFormInstance) }); it("should have correct editor values when opening for empty date cell - 1", async () => { const { POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { currentView: "week" })); POM.dblClickDateTableCell(0, 0); expect(POM.popup.getInputValue("subjectEditor")).toBe(""); expect(POM.popup.getInputValue("startDateEditor")).toBe("5/22/2017"); expect(POM.popup.getInputValue("startTimeEditor")).toBe("9:00 AM"); expect(POM.popup.getInputValue("endDateEditor")).toBe("5/22/2017"); expect(POM.popup.getInputValue("endTimeEditor")).toBe("9:30 AM"); expect(POM.popup.getInputValue("allDayEditor")).toBe("false"); expect(POM.popup.getInputValue("descriptionEditor")).toBe("") }); it("should have correct editor values when opening for empty date cell - 2", async () => { const { POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { currentView: "week" })); POM.dblClickDateTableCell(1, 1); expect(POM.popup.getInputValue("subjectEditor")).toBe(""); expect(POM.popup.getInputValue("startDateEditor")).toBe("5/23/2017"); expect(POM.popup.getInputValue("startTimeEditor")).toBe("9:30 AM"); expect(POM.popup.getInputValue("endDateEditor")).toBe("5/23/2017"); expect(POM.popup.getInputValue("endTimeEditor")).toBe("10:00 AM"); expect(POM.popup.getInputValue("allDayEditor")).toBe("false"); expect(POM.popup.getInputValue("descriptionEditor")).toBe("") }); it("should have correct editor values when opening for empty all day cell", async () => { const { POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { currentView: "week" })); POM.dblClickAllDayTableCell(1); expect(POM.popup.getInputValue("subjectEditor")).toBe(""); expect(POM.popup.getInputValue("startDateEditor")).toBe("5/23/2017"); expect(POM.popup.isInputVisible("startTimeEditor")).toBe(false); expect(POM.popup.getInputValue("endDateEditor")).toBe("5/23/2017"); expect(POM.popup.isInputVisible("endTimeEditor")).toBe(false); expect(POM.popup.getInputValue("allDayEditor")).toBe("true"); expect(POM.popup.getInputValue("descriptionEditor")).toBe("") }) }); describe("Readonly state", () => { it("form should be readonly when editing.allowUpdating is false", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { editing: { allowUpdating: false } })); scheduler.showAppointmentPopup(Object.assign({}, commonAppointment)); expect(POM.popup.dxForm.option("readOnly")).toBe(true) }); it("form should not be readonly when editing.allowUpdating is false and adding a new appointment", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { editing: { allowUpdating: false, allowAdding: true } })); scheduler.showAppointmentPopup(Object.assign({}, commonAppointment), true); expect(POM.popup.dxForm.option("readOnly")).toBe(false) }); it("form should be readonly after adding new appointment if editing.allowUpdating is false", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { editing: { allowUpdating: false, allowAdding: true } })); const dataSource = scheduler.getDataSource(); scheduler.showAppointmentPopup(Object.assign({}, commonAppointment), true); scheduler.hideAppointmentPopup(true); const item = dataSource.items()[0]; scheduler.showAppointmentPopup(item); expect(POM.popup.dxForm.option("readOnly")).toBe(true) }); it("form should be readonly when appointment is disabled", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { dataSource: [Object.assign({}, disabledAppointment)] })); const dataSource = scheduler.getDataSource(); const item = dataSource.items()[0]; scheduler.showAppointmentPopup(item); expect(POM.popup.dxForm.option("readOnly")).toBe(true) }) }); describe("startDate/endDate editors behavior", () => { it.each([ ["startDateEditor", "startTimeEditor"], ["endDateEditor", "endTimeEditor"], ["startTimeEditor", "startDateEditor"], ["endTimeEditor", "endDateEditor"] ])("when %s value is set to null, %s value should not be null", async (dateEditorName, timeEditorName) => { const { scheduler: scheduler, POM: POM } = await createScheduler(getDefaultConfig()); scheduler.showAppointmentPopup(Object.assign({}, commonAppointment)); POM.popup.setInputValue(dateEditorName, null); expect(POM.popup.getInputValue(timeEditorName)).not.toBeNull() }); it("should update endDate when startDate is changed to a value greater than endDate", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(getDefaultConfig()); scheduler.showAppointmentPopup({ text: "test app", startDate: new Date(2017, 4, 9, 9, 30), endDate: new Date(2017, 4, 9, 11) }); POM.popup.setInputValue("startDateEditor", new Date(2017, 4, 10)); expect(POM.popup.getInputValue("startTimeEditor")).toEqual("9:30 AM"); expect(POM.popup.getInputValue("endDateEditor")).toEqual("5/10/2017"); expect(POM.popup.getInputValue("endTimeEditor")).toEqual("11:00 AM") }); it("should update endDate when startTime is changed to a value greater than endDate time", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(getDefaultConfig()); scheduler.showAppointmentPopup({ text: "test app", startDate: new Date(2017, 4, 9, 9, 30), endDate: new Date(2017, 4, 9, 11) }); POM.popup.setInputValue("startTimeEditor", new Date(2017, 4, 9, 12)); expect(POM.popup.getInputValue("startDateEditor")).toEqual("5/9/2017"); expect(POM.popup.getInputValue("endDateEditor")).toEqual("5/9/2017"); expect(POM.popup.getInputValue("endTimeEditor")).toEqual("1:30 PM") }); it("should update startDate when endDate is changed to a value less than startDate", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(getDefaultConfig()); scheduler.showAppointmentPopup({ text: "test app", startDate: new Date(2017, 4, 9, 9, 30), endDate: new Date(2017, 4, 9, 11) }); POM.popup.setInputValue("endDateEditor", new Date(2017, 4, 8)); expect(POM.popup.getInputValue("startDateEditor")).toEqual("5/8/2017"); expect(POM.popup.getInputValue("startTimeEditor")).toEqual("9:30 AM"); expect(POM.popup.getInputValue("endTimeEditor")).toEqual("11:00 AM") }); it("should update startDate when endTime is changed to a value less than startDate time", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(getDefaultConfig()); scheduler.showAppointmentPopup({ text: "test app", startDate: new Date(2017, 4, 9, 9, 30), endDate: new Date(2017, 4, 9, 11) }); POM.popup.setInputValue("endTimeEditor", new Date(2017, 4, 9, 9, 0)); expect(POM.popup.getInputValue("startDateEditor")).toEqual("5/9/2017"); expect(POM.popup.getInputValue("startTimeEditor")).toEqual("7:30 AM"); expect(POM.popup.getInputValue("endDateEditor")).toEqual("5/9/2017") }); it("should not update endDate when startDate is changed to a value less than endDate", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(getDefaultConfig()); scheduler.showAppointmentPopup({ text: "test app", startDate: new Date(2017, 4, 9, 9, 30), endDate: new Date(2017, 4, 9, 11) }); POM.popup.setInputValue("startDateEditor", new Date(2017, 4, 8)); expect(POM.popup.getInputValue("startTimeEditor")).toEqual("9:30 AM"); expect(POM.popup.getInputValue("endDateEditor")).toEqual("5/9/2017"); expect(POM.popup.getInputValue("endTimeEditor")).toEqual("11:00 AM") }); it("should not update endDate when startTime is changed to a value less than endDate time", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(getDefaultConfig()); scheduler.showAppointmentPopup({ text: "test app", startDate: new Date(2017, 4, 9, 9, 30), endDate: new Date(2017, 4, 9, 11) }); POM.popup.setInputValue("startTimeEditor", new Date(2017, 4, 9, 10, 0)); expect(POM.popup.getInputValue("startDateEditor")).toEqual("5/9/2017"); expect(POM.popup.getInputValue("endDateEditor")).toEqual("5/9/2017"); expect(POM.popup.getInputValue("endTimeEditor")).toEqual("11:00 AM") }); it("should not update startDate when endDate is changed to a value greater than startDate", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(getDefaultConfig()); scheduler.showAppointmentPopup({ text: "test app", startDate: new Date(2017, 4, 9, 9, 30), endDate: new Date(2017, 4, 9, 11) }); POM.popup.setInputValue("endDateEditor", new Date(2017, 4, 10)); expect(POM.popup.getInputValue("startDateEditor")).toEqual("5/9/2017"); expect(POM.popup.getInputValue("startTimeEditor")).toEqual("9:30 AM"); expect(POM.popup.getInputValue("endTimeEditor")).toEqual("11:00 AM") }); it("should not update startDate when endTime is changed to a value greater than startDate time", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(getDefaultConfig()); scheduler.showAppointmentPopup({ text: "test app", startDate: new Date(2017, 4, 9, 9, 30), endDate: new Date(2017, 4, 9, 11) }); POM.popup.setInputValue("endTimeEditor", new Date(2017, 4, 9, 12)); expect(POM.popup.getInputValue("startDateEditor")).toEqual("5/9/2017"); expect(POM.popup.getInputValue("startTimeEditor")).toEqual("9:30 AM"); expect(POM.popup.getInputValue("endDateEditor")).toEqual("5/9/2017") }) }); describe.each([ ["Field expressions", "customField"], ["Nested field expressions", "nested.customField"] ])("%s", exprValue => { it.each([ ["textExpr", "subjectEditor", "qwerty"], ["allDayExpr", "allDayEditor", true], ["startDateTimeZoneExpr", "startDateTimeZoneEditor", "Pacific/Midway"], ["endDateTimeZoneExpr", "endDateTimeZoneEditor", "Pacific/Midway"], ["descriptionExpr", "descriptionEditor", "qwerty"] ])("should update correct field if %s is defined", async (fieldExpr, editorName, value) => { const defaultField = DEFAULT_SCHEDULER_OPTIONS[fieldExpr]; const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { editing: { allowUpdating: true, allowTimeZoneEditing: true }, [fieldExpr]: exprValue })); scheduler.showAppointmentPopup(); POM.popup.setInputValue(editorName, value); scheduler.hideAppointmentPopup(true); const customFieldValue = scheduler.option(`dataSource[0].${exprValue}`); const defaultFieldValue = scheduler.option(`dataSource[0].${defaultField}`); expect(customFieldValue).toBe(value); expect(defaultFieldValue).toBeUndefined() }); it.each([ ["startDateExpr", "startDateEditor", "startTimeEditor"], ["endDateExpr", "endDateEditor", "endTimeEditor"] ])("should update correct field if %s is defined", async (fieldExpr, dateEditorName, timeEditorName) => { const value = new Date(2017, 4, 9, 9, 30); const defaultField = DEFAULT_SCHEDULER_OPTIONS[fieldExpr]; const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { editing: { allowUpdating: true, allowTimeZoneEditing: true }, [fieldExpr]: exprValue })); scheduler.showAppointmentPopup(); POM.popup.setInputValue(dateEditorName, value); POM.popup.setInputValue(timeEditorName, value); scheduler.hideAppointmentPopup(true); const customFieldValue = scheduler.option(`dataSource[0].${exprValue}`); const defaultFieldValue = scheduler.option(`dataSource[0].${defaultField}`); expect(customFieldValue).toEqual(new Date(value)); expect(defaultFieldValue).toBeUndefined() }); it("should update correct field if recurrenceRuleExpr is defined", async () => { const fieldExpr = "recurrenceRuleExpr"; const defaultField = DEFAULT_SCHEDULER_OPTIONS.recurrenceRuleExpr; const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { editing: { allowUpdating: true, allowTimeZoneEditing: true }, [fieldExpr]: exprValue })); scheduler.showAppointmentPopup(); POM.popup.selectRepeatValue("daily"); scheduler.hideAppointmentPopup(true); const customFieldValue = scheduler.option(`dataSource[0].${exprValue}`); const defaultFieldValue = scheduler.option(`dataSource[0].${defaultField}`); expect(customFieldValue).toBe("FREQ=DAILY"); expect(defaultFieldValue).toBeUndefined() }); it("should update correct resource field if fieldExpr for resource is defined", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { editing: { allowUpdating: true, allowTimeZoneEditing: true }, resources: [{ fieldExpr: exprValue, allowMultiple: false, dataSource: [{ text: "Room 1", id: 1, color: "#00af2c" }, { text: "Room 2", id: 2, color: "#56ca85" }, { text: "Room 3", id: 3, color: "#8ecd3c" }] }] })); scheduler.showAppointmentPopup(); POM.popup.setInputValue(exprValue, 2); scheduler.hideAppointmentPopup(true); const customFieldValue = scheduler.option(`dataSource[0].${exprValue}`); const defaultFieldValue = scheduler.option("dataSource[0].roomId"); expect(customFieldValue).toBe(2); expect(defaultFieldValue).toBeUndefined() }) }); describe("allDay switch", () => { it("should be turned on when opening allDay appointment", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(getDefaultConfig()); scheduler.showAppointmentPopup(allDayAppointment); expect(POM.popup.getInputValue("allDayEditor")).toBe("true") }); it("should be turned off when opening non-allDay appointment", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(getDefaultConfig()); scheduler.showAppointmentPopup(commonAppointment); expect(POM.popup.getInputValue("allDayEditor")).toBe("false") }); it("should hide time editors when switched on", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(getDefaultConfig()); scheduler.showAppointmentPopup(commonAppointment); expect(POM.popup.isInputVisible("startDateEditor")).toBeTruthy(); expect(POM.popup.isInputVisible("startTimeEditor")).toBeTruthy(); expect(POM.popup.isInputVisible("endDateEditor")).toBeTruthy(); expect(POM.popup.isInputVisible("endTimeEditor")).toBeTruthy(); POM.popup.getInput("allDayEditor").click(); expect(POM.popup.isInputVisible("startDateEditor")).toBeTruthy(); expect(POM.popup.isInputVisible("startTimeEditor")).toBeFalsy(); expect(POM.popup.isInputVisible("endDateEditor")).toBeTruthy(); expect(POM.popup.isInputVisible("endTimeEditor")).toBeFalsy() }); it("should show time editors when switched off", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(getDefaultConfig()); scheduler.showAppointmentPopup(allDayAppointment); expect(POM.popup.isInputVisible("startDateEditor")).toBeTruthy(); expect(POM.popup.isInputVisible("startTimeEditor")).toBeFalsy(); expect(POM.popup.isInputVisible("endDateEditor")).toBeTruthy(); expect(POM.popup.isInputVisible("endTimeEditor")).toBeFalsy(); POM.popup.getInput("allDayEditor").click(); expect(POM.popup.isInputVisible("startDateEditor")).toBeTruthy(); expect(POM.popup.isInputVisible("startTimeEditor")).toBeTruthy(); expect(POM.popup.isInputVisible("endDateEditor")).toBeTruthy(); expect(POM.popup.isInputVisible("endTimeEditor")).toBeTruthy() }); it("should set correct dates when switching on then off in day view", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { currentView: "day" })); scheduler.showAppointmentPopup(commonAppointment); POM.popup.getInput("allDayEditor").click(); POM.popup.getInput("allDayEditor").click(); expect(POM.popup.getInputValue("startDateEditor")).toBe("5/9/2017"); expect(POM.popup.getInputValue("startTimeEditor")).toBe("9:00 AM"); expect(POM.popup.getInputValue("endDateEditor")).toBe("5/9/2017"); expect(POM.popup.getInputValue("endTimeEditor")).toBe("9:30 AM") }); it("should set correct dates when switching off then on in day view", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { currentView: "day" })); scheduler.showAppointmentPopup(allDayAppointment); POM.popup.getInput("allDayEditor").click(); POM.popup.getInput("allDayEditor").click(); expect(POM.popup.getInputValue("startDateEditor")).toBe("5/1/2017"); expect(POM.popup.isInputVisible("startTimeEditor")).toBeFalsy(); expect(POM.popup.getInputValue("endDateEditor")).toBe("5/1/2017"); expect(POM.popup.isInputVisible("endTimeEditor")).toBeFalsy() }); it("should set correct dates when switching on then off in month view", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { currentView: "month" })); scheduler.showAppointmentPopup(commonAppointment); POM.popup.getInput("allDayEditor").click(); POM.popup.getInput("allDayEditor").click(); expect(POM.popup.getInputValue("startDateEditor")).toBe("5/9/2017"); expect(POM.popup.getInputValue("startTimeEditor")).toBe("9:00 AM"); expect(POM.popup.getInputValue("endDateEditor")).toBe("5/10/2017"); expect(POM.popup.getInputValue("endTimeEditor")).toBe("12:00 AM") }); it("should set correct dates when switching off then on in month view", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { currentView: "month" })); scheduler.showAppointmentPopup(allDayAppointment); POM.popup.getInput("allDayEditor").click(); POM.popup.getInput("allDayEditor").click(); expect(POM.popup.getInputValue("startDateEditor")).toBe("5/1/2017"); expect(POM.popup.isInputVisible("startTimeEditor")).toBeFalsy(); expect(POM.popup.getInputValue("endDateEditor")).toBe("5/1/2017"); expect(POM.popup.isInputVisible("endTimeEditor")).toBeFalsy() }) }); describe("Timezone Editors", () => { it("should have correct timezone editors values", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { editing: { allowUpdating: true, allowTimeZoneEditing: true } })); scheduler.showAppointmentPopup({ text: "Watercolor Landscape", startDate: new Date("2020-06-01T17:30:00.000Z"), endDate: new Date("2020-06-01T19:00:00.000Z"), startDateTimeZone: "Etc/GMT+10", endDateTimeZone: "US/Alaska" }); expect(POM.popup.getInputValue("startDateTimeZoneEditor")).toBe("Etc/GMT+10"); expect(POM.popup.getInputValue("endDateTimeZoneEditor")).toBe("US/Alaska") }); it("should be shown when editing.allowTimeZoneEditing is true", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { editing: { allowTimeZoneEditing: true } })); scheduler.showAppointmentPopup(commonAppointment); expect(POM.popup.isInputVisible("startDateTimeZoneEditor")).toBeTruthy(); expect(POM.popup.isInputVisible("endDateTimeZoneEditor")).toBeTruthy() }); it("should be hidden when editing.allowTimeZoneEditing is false", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { editing: { allowTimeZoneEditing: false } })); scheduler.showAppointmentPopup(commonAppointment); expect(POM.popup.isInputVisible("startDateTimeZoneEditor")).toBeFalsy(); expect(POM.popup.isInputVisible("endDateTimeZoneEditor")).toBeFalsy() }); it("change of startTimeZone value should trigger endTimeZone value change", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { editing: { allowTimeZoneEditing: true } })); scheduler.showAppointmentPopup(commonAppointment); POM.popup.setInputValue("startDateTimeZoneEditor", "America/Los_Angeles"); expect(POM.popup.getInputValue("startDateTimeZoneEditor")).toBe("America/Los_Angeles"); expect(POM.popup.getInputValue("endDateTimeZoneEditor")).toBe("America/Los_Angeles") }); it("change of endTimeZone value should not trigger startTimeZone value change", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { editing: { allowTimeZoneEditing: true } })); scheduler.showAppointmentPopup(commonAppointment); POM.popup.setInputValue("startDateTimeZoneEditor", "America/Los_Angeles"); POM.popup.setInputValue("endDateTimeZoneEditor", "America/New_York"); expect(POM.popup.getInputValue("startDateTimeZoneEditor")).toBe("America/Los_Angeles"); expect(POM.popup.getInputValue("endDateTimeZoneEditor")).toBe("America/New_York") }) }); describe("Resources", () => { it("should have correct resource editor value", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { dataSource: [{ text: "Resource test app", startDate: new Date(2017, 4, 9, 9, 30), endDate: new Date(2017, 4, 9, 11), roomId: 2 }], resources: [{ fieldExpr: "roomId", dataSource: [{ text: "Room 1", id: 1, color: "#00af2c" }, { text: "Room 2", id: 2, color: "#56ca85" }, { text: "Room 3", id: 3, color: "#8ecd3c" }] }] })); const dataSource = scheduler.getDataSource(); const item = dataSource.items()[0]; scheduler.showAppointmentPopup(item); expect(POM.popup.getInputValue("roomId")).toBe("Room 2") }); it("should create resourceEditorsGroup when resources have no custom icons", async () => { var _resourcesGroup$items; const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { resources: [{ fieldExpr: "roomId" }, { fieldExpr: "ownerId" }] })); scheduler.showAppointmentPopup(); const resourcesGroup = POM.popup.dxForm.itemOption("mainGroup.resourcesGroup"); expect(resourcesGroup).toBeDefined(); expect(null === resourcesGroup || void 0 === resourcesGroup || null === (_resourcesGroup$items = resourcesGroup.items) || void 0 === _resourcesGroup$items ? void 0 : _resourcesGroup$items.length).toBe(2); expect(null === resourcesGroup || void 0 === resourcesGroup ? void 0 : resourcesGroup.items).toEqual(expect.arrayContaining([expect.objectContaining({ name: "resourcesGroupIcon" }), expect.objectContaining({ name: "resourceEditorsGroup", itemType: "group", items: expect.arrayContaining([expect.objectContaining({ name: "roomIdEditor" }), expect.objectContaining({ name: "ownerIdEditor" })]) })])) }); it("should create individual resource groups when resources have custom icons", async () => { var _resourcesGroup$items2; const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { resources: [{ fieldExpr: "roomId", icon: "home" }, { fieldExpr: "ownerId", icon: "user" }] })); scheduler.showAppointmentPopup(); const resourcesGroup = POM.popup.dxForm.itemOption("mainGroup.resourcesGroup"); expect(resourcesGroup).toBeDefined(); expect(null === resourcesGroup || void 0 === resourcesGroup || null === (_resourcesGroup$items2 = resourcesGroup.items) || void 0 === _resourcesGroup$items2 ? void 0 : _resourcesGroup$items2.length).toBe(2); expect(null === resourcesGroup || void 0 === resourcesGroup ? void 0 : resourcesGroup.items).toEqual(expect.arrayContaining([expect.objectContaining({ name: "roomIdGroup", itemType: "group", items: expect.arrayContaining([expect.objectContaining({ name: "roomIdIcon" }), expect.objectContaining({ name: "roomIdEditor" })]) }), expect.objectContaining({ name: "ownerIdGroup", itemType: "group", items: expect.arrayContaining([expect.objectContaining({ name: "ownerIdIcon" }), expect.objectContaining({ name: "ownerIdEditor" })]) })])) }); it("should render FontAwesome icon with correct CSS classes (T1322161)", async () => { const { scheduler: scheduler, POM: POM } = await createScheduler(Object.assign({}, getDefaultConfig(), { dataSource: [{ text: "Resource test app", startDate: new Date(2017, 4, 9, 9, 30), endDate: new Date(2017, 4, 9, 11), roomId: 1 }], resources: [{ fieldExpr: "roomId", icon: "fas fa-home", dataSource: [{ text: "Room 1", id: 1 }, { text: "Room 2", id: 2 }] }] })); const dataSource = scheduler.getDataSource(); const appointment = dataSource.items()[0]; scheduler.showAppointmentPopup(appointment); const {