diff --git a/packages/devextreme/js/__internal/grids/grid_core/validating/__tests__/validating.integration.test.ts b/packages/devextreme/js/__internal/grids/grid_core/validating/__tests__/validating.integration.test.ts index c4200ccd0795..520abc074905 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/validating/__tests__/validating.integration.test.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/validating/__tests__/validating.integration.test.ts @@ -1,6 +1,7 @@ import { afterEach, beforeEach, describe, expect, it, jest, } from '@jest/globals'; +import type { CustomRule } from '@js/common'; import { afterTest, beforeTest, @@ -69,5 +70,95 @@ describe('DataGrid Cell Editing', () => { expect(instance.cellValue(1, 'name')).toBe('Job 2'); expect(component.getDataCell(1, 0).isValidCell).toBe(true); }); + + // T1323690 + it('should pass real row data to validationCallback after canceling changes (T1323690)', async () => { + const validationCallback = jest.fn>( + (e) => !e.value?.toString().includes('X'), + ); + const data = [ + { id: 1, name: 'Item 1', description: 'Desc A' }, + { id: 2, name: 'Item 2', description: 'Desc B' }, + ]; + + const { component } = await createDataGrid({ + dataSource: data, + keyExpr: 'id', + repaintChangesOnly: true, + editing: { + mode: 'cell', + allowUpdating: true, + }, + columns: [ + { + dataField: 'name', + showEditorAlways: true, + validationRules: [ + { + type: 'custom', + validationCallback, + }, + ], + }, + 'description', + ], + }); + + const firstEditor = component.getDataCell(0, 0).getEditor(); + firstEditor.setValue('Item 1X'); + jest.runAllTimers(); + + expect(validationCallback).toHaveBeenCalledTimes(1); + expect(component.getDataCell(0, 0).isValidCell).toBe(false); + + component.getRevertButton().click(); + jest.runAllTimers(); + + const secondCell = component.getDataCell(1, 0); + secondCell.getElement()?.click(); + jest.runAllTimers(); + + expect(validationCallback).toHaveBeenCalled(); + const lastCallData = validationCallback.mock.lastCall?.[0].data; + expect(lastCallData).toMatchObject(data[1]); + }); + + it('should pass edited data to validationCallback during active editing (T1323690)', async () => { + const validationCallback = jest.fn>(() => true); + const data = [ + { id: 1, name: 'Item 1', description: 'Desc A' }, + ]; + + const { component } = await createDataGrid({ + dataSource: data, + keyExpr: 'id', + repaintChangesOnly: true, + editing: { + mode: 'cell', + allowUpdating: true, + }, + columns: [ + { + dataField: 'name', + showEditorAlways: true, + validationRules: [ + { + type: 'custom', + validationCallback, + }, + ], + }, + 'description', + ], + }); + + const editor = component.getDataCell(0, 0).getEditor(); + editor.setValue('Changed'); + jest.runAllTimers(); + + expect(validationCallback).toHaveBeenCalled(); + const lastCallData = validationCallback.mock.lastCall?.[0].data; + expect(lastCallData).toMatchObject({ id: 1, name: 'Changed', description: 'Desc A' }); + }); }); }); diff --git a/packages/devextreme/js/__internal/grids/grid_core/validating/m_validating.ts b/packages/devextreme/js/__internal/grids/grid_core/validating/m_validating.ts index a8e5ac0d4485..f1ce44842731 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/validating/m_validating.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/validating/m_validating.ts @@ -503,7 +503,9 @@ export class ValidatingController extends modules.Controller { const change = editingController.getChangeByKey(key); const oldData = editingController._getOldData(key); return { - data: createObjectWithChanges(oldData, change?.data), + data: change + ? createObjectWithChanges(oldData, change.data) + : { ...(oldData ?? parameters.data) }, column, }; },