Skip to content

Commit f4cd533

Browse files
committed
Scheduler: refactor recurrence tests by jest
1 parent 0762dad commit f4cd533

File tree

10 files changed

+1640
-787
lines changed

10 files changed

+1640
-787
lines changed

packages/devextreme/js/__internal/scheduler/__tests__/__mock__/m_mock_scheduler.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { jest } from '@jest/globals';
2+
import { logger } from '@ts/core/utils/m_console';
23
import DOMComponent from '@ts/core/widget/dom_component';
34

45
import SchedulerWorkSpace from '../../workspaces/m_work_space';
@@ -16,6 +17,7 @@ export const setupSchedulerTestEnvironment = ({
1617
width = DEFAULT_CELL_WIDTH,
1718
height = DEFAULT_CELL_HEIGHT,
1819
}: SetupSchedulerTestEnvironmentOptions = {}): void => {
20+
jest.spyOn(logger, 'warn').mockImplementation(() => {});
1921
DOMComponent.prototype._isVisible = jest.fn((): boolean => true);
2022
SchedulerWorkSpace.prototype._createCrossScrollingConfig = (): {
2123
direction: string;
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
const EMPTY_POSITION = {
2+
top: 0, left: 0, width: 0, height: 0,
3+
};
4+
5+
type Position = typeof EMPTY_POSITION;
6+
export interface AppointmentModel<T = HTMLDivElement> {
7+
element: T;
8+
getText: () => string;
9+
getDisplayDate: () => string;
10+
getAriaLabel: () => string;
11+
getGeometry: () => Position;
12+
getColor: (view: string) => string | undefined;
13+
getSnapshot: () => object;
14+
}
15+
16+
const getColor = (appointment: HTMLDivElement): string => appointment.style.backgroundColor;
17+
const getAgendaColor = (appointment: HTMLDivElement): string => {
18+
const marker = appointment.querySelector('.dx-scheduler-agenda-appointment-marker') as HTMLDivElement;
19+
return getColor(marker);
20+
};
21+
const getText = (element: HTMLDivElement | null): string => element?.querySelector('.dx-scheduler-appointment-title')?.textContent ?? '';
22+
const getDisplayDate = (element: HTMLDivElement | null): string => element?.querySelector('.dx-scheduler-appointment-content-date')?.textContent ?? '';
23+
const getGeometry = (element: HTMLDivElement | null): Position => {
24+
if (!element) {
25+
return EMPTY_POSITION;
26+
}
27+
28+
const match = /translate\(([0-9.]*)px, ([0-9.]*)px\)/.exec(element.style.transform);
29+
if (!match) {
30+
return EMPTY_POSITION;
31+
}
32+
33+
return {
34+
top: parseInt(match[2], 10),
35+
left: parseInt(match[1], 10),
36+
width: parseInt(element.style.width, 10),
37+
height: parseInt(element.style.height, 10),
38+
};
39+
};
40+
41+
export const createAppointmentModel = <T extends HTMLDivElement | null>(
42+
element: T,
43+
): AppointmentModel<T> => ({
44+
element,
45+
getText: () => getText(element),
46+
getDisplayDate: () => getDisplayDate(element),
47+
getAriaLabel: () => element?.getAttribute('aria-label') ?? '',
48+
getGeometry: () => getGeometry(element),
49+
getColor(view: string): string | undefined {
50+
if (!element) {
51+
return undefined;
52+
}
53+
54+
return view === 'agenda'
55+
? getAgendaColor(element)
56+
: getColor(element);
57+
},
58+
getSnapshot: (): object => ({
59+
text: getText(element),
60+
date: getDisplayDate(element),
61+
...getGeometry(element),
62+
}),
63+
});

packages/devextreme/js/__internal/scheduler/__tests__/__mock__/model/scheduler.ts

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,27 @@
1-
const getAppointmentColor = (container: HTMLDivElement): string => {
2-
const appointment = container.querySelector('.dx-scheduler-appointment') as HTMLDivElement;
3-
return appointment.style.backgroundColor;
4-
};
5-
const getAgendaAppointmentColor = (container: HTMLDivElement): string => {
6-
const appointment = container.querySelector('.dx-scheduler-agenda-appointment-marker') as HTMLDivElement;
7-
return appointment.style.backgroundColor;
8-
};
1+
import type { AppointmentModel } from './appointment';
2+
import { createAppointmentModel } from './appointment';
3+
94
const getTexts = (
105
cells: NodeListOf<Element>,
116
): string[] => Array.from(cells).map((cell) => cell.textContent?.trim() ?? '');
127

138
export interface SchedulerModel {
14-
getAppointment: () => HTMLDivElement | null;
15-
getAppointments: () => NodeListOf<HTMLDivElement>;
16-
getAppointmentColor: (view: string) => string;
9+
getAppointment: () => AppointmentModel<HTMLDivElement | null>;
10+
getAppointments: () => AppointmentModel[];
1711
getDateTableContent: () => string[];
1812
getHeaderPanelContent: () => string[];
1913
getTimePanelContent: () => string[];
2014
getGroupTableContent: () => string[];
2115
}
2216

2317
export const createSchedulerModel = (container: HTMLDivElement): SchedulerModel => ({
24-
getAppointment(): HTMLDivElement | null {
25-
return container.querySelector('.dx-scheduler-appointment');
26-
},
27-
getAppointments(): NodeListOf<HTMLDivElement> {
28-
return container.querySelectorAll('.dx-scheduler-appointment');
18+
getAppointment(): AppointmentModel<HTMLDivElement | null> {
19+
return createAppointmentModel(container.querySelector('.dx-scheduler-appointment'));
2920
},
30-
getAppointmentColor(view: string): string {
31-
return view === 'agenda'
32-
? getAgendaAppointmentColor(container)
33-
: getAppointmentColor(container);
21+
getAppointments(): AppointmentModel[] {
22+
return [...container.querySelectorAll('.dx-scheduler-appointment')].map(
23+
(element) => createAppointmentModel(element as HTMLDivElement),
24+
);
3425
},
3526
getDateTableContent(): string[] {
3627
const cells = container.querySelectorAll('.dx-scheduler-date-table-cell');

packages/devextreme/js/__internal/scheduler/__tests__/appointments.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ describe('Appointments', () => {
2020
});
2121

2222
const appointment = POM.getAppointment();
23-
expect(appointment && !appointment.classList.contains('dx-resizable')).toBe(true);
23+
expect(appointment.element && !appointment.element.classList.contains('dx-resizable')).toBe(true);
2424
});
2525
});
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* @timezone Pacific/Auckland
3+
*/
4+
5+
import {
6+
describe, expect, it,
7+
} from '@jest/globals';
8+
9+
import { createScheduler } from './__mock__/create_scheduler';
10+
import { setupSchedulerTestEnvironment } from './__mock__/m_mock_scheduler';
11+
12+
describe('Recurrence appointments', () => {
13+
it('Weekly appointment should show in correct day and hours (T1185479)', async () => {
14+
setupSchedulerTestEnvironment();
15+
const { POM } = await createScheduler({
16+
dataSource: [{
17+
startDate: new Date(2023, 3, 27, 1),
18+
endDate: new Date(2023, 3, 27, 2),
19+
allDay: false,
20+
text: 'Weekly meeting',
21+
recurrenceRule: 'FREQ=WEEKLY;BYDAY=TH',
22+
}],
23+
currentView: 'week',
24+
currentDate: new Date(2023, 3, 27),
25+
});
26+
27+
const appointment = POM.getAppointment();
28+
expect(appointment.getAriaLabel()).toBe('Weekly meeting: April 27, 2023, 1:00 AM - 2:00 AM');
29+
expect(appointment.getDisplayDate()).toBe('1:00 AM - 2:00 AM');
30+
});
31+
});

packages/devextreme/js/__internal/scheduler/__tests__/resources.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ describe('Resources', () => {
5353
await dataPromise;
5454
await new Promise(process.nextTick);
5555

56-
expect(POM.getAppointmentColor(view)).toBe(rooms[0].color);
56+
expect(POM.getAppointment().getColor(view)).toBe(rooms[0].color);
5757
});
5858

5959
it('should render correct appointment color for local datasource (T1300252)', async () => {
@@ -71,7 +71,7 @@ describe('Resources', () => {
7171
}],
7272
});
7373

74-
expect(POM.getAppointmentColor(view)).toBe(rooms[0].color);
74+
expect(POM.getAppointment().getColor(view)).toBe(rooms[0].color);
7575
});
7676

7777
it('should render appointments after resources update (T1301345)', async () => {
@@ -95,7 +95,7 @@ describe('Resources', () => {
9595
}]);
9696
await new Promise(process.nextTick);
9797

98-
expect(POM.getAppointmentColor(view)).toBe(rooms2[0].color);
98+
expect(POM.getAppointment().getColor(view)).toBe(rooms2[0].color);
9999
});
100100
});
101101
});

packages/devextreme/js/__internal/scheduler/__tests__/views.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe('views', () => {
3535
await new Promise(process.nextTick);
3636

3737
const appointment = POM.getAppointment();
38-
expect(appointment !== null).toBe(true);
38+
expect(appointment.element !== null).toBe(true);
3939
});
4040

4141
it('should render all-day appointment correctly with fractional cell values', async () => {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/**
2+
* @timezone America/Los_Angeles
3+
*/
4+
5+
import './m_recurrence.test';

0 commit comments

Comments
 (0)