Skip to content

Commit 20a69e6

Browse files
committed
Add test
1 parent 765bf41 commit 20a69e6

File tree

3 files changed

+136
-0
lines changed

3 files changed

+136
-0
lines changed

packages/devextreme/js/__internal/grids/grid_core/__tests__/__mock__/model/cell/data_cell.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
import { TextBoxModel } from '@ts/ui/__tests__/__mock__/model/textbox';
2+
13
const SELECTORS = {
24
editCell: 'dx-editor-cell',
35
invalidCell: 'invalid',
6+
textBox: 'dx-textbox',
47
};
58

69
export class DataCellModel {
@@ -27,4 +30,9 @@ export class DataCellModel {
2730
public getHTML(): string {
2831
return this.root?.innerHTML ?? '';
2932
}
33+
34+
public getEditor(): TextBoxModel {
35+
const editorElement = this.root?.querySelector(`.${SELECTORS.textBox}`) as HTMLElement;
36+
return new TextBoxModel(editorElement);
37+
}
3038
}

packages/devextreme/js/__internal/grids/grid_core/__tests__/__mock__/model/grid_core.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const SELECTORS = {
2525
editForm: 'edit-form',
2626
headerCellIndicators: 'dx-column-indicators',
2727
headerCellFilter: 'dx-header-filter',
28+
revertButton: 'dx-revert-button',
2829
};
2930

3031
export abstract class GridCoreModel<TInstance extends GridBase = GridBase> {
@@ -101,6 +102,10 @@ export abstract class GridCoreModel<TInstance extends GridBase = GridBase> {
101102
return new ToastModel(this.getToastContainer());
102103
}
103104

105+
public getRevertButton(): HTMLElement {
106+
return document.body.querySelector(`.${SELECTORS.revertButton}`) as HTMLElement;
107+
}
108+
104109
public addWidgetPrefix(classNames: string): string {
105110
const componentName = this.NAME;
106111

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import {
2+
afterEach, beforeEach, describe, expect, it, jest,
3+
} from '@jest/globals';
4+
import type { dxElementWrapper } from '@js/core/renderer';
5+
import $ from '@js/core/renderer';
6+
import type { Properties as DataGridProperties } from '@js/ui/data_grid';
7+
import DataGrid from '@js/ui/data_grid';
8+
import errors from '@js/ui/widget/ui.errors';
9+
import { DataGridModel } from '@ts/grids/data_grid/__tests__/__mock__/model/data_grid';
10+
11+
const SELECTORS = {
12+
gridContainer: '#gridContainer',
13+
};
14+
15+
const GRID_CONTAINER_ID = 'gridContainer';
16+
17+
const createDataGrid = async (
18+
options: DataGridProperties = {},
19+
): Promise<{
20+
$container: dxElementWrapper;
21+
component: DataGridModel;
22+
instance: DataGrid;
23+
}> => new Promise((resolve) => {
24+
const $container = $('<div>')
25+
.attr('id', GRID_CONTAINER_ID)
26+
.appendTo(document.body);
27+
28+
const dataGridOptions: DataGridProperties = {
29+
keyExpr: 'id',
30+
...options,
31+
};
32+
33+
const instance = new DataGrid($container.get(0) as HTMLDivElement, dataGridOptions);
34+
const component = new DataGridModel($container.get(0) as HTMLElement);
35+
36+
jest.runAllTimers();
37+
38+
resolve({
39+
$container,
40+
component,
41+
instance,
42+
});
43+
});
44+
45+
const beforeTest = (): void => {
46+
jest.useFakeTimers();
47+
jest.spyOn(errors, 'log').mockImplementation(jest.fn());
48+
jest.spyOn(errors, 'Error').mockImplementation(() => ({}));
49+
};
50+
51+
const afterTest = (): void => {
52+
const $container = $(SELECTORS.gridContainer);
53+
const dataGrid = ($container as any).dxDataGrid('instance') as DataGrid;
54+
55+
dataGrid.dispose();
56+
$container.remove();
57+
jest.clearAllMocks();
58+
jest.useRealTimers();
59+
};
60+
61+
describe('Bugs', () => {
62+
beforeEach(beforeTest);
63+
afterEach(afterTest);
64+
65+
describe('T1308327 - DataGrid - Cell value is not restored after canceling changes in cell editing mode if repaintChangesOnly is enabled', () => {
66+
it('should restore cell value after canceling changes with validation error', async () => {
67+
const data = [
68+
{ id: 1, name: 'Job 1', article: 'Article A' },
69+
{ id: 2, name: 'Job 2', article: 'Article B' },
70+
];
71+
72+
const { instance, component } = await createDataGrid({
73+
dataSource: data,
74+
keyExpr: 'id',
75+
repaintChangesOnly: true,
76+
editing: {
77+
mode: 'cell',
78+
allowUpdating: true,
79+
},
80+
columns: [
81+
{
82+
dataField: 'name',
83+
showEditorAlways: true,
84+
validationRules: [
85+
{ type: 'required', message: 'Required field' },
86+
],
87+
},
88+
{
89+
dataField: 'article',
90+
},
91+
],
92+
});
93+
94+
const firstCell = component.getDataCell(0, 0);
95+
const firstEditor = firstCell.getEditor();
96+
97+
firstEditor.setValue('');
98+
jest.runAllTimers();
99+
100+
expect(component.getDataCell(0, 0).isValidCell).toBe(false);
101+
102+
component.getRevertButton().click();
103+
jest.runAllTimers();
104+
105+
expect(instance.cellValue(0, 'name')).toBe('Job 1');
106+
expect(component.getDataCell(0, 0).isValidCell).toBe(true);
107+
108+
const secondCell = component.getDataCell(1, 0);
109+
const secondEditor = secondCell.getEditor();
110+
111+
secondEditor.setValue('');
112+
jest.runAllTimers();
113+
114+
expect(component.getDataCell(1, 0).isValidCell).toBe(false);
115+
116+
component.getRevertButton().click();
117+
jest.runAllTimers();
118+
119+
expect(instance.cellValue(1, 'name')).toBe('Job 2');
120+
expect(component.getDataCell(1, 0).isValidCell).toBe(true);
121+
});
122+
});
123+
});

0 commit comments

Comments
 (0)