diff --git a/client/src/__tests__/pages/ManageRoom/ManageRoom.test.tsx b/client/src/__tests__/pages/ManageRoom/ManageRoom.test.tsx index 01957df..beaa7b2 100644 --- a/client/src/__tests__/pages/ManageRoom/ManageRoom.test.tsx +++ b/client/src/__tests__/pages/ManageRoom/ManageRoom.test.tsx @@ -75,36 +75,36 @@ describe('ManageRoom', () => { ); }); - + await act(async () => { const createSuccessCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'create-success')[1]; createSuccessCallback('Test Room'); }); - + await waitFor(() => { expect(ApiService.getQuiz).toHaveBeenCalledWith('test-quiz-id'); }); - + const launchButton = screen.getByText('Lancer'); fireEvent.click(launchButton); - + const rythmeButton = screen.getByText('Rythme du professeur'); fireEvent.click(rythmeButton); - + const secondLaunchButton = screen.getAllByText('Lancer'); fireEvent.click(secondLaunchButton[1]); - + await waitFor(() => { expect(screen.getByText('Test Quiz')).toBeInTheDocument(); - + const roomHeader = document.querySelector('h1'); expect(roomHeader).toHaveTextContent('Salle : TEST ROOM'); - + expect(screen.getByText('0/60')).toBeInTheDocument(); expect(screen.getByText('Question 1/2')).toBeInTheDocument(); }); }); - + test('handles create-success event', async () => { await act(async () => { render( @@ -171,30 +171,30 @@ describe('ManageRoom', () => { ); }); - + await act(async () => { const createSuccessCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'create-success')[1]; createSuccessCallback('Test Room'); }); - + fireEvent.click(screen.getByText('Lancer')); fireEvent.click(screen.getByText('Rythme du professeur')); fireEvent.click(screen.getAllByText('Lancer')[1]); - + await waitFor(() => { screen.debug(); }); - + const nextQuestionButton = await screen.findByRole('button', { name: /Prochaine question/i }); expect(nextQuestionButton).toBeInTheDocument(); - + fireEvent.click(nextQuestionButton); - + await waitFor(() => { expect(screen.getByText('Question 2/2')).toBeInTheDocument(); }); }); - + test('handles disconnect', async () => { await act(async () => { render( @@ -230,38 +230,38 @@ describe('ManageRoom', () => { ); }); - + await act(async () => { const createSuccessCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'create-success')[1]; createSuccessCallback('Test Room'); }); - + const launchButton = screen.getByText('Lancer'); fireEvent.click(launchButton); - + const rythmeButton = screen.getByText('Rythme du professeur'); fireEvent.click(rythmeButton); - + const secondLaunchButton = screen.getAllByText('Lancer'); fireEvent.click(secondLaunchButton[1]); - + await act(async () => { const userJoinedCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'user-joined')[1]; userJoinedCallback(mockStudents[0]); }); - + await act(async () => { const submitAnswerCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'submit-answer-room')[1]; submitAnswerCallback(mockAnswerData); }); - + await waitFor(() => { // console.info(consoleSpy.mock.calls); expect(consoleSpy).toHaveBeenCalledWith( 'Received answer from Student 1 for question 1: Answer1' ); }); - + consoleSpy.mockRestore(); }); @@ -294,5 +294,66 @@ describe('ManageRoom', () => { expect(screen.queryByText('Student 1')).not.toBeInTheDocument(); }); }); + test('initializes isQuestionShown based on quizMode', async() => { + render( + + ); + + await act(async () => { + const createSuccessCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'create-success')[1]; + createSuccessCallback('Test Room'); + }); + + await waitFor(() => { + expect(ApiService.getQuiz).toHaveBeenCalledWith('test-quiz-id'); + }); + const launchButton = screen.getByText('Lancer'); + fireEvent.click(launchButton); + + const rythmeButton = screen.getByText(`Rythme de l'étudiant`); + fireEvent.click(rythmeButton); + + const secondLaunchButton = screen.getAllByText('Lancer'); + fireEvent.click(secondLaunchButton[1]); + + expect(screen.queryByText('Question')).not.toBeInTheDocument(); + }); + + test('renders the close button when quizMode is student and isQuestionShown is true', async() => { + render( + + ); + + await act(async () => { + const createSuccessCallback = (mockSocket.on as jest.Mock).mock.calls.find(call => call[0] === 'create-success')[1]; + createSuccessCallback('Test Room'); + }); + + await waitFor(() => { + expect(ApiService.getQuiz).toHaveBeenCalledWith('test-quiz-id'); + }); + + const launchButton = screen.getByText('Lancer'); + fireEvent.click(launchButton); + + const rythmeButton = screen.getByText(`Rythme de l'étudiant`); + fireEvent.click(rythmeButton); + + const secondLaunchButton = screen.getAllByText('Lancer'); + fireEvent.click(secondLaunchButton[1]); + + const tableHeader = screen.getByText('Q1'); + fireEvent.click(tableHeader); + + const questionVisibilitySwitch = screen.getByTestId('question-visibility-switch'); // Get the specific switch + expect(screen.getByText(/Question 1\//i)).toBeInTheDocument(); + + fireEvent.click(questionVisibilitySwitch); + + expect(screen.queryByRole('button', { name: /✖/i })).not.toBeInTheDocument(); + expect(screen.queryByText(/Question 1\//i)).not.toBeInTheDocument(); + + }); + }); diff --git a/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx b/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx index 8c3d699..37489c1 100644 --- a/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx +++ b/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx @@ -18,14 +18,14 @@ import DisconnectButton from 'src/components/DisconnectButton/DisconnectButton'; import QuestionDisplay from 'src/components/QuestionsDisplay/QuestionDisplay'; import ApiService from '../../../services/ApiService'; import { QuestionType } from 'src/Types/QuestionType'; -import { Button } from '@mui/material'; +import { Button, FormControlLabel, Switch } from '@mui/material'; import { checkIfIsCorrect } from './useRooms'; const ManageRoom: React.FC = () => { const navigate = useNavigate(); const [socket, setSocket] = useState(null); const [students, setStudents] = useState([]); - const { quizId = '', roomName = '' } = useParams<{ quizId: string, roomName: string }>(); + const { quizId = '', roomName = '' } = useParams<{ quizId: string, roomName: string }>(); const [quizQuestions, setQuizQuestions] = useState(); const [quiz, setQuiz] = useState(null); const [quizMode, setQuizMode] = useState<'teacher' | 'student'>('teacher'); @@ -34,6 +34,7 @@ const ManageRoom: React.FC = () => { const [quizStarted, setQuizStarted] = useState(false); const [formattedRoomName, setFormattedRoomName] = useState(""); const [newlyConnectedUser, setNewlyConnectedUser] = useState(null); + const [isQuestionShown, setIsQuestionShown] = useState(quizMode === 'student' ? false : true); // Handle the newly connected user in useEffect, because it needs state info // not available in the socket.on() callback @@ -41,13 +42,13 @@ const ManageRoom: React.FC = () => { if (newlyConnectedUser) { console.log(`Handling newly connected user: ${newlyConnectedUser.name}`); setStudents((prevStudents) => [...prevStudents, newlyConnectedUser]); - + // only send nextQuestion if the quiz has started if (!quizStarted) { console.log(`!quizStarted: returning.... `); return; } - + if (quizMode === 'teacher') { webSocketService.nextQuestion({ roomName: formattedRoomName, @@ -60,12 +61,16 @@ const ManageRoom: React.FC = () => { } else { console.error('Invalid quiz mode:', quizMode); } - + // Reset the newly connected user state setNewlyConnectedUser(null); } }, [newlyConnectedUser]); + useEffect(() => { + setIsQuestionShown(quizMode === 'student' ? false : true); + }, [quizMode]); + useEffect(() => { const verifyLogin = async () => { if (!ApiService.isLoggedIn()) { @@ -91,7 +96,7 @@ const ManageRoom: React.FC = () => { return () => { disconnectWebSocket(); }; - }, [roomName, navigate]); + }, [roomName, navigate]); useEffect(() => { if (quizId) { @@ -213,14 +218,14 @@ const ManageRoom: React.FC = () => { console.log(`Comparing ${ans.idQuestion} to ${idQuestion}`); return ans.idQuestion === idQuestion ? { - ...ans, - answer, - isCorrect: checkIfIsCorrect( - answer, - idQuestion, - quizQuestions! - ) - } + ...ans, + answer, + isCorrect: checkIfIsCorrect( + answer, + idQuestion, + quizQuestions! + ) + } : ans; }); } else { @@ -253,10 +258,12 @@ const ManageRoom: React.FC = () => { if (nextQuestionIndex === undefined || nextQuestionIndex > quizQuestions.length - 1) return; setCurrentQuestion(quizQuestions[nextQuestionIndex]); - webSocketService.nextQuestion({roomName: formattedRoomName, - questions: quizQuestions, - questionIndex: nextQuestionIndex, - isLaunch: false}); + webSocketService.nextQuestion({ + roomName: formattedRoomName, + questions: quizQuestions, + questionIndex: nextQuestionIndex, + isLaunch: false + }); }; const previousQuestion = () => { @@ -266,7 +273,7 @@ const ManageRoom: React.FC = () => { if (prevQuestionIndex === undefined || prevQuestionIndex < 0) return; setCurrentQuestion(quizQuestions[prevQuestionIndex]); - webSocketService.nextQuestion({roomName: formattedRoomName, questions: quizQuestions, questionIndex: prevQuestionIndex, isLaunch: false}); + webSocketService.nextQuestion({ roomName: formattedRoomName, questions: quizQuestions, questionIndex: prevQuestionIndex, isLaunch: false }); }; const initializeQuizQuestion = () => { @@ -294,7 +301,7 @@ const ManageRoom: React.FC = () => { } setCurrentQuestion(quizQuestions[0]); - webSocketService.nextQuestion({roomName: formattedRoomName, questions: quizQuestions, questionIndex: 0, isLaunch: true}); + webSocketService.nextQuestion({ roomName: formattedRoomName, questions: quizQuestions, questionIndex: 0, isLaunch: true }); }; const launchStudentMode = () => { @@ -306,6 +313,7 @@ const ManageRoom: React.FC = () => { return; } setQuizQuestions(quizQuestions); + setCurrentQuestion(quizQuestions[0]); webSocketService.launchStudentModeQuiz(formattedRoomName, quizQuestions); }; @@ -331,9 +339,11 @@ const ManageRoom: React.FC = () => { if (quiz?.content && quizQuestions) { setCurrentQuestion(quizQuestions[questionIndex]); if (quizMode === 'teacher') { - webSocketService.nextQuestion({roomName: formattedRoomName, questions: quizQuestions, questionIndex, isLaunch: false}); + webSocketService.nextQuestion({ roomName: formattedRoomName, questions: quizQuestions, questionIndex, isLaunch: false }); } + setIsQuestionShown(true); } + }; const handleReturn = () => { @@ -398,15 +408,35 @@ const ManageRoom: React.FC = () => { {/* the following breaks the css (if 'room' classes are nested) */}
+ {quizQuestions ? ( +
{quiz?.title}
- {!isNaN(Number(currentQuestion?.question.id)) && ( - - Question {Number(currentQuestion?.question.id)}/ - {quizQuestions?.length} - - )} + +
+ Afficher les questions
} + control={ + ) => + setIsQuestionShown(e.target.checked) + } + /> + } + /> +
+ + {!isNaN(Number(currentQuestion?.question.id)) + && isQuestionShown && ( + + Question {Number(currentQuestion?.question.id)}/ + {quizQuestions?.length} + + ) + } {quizMode === 'teacher' && (
@@ -421,11 +451,11 @@ const ManageRoom: React.FC = () => {
- {currentQuestion && ( + {currentQuestion && isQuestionShown && ( )} diff --git a/client/src/pages/Teacher/ManageRoom/manageRoom.css b/client/src/pages/Teacher/ManageRoom/manageRoom.css index ad870a9..bd4b6fb 100644 --- a/client/src/pages/Teacher/ManageRoom/manageRoom.css +++ b/client/src/pages/Teacher/ManageRoom/manageRoom.css @@ -37,10 +37,11 @@ /* align-items: center; */ } - - - - +.close-button-wrapper{ + display: flex; + justify-content: flex-start; + margin-right: 1rem; +} /* .create-room-container { display: flex;