Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.

Commit 9dc1abe

Browse files
committed
feat(tests): add more Single & MultipleSelectEditor unit tests
1 parent c65c781 commit 9dc1abe

File tree

6 files changed

+574
-138
lines changed

6 files changed

+574
-138
lines changed

src/app/examples/grid-editor.component.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -180,33 +180,36 @@ export class GridEditorComponent implements OnInit {
180180
}, {
181181
id: 'duration',
182182
name: 'Duration (days)',
183-
field: 'duration',
183+
field: 'task.duration',
184184
minWidth: 100,
185185
filterable: true,
186186
sortable: true,
187+
formatter: Formatters.complexObject,
187188
type: FieldType.number,
189+
exportWithFormatter: true,
188190
filter: { model: Filters.slider, params: { hideSliderNumber: false } },
191+
/*
189192
editor: {
190193
model: Editors.slider,
191194
minValue: 0,
192195
maxValue: 100,
193196
// params: { hideSliderNumber: true },
194197
},
195-
/*
198+
*/
196199
editor: {
197200
// default is 0 decimals, if no decimals is passed it will accept 0 or more decimals
198201
// however if you pass the "decimalPlaces", it will validate with that maximum
199202
alwaysSaveOnEnterKey: true, // defaults to False, when set to true and user presses ENTER it will always call a Save even if value is empty
200203
model: Editors.float,
201204
placeholder: 'enter number',
202-
title: 'Your number must be bigger than 5', title: 'show a custom title', // add a custom title, to see it as a real tooltip you'll need to implement something like tipsy jquery lib
205+
title: 'Your number must be bigger than 5', // add a custom title, to see it as a real tooltip you'll need to implement something like tipsy jquery lib
203206
minValue: 5,
204207
maxValue: 365,
205208
// the default validation error message is in English but you can override it by using "errorMessage"
206209
// errorMessage: this.i18n.tr('INVALID_FLOAT', { maxDecimal: 2 }),
207210
params: { decimalPlaces: 2 },
208211
},
209-
*/
212+
210213
}, {
211214
id: 'complete',
212215
name: '% Complete',
@@ -247,11 +250,14 @@ export class GridEditorComponent implements OnInit {
247250
}, {
248251
id: 'start',
249252
name: 'Start',
250-
field: 'start',
253+
field: 'task.start',
251254
minWidth: 100,
252255
filterable: true,
253256
filter: { model: Filters.compoundDate },
254-
formatter: Formatters.dateIso,
257+
formatter: Formatters.multiple,
258+
params: {
259+
formatters: [Formatters.complexObject, Formatters.dateIso,]
260+
},
255261
exportWithFormatter: true,
256262
sortable: true,
257263
type: FieldType.date,
@@ -383,6 +389,7 @@ export class GridEditorComponent implements OnInit {
383389
sortable: true,
384390
type: FieldType.string,
385391
editor: {
392+
placeholder: 'choose option',
386393
collectionAsync: this.http.get<{ value: string; label: string; }[]>(URL_SAMPLE_COLLECTION_DATA),
387394
// OR a regular collection load
388395
// collection: Array.from(Array(100).keys()).map(k => ({ value: k, prefix: 'Task', label: k })),
@@ -530,10 +537,12 @@ export class GridEditorComponent implements OnInit {
530537
tempDataset.push({
531538
id: i,
532539
title: 'Task ' + i,
533-
duration: (i % 33 === 0) ? null : Math.round(Math.random() * 100) + '',
540+
task: {
541+
duration: (i % 33 === 0) ? null : Math.round(Math.random() * 100) + '',
542+
start: new Date(randomYear, randomMonth, randomDay),
543+
},
534544
percentComplete: randomPercent,
535545
percentCompleteNumber: randomPercent,
536-
start: new Date(randomYear, randomMonth, randomDay),
537546
finish: randomFinish < new Date() ? '' : randomFinish, // make sure the random date is earlier than today
538547
effortDriven: (i % 5 === 0),
539548
prerequisites: (i % 2 === 0) && i !== 0 && i < 12 ? [i, i - 1] : [],
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
// import 3rd party lib multiple-select for the tests
2+
import '../../../../../assets/lib/multiple-select/multiple-select';
3+
4+
import { TestBed } from '@angular/core/testing';
5+
import { TranslateService, TranslateModule } from '@ngx-translate/core';
6+
import { Editors } from '../index';
7+
import { MultipleSelectEditor } from '../multipleSelectEditor';
8+
import { CollectionService } from '../../services/collection.service';
9+
import { AutocompleteOption, Column, EditorArgs, EditorArguments, GridOption, KeyCode } from '../../models';
10+
11+
const KEY_CHAR_A = 97;
12+
const containerId = 'demo-container';
13+
14+
// define a <div> container to simulate the grid container
15+
const template = `<div id="${containerId}"></div>`;
16+
17+
const dataViewStub = {
18+
refresh: jest.fn(),
19+
};
20+
21+
const gridOptionMock = {
22+
autoCommitEdit: false,
23+
editable: true,
24+
i18n: null,
25+
} as GridOption;
26+
27+
const getEditorLockMock = {
28+
commitCurrentEdit: jest.fn(),
29+
};
30+
31+
const gridStub = {
32+
getOptions: () => gridOptionMock,
33+
getColumns: jest.fn(),
34+
getEditorLock: () => getEditorLockMock,
35+
getHeaderRowColumn: jest.fn(),
36+
navigateNext: jest.fn(),
37+
navigatePrev: jest.fn(),
38+
render: jest.fn(),
39+
};
40+
41+
describe('SelectEditor', () => {
42+
let divContainer: HTMLDivElement;
43+
let editor: MultipleSelectEditor;
44+
let editorArguments: EditorArguments;
45+
let mockColumn: Column;
46+
let mockItemData: any;
47+
let translate: TranslateService;
48+
49+
beforeEach(() => {
50+
divContainer = document.createElement('div');
51+
divContainer.innerHTML = template;
52+
document.body.appendChild(divContainer);
53+
54+
TestBed.configureTestingModule({
55+
providers: [],
56+
imports: [TranslateModule.forRoot()]
57+
});
58+
translate = TestBed.get(TranslateService);
59+
60+
translate.setTranslation('en', {
61+
CANCEL: 'Cancel',
62+
SAVE: 'Save',
63+
});
64+
translate.setTranslation('fr', {
65+
CANCEL: 'Annuler',
66+
SAVE: 'Sauvegarder',
67+
});
68+
translate.setDefaultLang('fr');
69+
70+
mockColumn = { id: 'gender', field: 'gender', editable: true, editor: { model: Editors.multipleSelect }, internalColumnEditor: {} } as Column;
71+
72+
editorArguments = {
73+
grid: gridStub,
74+
column: mockColumn,
75+
item: mockItemData,
76+
event: null,
77+
cancelChanges: jest.fn(),
78+
commitChanges: jest.fn(),
79+
container: divContainer,
80+
columnMetaData: null,
81+
dataView: dataViewStub,
82+
gridPosition: { top: 0, left: 0, bottom: 10, right: 10, height: 100, width: 100, visible: true },
83+
position: { top: 0, left: 0, bottom: 10, right: 10, height: 100, width: 100, visible: true },
84+
};
85+
});
86+
87+
describe('with valid Editor instance', () => {
88+
beforeEach(() => {
89+
mockItemData = { id: 1, gender: 'male', isActive: true };
90+
mockColumn = { id: 'gender', field: 'gender', editable: true, editor: { model: Editors.multipleSelect }, internalColumnEditor: {} } as Column;
91+
mockColumn.internalColumnEditor.collection = [{ value: 'male', label: 'male' }, { value: 'female', label: 'female' }];
92+
93+
editorArguments.column = mockColumn;
94+
editorArguments.item = mockItemData;
95+
});
96+
97+
afterEach(() => {
98+
editor.destroy();
99+
});
100+
101+
it('should initialize the editor', (done) => {
102+
mockColumn.internalColumnEditor.collection = [{ value: 'male', label: 'male' }, { value: 'female', label: 'female' }];
103+
gridOptionMock.i18n = translate;
104+
editor = new MultipleSelectEditor(editorArguments);
105+
const editorCount = document.body.querySelectorAll('select.ms-filter.editor-gender').length;
106+
const spy = jest.spyOn(editor, 'show');
107+
108+
setTimeout(() => {
109+
expect(spy).toHaveBeenCalled();
110+
expect(editorCount).toBe(1);
111+
done();
112+
});
113+
});
114+
115+
it('should call "setValue" with a single string and expect the string to be returned as an array when calling "getValue"', () => {
116+
editor = new MultipleSelectEditor(editorArguments);
117+
editor.setValue(['male']);
118+
119+
expect(editor.getValue()).toEqual(['male']);
120+
});
121+
122+
it('should hide the DOM element div wrapper when the "hide" method is called', () => {
123+
editor = new MultipleSelectEditor(editorArguments);
124+
const editorElm = document.body.querySelector<HTMLDivElement>('[name=editor-gender].ms-drop');
125+
126+
editor.show();
127+
expect(editorElm.style.display).toBe('');
128+
129+
editor.hide();
130+
expect(editorElm.style.display).toBe('none');
131+
});
132+
133+
it('should show the DOM element div wrapper when the "show" method is called', () => {
134+
editor = new MultipleSelectEditor(editorArguments);
135+
const editorElm = document.body.querySelector<HTMLDivElement>('[name=editor-gender].ms-drop');
136+
137+
editor.hide();
138+
expect(editorElm.style.display).toBe('none');
139+
140+
editor.show();
141+
expect(editorElm.style.display).toBe('');
142+
});
143+
});
144+
});

0 commit comments

Comments
 (0)