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

Commit 45348a0

Browse files
Ghislain BeaulacGhislain Beaulac
authored andcommitted
feat(filter): add CompoundDate Filter unit tests
1 parent c1588e7 commit 45348a0

File tree

4 files changed

+382
-55
lines changed

4 files changed

+382
-55
lines changed
Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
2+
import { TestBed } from '@angular/core/testing';
3+
import { TranslateService, TranslateModule } from '@ngx-translate/core';
4+
import { Column, FilterArguments, GridOption, FieldType } from '../../models';
5+
import { Filters } from '..';
6+
import { CompoundDateFilter } from '../compoundDateFilter';
7+
8+
const containerId = 'demo-container';
9+
10+
// define a <div> container to simulate the grid container
11+
const template = `<div id="${containerId}"></div>`;
12+
13+
const gridOptionMock = {
14+
enableFiltering: true,
15+
enableFilterTrimWhiteSpace: true,
16+
} as GridOption;
17+
18+
const gridStub = {
19+
getOptions: () => gridOptionMock,
20+
getColumns: jest.fn(),
21+
getHeaderRowColumn: jest.fn(),
22+
render: jest.fn(),
23+
};
24+
25+
describe('CompoundDateFilter', () => {
26+
let divContainer: HTMLDivElement;
27+
let filter: CompoundDateFilter;
28+
let filterArguments: FilterArguments;
29+
let spyGetHeaderRow;
30+
let mockColumn: Column;
31+
let translate: TranslateService;
32+
33+
beforeEach(() => {
34+
divContainer = document.createElement('div');
35+
divContainer.innerHTML = template;
36+
document.body.appendChild(divContainer);
37+
spyGetHeaderRow = jest.spyOn(gridStub, 'getHeaderRowColumn').mockReturnValue(divContainer);
38+
39+
mockColumn = { id: 'finish', field: 'finish', filterable: true, outputType: FieldType.dateIso, filter: { model: Filters.compoundDate, operator: '>' } };
40+
filterArguments = {
41+
grid: gridStub,
42+
columnDef: mockColumn,
43+
callback: jest.fn()
44+
};
45+
46+
TestBed.configureTestingModule({
47+
providers: [],
48+
imports: [TranslateModule.forRoot()]
49+
});
50+
translate = TestBed.get(TranslateService);
51+
52+
translate.setTranslation('en', {
53+
CONTAINS: 'Contains',
54+
EQUALS: 'Equals',
55+
ENDS_WITH: 'Ends With',
56+
STARTS_WITH: 'Starts With',
57+
});
58+
translate.setTranslation('fr', {
59+
CONTAINS: 'Contient',
60+
EQUALS: 'Égale',
61+
ENDS_WITH: 'Se termine par',
62+
STARTS_WITH: 'Commence par',
63+
});
64+
translate.setDefaultLang('en');
65+
66+
filter = new CompoundDateFilter(translate);
67+
});
68+
69+
afterEach(() => {
70+
filter.destroy();
71+
});
72+
73+
it('should throw an error when trying to call init without any arguments', () => {
74+
expect(() => filter.init(null)).toThrowError('[Angular-SlickGrid] A filter must always have an "init()" with valid arguments.');
75+
});
76+
77+
it('should initialize the filter', () => {
78+
filter.init(filterArguments);
79+
const filterCount = divContainer.querySelectorAll('.form-group.search-filter.filter-finish').length;
80+
81+
expect(spyGetHeaderRow).toHaveBeenCalled();
82+
expect(filterCount).toBe(1);
83+
});
84+
85+
it('should have a placeholder when defined in its column definition', () => {
86+
const testValue = 'test placeholder';
87+
mockColumn.filter.placeholder = testValue;
88+
89+
filter.init(filterArguments);
90+
const filterElm = divContainer.querySelector<HTMLInputElement>('.search-filter.filter-finish .flatpickr input.flatpickr');
91+
92+
expect(filterElm.placeholder).toBe(testValue);
93+
});
94+
95+
it('should be able to retrieve default flatpickr options through the Getter', () => {
96+
filter.init(filterArguments);
97+
98+
expect(filter.flatInstance).toBeTruthy();
99+
expect(filter.flatpickrOptions).toEqual({
100+
altFormat: 'Y-m-d',
101+
altInput: true,
102+
closeOnSelect: true,
103+
dateFormat: 'Y-m-d',
104+
defaultDate: '',
105+
locale: 'en',
106+
onChange: expect.anything(),
107+
wrap: true,
108+
});
109+
});
110+
111+
it('should be able to call "setValues" and have that value set in the picker', () => {
112+
const mockDate = '2001-01-02T16:02:02.239Z';
113+
filter.init(filterArguments);
114+
filter.setValues(mockDate);
115+
expect(filter.currentDate).toEqual(mockDate);
116+
});
117+
118+
it('should be able to call "setValues" as an array and have that value set in the picker', () => {
119+
const mockDate = '2001-01-02T16:02:02.239Z';
120+
filter.init(filterArguments);
121+
filter.setValues([mockDate]);
122+
expect(filter.currentDate).toEqual(mockDate);
123+
});
124+
125+
it('should trigger input change event and expect the callback to be called with the date provided in the input', () => {
126+
mockColumn.filter.filterOptions = { allowInput: true }; // change to allow input value only for testing purposes
127+
mockColumn.filter.operator = '>';
128+
const spyCallback = jest.spyOn(filterArguments, 'callback');
129+
130+
filter.init(filterArguments);
131+
const filterInputElm = divContainer.querySelector<HTMLInputElement>('.search-filter.filter-finish .flatpickr input.flatpickr');
132+
filterInputElm.value = '2001-01-02T16:02:02.239Z';
133+
filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { keyCode: 13, bubbles: true, cancelable: true }));
134+
const filterFilledElms = divContainer.querySelectorAll<HTMLInputElement>('.form-group.search-filter.filter-finish.filled');
135+
136+
expect(filterFilledElms.length).toBe(1);
137+
expect(spyCallback).toHaveBeenCalledWith(undefined, {
138+
columnDef: mockColumn, operator: '>', searchTerms: ['2001-01-02'], shouldTriggerQuery: true
139+
});
140+
});
141+
142+
it('should pass a different operator then trigger an input change event and expect the callback to be called with the date provided in the input', () => {
143+
mockColumn.filter.filterOptions = { allowInput: true }; // change to allow input value only for testing purposes
144+
mockColumn.filter.operator = '>';
145+
const spyCallback = jest.spyOn(filterArguments, 'callback');
146+
147+
filter.init(filterArguments);
148+
const filterInputElm = divContainer.querySelector<HTMLInputElement>('.search-filter.filter-finish .flatpickr input.flatpickr');
149+
filterInputElm.value = '2001-01-02T16:02:02.239Z';
150+
filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { keyCode: 13, bubbles: true, cancelable: true }));
151+
const filterFilledElms = divContainer.querySelectorAll<HTMLInputElement>('.form-group.search-filter.filter-finish.filled');
152+
153+
expect(filterFilledElms.length).toBe(1);
154+
expect(spyCallback).toHaveBeenCalledWith(undefined, { columnDef: mockColumn, operator: '>', searchTerms: ['2001-01-02'], shouldTriggerQuery: true });
155+
});
156+
157+
it('should create the input filter with a default search term when passed as a filter argument', () => {
158+
filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z'];
159+
mockColumn.filter.operator = '<=';
160+
const spyCallback = jest.spyOn(filterArguments, 'callback');
161+
162+
filter.init(filterArguments);
163+
const filterInputElm = divContainer.querySelector<HTMLInputElement>('.search-filter.filter-finish .flatpickr input.flatpickr');
164+
165+
filterInputElm.focus();
166+
filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keyup', { keyCode: 97, bubbles: true, cancelable: true }));
167+
const filterFilledElms = divContainer.querySelectorAll<HTMLInputElement>('.form-group.search-filter.filter-finish.filled');
168+
169+
expect(filterFilledElms.length).toBe(1);
170+
expect(filter.currentDate).toBe('2000-01-01T05:00:00.000Z');
171+
expect(filterInputElm.value).toBe('2000-01-01');
172+
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '<=', searchTerms: ['2000-01-01T05:00:00.000Z'], shouldTriggerQuery: true });
173+
});
174+
175+
it('should trigger an operator change event and expect the callback to be called with the searchTerms and operator defined', () => {
176+
filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z'];
177+
mockColumn.filter.operator = '>';
178+
const spyCallback = jest.spyOn(filterArguments, 'callback');
179+
180+
filter.init(filterArguments);
181+
const filterSelectElm = divContainer.querySelector<HTMLInputElement>('.search-filter.filter-finish select');
182+
183+
filterSelectElm.value = '<=';
184+
filterSelectElm.dispatchEvent(new Event('change'));
185+
const filterFilledElms = divContainer.querySelectorAll<HTMLInputElement>('.form-group.search-filter.filter-finish.filled');
186+
187+
expect(filterFilledElms.length).toBe(1);
188+
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '<=', searchTerms: ['2000-01-01T05:00:00.000Z'], shouldTriggerQuery: true });
189+
});
190+
191+
it('should work with different locale when locale is changed', () => {
192+
translate.use('fr-CA');
193+
filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z'];
194+
mockColumn.filter.operator = '<=';
195+
const spyCallback = jest.spyOn(filterArguments, 'callback');
196+
197+
filter.init(filterArguments);
198+
const filterInputElm = divContainer.querySelector<HTMLInputElement>('.search-filter.filter-finish .flatpickr input.flatpickr');
199+
200+
filterInputElm.focus();
201+
filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keyup', { keyCode: 97, bubbles: true, cancelable: true }));
202+
const filterFilledElms = divContainer.querySelectorAll<HTMLInputElement>('.form-group.search-filter.filter-finish.filled');
203+
204+
expect(filterFilledElms.length).toBe(1);
205+
expect(filter.currentDate).toBe('2000-01-01T05:00:00.000Z');
206+
expect(filterInputElm.value).toBe('2000-01-01');
207+
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '<=', searchTerms: ['2000-01-01T05:00:00.000Z'], shouldTriggerQuery: true });
208+
});
209+
210+
it('should trigger a callback with the clear filter set when calling the "clear" method', () => {
211+
filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z'];
212+
const spyCallback = jest.spyOn(filterArguments, 'callback');
213+
214+
filter.init(filterArguments);
215+
filter.clear();
216+
const filterInputElm = divContainer.querySelector<HTMLInputElement>('.search-filter.filter-finish .flatpickr input.flatpickr');
217+
const filterFilledElms = divContainer.querySelectorAll<HTMLInputElement>('.form-group.search-filter.filter-finish.filled');
218+
219+
expect(filterInputElm.value).toBe('');
220+
expect(filterFilledElms.length).toBe(0);
221+
expect(spyCallback).toHaveBeenCalledWith(undefined, { columnDef: mockColumn, clearFilterTriggered: true, shouldTriggerQuery: true });
222+
});
223+
224+
it('should trigger a callback with the clear filter but without querying when when calling the "clear" method with False as argument', () => {
225+
filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z'];
226+
const spyCallback = jest.spyOn(filterArguments, 'callback');
227+
228+
filter.init(filterArguments);
229+
filter.clear(false);
230+
const filterInputElm = divContainer.querySelector<HTMLInputElement>('.search-filter.filter-finish .flatpickr input.flatpickr');
231+
const filterFilledElms = divContainer.querySelectorAll<HTMLInputElement>('.form-group.search-filter.filter-finish.filled');
232+
233+
expect(filterInputElm.value).toBe('');
234+
expect(filterFilledElms.length).toBe(0);
235+
expect(spyCallback).toHaveBeenCalledWith(undefined, { columnDef: mockColumn, clearFilterTriggered: true, shouldTriggerQuery: false });
236+
});
237+
238+
it('should have a value with date & time in the picker when "enableTime" option is set and we trigger a change', () => {
239+
mockColumn.filter.filterOptions = { enableTime: true, allowInput: true }; // change to allow input value only for testing purposes
240+
mockColumn.outputType = FieldType.dateTimeIsoAmPm;
241+
mockColumn.filter.operator = '>';
242+
const spyCallback = jest.spyOn(filterArguments, 'callback');
243+
244+
filter.init(filterArguments);
245+
const filterInputElm = divContainer.querySelector<HTMLInputElement>('.search-filter.filter-finish .flatpickr input.flatpickr');
246+
filterInputElm.value = '2001-01-02T16:02:02.000Z';
247+
filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { keyCode: 13, bubbles: true, cancelable: true }));
248+
const filterFilledElms = divContainer.querySelectorAll<HTMLInputElement>('.form-group.search-filter.filter-finish.filled');
249+
250+
expect(filterFilledElms.length).toBe(1);
251+
expect(filter.currentDate.toISOString()).toBe('2001-01-02T16:02:02.000Z');
252+
expect(filterInputElm.value).toBe('2001-01-02 11:02:02 AM');
253+
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), {
254+
columnDef: mockColumn, operator: '>', searchTerms: ['2001-01-02'], shouldTriggerQuery: true
255+
});
256+
});
257+
258+
it('should have a value with date & time in the picker when using no "outputType" which will default to UTC date', () => {
259+
mockColumn.outputType = null;
260+
filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z'];
261+
mockColumn.filter.operator = '<=';
262+
const spyCallback = jest.spyOn(filterArguments, 'callback');
263+
264+
filter.init(filterArguments);
265+
const filterInputElm = divContainer.querySelector<HTMLInputElement>('.search-filter.filter-finish .flatpickr input.flatpickr');
266+
267+
filterInputElm.focus();
268+
filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keyup', { keyCode: 97, bubbles: true, cancelable: true }));
269+
const filterFilledElms = divContainer.querySelectorAll<HTMLInputElement>('.form-group.search-filter.filter-finish.filled');
270+
271+
expect(filterFilledElms.length).toBe(1);
272+
expect(filter.currentDate).toBe('2000-01-01T05:00:00.000Z');
273+
expect(filterInputElm.value).toBe('2000-01-01T05:00:00.000Z');
274+
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '<=', searchTerms: ['2000-01-01T05:00:00.000Z'], shouldTriggerQuery: true });
275+
});
276+
});

