Create quizzes

This commit is contained in:
JubaAzul 2025-02-26 12:31:23 -05:00
parent bd7df6dcf5
commit b1d0129128
5 changed files with 156 additions and 19 deletions

View file

@ -1,28 +1,32 @@
const request = require('supertest'); const request = require('supertest');
const express = require('express'); const express = require('express');
const bodyParser = require('body-parser'); const bodyParser = require('body-parser');
const answersRouter = require('../routers/answers.js'); const answersRouter = require('../routers/answers'); // Ensure the correct path
const Answer = require('../models/answer'); const Answer = require('../models/answers');
const app = express(); const app = express();
const cors = require("cors");
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json()); app.use(bodyParser.json());
app.use('/api', answersRouter); app.use('/api', answersRouter);
// Mock the Answer model methods
jest.mock('../models/answers');
describe('Answers API', () => { describe('Answers API', () => {
beforeEach(() => { beforeEach(() => {
// Reset the in-memory database before each test // Clear all instances and calls to constructor and all methods:
while (Answer.getAll().length > 0) { Answer.create.mockClear();
Answer.delete(Answer.getAll()[0].id); Answer.get.mockClear();
} Answer.getAll.mockClear();
Answer.delete.mockClear();
}); });
test('should create a new answer', async () => { test('should create a new answer', async () => {
const mockAnswer = { id: 1, answerText: 'This is an answer', showFeedback: true, points: 10 };
Answer.create.mockReturnValue(mockAnswer);
const response = await request(app) const response = await request(app)
.post('/api/answers') .post('/api/answers')
.send({ answerText: 'This is an answer', showFeedback: true, points: 10,goodAnswer: true}); .send({ answerText: 'This is an answer', showFeedback: true, points: 10 });
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(response.body.message).toBe('Answer created successfully.'); expect(response.body.message).toBe('Answer created successfully.');
@ -30,23 +34,23 @@ describe('Answers API', () => {
expect(response.body.answer.answerText).toBe('This is an answer'); expect(response.body.answer.answerText).toBe('This is an answer');
expect(response.body.answer.showFeedback).toBe(true); expect(response.body.answer.showFeedback).toBe(true);
expect(response.body.answer.points).toBe(10); expect(response.body.answer.points).toBe(10);
expect(response.body.answer.goodAnswer).toBe(true);
}); });
test('should get an answer by ID', async () => { test('should get an answer by ID', async () => {
const answer = Answer.create('This is an answer', true, 10, true); const mockAnswer = { id: 1, answerText: 'This is an answer', showFeedback: true, points: 10 };
const response = await request(app).get(`/api/answers/${answer.id}`); Answer.get.mockReturnValue(mockAnswer);
const response = await request(app).get(`/api/answers/1`);
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(response.body.answerText).toBe('This is an answer'); expect(response.body.answerText).toBe('This is an answer');
expect(response.body.showFeedback).toBe(true); expect(response.body.showFeedback).toBe(true);
expect(response.body.points).toBe(10); expect(response.body.points).toBe(10);
expect(response.body.goodAnswer).toBe(true);
}); });
test('should return 404 if answer not found', async () => { test('should return 404 if answer not found', async () => {
Answer.get.mockReturnValue(null);
const response = await request(app).get('/api/answers/999'); const response = await request(app).get('/api/answers/999');
expect(response.status).toBe(404); expect(response.status).toBe(404);
@ -54,17 +58,21 @@ describe('Answers API', () => {
}); });
test('should delete an answer by ID', async () => { test('should delete an answer by ID', async () => {
const answer = Answer.create('This is an answer', true, 10); const mockAnswer = { id: 1, answerText: 'This is an answer', showFeedback: true, points: 10 };
const response = await request(app).delete(`/api/answers/${answer.id}`); Answer.delete.mockReturnValue(mockAnswer);
const response = await request(app).delete(`/api/answers/1`);
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(response.body.message).toBe('Answer deleted successfully.'); expect(response.body.message).toBe('Answer deleted successfully.');
const getResponse = await request(app).get(`/api/answers/${answer.id}`); const getResponse = await request(app).get(`/api/answers/1`);
expect(getResponse.status).toBe(404); expect(getResponse.status).toBe(404);
}); });
test('should return 404 if deleting an answer that does not exist', async () => { test('should return 404 if deleting an answer that does not exist', async () => {
Answer.delete.mockReturnValue(null);
const response = await request(app).delete('/api/answers/999'); const response = await request(app).delete('/api/answers/999');
expect(response.status).toBe(404); expect(response.status).toBe(404);

View file

@ -22,6 +22,8 @@ const students = require('./models/students.js');
const studentModel = new students(); const studentModel = new students();
const answers = require('./models/answers.js'); const answers = require('./models/answers.js');
const answersModel = new answers(); const answersModel = new answers();
const quizzes = require('./models/quizzes.js');
const quizzesModel = new quizzes();
// instantiate the controllers // instantiate the controllers
const usersController = require('./controllers/users.js'); const usersController = require('./controllers/users.js');
@ -36,6 +38,8 @@ const studentsController = require('./controllers/students.js');
const studentsControllerInstance = new studentsController(studentModel); const studentsControllerInstance = new studentsController(studentModel);
const answersController = require('./controllers/answers.js'); const answersController = require('./controllers/answers.js');
const answersControllerInstance = new answersController(answersModel); const answersControllerInstance = new answersController(answersModel);
const quizzesController = require('./controllers/quizzes.js');
const quizzesControllerInstance = new quizzesController(quizzesModel);
// export the controllers // export the controllers
module.exports.users = usersControllerInstance; module.exports.users = usersControllerInstance;
@ -44,6 +48,7 @@ module.exports.questionnaires = questionnaireControllerInstance;
module.exports.images = imagesControllerInstance; module.exports.images = imagesControllerInstance;
module.exports.students = studentsControllerInstance; module.exports.students = studentsControllerInstance;
module.exports.answers = answersControllerInstance; module.exports.answers = answersControllerInstance;
module.exports.quizzes = quizzesControllerInstance;
//import routers (instantiate controllers as side effect) //import routers (instantiate controllers as side effect)
const userRouter = require('./routers/users.js'); const userRouter = require('./routers/users.js');
@ -52,6 +57,7 @@ const questionnaireRouter = require('./routers/questionnaires.js');
const imagesRouter = require('./routers/images.js'); const imagesRouter = require('./routers/images.js');
const studentsRouter = require('./routers/students.js'); const studentsRouter = require('./routers/students.js');
const answersRouter = require('./routers/answers.js'); const answersRouter = require('./routers/answers.js');
const quizzesRouter = require('./routers/quizzes.js');
// Setup environment // Setup environment
dotenv.config(); dotenv.config();
@ -98,6 +104,7 @@ app.use('/api/questionnaire', questionnaireRouter);
app.use('/api/image', imagesRouter); app.use('/api/image', imagesRouter);
app.use('/api/students', studentsRouter); app.use('/api/students', studentsRouter);
app.use('/api/answers', answersRouter); app.use('/api/answers', answersRouter);
app.use('/api/quizzes', quizzesRouter);
app.use(errorHandler); app.use(errorHandler);

View file

@ -0,0 +1,74 @@
const AppError = require('../middleware/AppError.js');
const { MISSING_REQUIRED_PARAMETER, QUIZ_NOT_FOUND } = require('../constants/errorCodes.js');
class QuizController {
constructor(quizModel) {
this.quizzes = quizModel;
}
create = async (req, res, next) => {
try {
const { students, questionnaire } = req.body;
if (!students || !questionnaire) {
throw new AppError(MISSING_REQUIRED_PARAMETER);
}
const result = this.quizzes.create(students, questionnaire);
return res.status(200).json({
message: 'Quiz created successfully.',
quiz: result
});
} catch (error) {
return next(error);
}
};
get = async (req, res, next) => {
try {
const { quizId } = req.params;
if (!quizId) {
throw new AppError(MISSING_REQUIRED_PARAMETER);
}
const quiz = this.quizzes.get(parseInt(quizId));
if (!quiz) {
throw new AppError(QUIZ_NOT_FOUND);
}
return res.status(200).json(quiz);
} catch (error) {
return next(error);
}
};
delete = async (req, res, next) => {
try {
const { quizId } = req.params;
if (!quizId) {
throw new AppError(MISSING_REQUIRED_PARAMETER);
}
const result = this.quizzes.delete(parseInt(quizId));
if (!result) {
throw new AppError(QUIZ_NOT_FOUND);
}
return res.status(200).json({
message: 'Quiz deleted successfully.'
});
} catch (error) {
return next(error);
}
};
}
module.exports = QuizController;

37
server/models/quizzes.js Normal file
View file

@ -0,0 +1,37 @@
let quizzes = []; // This will act as our in-memory database
class Quiz {
constructor(students, questionnaire) {
this.id = Quiz.generateId();
this.students = students;
this.questionnaire = questionnaire;
}
static generateId() {
return quizzes.length ? quizzes[quizzes.length - 1].id + 1 : 1;
}
static create(students, questionnaire) {
const quiz = new Quiz(students, questionnaire);
quizzes.push(quiz);
return quiz;
}
static get(id) {
return quizzes.find(quiz => quiz.id === id);
}
static getAll() {
return quizzes;
}
static delete(id) {
const index = quizzes.findIndex(quiz => quiz.id === id);
if (index !== -1) {
return quizzes.splice(index, 1)[0];
}
return null;
}
}
module.exports = Quiz;

11
server/routers/quizzes.js Normal file
View file

@ -0,0 +1,11 @@
const express = require('express');
const router = express.Router();
const quizzes = require('../app.js').quizzes;
const jwt = require('../middleware/jwtToken.js');
const asyncHandler = require('./routerUtils.js');
router.post('/create', jwt.authenticate, asyncHandler(quizzes.create));
router.get('/get/:quizId',jwt.authenticate, asyncHandler(quizzes.get));
router.delete('/delete/:quizId', jwt.authenticate, asyncHandler(quizzes.delete));
module.exports = router;