UNPKG

devextreme

Version:

JavaScript/TypeScript Component Suite for Responsive Web Development

414 lines (413 loc) • 15.4 kB
/** * DevExtreme (esm/__internal/grids/new/grid_core/editing/options.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, describe, expect, it, jest } from "@jest/globals"; import $ from "../../../../../core/renderer"; import dxCalendar from "../../../../../ui/calendar"; import CardView from "../../../../grids/new/card_view/widget"; import { rerender } from "inferno"; import { getContext } from "../di.test_utils"; import { OptionsControllerMock } from "../options_controller/options_controller.mock"; import { ToolbarController } from "../toolbar/controller"; import { ConfirmController } from "./confirm_controller"; import { EditingController } from "./controller"; import { EditPopupView } from "./popup/view"; const SELECTORS = { cardView: ".dx-cardview", card: ".dx-cardview-card" }; class MockConfirmController { constructor() { this.confirm = jest.fn().mockImplementation(() => Promise.resolve(true)) } } MockConfirmController.dependencies = []; const rootQuerySelector = selector => document.body.querySelector(selector); const setupCardView = function() { let options = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}; const container = document.createElement("div"); const { body: body } = document; body.append(container); const cardView = new CardView(container, options); rerender(); return cardView }; const setup = config => { const rootElement = document.createElement("div"); const context = getContext(config); const mockConfirmController = new MockConfirmController; context.registerInstance(ConfirmController, mockConfirmController); const optionsController = context.get(OptionsControllerMock); const editingController = context.get(EditingController); const toolbarController = context.get(ToolbarController); const editPopupView = context.get(EditPopupView); editPopupView.render(rootElement); rerender(); return { optionsController: optionsController, editingController: editingController, editPopupView: editPopupView, rootElement: rootElement, toolbarController: toolbarController, context: context, getForm: () => { const form = editPopupView.formRef.current; if (!form) { throw new Error("form is not visible") } return form }, mockConfirmController: mockConfirmController } }; describe("ColumnProperties", () => { describe("allowEditing", () => { describe("when it is false", () => { it("should make editor disabled", () => { const { getForm: getForm } = setup({ dataSource: [{ field1: 1 }], keyExpr: "field1", editing: { editCardKey: 1 }, columns: [{ dataField: "field1", allowEditing: false }] }); expect(getForm().getEditor("field1").option("disabled")).toBe(true) }) }) }); describe("editorOptions", () => { it("should be passed to form item editorOptions", () => { const { getForm: getForm } = setup({ dataSource: [{ field1: 1 }], keyExpr: "field1", editing: { editCardKey: 1 }, columns: [{ dataField: "field1", editorOptions: { someEditOption: "someEditOptionValue" } }] }); expect(getForm().getEditor("field1").option("someEditOption")).toBe("someEditOptionValue") }) }); describe("setFieldValue", () => { it("should be used as callback for setting editor value", async () => { const setFieldValue = jest.fn((newData, value) => { newData.mycustomfield = value }); const { editPopupView: editPopupView, editingController: editingController, getForm: getForm } = setup({ columns: [{ dataField: "field1", setFieldValue: setFieldValue }, "id"], dataSource: [{ id: 1, field1: "value1" }], keyExpr: "id", editing: { editCardKey: 1 } }); getForm().getEditor("field1").option("value", "qwe"); await editPopupView.promises.waitForAll(); expect(setFieldValue.mock.calls[0]).toMatchSnapshot(); expect(editingController.changes.peek()).toMatchSnapshot() }) }); describe("formItem", () => { it("should be passed to form item", () => { const { getForm: getForm } = setup({ dataSource: [{ field1: 1 }], keyExpr: "field1", editing: { editCardKey: 1 }, columns: [{ dataField: "field1", formItem: { editorType: "dxCalendar" } }] }); expect(getForm().getEditor("field1")).toBeInstanceOf(dxCalendar) }) }); describe("validationRules", () => { it("should be passed to form item", async () => { const { getForm: getForm, editingController: editingController } = setup({ dataSource: [], keyExpr: "field1", columns: [{ dataField: "field1", validationRules: [{ type: "required" }] }] }); await editingController.addCard(); const validationResult = getForm().validate(); expect(validationResult.isValid).toBe(false) }) }) }); describe("Options", () => { describe("editing", () => { afterEach(() => { var _$; const cardView = rootQuerySelector(SELECTORS.cardView); null === (_$ = $(cardView ?? void 0)) || void 0 === _$ || _$.dxCardView("dispose") }); describe("editCardKey", () => { it("should open popup with given item", () => { const { getForm: getForm } = setup({ columns: [{ dataField: "field1" }, "id"], dataSource: [{ id: 1, field1: "value1" }], keyExpr: "id", editing: { editCardKey: 1 } }); expect(getForm().getEditor("field1").option("value")).toBe("value1"); expect(getForm().getEditor("id").option("value")).toBe(1) }) }); describe("allowAdding", () => { it('should add "add" button to toolbar', () => { const { toolbarController: toolbarController, optionsController: optionsController } = setup({}); expect(toolbarController.items.peek()).toEqual([]); optionsController.option("editing.allowAdding", "true"); expect(toolbarController.items.peek()).toMatchSnapshot() }) }); describe("allowUpdating", () => { it('should add "edit" button to card', () => { setupCardView({ columns: [{ dataField: "field1" }, "id"], dataSource: [{ id: 1, field1: "value1" }], keyExpr: "id", editing: { allowUpdating: true } }); rerender(); const card = rootQuerySelector(SELECTORS.card); expect(null === card || void 0 === card ? void 0 : card.innerHTML).toContain('aria-label="edit"') }) }); describe("allowRemoving", () => { it('should add "remove" button to card', () => { setupCardView({ columns: [{ dataField: "field1" }, "id"], dataSource: [{ id: 1, field1: "value1" }], keyExpr: "id", editing: { allowDeleting: true } }); rerender(); const card = rootQuerySelector(SELECTORS.card); expect(null === card || void 0 === card ? void 0 : card.innerHTML).toContain('aria-label="trash"') }) }); describe("changes", () => { const config = { dataSource: [{ key: 1, some_field: "asd" }], columns: ["some_field"], keyExpr: "key", editing: { editCardKey: 1 } }; it("should be empty initially", () => { const { editingController: editingController } = setup(config); expect(editingController.changes.peek()).toEqual([]) }); it("should contain unsaved changes", async () => { var _getForm$getEditor; const { editingController: editingController, editPopupView: editPopupView, getForm: getForm } = setup(config); null === (_getForm$getEditor = getForm().getEditor("some_field")) || void 0 === _getForm$getEditor || _getForm$getEditor.option("value", "qwe"); await editPopupView.promises.waitForAll(); expect(editingController.changes.peek()).toMatchSnapshot() }) }); describe("form", () => { it("should pass options to edit form", () => { const { getForm: getForm } = setup({ dataSource: [{ key: 1, some_field: "asd" }], columns: ["some_field"], keyExpr: "key", editing: { editCardKey: 1, form: { disabled: true } } }); expect(getForm().option("disabled")).toBe(true) }) }); describe("texts", () => { describe("confirmDeleteMessage", () => { it("should be used to show confirm delete dialog", async () => { const { editingController: editingController, mockConfirmController: mockConfirmController } = setup({ columns: [{ dataField: "field1" }, "id"], dataSource: [{ id: 1, field1: "value1" }], keyExpr: "id", editing: { texts: { confirmDeleteMessage: "my custom title" } } }); await editingController.deleteCard(1); expect(mockConfirmController.confirm.mock.calls[0][0]).toBe("my custom title") }) }); describe("confirmDeleteTitle", () => { it("should be used to show confirm delete dialog", async () => { const { editingController: editingController, mockConfirmController: mockConfirmController } = setup({ columns: [{ dataField: "field1" }, "id"], dataSource: [{ id: 1, field1: "value1" }], keyExpr: "id", editing: { texts: { confirmDeleteTitle: "my custom title" } } }); await editingController.deleteCard(1); expect(mockConfirmController.confirm.mock.calls[0][1]).toBe("my custom title") }); describe("when it is undefined", () => { it("should hide title", async () => { const { editingController: editingController, mockConfirmController: mockConfirmController } = setup({ columns: [{ dataField: "field1" }, "id"], dataSource: [{ id: 1, field1: "value1" }], keyExpr: "id", editing: { texts: { confirmDeleteTitle: void 0 } } }); await editingController.deleteCard(1); expect(mockConfirmController.confirm.mock.calls[0][1]).toBe(""); expect(mockConfirmController.confirm.mock.calls[0][2]).toBe(false) }) }) }) }) }) });