Skip to content

Commit 235e54f

Browse files
Calendars - render tests (#2032)
* Expandable - open (CalendarList) - day press render test * Updating testIDs to have a complete flow * Test driver - bug * Fix testIDs and add tests to expandable knob behavior * Fix TS error * Change expandableHeader testID to expandableContainer * Change testID of week calendar * Change header testID to staticHeader * removed comma * Change header testID to title * renaming stuff * Change week testID to weekNumber * Add documentation for testIDs * rename variable * Fix tests that depends on time * render tests - fixes * CalendarList - add render tests * format item title from date * Test list length * add list props tests * Removing initialNumToRender tests * testUtils - adding getMonthTitle; moving driver to tests folder; moving calendar tests and driver to tests directory * moving drivers out of _tests_ dir * fix import paths * props tests * ExpandableCalendar - add render tests * ExpandableCalendar - tests - add WeekCalendar day press * WeekCalendar - add render tests * fix tests for master merge Co-authored-by: Ethan Sharabi <[email protected]>
1 parent c6ed03c commit 235e54f

File tree

14 files changed

+485
-30
lines changed

14 files changed

+485
-30
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"@babel/runtime": "^7.12.5",
4848
"@testing-library/react-native": "^11.0.0",
4949
"@tsconfig/docusaurus": "^1.0.4",
50+
"@types/jest": "^29.0.1",
5051
"@types/lodash": "^4.14.170",
5152
"@types/react": "^17.0.44",
5253
"@types/react-native": "^0.64.19",
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
import React from 'react';
2+
import CalendarList from '../index';
3+
import {CalendarListDriver} from '../driver';
4+
//@ts-expect-error
5+
import {getMonthTitle} from '../../testUtils';
6+
7+
const CURRENT = '2022-09-09';
8+
const NEXT_MONTH = '2022-10-09';
9+
const PREV_MONTH = '2022-08-09';
10+
const nextMonthData = {dateString: '2022-10-09', day: 9, month: 10, timestamp: 1665273600000, year: 2022};
11+
const prevMonthData = {dateString: '2022-08-09', day: 9, month: 8, timestamp: 1660003200000, year: 2022};
12+
13+
const testIdCalendarList = 'myCalendarList';
14+
const onMonthChangeMock = jest.fn();
15+
const onVisibleMonthsChangeMock = jest.fn();
16+
const pastScrollRange = 10;
17+
const futureScrollRange = 5;
18+
// const initialVisibleItems = [
19+
// {
20+
// "index": 50,
21+
// "isViewable": true,
22+
// "item": "2022-09-09T00:00:00.000Z",
23+
// "key": "50"
24+
// }
25+
// ];
26+
// const changed = [
27+
// {
28+
// "index": 51,
29+
// "isViewable": true,
30+
// "item": "2022-10-09T00:00:00.000Z",
31+
// "key": "51"
32+
// },
33+
// {
34+
// "index": 50,
35+
// "isViewable": false,
36+
// "item": "2022-09-09T00:00:00.000Z",
37+
// "key":"50"
38+
// }
39+
// ];
40+
// const visibleItems = [
41+
// {
42+
// "index": 51,
43+
// "isViewable": true,
44+
// "item": "2022-10-09T00:00:00.000Z",
45+
// "key": "51"
46+
// }
47+
// ];
48+
49+
const defaultProps = {
50+
testID: testIdCalendarList,
51+
current: CURRENT,
52+
onMonthChange: onMonthChangeMock,
53+
onVisibleMonthsChange: onVisibleMonthsChangeMock
54+
};
55+
56+
const TestCase = props => {
57+
return <CalendarList {...defaultProps} {...props} />;
58+
};
59+
60+
describe('CalendarList', () => {
61+
describe('Props', () => {
62+
describe('past/futureScrollRange', () => {
63+
const driver = new CalendarListDriver(
64+
testIdCalendarList,
65+
<TestCase pastScrollRange={pastScrollRange} futureScrollRange={futureScrollRange} />
66+
);
67+
68+
beforeEach(() => {
69+
jest.useFakeTimers();
70+
driver.render();
71+
});
72+
73+
it('should have correct number of list items', () => {
74+
expect(driver.getListProps().data.length).toBe(pastScrollRange + futureScrollRange + 1);
75+
});
76+
});
77+
});
78+
79+
describe('Horizontal Mode', () => {
80+
const driver = new CalendarListDriver(testIdCalendarList, <TestCase horizontal={true} staticHeader={true} />);
81+
82+
beforeEach(() => {
83+
jest.useFakeTimers();
84+
driver.render();
85+
86+
onMonthChangeMock.mockClear();
87+
onVisibleMonthsChangeMock.mockClear();
88+
});
89+
90+
// afterEach(() => driver.clear());
91+
92+
describe('Init', () => {
93+
it('should display current month', () => {
94+
// static header
95+
expect(driver.getStaticHeaderTitle()).toBe(getMonthTitle(CURRENT));
96+
97+
// list
98+
expect(driver.getListProps().horizontal).toBe(true);
99+
expect(driver.getListProps().data.length).toBe(101);
100+
expect(driver.getListProps().initialScrollIndex).toBe(50);
101+
expect(driver.getListProps().initialNumToRender).toBe(1);
102+
103+
// list items
104+
expect(driver.getListItem(CURRENT)).toBeDefined();
105+
expect(driver.getListItemTitle(CURRENT)).toBeDefined();
106+
107+
// events
108+
expect(onMonthChangeMock).not.toHaveBeenCalled();
109+
expect(onVisibleMonthsChangeMock).not.toHaveBeenCalled();
110+
});
111+
});
112+
113+
describe('Static Header Arrows', () => {
114+
it('should change month on right arrow press', () => {
115+
driver.pressRightArrow();
116+
117+
expect(onMonthChangeMock).toHaveBeenCalledWith(nextMonthData);
118+
expect(onVisibleMonthsChangeMock).toHaveBeenCalledWith([nextMonthData]);
119+
120+
expect(driver.getStaticHeaderTitle()).toBe(getMonthTitle(NEXT_MONTH));
121+
122+
// NOTE: check visible list item - only first item is rendered and arrow press doesn't actually scrolls the list
123+
// expect(driver.getListItemTitle(NEXT_MONTH)).toBeDefined();
124+
});
125+
126+
it('should change month on left arrow press', () => {
127+
driver.pressLeftArrow();
128+
129+
expect(onMonthChangeMock).toHaveBeenCalledWith(prevMonthData);
130+
expect(onVisibleMonthsChangeMock).toHaveBeenCalledWith([prevMonthData]);
131+
132+
expect(driver.getStaticHeaderTitle()).toBe(getMonthTitle(PREV_MONTH));
133+
});
134+
});
135+
136+
// describe('List Scroll', () => {
137+
// it('scroll to next month', () => {
138+
// driver.fireOnViewableItemsChanged(changed, visibleItems);
139+
140+
// expect(onMonthChangeMock).toHaveBeenCalled();
141+
// expect(onMonthChangeMock).toHaveBeenCalledWith(nextMonthData);
142+
// expect(onVisibleMonthsChangeMock).toHaveBeenCalledWith([nextMonthData]);
143+
144+
// expect(driver.getStaticHeaderTitle()).toBe(getMonthTitle(NEXT_MONTH));
145+
// });
146+
// });
147+
});
148+
});

src/calendar-list/driver.ts

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import React from 'react';
2+
import {fireEvent, render, screen, within} from '@testing-library/react-native';
3+
//@ts-expect-error
4+
import {getMonthTitle} from '../testUtils';
5+
6+
export class CalendarListDriver {
7+
testID: string;
8+
element: React.ReactElement;
9+
10+
constructor(testID: string, element: React.ReactElement) {
11+
this.testID = testID;
12+
this.element = element;
13+
this.render(element);
14+
}
15+
16+
render(element = this.element): ReturnType<typeof render> {
17+
if (!element) throw 'Element is missing';
18+
return render(element);
19+
}
20+
21+
/** List */
22+
23+
// fireOnViewableItemsChanged(changed: any[], visibleItems: any[]) {
24+
// fireEvent(screen.getByTestId(this.testID), 'viewabilityConfigCallbackPairs.onViewableItemsChanged', {info: {changed: changed, viewableItems: visibleItems}});
25+
// }
26+
27+
getListProps() {
28+
const props = screen.getByTestId(`${this.testID}.list`).props;
29+
return props;
30+
}
31+
32+
getItemTestID(date: string) {
33+
const [year, month] = date.split('-');
34+
return `${this.testID}.item_${year}-${month}`;
35+
}
36+
37+
getListItem(date: string) {
38+
return screen.getByTestId(this.getItemTestID(date));
39+
}
40+
41+
getListItemTitle(date: string) {
42+
return within(this.getListItem(date)).getByText(getMonthTitle(date));
43+
}
44+
45+
/** Static header */
46+
47+
get staticHeaderTestID() {
48+
return `${this.testID}.staticHeader`;
49+
}
50+
51+
getStaticHeader() {
52+
return screen.getByTestId(this.staticHeaderTestID);
53+
}
54+
55+
getStaticHeaderTitle() {
56+
return screen.getByTestId(`${this.staticHeaderTestID}.title`).children[0];
57+
}
58+
59+
getStaticHeaderLeftArrow() {
60+
return screen.getByTestId(`${this.staticHeaderTestID}.leftArrow`);
61+
}
62+
63+
getStaticHeaderRightArrow() {
64+
return screen.getByTestId(`${this.staticHeaderTestID}.rightArrow`);
65+
}
66+
67+
pressLeftArrow() {
68+
fireEvent(this.getStaticHeaderLeftArrow(), 'onPress');
69+
}
70+
71+
pressRightArrow() {
72+
fireEvent(this.getStaticHeaderRightArrow(), 'onPress');
73+
}
74+
75+
/** Day press */
76+
77+
getDayTestID(date: string) {
78+
const [year, month] = date.split('-');
79+
return `${this.testID}.item_${year}-${month}.day_${date}`;
80+
}
81+
82+
getDay(date: string) {
83+
return screen.getByTestId(this.getDayTestID(date));
84+
}
85+
86+
selectDay(date: string) {
87+
fireEvent(this.getDay(date), 'onPress');
88+
}
89+
}

src/calendar-list/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ const CalendarList = (props: CalendarListProps, ref: any) => {
281281
]);
282282

