Redesign how answers are submitted and updated (react state management)
This commit is contained in:
C. Fuhrman 2024-09-26 00:34:30 -04:00
parent ab18283db0
commit c0cc4d01e0
10 changed files with 531 additions and 320 deletions

View file

@ -48,7 +48,7 @@ describe('StudentModeQuiz', () => {
fireEvent.click(screen.getByText('Répondre'));
});
expect(mockSubmitAnswer).toHaveBeenCalledWith('Option A', '1');
expect(mockSubmitAnswer).toHaveBeenCalledWith('Option A', 1);
});
test('handles quit button click', async () => {

View file

@ -47,7 +47,7 @@ describe('TeacherModeQuiz', () => {
act(() => {
fireEvent.click(screen.getByText('Répondre'));
});
expect(mockSubmitAnswer).toHaveBeenCalledWith('Option A', '1');
expect(mockSubmitAnswer).toHaveBeenCalledWith('Option A', 1);
expect(screen.getByText('Votre réponse est "Option A".')).toBeInTheDocument();
});

View file

@ -1,7 +1,6 @@
// LiveResults.tsx
import React, { useEffect, useMemo, useState } from 'react';
import React, { useMemo, useState } from 'react';
import { Socket } from 'socket.io-client';
import { GIFTQuestion } from 'gift-pegjs';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCheck, faCircleXmark } from '@fortawesome/free-solid-svg-icons';
import { QuestionType } from '../../Types/QuestionType';
@ -15,11 +14,12 @@ import {
Table,
TableBody,
TableCell,
TableContainer,
TableFooter,
TableHead,
TableRow
} from '@mui/material';
import { StudentType, Answer } from '../../Types/StudentType';
import { StudentType } from '../../Types/StudentType';
import { formatLatex } from '../GiftTemplate/templates/TextType';
interface LiveResultsProps {
@ -27,7 +27,7 @@ interface LiveResultsProps {
questions: QuestionType[];
showSelectedQuestion: (index: number) => void;
quizMode: 'teacher' | 'student';
connectedStudents: StudentType[]
students: StudentType[]
}
// interface Answer {
@ -42,10 +42,10 @@ interface LiveResultsProps {
// answers: Answer[];
// }
const LiveResults: React.FC<LiveResultsProps> = ({ socket, questions, showSelectedQuestion, connectedStudents }) => {
const LiveResults: React.FC<LiveResultsProps> = ({ questions, showSelectedQuestion, students }) => {
const [showUsernames, setShowUsernames] = useState<boolean>(false);
const [showCorrectAnswers, setShowCorrectAnswers] = useState<boolean>(false);
const [students, setStudents] = useState<StudentType[]>(connectedStudents);
// const [students, setStudents] = useState<StudentType[]>(initialStudents);
// const [studentResultsMap, setStudentResultsMap] = useState<Map<string, StudentResult>>(new Map());
const maxQuestions = questions.length;
@ -69,83 +69,77 @@ const LiveResults: React.FC<LiveResultsProps> = ({ socket, questions, showSelect
// }
// }, [students])
useEffect(() => {
// Update the students state when the initialStudents prop changes
setStudents(connectedStudents);
console.log(`useEffect: connectedStudents: ${JSON.stringify(connectedStudents)}`);
}, [connectedStudents]);
// useEffect(() => {
// if (socket) {
// const submitAnswerHandler = ({
// idUser,
// answer,
// idQuestion
// }: {
// idUser: string;
// username: string;
// answer: string | number | boolean;
// idQuestion: number;
// }) => {
// console.log(`Received answer from ${idUser} for question ${idQuestion}: ${answer}`);
useEffect(() => {
if (socket) {
const submitAnswerHandler = ({
idUser,
answer,
idQuestion
}: {
idUser: string;
username: string;
answer: string | number | boolean;
idQuestion: number;
}) => {
console.log(`Received answer from ${idUser} for question ${idQuestion}: ${answer}`);
// print the list of current student names
console.log('Current students:');
students.forEach((student) => {
console.log(student.name);
});
// Update the students state using the functional form of setStudents
setStudents((prevStudents) => {
let foundStudent = false;
const updatedStudents = prevStudents.map((student) => {
if (student.id === idUser) {
foundStudent = true;
const updatedAnswers = student.answers.map((ans) => {
const newAnswer: Answer = { answer, isCorrect: checkIfIsCorrect(answer, idQuestion), idQuestion };
console.log(`Updating answer for ${student.name} for question ${idQuestion} to ${answer}`);
return (ans.idQuestion === idQuestion ? { ...ans, newAnswer } : ans);
}
);
return { ...student, answers: updatedAnswers };
}
return student;
});
if (!foundStudent) {
console.log(`Student ${idUser} not found in the list of students in LiveResults`);
}
return updatedStudents;
});
// make a copy of the students array so we can update it
// const updatedStudents = [...students];
// const student = updatedStudents.find((student) => student.id === idUser);
// if (!student) {
// // this is a bad thing if an answer was submitted but the student isn't in the list
// console.log(`Student ${idUser} not found in the list of students in LiveResults`);
// return;
// }
// const isCorrect = checkIfIsCorrect(answer, idQuestion);
// const newAnswer: Answer = { answer, isCorrect, idQuestion };
// student.answers.push(newAnswer);
// // print list of answers
// console.log('Answers:');
// student.answers.forEach((answer) => {
// console.log(answer.answer);
// // print the list of current student names
// console.log('Current students:');
// students.forEach((student) => {
// console.log(student.name);
// });
// setStudents(updatedStudents); // update the state
};
socket.on('submit-answer', submitAnswerHandler);
return () => {
socket.off('submit-answer');
};
}
}, [socket]);
// // Update the students state using the functional form of setStudents
// setStudents((prevStudents) => {
// let foundStudent = false;
// const updatedStudents = prevStudents.map((student) => {
// if (student.id === idUser) {
// foundStudent = true;
// const updatedAnswers = student.answers.map((ans) => {
// const newAnswer: Answer = { answer, isCorrect: checkIfIsCorrect(answer, idQuestion), idQuestion };
// console.log(`Updating answer for ${student.name} for question ${idQuestion} to ${answer}`);
// return (ans.idQuestion === idQuestion ? { ...ans, newAnswer } : ans);
// }
// );
// return { ...student, answers: updatedAnswers };
// }
// return student;
// });
// if (!foundStudent) {
// console.log(`Student ${idUser} not found in the list of students in LiveResults`);
// }
// return updatedStudents;
// });
// // make a copy of the students array so we can update it
// // const updatedStudents = [...students];
// // const student = updatedStudents.find((student) => student.id === idUser);
// // if (!student) {
// // // this is a bad thing if an answer was submitted but the student isn't in the list
// // console.log(`Student ${idUser} not found in the list of students in LiveResults`);
// // return;
// // }
// // const isCorrect = checkIfIsCorrect(answer, idQuestion);
// // const newAnswer: Answer = { answer, isCorrect, idQuestion };
// // student.answers.push(newAnswer);
// // // print list of answers
// // console.log('Answers:');
// // student.answers.forEach((answer) => {
// // console.log(answer.answer);
// // });
// // setStudents(updatedStudents); // update the state
// };
// socket.on('submit-answer', submitAnswerHandler);
// return () => {
// socket.off('submit-answer');
// };
// }
// }, [socket]);
const getStudentGrade = (student: StudentType): number => {
if (student.answers.length === 0) {
@ -202,73 +196,73 @@ const LiveResults: React.FC<LiveResultsProps> = ({ socket, questions, showSelect
// );
// };
function checkIfIsCorrect(answer: string | number | boolean, idQuestion: number): boolean {
const questionInfo = questions.find((q) =>
q.question.id ? q.question.id === idQuestion.toString() : false
) as QuestionType | undefined;
// function checkIfIsCorrect(answer: string | number | boolean, idQuestion: number): boolean {
// const questionInfo = questions.find((q) =>
// q.question.id ? q.question.id === idQuestion.toString() : false
// ) as QuestionType | undefined;
const answerText = answer.toString();
if (questionInfo) {
const question = questionInfo.question as GIFTQuestion;
if (question.type === 'TF') {
return (
(question.isTrue && answerText == 'true') ||
(!question.isTrue && answerText == 'false')
);
} else if (question.type === 'MC') {
return question.choices.some(
(choice) => choice.isCorrect && choice.text.text === answerText
);
} else if (question.type === 'Numerical') {
if (question.choices && !Array.isArray(question.choices)) {
if (
question.choices.type === 'high-low' &&
question.choices.numberHigh &&
question.choices.numberLow
) {
const answerNumber = parseFloat(answerText);
if (!isNaN(answerNumber)) {
return (
answerNumber <= question.choices.numberHigh &&
answerNumber >= question.choices.numberLow
);
}
}
}
if (question.choices && Array.isArray(question.choices)) {
if (
question.choices[0].text.type === 'range' &&
question.choices[0].text.number &&
question.choices[0].text.range
) {
const answerNumber = parseFloat(answerText);
const range = question.choices[0].text.range;
const correctAnswer = question.choices[0].text.number;
if (!isNaN(answerNumber)) {
return (
answerNumber <= correctAnswer + range &&
answerNumber >= correctAnswer - range
);
}
}
if (
question.choices[0].text.type === 'simple' &&
question.choices[0].text.number
) {
const answerNumber = parseFloat(answerText);
if (!isNaN(answerNumber)) {
return answerNumber === question.choices[0].text.number;
}
}
}
} else if (question.type === 'Short') {
return question.choices.some(
(choice) => choice.text.text.toUpperCase() === answerText.toUpperCase()
);
}
}
return false;
}
// const answerText = answer.toString();
// if (questionInfo) {
// const question = questionInfo.question as GIFTQuestion;
// if (question.type === 'TF') {
// return (
// (question.isTrue && answerText == 'true') ||
// (!question.isTrue && answerText == 'false')
// );
// } else if (question.type === 'MC') {
// return question.choices.some(
// (choice) => choice.isCorrect && choice.text.text === answerText
// );
// } else if (question.type === 'Numerical') {
// if (question.choices && !Array.isArray(question.choices)) {
// if (
// question.choices.type === 'high-low' &&
// question.choices.numberHigh &&
// question.choices.numberLow
// ) {
// const answerNumber = parseFloat(answerText);
// if (!isNaN(answerNumber)) {
// return (
// answerNumber <= question.choices.numberHigh &&
// answerNumber >= question.choices.numberLow
// );
// }
// }
// }
// if (question.choices && Array.isArray(question.choices)) {
// if (
// question.choices[0].text.type === 'range' &&
// question.choices[0].text.number &&
// question.choices[0].text.range
// ) {
// const answerNumber = parseFloat(answerText);
// const range = question.choices[0].text.range;
// const correctAnswer = question.choices[0].text.number;
// if (!isNaN(answerNumber)) {
// return (
// answerNumber <= correctAnswer + range &&
// answerNumber >= correctAnswer - range
// );
// }
// }
// if (
// question.choices[0].text.type === 'simple' &&
// question.choices[0].text.number
// ) {
// const answerNumber = parseFloat(answerText);
// if (!isNaN(answerNumber)) {
// return answerNumber === question.choices[0].text.number;
// }
// }
// }
// } else if (question.type === 'Short') {
// return question.choices.some(
// (choice) => choice.text.text.toUpperCase() === answerText.toUpperCase()
// );
// }
// }
// return false;
// }
return (
<div>
@ -301,7 +295,8 @@ const LiveResults: React.FC<LiveResultsProps> = ({ socket, questions, showSelect
</div>
<div className="table-container">
<Table size="small" component={Paper}>
<TableContainer component={Paper}>
<Table size="small">
<TableHead>
<TableRow>
<TableCell className="sticky-column">
@ -439,6 +434,7 @@ const LiveResults: React.FC<LiveResultsProps> = ({ socket, questions, showSelect
</TableRow>
</TableFooter>
</Table>
</TableContainer>
</div>
</div>
);

View file

@ -12,7 +12,7 @@ import DisconnectButton from '../../components/DisconnectButton/DisconnectButton
interface StudentModeQuizProps {
questions: QuestionType[];
submitAnswer: (answer: string | number | boolean, idQuestion: string) => void;
submitAnswer: (answer: string | number | boolean, idQuestion: number) => void;
disconnectWebSocket: () => void;
}
@ -38,7 +38,7 @@ const StudentModeQuiz: React.FC<StudentModeQuizProps> = ({
};
const handleOnSubmitAnswer = (answer: string | number | boolean) => {
const idQuestion = questionInfos.question.id || '-1';
const idQuestion = Number(questionInfos.question.id) || -1;
submitAnswer(answer, idQuestion);
setIsAnswerSubmitted(true);
};

View file

@ -11,7 +11,7 @@ import { Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@mui/
interface TeacherModeQuizProps {
questionInfos: QuestionType;
submitAnswer: (answer: string | number | boolean, idQuestion: string) => void;
submitAnswer: (answer: string | number | boolean, idQuestion: number) => void;
disconnectWebSocket: () => void;
}
@ -29,7 +29,7 @@ const TeacherModeQuiz: React.FC<TeacherModeQuizProps> = ({
}, [questionInfos]);
const handleOnSubmitAnswer = (answer: string | number | boolean) => {
const idQuestion = questionInfos.question.id || '-1';
const idQuestion = Number(questionInfos.question.id) || -1;
submitAnswer(answer, idQuestion);
setFeedbackMessage(`Votre réponse est "${answer.toString()}".`);
setIsFeedbackDialogOpen(true);

View file

@ -5,7 +5,7 @@ import { ENV_VARIABLES } from '../../../constants';
import StudentModeQuiz from '../../../components/StudentModeQuiz/StudentModeQuiz';
import TeacherModeQuiz from '../../../components/TeacherModeQuiz/TeacherModeQuiz';
import webSocketService from '../../../services/WebsocketService';
import webSocketService, { AnswerSubmissionToBackendType } from '../../../services/WebsocketService';
import DisconnectButton from '../../../components/DisconnectButton/DisconnectButton';
import './joinRoom.css';
@ -99,8 +99,15 @@ const JoinRoom: React.FC = () => {
}
};
const handleOnSubmitAnswer = (answer: string | number | boolean, idQuestion: string) => {
webSocketService.submitAnswer(roomName, answer, username, idQuestion);
const handleOnSubmitAnswer = (answer: string | number | boolean, idQuestion: number) => {
const answerData: AnswerSubmissionToBackendType = {
roomName: roomName,
answer: answer,
username: username,
idQuestion: idQuestion
};
webSocketService.submitAnswer(answerData);
};
if (isWaitingForTeacher) {

View file

@ -2,16 +2,16 @@
import React, { useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { Socket } from 'socket.io-client';
import { parse } from 'gift-pegjs';
import { GIFTQuestion, parse } from 'gift-pegjs';
import { QuestionType } from '../../../Types/QuestionType';
import LiveResultsComponent from '../../../components/LiveResults/LiveResults';
// import { QuestionService } from '../../../services/QuestionService';
import webSocketService from '../../../services/WebsocketService';
import webSocketService, { AnswerReceptionFromBackendType } from '../../../services/WebsocketService';
import { QuizType } from '../../../Types/QuizType';
import './manageRoom.css';
import { ENV_VARIABLES } from '../../../constants';
import { StudentType } from '../../../Types/StudentType';
import { StudentType, Answer } from '../../../Types/StudentType';
import { Button } from '@mui/material';
import LoadingCircle from '../../../components/LoadingCircle/LoadingCircle';
import { Refresh, Error } from '@mui/icons-material';
@ -121,10 +121,9 @@ const ManageRoom: React.FC = () => {
useEffect(() => {
// This is here to make sure the correct value is sent when user join
if (socket) {
console.log(`Listening for user-joined in room ${roomName}`);
socket.on('user-joined', (_student: StudentType) => {
// setUsers((prevUsers) => [...prevUsers, user]);
if (quizMode === 'teacher') {
webSocketService.nextQuestion(roomName, currentQuestion);
} else if (quizMode === 'student') {
@ -132,7 +131,122 @@ const ManageRoom: React.FC = () => {
}
});
}
}, [currentQuestion, quizQuestions]);
if (socket) {
// handle the case where user submits an answer
console.log(`Listening for submit-answer-room in room ${roomName}`);
socket.on('submit-answer-room', (answerData: AnswerReceptionFromBackendType) => {
const { answer, idQuestion, idUser, username } = answerData;
console.log(`Received answer from ${username} for question ${idQuestion}: ${answer}`);
if (!quizQuestions) {
console.log('Quiz questions not found (cannot update answers without them).');
return;
}
// Update the students state using the functional form of setStudents
setStudents((prevStudents) => {
// print the list of current student names
console.log('Current students:');
prevStudents.forEach((student) => {
console.log(student.name);
});
let foundStudent = false;
const updatedStudents = prevStudents.map((student) => {
console.log(`Comparing ${student.id} to ${idUser}`);
if (student.id === idUser) {
foundStudent = true;
const existingAnswer = student.answers.find((ans) => ans.idQuestion === idQuestion);
let updatedAnswers: Answer[] = [];
if (existingAnswer) {
// Update the existing answer
updatedAnswers = student.answers.map((ans) => {
console.log(`Comparing ${ans.idQuestion} to ${idQuestion}`);
return (ans.idQuestion === idQuestion ? { ...ans, answer, isCorrect: checkIfIsCorrect(answer, idQuestion, quizQuestions!) } : ans);
});
} else {
// Add a new answer
const newAnswer = { idQuestion, answer, isCorrect: checkIfIsCorrect(answer, idQuestion, quizQuestions!) };
updatedAnswers = [...student.answers, newAnswer];
}
return { ...student, answers: updatedAnswers };
}
return student;
});
if (!foundStudent) {
console.log(`Student ${username} not found in the list.`);
}
return updatedStudents;
});
});
setSocket(socket);
}
}, [socket, currentQuestion, quizQuestions]);
// useEffect(() => {
// if (socket) {
// const submitAnswerHandler = (answerData: answerSubmissionType) => {
// const { answer, idQuestion, username } = answerData;
// console.log(`Received answer from ${username} for question ${idQuestion}: ${answer}`);
// // print the list of current student names
// console.log('Current students:');
// students.forEach((student) => {
// console.log(student.name);
// });
// // Update the students state using the functional form of setStudents
// setStudents((prevStudents) => {
// let foundStudent = false;
// const updatedStudents = prevStudents.map((student) => {
// if (student.id === username) {
// foundStudent = true;
// const updatedAnswers = student.answers.map((ans) => {
// const newAnswer: Answer = { answer, isCorrect: checkIfIsCorrect(answer, idQuestion, quizQuestions!), idQuestion };
// console.log(`Updating answer for ${student.name} for question ${idQuestion} to ${answer}`);
// return (ans.idQuestion === idQuestion ? { ...ans, newAnswer } : ans);
// }
// );
// return { ...student, answers: updatedAnswers };
// }
// return student;
// });
// if (!foundStudent) {
// console.log(`Student ${username} not found in the list of students in LiveResults`);
// }
// return updatedStudents;
// });
// // make a copy of the students array so we can update it
// // const updatedStudents = [...students];
// // const student = updatedStudents.find((student) => student.id === idUser);
// // if (!student) {
// // // this is a bad thing if an answer was submitted but the student isn't in the list
// // console.log(`Student ${idUser} not found in the list of students in LiveResults`);
// // return;
// // }
// // const isCorrect = checkIfIsCorrect(answer, idQuestion);
// // const newAnswer: Answer = { answer, isCorrect, idQuestion };
// // student.answers.push(newAnswer);
// // // print list of answers
// // console.log('Answers:');
// // student.answers.forEach((answer) => {
// // console.log(answer.answer);
// // });
// // setStudents(updatedStudents); // update the state
// };
// socket.on('submit-answer', submitAnswerHandler);
// return () => {
// socket.off('submit-answer');
// };
// }
// }, [socket]);
const nextQuestion = () => {
if (!quizQuestions || !currentQuestion || !quiz?.content) return;
@ -173,8 +287,12 @@ const ManageRoom: React.FC = () => {
const launchTeacherMode = () => {
const quizQuestions = initializeQuizQuestion();
console.log('launchTeacherMode - quizQuestions:', quizQuestions);
if (!quizQuestions) return;
if (!quizQuestions) {
console.log('Error launching quiz (launchTeacherMode). No questions found.');
return;
}
setCurrentQuestion(quizQuestions[0]);
webSocketService.nextQuestion(roomName, quizQuestions[0]);
@ -182,18 +300,20 @@ const ManageRoom: React.FC = () => {
const launchStudentMode = () => {
const quizQuestions = initializeQuizQuestion();
console.log('launchStudentMode - quizQuestions:', quizQuestions);
if (!quizQuestions) {
console.log('Error launching quiz (launchStudentMode). No questions found.');
return;
}
setQuizQuestions(quizQuestions);
webSocketService.launchStudentModeQuiz(roomName, quizQuestions);
};
const launchQuiz = () => {
if (!socket || !roomName || !quiz?.content || quiz?.content.length === 0) {
// TODO: This error happens when token expires! Need to handle it properly
console.log('Error launching quiz. No socket, room name or no questions.');
console.log(`Error launching quiz. socket: ${socket}, roomName: ${roomName}, quiz: ${quiz}`);
return;
}
switch (quizMode) {
@ -219,6 +339,75 @@ const ManageRoom: React.FC = () => {
navigate('/teacher/dashboard');
};
function checkIfIsCorrect(answer: string | number | boolean, idQuestion: number, questions: QuestionType[]): boolean {
const questionInfo = questions.find((q) =>
q.question.id ? q.question.id === idQuestion.toString() : false
) as QuestionType | undefined;
const answerText = answer.toString();
if (questionInfo) {
const question = questionInfo.question as GIFTQuestion;
if (question.type === 'TF') {
return (
(question.isTrue && answerText == 'true') ||
(!question.isTrue && answerText == 'false')
);
} else if (question.type === 'MC') {
return question.choices.some(
(choice) => choice.isCorrect && choice.text.text === answerText
);
} else if (question.type === 'Numerical') {
if (question.choices && !Array.isArray(question.choices)) {
if (
question.choices.type === 'high-low' &&
question.choices.numberHigh &&
question.choices.numberLow
) {
const answerNumber = parseFloat(answerText);
if (!isNaN(answerNumber)) {
return (
answerNumber <= question.choices.numberHigh &&
answerNumber >= question.choices.numberLow
);
}
}
}
if (question.choices && Array.isArray(question.choices)) {
if (
question.choices[0].text.type === 'range' &&
question.choices[0].text.number &&
question.choices[0].text.range
) {
const answerNumber = parseFloat(answerText);
const range = question.choices[0].text.range;
const correctAnswer = question.choices[0].text.number;
if (!isNaN(answerNumber)) {
return (
answerNumber <= correctAnswer + range &&
answerNumber >= correctAnswer - range
);
}
}
if (
question.choices[0].text.type === 'simple' &&
question.choices[0].text.number
) {
const answerNumber = parseFloat(answerText);
if (!isNaN(answerNumber)) {
return answerNumber === question.choices[0].text.number;
}
}
}
} else if (question.type === 'Short') {
return question.choices.some(
(choice) => choice.text.text.toUpperCase() === answerText.toUpperCase()
);
}
}
return false;
}
if (!roomName) {
return (
<div className="center">
@ -258,7 +447,7 @@ const ManageRoom: React.FC = () => {
<div className='dumb'></div>
</div>
{/* the following breaks the css (if 'room' classes are nested) */}
{/* the following breaks the css (if 'room' classes are nested) */}
<div className=''>
{quizQuestions ? (
@ -295,7 +484,7 @@ const ManageRoom: React.FC = () => {
socket={socket}
questions={quizQuestions}
showSelectedQuestion={showSelectedQuestion}
connectedStudents={students}
students={students}
></LiveResultsComponent>
</div>

View file

@ -1,6 +1,22 @@
// WebSocketService.tsx
import { io, Socket } from 'socket.io-client';
// Must (manually) sync these types to server/socket/socket.js
export type AnswerSubmissionToBackendType = {
roomName: string;
username: string;
answer: string | number | boolean;
idQuestion: number;
};
export type AnswerReceptionFromBackendType = {
idUser: string;
username: string;
answer: string | number | boolean;
idQuestion: number;
};
class WebSocketService {
private socket: Socket | null = null;
@ -51,19 +67,22 @@ class WebSocketService {
}
}
submitAnswer(
roomName: string,
answer: string | number | boolean,
username: string,
idQuestion: string
submitAnswer(answerData: AnswerSubmissionToBackendType
// roomName: string,
// answer: string | number | boolean,
// username: string,
// idQuestion: string
) {
if (this.socket) {
this.socket?.emit('submit-answer', {
answer: answer,
roomName: roomName,
username: username,
idQuestion: idQuestion
});
this.socket?.emit('submit-answer',
// {
// answer: answer,
// roomName: roomName,
// username: username,
// idQuestion: idQuestion
// }
answerData
);
}
}
}

View file

@ -125,7 +125,7 @@ describe("websocket server", () => {
answer: "answer1",
idQuestion: 1,
});
teacherSocket.on("submit-answer", (answer) => {
teacherSocket.on("submit-answer-room", (answer) => {
expect(answer).toEqual({
idUser: studentSocket.id,
username: "student1",

View file

@ -101,7 +101,7 @@ const setupWebsocket = (io) => {
});
socket.on("submit-answer", ({ roomName, username, answer, idQuestion }) => {
socket.to(roomName).emit("submit-answer", {
socket.to(roomName).emit("submit-answer-room", {
idUser: socket.id,
username,
answer,