src/app/modules/angular-slickgrid/filters/__tests__/dateRangeFilter.spec.ts

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
import { TestBed } from '@angular/core/testing';
33
import { TranslateService, TranslateModule } from '@ngx-translate/core';
4-
import { Column, FilterArguments, GridOption } from '../../models';
4+
import { Column, FilterArguments, GridOption, FieldType } from '../../models';
55
import { Filters } from '..';
66
import { DateRangeFilter } from '../dateRangeFilter';
77

@@ -141,7 +141,7 @@ describe('DateRangeFilter', () => {
141141
});
142142

143143
it('should pass a different operator then trigger an input change event and expect the callback to be called with the date provided in the input', () => {
144-
mockColumn.filter.filterOptions = { allowInput: true }; // change to allow input value only for testing purposes
144+
mockColumn.filter.filterOptions = { allowInput: true, enableTime: false }; // change to allow input value only for testing purposes
145145
mockColumn.filter.operator = 'RangeExclusive';
146146
const spyCallback = jest.spyOn(filterArguments, 'callback');
147147

@@ -235,4 +235,43 @@ describe('DateRangeFilter', () => {
235235
expect(filterFilledElms.length).toBe(0);
236236
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, clearFilterTriggered: true, shouldTriggerQuery: false });
237237
});
238+
239+
it('should have a value with date & time in the picker when "enableTime" option is set and we trigger a change', () => {
240+
mockColumn.filter.filterOptions = { enableTime: true, allowInput: true }; // change to allow input value only for testing purposes
241+
mockColumn.outputType = FieldType.dateTimeIsoAmPm;
242+
mockColumn.filter.operator = '>';
243+
const spyCallback = jest.spyOn(filterArguments, 'callback');
244+
245+
filter.init(filterArguments);
246+
const filterInputElm = divContainer.querySelector<HTMLInputElement>('input.flatpickr.search-filter.filter-finish');
247+
filterInputElm.value = '2000-01-01T05:00:00.000Z to 2000-01-31T05:00:00.000Z';
248+
filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { keyCode: 13, bubbles: true, cancelable: true }));
249+
const filterFilledElms = divContainer.querySelectorAll<HTMLInputElement>('.flatpickr.search-filter.filter-finish.filled');
250+
251+
expect(filterFilledElms.length).toBe(1);
252+
expect(filter.currentDates.map((date) => date.toISOString())).toEqual(['2000-01-01T05:00:00.000Z', '2000-01-31T05:00:00.000Z']);
253+
expect(filterInputElm.value).toBe('2000-01-01 12:00:00 AM to 2000-01-31 12:00:00 AM');
254+
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), {
255+
columnDef: mockColumn, operator: '>', searchTerms: ['2000-01-01 12:00:00 am', '2000-01-31 12:00:00 am'], shouldTriggerQuery: true
256+
});
257+
});
258+
259+
it('should have a value with date & time in the picker when using no "outputType" which will default to UTC date', () => {
260+
mockColumn.outputType = null;
261+
filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z', '2000-01-31T05:00:00.000Z'];
262+
mockColumn.filter.operator = '<=';
263+
const spyCallback = jest.spyOn(filterArguments, 'callback');
264+
265+
filter.init(filterArguments);
266+
const filterInputElm = divContainer.querySelector<HTMLInputElement>('input.flatpickr.search-filter.filter-finish');
267+
268+
filterInputElm.focus();
269+
filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keyup', { keyCode: 97, bubbles: true, cancelable: true }));
270+
const filterFilledElms = divContainer.querySelectorAll<HTMLInputElement>('.flatpickr.search-filter.filter-finish.filled');
271+
272+
expect(filterFilledElms.length).toBe(1);
273+
expect(filter.currentDates).toEqual(['2000-01-01T05:00:00.000Z', '2000-01-31T05:00:00.000Z']);
274+
expect(filterInputElm.value).toBe('2000-01-01T05:00:00.000Z to 2000-01-31T05:00:00.000Z');
275+
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '<=', searchTerms: ['2000-01-01', '2000-01-31'], shouldTriggerQuery: true });
276+
});
238277
});

0 commit comments

Comments
 (0)