283283
return (
284-
<View style={style.current.flatListContainer}>
284+
<View style={style.current.flatListContainer} testID={testID}>
285285
<FlatList
286286
// @ts-expect-error
287287
ref={list}
@@ -294,7 +294,7 @@ const CalendarList = (props: CalendarListProps, ref: any) => {
294294
initialNumToRender={range.current}
295295
initialScrollIndex={initialDateIndex}
296296
viewabilityConfigCallbackPairs={viewabilityConfigCallbackPairs.current}
297-
testID={testID}
297+
testID={`${testID}.list`}
298298
onLayout={onLayout}
299299
removeClippedSubviews={removeClippedSubviews}
300300
pagingEnabled={pagingEnabled}

src/calendar/index.spec.js renamed to src/calendar/__tests__/index.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import XDate from 'xdate';
22
import React from 'react';
33
import {getTextNodes} from 'react-component-driver';
44
import {advanceTo, clear as clearDate} from 'jest-date-mock';
5-
import {getDaysArray, partial} from '../testUtils';
6-
import {CalendarDriver} from './driver';
5+
import {getDaysArray, partial} from '../../testUtils';
6+
import {CalendarDriver} from '../driver';
77

88
describe('Calendar', () => {
99
let currentDate;

src/calendar/driver.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {swipeDirections} from 'react-native-swipe-gestures';
33
import Calendar from '.';
44
import {BasicDayDriver} from './day/basic/driver';
55
import {CalendarHeaderDriver} from './header/driver';
6-
import {SELECT_DATE_SLOT, WEEK_NUMBER} from '../testIDs';
76

87
export class CalendarDriver extends ComponentDriver {
98
constructor(testID = 'calendar') {

src/calendar/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ const Calendar = (props: CalendarProps) => {
283283
<GestureComponent {...gestureProps}>
284284
<View
285285
style={[style.current.container, propsStyle]}
286+
testID={testID}
286287
accessibilityElementsHidden={accessibilityElementsHidden} // iOS
287288
importantForAccessibility={importantForAccessibility} // Android
288289
>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import React from 'react';
2+
import WeekCalendar from '../index';
3+
import {WeekCalendarDriver} from '../driver';
4+
5+
const CURRENT = '2022-09-09';
6+
7+
const testIdWeekCalendar = 'myWeekCalendar';
8+
9+
const defaultProps = {
10+
testID: testIdWeekCalendar,
11+
current: CURRENT
12+
};
13+
14+
const TestCase = props => {
15+
return <WeekCalendar {...defaultProps} {...props} />;
16+
};
17+
18+
describe('WeekCalendar', () => {
19+
describe('Week', () => {
20+
const driver = new WeekCalendarDriver(testIdWeekCalendar, <TestCase />);
21+
22+
beforeEach(() => {
23+
jest.useFakeTimers();
24+
driver.render();
25+
});
26+
27+
// afterEach(() => driver.clear());
28+
29+
describe('Init', () => {
30+
it('should display current week', () => {
31+
// list
32+
expect(driver.getListProps().horizontal).toBe(true);
33+
expect(driver.getListProps().data.length).toBe(13);
34+
expect(driver.getListProps().initialScrollIndex).toBe(6);
35+
36+
// list items
37+
expect(driver.getListItem(CURRENT)).toBeDefined();
38+
});
39+
});
40+
});
41+
});
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import React from 'react';
2+
import {fireEvent, render, screen} from '@testing-library/react-native';
3+
4+
export class WeekCalendarDriver {
5+
testID: string;
6+
element: React.ReactElement;
7+
renderTree: ReturnType<typeof render>;
8+
9+
constructor(testID: string, element: React.ReactElement) {
10+
this.testID = testID;
11+
this.element = element;
12+
this.renderTree = this.render(element);
13+
}
14+
15+
render(element = this.element): ReturnType<typeof render> {
16+
if (!element) throw 'Element is missing';
17+
this.renderTree = render(element);
18+
return this.renderTree;
19+
}
20+
21+
getWeekCalendar() {
22+
return this.renderTree.getByTestId(`${this.testID}.weekCalendar.list`);
23+
}
24+
25+
/** List */
26+
27+
getListProps() {
28+
const props = screen.getByTestId(`${this.testID}.list`).props;
29+
return props;
30+
}
31+
32+
getItemTestID(date: string) {
33+
return `${this.testID}.week_${date}`;
34+
}
35+
36+
getListItem(date: string) {
37+
return screen.getByTestId(this.getItemTestID(date));
38+
}
39+
40+
/** Day */
41+
42+
getDayTestID(date: string) {
43+
return `${this.testID}.day_${date}`;
44+
}
45+
46+
getDay(date: string) {
47+
return this.renderTree?.getByTestId(this.getDayTestID(date));
48+
}
49+
50+
selectDay(date: string) {
51+
fireEvent(this.getDay(date), 'onPress');
52+
}
53+
}

0 commit comments

Comments
 (0)