@transferwise/components 0.0.0-experimental-03832a1 → 0.0.0-experimental-602fe37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { mockMatchMedia, render, screen, userEvent } from '../test-utils';
|
|
2
|
+
import CalendarInput from './CalendarInput';
|
|
3
|
+
|
|
4
|
+
mockMatchMedia();
|
|
5
|
+
|
|
6
|
+
const user = userEvent.setup();
|
|
7
|
+
|
|
8
|
+
const initialValue = new Date(2000, 0, 1);
|
|
9
|
+
|
|
10
|
+
describe('CalendarInput', () => {
|
|
11
|
+
describe('in day view', () => {
|
|
12
|
+
it.each([
|
|
13
|
+
['{ArrowLeft}', -1],
|
|
14
|
+
['{ArrowRight}', +1],
|
|
15
|
+
['{ArrowUp}', -7],
|
|
16
|
+
['{ArrowDown}', +7],
|
|
17
|
+
])("handles '%s' to step %d day(s)", async (text: string, step: number) => {
|
|
18
|
+
const handleChange = jest.fn();
|
|
19
|
+
render(<CalendarInput value={initialValue} onChange={handleChange} />);
|
|
20
|
+
|
|
21
|
+
await user.click(screen.getByRole('button', { name: /selected day/iu }));
|
|
22
|
+
await user.keyboard(text);
|
|
23
|
+
|
|
24
|
+
const expected = new Date(initialValue);
|
|
25
|
+
expected.setDate(initialValue.getDate() + step);
|
|
26
|
+
expect(handleChange).toHaveBeenCalledWith(expected);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('selects a day on click', async () => {
|
|
30
|
+
const handleChange = jest.fn();
|
|
31
|
+
render(<CalendarInput value={initialValue} onChange={handleChange} />);
|
|
32
|
+
|
|
33
|
+
await user.click(screen.getByText('15'));
|
|
34
|
+
|
|
35
|
+
expect(handleChange).toHaveBeenCalledWith(new Date(2000, 0, 15));
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('calls onSelect instead of onChange when clicking a day', async () => {
|
|
39
|
+
const handleChange = jest.fn();
|
|
40
|
+
const handleSelect = jest.fn();
|
|
41
|
+
render(
|
|
42
|
+
<CalendarInput value={initialValue} onChange={handleChange} onSelect={handleSelect} />,
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
await user.click(screen.getByText('15'));
|
|
46
|
+
|
|
47
|
+
expect(handleSelect).toHaveBeenCalledWith(new Date(2000, 0, 15));
|
|
48
|
+
expect(handleChange).not.toHaveBeenCalled();
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe('in year view', () => {
|
|
53
|
+
it.each([
|
|
54
|
+
['{ArrowLeft}', -1],
|
|
55
|
+
['{ArrowRight}', +1],
|
|
56
|
+
['{ArrowUp}', -4],
|
|
57
|
+
['{ArrowDown}', +4],
|
|
58
|
+
])("handles '%s' to step %d year(s)", async (text: string, step: number) => {
|
|
59
|
+
const handleChange = jest.fn();
|
|
60
|
+
render(<CalendarInput value={initialValue} onChange={handleChange} />);
|
|
61
|
+
|
|
62
|
+
await user.click(screen.getByRole('button', { name: /year view/iu }));
|
|
63
|
+
await user.keyboard(text);
|
|
64
|
+
|
|
65
|
+
const expected = new Date(initialValue);
|
|
66
|
+
expected.setFullYear(initialValue.getFullYear() + step);
|
|
67
|
+
expect(handleChange).toHaveBeenCalledWith(expected);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
describe('in month view', () => {
|
|
72
|
+
it.each([
|
|
73
|
+
['{ArrowLeft}', -1],
|
|
74
|
+
['{ArrowRight}', +1],
|
|
75
|
+
['{ArrowUp}', -4],
|
|
76
|
+
['{ArrowDown}', +4],
|
|
77
|
+
])("handles '%s' to step %d month(s)", async (text: string, step: number) => {
|
|
78
|
+
const handleChange = jest.fn();
|
|
79
|
+
render(<CalendarInput value={initialValue} onChange={handleChange} />);
|
|
80
|
+
|
|
81
|
+
await user.click(screen.getByRole('button', { name: /year view/iu }));
|
|
82
|
+
await user.keyboard(' ');
|
|
83
|
+
await user.keyboard(text);
|
|
84
|
+
|
|
85
|
+
const expected = new Date(initialValue);
|
|
86
|
+
expected.setMonth(initialValue.getMonth() + step);
|
|
87
|
+
expect(handleChange).toHaveBeenCalledWith(expected);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
describe('min/max clamping', () => {
|
|
92
|
+
it('limits navigation to min value', async () => {
|
|
93
|
+
const min = new Date(initialValue);
|
|
94
|
+
min.setDate(min.getDate() - 1);
|
|
95
|
+
const handleChange = jest.fn();
|
|
96
|
+
render(<CalendarInput value={initialValue} min={min} onChange={handleChange} />);
|
|
97
|
+
|
|
98
|
+
await user.click(screen.getByRole('button', { name: /selected day/iu }));
|
|
99
|
+
await user.keyboard('{ArrowLeft}{ArrowLeft}');
|
|
100
|
+
|
|
101
|
+
expect(handleChange).toHaveBeenLastCalledWith(min);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('limits navigation to max value', async () => {
|
|
105
|
+
const max = new Date(initialValue);
|
|
106
|
+
max.setDate(max.getDate() + 1);
|
|
107
|
+
const handleChange = jest.fn();
|
|
108
|
+
render(<CalendarInput value={initialValue} max={max} onChange={handleChange} />);
|
|
109
|
+
|
|
110
|
+
await user.click(screen.getByRole('button', { name: /selected day/iu }));
|
|
111
|
+
await user.keyboard('{ArrowRight}{ArrowRight}');
|
|
112
|
+
|
|
113
|
+
expect(handleChange).toHaveBeenLastCalledWith(max);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('clamps value to range when value is outside min/max', () => {
|
|
117
|
+
const min = new Date(2000, 0, 5);
|
|
118
|
+
const max = new Date(2000, 0, 20);
|
|
119
|
+
const handleChange = jest.fn();
|
|
120
|
+
render(<CalendarInput value={initialValue} min={min} max={max} onChange={handleChange} />);
|
|
121
|
+
|
|
122
|
+
expect(handleChange).toHaveBeenCalledWith(min);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
describe('view switching', () => {
|
|
127
|
+
it('switches to year view and back to day view', async () => {
|
|
128
|
+
render(<CalendarInput value={initialValue} onChange={jest.fn()} />);
|
|
129
|
+
|
|
130
|
+
await user.click(screen.getByRole('button', { name: /year view/iu }));
|
|
131
|
+
expect(screen.getByRole('button', { name: /selected year/iu })).toBeInTheDocument();
|
|
132
|
+
|
|
133
|
+
await user.click(screen.getByRole('button', { name: /selected year/iu }));
|
|
134
|
+
expect(screen.getByRole('button', { name: /selected month/iu })).toBeInTheDocument();
|
|
135
|
+
|
|
136
|
+
await user.click(screen.getByRole('button', { name: /selected month/iu }));
|
|
137
|
+
expect(screen.getByRole('button', { name: /next month/iu })).toBeInTheDocument();
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
});
|
|
@@ -198,28 +198,6 @@ describe('DateLookup', () => {
|
|
|
198
198
|
expect(handleChange).toHaveBeenCalledWith(initialValue);
|
|
199
199
|
});
|
|
200
200
|
});
|
|
201
|
-
|
|
202
|
-
it('limits min value', async () => {
|
|
203
|
-
const min = new Date(initialValue);
|
|
204
|
-
min.setDate(min.getDate() - 1);
|
|
205
|
-
const handleChange = jest.fn();
|
|
206
|
-
await setupAndOpenWithMouse({ min, onChange: handleChange });
|
|
207
|
-
|
|
208
|
-
await user.keyboard('{ArrowLeft}{ArrowLeft}');
|
|
209
|
-
|
|
210
|
-
expect(handleChange).toHaveBeenCalledWith(min);
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
it('limits max value', async () => {
|
|
214
|
-
const max = new Date(initialValue);
|
|
215
|
-
max.setDate(max.getDate() + 1);
|
|
216
|
-
const handleChange = jest.fn();
|
|
217
|
-
await setupAndOpenWithMouse({ max, onChange: handleChange });
|
|
218
|
-
|
|
219
|
-
await user.keyboard('{ArrowRight}{ArrowRight}');
|
|
220
|
-
|
|
221
|
-
expect(handleChange).toHaveBeenCalledWith(max);
|
|
222
|
-
});
|
|
223
201
|
});
|
|
224
202
|
|
|
225
203
|
describe('DateLookup propTypes', () => {
|
|
@@ -296,75 +274,6 @@ describe('DateLookup (events)', () => {
|
|
|
296
274
|
);
|
|
297
275
|
};
|
|
298
276
|
|
|
299
|
-
it('switches to years', async () => {
|
|
300
|
-
const view = await setup();
|
|
301
|
-
await openDateLookup();
|
|
302
|
-
await clickDateButton();
|
|
303
|
-
|
|
304
|
-
expect(getActiveYearButton(view)).toHaveFocus();
|
|
305
|
-
|
|
306
|
-
await closeDateLookup(view);
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
it('has aria-label for 20 years', async () => {
|
|
310
|
-
const view = await setup();
|
|
311
|
-
await openDateLookup();
|
|
312
|
-
await clickDateButton();
|
|
313
|
-
|
|
314
|
-
expect(getButtonByAriaLabel('next 20 years')).toBeInTheDocument();
|
|
315
|
-
expect(getButtonByAriaLabel('previous 20 years')).toBeInTheDocument();
|
|
316
|
-
|
|
317
|
-
await closeDateLookup(view);
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
it('switches to months', async () => {
|
|
321
|
-
const view = await setup();
|
|
322
|
-
await openDateLookup();
|
|
323
|
-
await clickDateButton();
|
|
324
|
-
await userEvent.click(getActiveYearButton(view));
|
|
325
|
-
|
|
326
|
-
expect(getActiveMonthButton(view)).toHaveFocus();
|
|
327
|
-
|
|
328
|
-
await closeDateLookup(view);
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
it('has aria label for year', async () => {
|
|
332
|
-
const view = await setup();
|
|
333
|
-
await openDateLookup();
|
|
334
|
-
await clickDateButton();
|
|
335
|
-
await userEvent.click(getActiveYearButton(view));
|
|
336
|
-
|
|
337
|
-
expect(getButtonByAriaLabel('next year')).toBeInTheDocument();
|
|
338
|
-
expect(getButtonByAriaLabel('previous year')).toBeInTheDocument();
|
|
339
|
-
|
|
340
|
-
await closeDateLookup(view);
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
it('switches to days', async () => {
|
|
344
|
-
const view = await setup();
|
|
345
|
-
await openDateLookup();
|
|
346
|
-
await clickDateButton();
|
|
347
|
-
await userEvent.click(getActiveYearButton(view));
|
|
348
|
-
await userEvent.click(getActiveMonthButton(view));
|
|
349
|
-
|
|
350
|
-
expect(getActiveDayButton(view)).toHaveFocus();
|
|
351
|
-
|
|
352
|
-
await closeDateLookup(view);
|
|
353
|
-
});
|
|
354
|
-
|
|
355
|
-
it('has aria label for month', async () => {
|
|
356
|
-
const view = await setup();
|
|
357
|
-
await openDateLookup();
|
|
358
|
-
await clickDateButton();
|
|
359
|
-
await userEvent.click(getActiveYearButton(view));
|
|
360
|
-
await userEvent.click(getActiveMonthButton(view));
|
|
361
|
-
|
|
362
|
-
expect(getButtonByAriaLabel('next month')).toBeInTheDocument();
|
|
363
|
-
expect(getButtonByAriaLabel('previous month')).toBeInTheDocument();
|
|
364
|
-
|
|
365
|
-
await closeDateLookup(view);
|
|
366
|
-
});
|
|
367
|
-
|
|
368
277
|
it('has aria label on selected date', async () => {
|
|
369
278
|
const view = await setup();
|
|
370
279
|
await openDateLookup();
|
|
@@ -440,44 +349,11 @@ describe('DateLookup (events)', () => {
|
|
|
440
349
|
});
|
|
441
350
|
};
|
|
442
351
|
|
|
443
|
-
const getDateButton = () => {
|
|
444
|
-
return screen.getByRole('button', {
|
|
445
|
-
name: /Go to 20 year view/i,
|
|
446
|
-
});
|
|
447
|
-
};
|
|
448
|
-
|
|
449
352
|
const openDateLookup = async () => userEvent.click(getOpenButton(labelProp));
|
|
450
353
|
|
|
451
|
-
const clickDateButton = async () => userEvent.click(getDateButton());
|
|
452
|
-
|
|
453
354
|
// Close dateLookup and removes events attached to documents.
|
|
454
355
|
const closeDateLookup = async (view: RenderResult) => userEvent.click(view.container);
|
|
455
356
|
|
|
456
357
|
// @ts-expect-error getClearButton returns node
|
|
457
358
|
const clickClearButton = async (view: RenderResult) => userEvent.click(getClearButton(view));
|
|
458
|
-
|
|
459
|
-
const getActiveYearButton = (view: RenderResult) => {
|
|
460
|
-
return screen.getByRole('button', {
|
|
461
|
-
name: /selected year/i,
|
|
462
|
-
pressed: true,
|
|
463
|
-
});
|
|
464
|
-
};
|
|
465
|
-
|
|
466
|
-
const getActiveMonthButton = (view: RenderResult) => {
|
|
467
|
-
return screen.getByRole('button', {
|
|
468
|
-
name: /selected month/i,
|
|
469
|
-
pressed: true,
|
|
470
|
-
});
|
|
471
|
-
};
|
|
472
|
-
|
|
473
|
-
const getActiveDayButton = (view: RenderResult) => {
|
|
474
|
-
return screen.getByRole('button', {
|
|
475
|
-
name: /selected day/i,
|
|
476
|
-
pressed: true,
|
|
477
|
-
});
|
|
478
|
-
};
|
|
479
|
-
|
|
480
|
-
const getButtonByAriaLabel = (ariaLabel: string) => {
|
|
481
|
-
return screen.getByRole('button', { name: ariaLabel });
|
|
482
|
-
};
|
|
483
359
|
});
|