Repository navigation
Expand file tree
/
Copy pathCreateMatchRequestDialog.test.tsx
More file actions
250 lines (207 loc) · 7.82 KB
/
Copy pathCreateMatchRequestDialog.test.tsx
File metadata and controls
250 lines (207 loc) · 7.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
import React from 'react';
import { screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { render } from '../utils/test-utils';
import CreateMatchRequestDialog from '../../components/CreateMatchRequestDialog';
import { mockOnSubmit, mockOnClose } from '../utils/mocks';
import { useUserID } from '../../contexts/UserIDContext';
// Mock date-fns to control date behavior in tests
jest.mock('date-fns', () => ({
isSameDay: jest.fn(() => false),
isBefore: jest.fn(() => false),
}));
jest.mock('../../contexts/UserIDContext', () => ({
useUserID: () => 'test-user-id',
}));
describe('CreateMatchRequestDialog', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('submits form with valid data when all required fields are filled', async () => {
const user = userEvent.setup();
render(<CreateMatchRequestDialog open={true} onClose={mockOnClose} onSubmit={mockOnSubmit} />);
// Fill in location - use the combobox directly since it has no accessible name
const locationSelect = screen.getByRole('combobox');
await user.click(locationSelect);
await user.click(screen.getByText('Mensa Garching'));
// For the date, let's try clicking the date picker and then pressing Enter to accept
const datePickerButton = screen.getByRole('button', { name: /choose date/i });
await user.click(datePickerButton);
// Press Enter to accept the current date (today)
await user.keyboard('{Enter}');
// Select timeslots (at least 3 as required) - use the actual timeslot values
const timeslotButtons = screen
.getAllByRole('button')
.filter(
(button) =>
button.textContent?.includes('12:00-12:15') ||
button.textContent?.includes('12:15-12:30') ||
button.textContent?.includes('12:30-12:45')
);
// Click each timeslot to select them (these correspond to values 9, 10, 11)
for (const button of timeslotButtons.slice(0, 3)) {
await user.click(button);
}
// Set preferences
const degreeCheckbox = screen.getByLabelText(/same degree/i);
await user.click(degreeCheckbox);
// Wait for form to be valid (submit button to be enabled)
await waitFor(
() => {
const submitButton = screen.getByRole('button', { name: /create/i });
expect(submitButton).not.toBeDisabled();
},
{ timeout: 5000 }
);
// Submit the form
const submitButton = screen.getByRole('button', { name: /create/i });
await user.click(submitButton);
await waitFor(() => {
expect(mockOnSubmit).toHaveBeenCalledWith({
userID: 'test-user-id',
location: 'GARCHING',
date: expect.stringMatching(/^[\d]{4}-[\d]{2}-[\d]{2}$/), // Any valid date format
timeslot: [9, 10, 11], // These correspond to the selected timeslots
preferences: {
degreePref: true,
agePref: false,
genderPref: false,
},
});
});
});
it('validates required fields correctly', async () => {
const user = userEvent.setup();
render(<CreateMatchRequestDialog open={true} onClose={mockOnClose} onSubmit={mockOnSubmit} />);
// Initially the submit button should be disabled
const submitButton = screen.getByRole('button', { name: /create/i });
expect(submitButton).toBeDisabled();
// Fill in location only - button should still be disabled
const locationSelect = screen.getByRole('combobox');
await user.click(locationSelect);
await user.click(screen.getByText('Mensa Garching'));
expect(submitButton).toBeDisabled();
// Select only 2 timeslots - button should still be disabled
const timeslotButtons = screen
.getAllByRole('button')
.filter(
(button) =>
button.textContent?.includes('12:00-12:15') || button.textContent?.includes('12:15-12:30')
);
for (const button of timeslotButtons.slice(0, 2)) {
await user.click(button);
}
expect(submitButton).toBeDisabled();
});
it('closes dialog when close button is clicked', async () => {
const user = userEvent.setup();
render(<CreateMatchRequestDialog open={true} onClose={mockOnClose} onSubmit={mockOnSubmit} />);
const closeButton = screen.getByText('Cancel');
await user.click(closeButton);
expect(mockOnClose).toHaveBeenCalled();
});
it('submits demo form with valid data when demo button is clicked', async () => {
const user = userEvent.setup();
const mockOnDemoSubmit = jest.fn();
render(
<CreateMatchRequestDialog
open={true}
onClose={mockOnClose}
onSubmit={mockOnSubmit}
onDemoSubmit={mockOnDemoSubmit}
/>
);
// Fill in location
const locationSelect = screen.getByRole('combobox');
await user.click(locationSelect);
await user.click(screen.getByText('Mensa Garching'));
// Set date
const datePickerButton = screen.getByRole('button', { name: /choose date/i });
await user.click(datePickerButton);
await user.keyboard('{Enter}');
// Select timeslots
const timeslotButtons = screen
.getAllByRole('button')
.filter(
(button) =>
button.textContent?.includes('12:00-12:15') ||
button.textContent?.includes('12:15-12:30') ||
button.textContent?.includes('12:30-12:45')
);
for (const button of timeslotButtons.slice(0, 3)) {
await user.click(button);
}
// Wait for demo button to be enabled
await waitFor(
() => {
const demoButton = screen.getByRole('button', { name: /demo/i });
expect(demoButton).not.toBeDisabled();
},
{ timeout: 5000 }
);
// Click demo button
const demoButton = screen.getByRole('button', { name: /demo/i });
await user.click(demoButton);
await waitFor(() => {
expect(mockOnDemoSubmit).toHaveBeenCalledWith({
userID: 'test-user-id',
location: 'GARCHING',
date: expect.stringMatching(/^[\d]{4}-[\d]{2}-[\d]{2}$/),
timeslot: [9, 10, 11],
preferences: {
degreePref: false,
agePref: false,
genderPref: false,
},
});
});
});
it('falls back to regular submit when demo handler is not provided', async () => {
const user = userEvent.setup();
render(<CreateMatchRequestDialog open={true} onClose={mockOnClose} onSubmit={mockOnSubmit} />);
// Fill in location
const locationSelect = screen.getByRole('combobox');
await user.click(locationSelect);
await user.click(screen.getByText('Mensa Garching'));
// Set date
const datePickerButton = screen.getByRole('button', { name: /choose date/i });
await user.click(datePickerButton);
await user.keyboard('{Enter}');
// Select timeslots
const timeslotButtons = screen
.getAllByRole('button')
.filter(
(button) =>
button.textContent?.includes('12:00-12:15') ||
button.textContent?.includes('12:15-12:30') ||
button.textContent?.includes('12:30-12:45')
);
for (const button of timeslotButtons.slice(0, 3)) {
await user.click(button);
}
// Wait for demo button to be enabled
await waitFor(
() => {
const demoButton = screen.getByRole('button', { name: /demo/i });
expect(demoButton).not.toBeDisabled();
},
{ timeout: 5000 }
);
// Click demo button (should fall back to regular submit)
const demoButton = screen.getByRole('button', { name: /demo/i });
await user.click(demoButton);
await waitFor(() => {
expect(mockOnSubmit).toHaveBeenCalledWith({
userID: 'test-user-id',
location: 'GARCHING',
date: expect.stringMatching(/^[\d]{4}-[\d]{2}-[\d]{2}$/),
timeslot: [9, 10, 11],
preferences: {
degreePref: false,
agePref: false,
genderPref: false,
},
});
});
});
});