Skip to content

Commit f236fa9

Browse files
authored
Merge pull request #51 from jolynloh/qa/d2-test
Write tests for create and update questions
2 parents 4fd4834 + 62575ad commit f236fa9

File tree

2 files changed

+266
-1
lines changed

2 files changed

+266
-1
lines changed

backend/question-service/tests/questionRoutes.spec.ts

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ import supertest from "supertest";
44
import app from "../app";
55
import Question from "../src/models/Question";
66
import {
7+
DUPLICATE_QUESTION_MESSAGE,
8+
MONGO_OBJ_ID_MALFORMED_MESSAGE,
79
PAGE_LIMIT_INCORRECT_FORMAT_MESSAGE,
810
PAGE_LIMIT_REQUIRED_MESSAGE,
11+
QN_DESC_CHAR_LIMIT,
12+
QN_DESC_EXCEED_CHAR_LIMIT_MESSAGE,
913
QN_NOT_FOUND_MESSAGE,
1014
SERVER_ERROR_MESSAGE,
1115
} from "../src/utils/constants";
@@ -166,4 +170,265 @@ describe("Question routes", () => {
166170
expect(res.body.message).toBe(QN_NOT_FOUND_MESSAGE);
167171
});
168172
});
173+
174+
describe("POST /", () => {
175+
it("Creates new question", async () => {
176+
const title = faker.lorem.lines(1);
177+
const complexity = "Easy";
178+
const categories = ["Algorithms"];
179+
const description = faker.lorem.lines(5);
180+
const newQuestion = {
181+
title,
182+
complexity,
183+
category: categories,
184+
description,
185+
};
186+
187+
const res = await request.post(`${BASE_URL}`).send(newQuestion);
188+
189+
expect(res.status).toBe(201);
190+
expect(res.body.question.title).toBe(title);
191+
expect(res.body.question.complexity).toBe(complexity);
192+
expect(res.body.question.categories).toEqual(categories);
193+
expect(res.body.question.description).toBe(description);
194+
});
195+
196+
it("Does not create duplicate questions (case-insensitive, upper case)", async () => {
197+
const title = faker.lorem.lines(1);
198+
const complexity = "Easy";
199+
const categories = ["Algorithms"];
200+
const description = faker.lorem.lines(5);
201+
const newQuestion = new Question({
202+
title,
203+
complexity,
204+
category: categories,
205+
description,
206+
});
207+
208+
await newQuestion.save();
209+
210+
const duplicateTitle = title.toUpperCase();
211+
const duplicateQuestion = {
212+
title: duplicateTitle,
213+
complexity,
214+
category: categories,
215+
description,
216+
};
217+
218+
const res = await request.post(`${BASE_URL}`).send(duplicateQuestion);
219+
220+
expect(res.status).toBe(400);
221+
expect(res.body.message).toBe(DUPLICATE_QUESTION_MESSAGE);
222+
});
223+
224+
it("Does not create duplicate questions (case-insensitive, lower case)", async () => {
225+
const title = faker.lorem.lines(1);
226+
const complexity = "Easy";
227+
const categories = ["Algorithms"];
228+
const description = faker.lorem.lines(5);
229+
const newQuestion = new Question({
230+
title,
231+
complexity,
232+
category: categories,
233+
description,
234+
});
235+
236+
await newQuestion.save();
237+
238+
const duplicateTitle = title.toLowerCase();
239+
const duplicateQuestion = {
240+
title: duplicateTitle,
241+
complexity,
242+
category: categories,
243+
description,
244+
};
245+
246+
const res = await request.post(`${BASE_URL}`).send(duplicateQuestion);
247+
248+
expect(res.status).toBe(400);
249+
expect(res.body.message).toBe(DUPLICATE_QUESTION_MESSAGE);
250+
});
251+
252+
it("Does not create questions that exceed the character limit", async () => {
253+
const title = faker.lorem.lines(1);
254+
const complexity = "Easy";
255+
const categories = ["Algorithms"];
256+
const description = faker.lorem.words(QN_DESC_CHAR_LIMIT + 5);
257+
const newQuestion = {
258+
title,
259+
complexity,
260+
category: categories,
261+
description,
262+
};
263+
264+
const res = await request.post(`${BASE_URL}`).send(newQuestion);
265+
266+
expect(res.status).toBe(400);
267+
expect(res.body.message).toBe(QN_DESC_EXCEED_CHAR_LIMIT_MESSAGE);
268+
});
269+
});
270+
271+
describe("PUT /:id", () => {
272+
it("Updates an existing question", async () => {
273+
const title = faker.lorem.lines(1);
274+
const complexity = "Easy";
275+
const categories = ["Algorithms"];
276+
const description = faker.lorem.lines(5);
277+
const newQuestion = new Question({
278+
title,
279+
complexity,
280+
category: categories,
281+
description,
282+
});
283+
284+
await newQuestion.save();
285+
286+
const updatedTitle = title.toUpperCase();
287+
const updatedQuestion = {
288+
title: updatedTitle,
289+
complexity,
290+
category: categories,
291+
description,
292+
};
293+
294+
const res = await request
295+
.put(`${BASE_URL}/${newQuestion.id}`)
296+
.send(updatedQuestion);
297+
298+
expect(res.status).toBe(200);
299+
expect(res.body.question.title).toBe(updatedTitle);
300+
expect(res.body.question.complexity).toBe(complexity);
301+
expect(res.body.question.categories).toEqual(categories);
302+
expect(res.body.question.description).toBe(description);
303+
});
304+
305+
it("Does not update non-existing question with invalid object id", async () => {
306+
const title = faker.lorem.lines(1);
307+
const complexity = "Easy";
308+
const categories = ["Algorithms"];
309+
const description = faker.lorem.lines(5);
310+
const newQuestion = new Question({
311+
title,
312+
complexity,
313+
category: categories,
314+
description,
315+
});
316+
317+
await newQuestion.save();
318+
319+
const updatedCategories = ["Algorithms", "Brainteaser"];
320+
const updatedQuestion = {
321+
title,
322+
complexity,
323+
category: updatedCategories,
324+
description,
325+
};
326+
327+
const res = await request.put(`${BASE_URL}/blah`).send(updatedQuestion);
328+
329+
expect(res.status).toBe(400);
330+
expect(res.body.message).toBe(MONGO_OBJ_ID_MALFORMED_MESSAGE);
331+
});
332+
333+
it("Does not update non-existing question with valid object id", async () => {
334+
const title = faker.lorem.lines(1);
335+
const complexity = "Easy";
336+
const categories = ["Algorithms"];
337+
const description = faker.lorem.lines(5);
338+
const newQuestion = new Question({
339+
title,
340+
complexity,
341+
category: categories,
342+
description,
343+
});
344+
345+
await newQuestion.save();
346+
347+
const updatedCategories = ["Algorithms", "Brainteaser"];
348+
const updatedQuestion = {
349+
title,
350+
complexity,
351+
category: updatedCategories,
352+
description,
353+
};
354+
355+
const res = await request
356+
.put(`${BASE_URL}/66f77e9f27ab3f794bdae664`)
357+
.send(updatedQuestion);
358+
359+
expect(res.status).toBe(404);
360+
expect(res.body.message).toBe(QN_NOT_FOUND_MESSAGE);
361+
});
362+
363+
it("Does not update an existing question if it causes a duplicate", async () => {
364+
const title = faker.lorem.lines(1);
365+
const complexity = "Easy";
366+
const categories = ["Algorithms"];
367+
const description = faker.lorem.lines(5);
368+
const newQuestion = new Question({
369+
title,
370+
complexity,
371+
category: categories,
372+
description,
373+
});
374+
375+
await newQuestion.save();
376+
377+
const otherTitle = faker.lorem.lines(1);
378+
const otherComplexity = "Medium";
379+
const otherCategories = ["String", "Data Structures"];
380+
const otherDescription = faker.lorem.lines(5);
381+
const otherQuestion = new Question({
382+
title: otherTitle,
383+
complexity: otherComplexity,
384+
category: otherCategories,
385+
description: otherDescription,
386+
});
387+
388+
await otherQuestion.save();
389+
390+
const updatedQuestion = {
391+
title: otherTitle.toLowerCase(),
392+
complexity,
393+
category: categories,
394+
description,
395+
};
396+
397+
const res = await request
398+
.put(`${BASE_URL}/${newQuestion.id}`)
399+
.send(updatedQuestion);
400+
401+
expect(res.status).toBe(400);
402+
expect(res.body.message).toBe(DUPLICATE_QUESTION_MESSAGE);
403+
});
404+
405+
it("Does not update an existing question if it exceeds the character limit", async () => {
406+
const title = faker.lorem.lines(1);
407+
const complexity = "Easy";
408+
const categories = ["Algorithms"];
409+
const description = faker.lorem.lines(5);
410+
const newQuestion = new Question({
411+
title,
412+
complexity,
413+
category: categories,
414+
description,
415+
});
416+
417+
await newQuestion.save();
418+
419+
const updatedQuestion = {
420+
title,
421+
complexity,
422+
category: categories,
423+
description: faker.lorem.words(QN_DESC_CHAR_LIMIT + 5),
424+
};
425+
426+
const res = await request
427+
.put(`${BASE_URL}/${newQuestion.id}`)
428+
.send(updatedQuestion);
429+
430+
expect(res.status).toBe(400);
431+
expect(res.body.message).toBe(QN_DESC_EXCEED_CHAR_LIMIT_MESSAGE);
432+
});
433+
});
169434
});

backend/question-service/tests/setup.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ beforeAll(async () => {
1010
if (mongoose.connection.readyState !== 0) {
1111
await mongoose.disconnect();
1212
}
13-
13+
1414
await mongoose.connect(mongoUri, {});
1515
});
1616

0 commit comments

Comments
 (0)