Skip to content

Commit 227501f

Browse files
committed
[Upd #209] Answer tests refactored to use React testing library.
1 parent 5c5a33c commit 227501f

File tree

1 file changed

+71
-57
lines changed

1 file changed

+71
-57
lines changed

test/__tests__/Answer.test.js

Lines changed: 71 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
import React from "react";
22
import { format } from "date-fns";
3-
import DatePicker from "react-datepicker";
4-
import Select from "react-select";
53

64
import * as Generator from "../environment/Generator";
75
import Answer from "../../src/components/Answer";
86
import Constants from "../../src/constants/Constants";
9-
import TypeaheadAnswer from "../../src/components/answer/TypeaheadAnswer";
10-
import MaskedInput from "../../src/components/MaskedInput";
117
import { FormGenContext } from "../../src/contexts/FormGenContext";
128
import { ConfigurationContext } from "../../src/contexts/ConfigurationContext";
139
import DefaultInput from "../../src/components/DefaultInput";
10+
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
11+
import "@testing-library/jest-dom";
1412

1513
describe("Answer component", () => {
1614
let question,
@@ -51,13 +49,17 @@ describe("Answer component", () => {
5149
},
5250
};
5351
inputComponent = DefaultInput;
52+
answer = {
53+
id: Generator.getRandomUri(),
54+
};
55+
question[Constants.HAS_ANSWER] = [answer];
5456
getOptions = jest.fn(() => []);
5557
loadFormOptions = jest.fn();
5658
});
5759

58-
it("renders a Typeahead when layout class is typeahead", () => {
60+
test("renders a Typeahead when layout class is typeahead", async () => {
5961
question[Constants.LAYOUT_CLASS].push(Constants.LAYOUT.QUESTION_TYPEAHEAD);
60-
const component = mount(
62+
render(
6163
<ConfigurationContext.Provider
6264
value={{
6365
componentsOptions,
@@ -71,11 +73,13 @@ describe("Answer component", () => {
7173
</ConfigurationContext.Provider>
7274
);
7375

74-
const typeahead = component.find(Select);
75-
expect(typeahead).not.toBeNull();
76+
await waitFor(() => {
77+
const typeahead = screen.getByRole("combobox");
78+
expect(typeahead).toBeInTheDocument();
79+
});
7680
});
7781

78-
it("maps answer object value to string label for the typeahead component", () => {
82+
it("maps answer object value to string label for the typeahead component", async () => {
7983
const value = Generator.getRandomUri();
8084
const valueLabel = "masterchief";
8185
const typeAheadOptions = Generator.generateTypeaheadOptions(
@@ -84,11 +88,12 @@ describe("Answer component", () => {
8488
);
8589
answer = answerWithCodeValue(value);
8690
getOptions = jest.fn(() => typeAheadOptions);
91+
8792
question[Constants.HAS_ANSWER] = [answer];
8893
question[Constants.LAYOUT_CLASS].push(Constants.LAYOUT.QUESTION_TYPEAHEAD);
8994
question[Constants.HAS_OPTIONS_QUERY] = "SELECT * WHERE {?x ?y ?z. }";
9095

91-
const component = mount(
96+
render(
9297
<ConfigurationContext.Provider
9398
value={{
9499
componentsOptions,
@@ -104,20 +109,23 @@ describe("Answer component", () => {
104109
</ConfigurationContext.Provider>
105110
);
106111

107-
waitForComponentToPaint(component);
108-
const typeahead = component.find(Answer).find(TypeaheadAnswer).find(Select);
112+
await waitFor(async () => {
113+
const typeahead = screen.getByRole("combobox");
109114

110-
expect(typeahead).not.toBeNull();
115+
fireEvent.click(typeahead);
116+
fireEvent.click(screen.getByText(valueLabel));
111117

112-
expect(typeahead.state("value")[0].name).toEqual(valueLabel);
118+
expect(typeahead).toBeInTheDocument();
119+
expect(screen.getByText(valueLabel)).toBeInTheDocument();
120+
});
113121
});
114122

115123
it("loads typeahead options when layout class is typeahead and no possible values are specified", () => {
116124
question[Constants.LAYOUT_CLASS].push(Constants.LAYOUT.QUESTION_TYPEAHEAD);
117125
const query = "SELECT * WHERE { ?x ?y ?z .}";
118126
question[Constants.HAS_OPTIONS_QUERY] = query;
119127

120-
const component = mount(
128+
render(
121129
<ConfigurationContext.Provider
122130
value={{
123131
componentsOptions,
@@ -131,8 +139,6 @@ describe("Answer component", () => {
131139
</ConfigurationContext.Provider>
132140
);
133141

134-
waitForComponentToPaint(component);
135-
136142
expect(loadFormOptions).toHaveBeenCalled();
137143
expect(loadFormOptions.mock.calls[0][1]).toEqual(query);
138144
});
@@ -152,7 +158,7 @@ describe("Answer component", () => {
152158
answer = answerWithTextValue(value);
153159
question[Constants.HAS_ANSWER] = [answer];
154160

155-
const component = mount(
161+
render(
156162
<ConfigurationContext.Provider
157163
value={{
158164
componentsOptions,
@@ -163,11 +169,12 @@ describe("Answer component", () => {
163169
<Answer answer={answer} question={question} onChange={onChange} />s
164170
</ConfigurationContext.Provider>
165171
);
166-
const input = component.find("input");
172+
173+
const input = screen.getByRole("textbox");
167174

168175
expect(input).not.toBeNull();
169-
expect(input.props().type).toEqual("text");
170-
expect(input.props().value).toEqual(value);
176+
expect(input.type).toEqual("text");
177+
expect(input.value).toEqual(value);
171178
});
172179

173180
function answerWithTextValue(value) {
@@ -189,7 +196,7 @@ describe("Answer component", () => {
189196
question[Constants.HAS_ANSWER] = [answer];
190197
question[Constants.LAYOUT_CLASS].push(Constants.LAYOUT.DATE);
191198

192-
const component = mount(
199+
render(
193200
<ConfigurationContext.Provider
194201
value={{
195202
componentsOptions,
@@ -200,12 +207,12 @@ describe("Answer component", () => {
200207
<Answer answer={answer} question={question} onChange={onChange} />
201208
</ConfigurationContext.Provider>
202209
);
203-
const picker = component.find(DatePicker);
210+
211+
const picker = screen.getByPlaceholderText("YYYY-MM-DD");
204212

205213
expect(picker).not.toBeNull();
206-
expect(picker.props().showTimeSelect).toEqual(false);
207-
expect(picker.props().showTimeSelectOnly).toEqual(false);
208-
expect(picker.props().selected).toEqual(date);
214+
expect(screen.queryByLabelText("month 2000-01")).toBeNull();
215+
expect(picker.value).toEqual(format(date, "yyyy-MM-dd"));
209216
});
210217

211218
it("renders time picker with answer value when time layout class is specified", () => {
@@ -216,7 +223,7 @@ describe("Answer component", () => {
216223
question[Constants.HAS_ANSWER] = [answer];
217224
question[Constants.LAYOUT_CLASS].push(Constants.LAYOUT.TIME);
218225

219-
const component = mount(
226+
render(
220227
<ConfigurationContext.Provider
221228
value={{
222229
componentsOptions,
@@ -227,22 +234,23 @@ describe("Answer component", () => {
227234
<Answer answer={answer} question={question} onChange={onChange} />
228235
</ConfigurationContext.Provider>
229236
);
230-
const picker = component.find(DatePicker);
237+
238+
const picker = screen.getByPlaceholderText("HH:MM:SS");
231239

232240
expect(picker).not.toBeNull();
233-
expect(picker.props().showTimeSelect).toEqual(true);
234-
expect(picker.props().showTimeSelectOnly).toEqual(true);
235-
expect(picker.props().selected).toEqual(new Date(`0 ${value}`));
241+
expect(screen.queryByText("Time")).toBeNull();
242+
expect(picker.value).toEqual(value);
236243
});
237244

238245
it("renders datetime picker with answer value when datetime layout class is specified", () => {
239246
const date = new Date();
247+
const testDate = format(date, "yyyy-MM");
240248
const value = format(date, "yyyy-MM-dd HH:mm:ss");
241249
answer = answerWithTextValue(value);
242250
question[Constants.HAS_ANSWER] = [answer];
243251
question[Constants.LAYOUT_CLASS].push(Constants.LAYOUT.DATETIME);
244252

245-
const component = mount(
253+
render(
246254
<ConfigurationContext.Provider
247255
value={{
248256
componentsOptions,
@@ -253,24 +261,27 @@ describe("Answer component", () => {
253261
<Answer answer={answer} question={question} onChange={onChange} />
254262
</ConfigurationContext.Provider>
255263
);
256-
const picker = component.find(DatePicker);
264+
265+
const picker = screen.getByPlaceholderText("YYYY-MM-DD HH:MM:SS");
257266

258267
expect(picker).not.toBeNull();
259-
expect(picker.props().showTimeSelect).toEqual(true);
260-
expect(picker.props().showTimeSelectOnly).toEqual(false);
261-
expect(picker.props().selected).toEqual(new Date(value));
268+
expect(screen.queryByText("Time")).toBeNull();
269+
expect(screen.queryByLabelText("month " + testDate)).toBeNull();
270+
expect(picker.value).toEqual(value);
262271
});
263272

264273
it("renders datetime picker with answer value when no layout class is specified and numeric answer value is used", () => {
265-
const value = Number(new Date());
274+
const date = new Date();
275+
const value = Number(date);
276+
const testDate = format(date, "yyyy-MM");
266277
answer = {
267278
"@id": Generator.getRandomUri(),
268279
};
269280
answer[Constants.HAS_DATA_VALUE] = value;
270281
question[Constants.HAS_ANSWER] = [answer];
271282
question[Constants.LAYOUT_CLASS].push(Constants.LAYOUT.DATETIME);
272283

273-
const component = mount(
284+
render(
274285
<ConfigurationContext.Provider
275286
value={{
276287
componentsOptions,
@@ -281,12 +292,15 @@ describe("Answer component", () => {
281292
<Answer answer={answer} question={question} onChange={onChange} />
282293
</ConfigurationContext.Provider>
283294
);
284-
const picker = component.find(DatePicker);
295+
296+
const picker = screen.getByPlaceholderText("YYYY-MM-DD HH:MM:SS");
285297

286298
expect(picker).not.toBeNull();
287-
expect(picker.props().showTimeSelect).toEqual(true);
288-
expect(picker.props().showTimeSelectOnly).toEqual(false);
289-
expect(picker.props().selected).toEqual(new Date(value));
299+
expect(screen.queryByText("Time")).toBeNull();
300+
expect(screen.queryByLabelText("month " + testDate)).toBeNull();
301+
expect(picker.value).toEqual(
302+
format(new Date(value), "yyyy-MM-dd HH:mm:ss")
303+
);
290304
});
291305

292306
it("renders checkbox with answer value when checkbox layout class is specified", () => {
@@ -297,7 +311,7 @@ describe("Answer component", () => {
297311
question[Constants.HAS_ANSWER] = [answer];
298312
question[Constants.LAYOUT_CLASS].push(Constants.LAYOUT.CHECKBOX);
299313

300-
const component = mount(
314+
render(
301315
<ConfigurationContext.Provider
302316
value={{
303317
componentsOptions,
@@ -308,11 +322,10 @@ describe("Answer component", () => {
308322
<Answer answer={answer} question={question} onChange={onChange} />
309323
</ConfigurationContext.Provider>
310324
);
311-
const input = component.find("input");
325+
const input = screen.getByRole("checkbox");
312326

313327
expect(input).toBeDefined();
314-
expect(input.props().type).toEqual("checkbox");
315-
expect(input.props().checked).toBeTruthy();
328+
expect(input.checked).toBeTruthy();
316329
});
317330

318331
it("renders numeric input with answer value when number layout class is specified", () => {
@@ -324,7 +337,7 @@ describe("Answer component", () => {
324337
question[Constants.HAS_ANSWER] = [answer];
325338
question[Constants.HAS_DATATYPE] = Constants.XSD.INT;
326339

327-
const component = mount(
340+
render(
328341
<ConfigurationContext.Provider
329342
value={{
330343
componentsOptions,
@@ -335,11 +348,12 @@ describe("Answer component", () => {
335348
<Answer answer={answer} question={question} onChange={onChange} />
336349
</ConfigurationContext.Provider>
337350
);
338-
const input = component.find("input");
351+
352+
// Spinbutton is aria role for input with restricted inputs
353+
const input = screen.getByRole("spinbutton");
339354

340355
expect(input).toBeDefined();
341-
expect(input.props().type).toEqual("number");
342-
expect(input.props().value).toEqual(value);
356+
expect(Number(input.value)).toEqual(value);
343357
});
344358

345359
it("renders textarea for answer with long value", () => {
@@ -351,7 +365,7 @@ describe("Answer component", () => {
351365
answer[Constants.HAS_DATA_VALUE] = value;
352366
question[Constants.HAS_ANSWER] = [answer];
353367

354-
const component = mount(
368+
render(
355369
<ConfigurationContext.Provider
356370
value={{
357371
componentsOptions,
@@ -362,10 +376,10 @@ describe("Answer component", () => {
362376
<Answer answer={answer} question={question} onChange={onChange} />
363377
</ConfigurationContext.Provider>
364378
);
365-
const input = component.find("textarea");
379+
const input = screen.getByRole("textbox");
366380

367381
expect(input).toBeDefined();
368-
expect(input.props().value).toEqual(value);
382+
expect(input.value).toEqual(value);
369383
});
370384

371385
it("renders masked input for question with masked-input layout class", () => {
@@ -379,7 +393,7 @@ describe("Answer component", () => {
379393
question[Constants.LAYOUT_CLASS].push(Constants.LAYOUT.MASKED_INPUT);
380394
question[Constants.INPUT_MASK] = mask;
381395

382-
const component = mount(
396+
const container = render(
383397
<ConfigurationContext.Provider
384398
value={{
385399
componentsOptions,
@@ -390,10 +404,10 @@ describe("Answer component", () => {
390404
<Answer answer={answer} question={question} onChange={onChange} />
391405
</ConfigurationContext.Provider>
392406
);
393-
const input = component.find(MaskedInput);
407+
const input = screen.getByRole("textbox");
394408

395409
expect(input).toBeDefined();
396-
expect(input.props().value).toEqual(value);
397-
expect(input.props().mask).toEqual(mask);
410+
expect(input.value).toEqual(value);
411+
expect(document.querySelector("input").getAttribute("mask")).toEqual(mask);
398412
});
399413
});

0 commit comments

Comments
 (0)