From 5d2777b485941f8e284b3006bc05aacd296d301b Mon Sep 17 00:00:00 2001 From: JubaAzul <118773284+JubaAzul@users.noreply.github.com> Date: Fri, 14 Mar 2025 17:06:01 -0400 Subject: [PATCH] =?UTF-8?q?[FEATURE]=20Ajout=20des=20r=C3=A9troactions=20p?= =?UTF-8?q?our=20les=20questions=20=C3=A0=20choix=20multiples=20et=20r?= =?UTF-8?q?=C3=A9ponses=20courtes=20Fixes=20#291?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NumericalQuestionDisplay.test.tsx | 91 ++++++++++++------- .../ShortAnswerQuestionDisplay.test.tsx | 66 ++++++++++---- .../TeacherModeQuiz/TeacherModeQuiz.test.tsx | 14 ++- .../ShortAnswerQuestionDisplay.tsx | 2 +- 4 files changed, 121 insertions(+), 52 deletions(-) diff --git a/client/src/__tests__/components/QuestionsDisplay/NumericalQuestionDisplay/NumericalQuestionDisplay.test.tsx b/client/src/__tests__/components/QuestionsDisplay/NumericalQuestionDisplay/NumericalQuestionDisplay.test.tsx index 639537a..1ebc451 100644 --- a/client/src/__tests__/components/QuestionsDisplay/NumericalQuestionDisplay/NumericalQuestionDisplay.test.tsx +++ b/client/src/__tests__/components/QuestionsDisplay/NumericalQuestionDisplay/NumericalQuestionDisplay.test.tsx @@ -1,44 +1,21 @@ -import React from 'react'; -import { render, screen, fireEvent } from '@testing-library/react'; import '@testing-library/jest-dom'; -import { NumericalQuestion, parse, ParsedGIFTQuestion } from 'gift-pegjs'; -import { MemoryRouter } from 'react-router-dom'; +import { render, screen, fireEvent } from '@testing-library/react'; +import { parse, NumericalQuestion } from 'gift-pegjs'; +import React from 'react'; import NumericalQuestionDisplay from 'src/components/QuestionsDisplay/NumericalQuestionDisplay/NumericalQuestionDisplay'; -const questions = parse( - ` - ::Sample Question 1:: Question stem - { - #5..10 - }` -) as ParsedGIFTQuestion[]; - -const question = questions[0] as NumericalQuestion; - -describe('NumericalQuestion parse', () => { - const q = questions[0]; - - it('The question is Numerical', () => { - expect(q.type).toBe('Numerical'); - }); -}); - -describe('NumericalQuestion Component', () => { +describe('NumericalQuestionDisplay Component', () => { const mockHandleOnSubmitAnswer = jest.fn(); + const question = + parse('::Sample Numerical Question:: What is 2+2? {#4}')[0] as NumericalQuestion; const sampleProps = { - question: question, handleOnSubmitAnswer: mockHandleOnSubmitAnswer, showAnswer: false }; beforeEach(() => { - render( - - - ); + render(); }); it('renders correctly', () => { @@ -55,13 +32,13 @@ describe('NumericalQuestion Component', () => { expect(inputElement.value).toBe('7'); }); - it('Submit button should be disable if nothing is entered', () => { + it('Submit button should be disabled if nothing is entered', () => { const submitButton = screen.getByText('Répondre'); expect(submitButton).toBeDisabled(); }); - it('not submited answer if nothing is entered', () => { + it('does not submit answer if nothing is entered', () => { const submitButton = screen.getByText('Répondre'); fireEvent.click(submitButton); @@ -79,4 +56,52 @@ describe('NumericalQuestion Component', () => { expect(mockHandleOnSubmitAnswer).toHaveBeenCalledWith(7); }); -}); + + it('renders correctly with the correct answer shown', () => { + render(); + expect(screen.getByText('Réponse(s) accepté(es):')).toBeInTheDocument(); + expect(screen.getAllByText('4')).toHaveLength(2); + }); + + it('handles input change and checks if the answer is correct', () => { + const inputElement = screen.getByTestId('number-input') as HTMLInputElement; + + fireEvent.change(inputElement, { target: { value: '4' } }); + + expect(inputElement.value).toBe('4'); + + const submitButton = screen.getByText('Répondre'); + fireEvent.click(submitButton); + + expect(mockHandleOnSubmitAnswer).toHaveBeenCalledWith(4); + }); + + it('submits the correct answer', () => { + const inputElement = screen.getByTestId('number-input') as HTMLInputElement; + + fireEvent.change(inputElement, { target: { value: '4' } }); + + const submitButton = screen.getByText('Répondre'); + fireEvent.click(submitButton); + + expect(mockHandleOnSubmitAnswer).toHaveBeenCalledWith(4); + }); + + it('submits an incorrect answer', () => { + const inputElement = screen.getByTestId('number-input') as HTMLInputElement; + + fireEvent.change(inputElement, { target: { value: '5' } }); + + const submitButton = screen.getByText('Répondre'); + fireEvent.click(submitButton); + + expect(mockHandleOnSubmitAnswer).toHaveBeenCalledWith(5); + }); + + it('displays feedback when the answer is shown', () => { + render(); + expect(screen.getByText('❌ Incorrect!')).toBeInTheDocument(); + expect(screen.getByText('Réponse(s) accepté(es):')).toBeInTheDocument(); + expect(screen.getByText('5')).toBeInTheDocument(); + }); +}); \ No newline at end of file diff --git a/client/src/__tests__/components/QuestionsDisplay/ShortAnswerQuestionDisplay/ShortAnswerQuestionDisplay.test.tsx b/client/src/__tests__/components/QuestionsDisplay/ShortAnswerQuestionDisplay/ShortAnswerQuestionDisplay.test.tsx index c4326eb..ec3fd84 100644 --- a/client/src/__tests__/components/QuestionsDisplay/ShortAnswerQuestionDisplay/ShortAnswerQuestionDisplay.test.tsx +++ b/client/src/__tests__/components/QuestionsDisplay/ShortAnswerQuestionDisplay/ShortAnswerQuestionDisplay.test.tsx @@ -1,7 +1,7 @@ -import React from 'react'; -import { render, screen, fireEvent, within } from '@testing-library/react'; import '@testing-library/jest-dom'; +import { render, screen, fireEvent } from '@testing-library/react'; import { parse, ShortAnswerQuestion } from 'gift-pegjs'; +import React from 'react'; import ShortAnswerQuestionDisplay from 'src/components/QuestionsDisplay/ShortAnswerQuestionDisplay/ShortAnswerQuestionDisplay'; describe('ShortAnswerQuestion Component', () => { @@ -20,28 +20,26 @@ describe('ShortAnswerQuestion Component', () => { it('renders correctly', () => { expect(screen.getByText(question.formattedStem.text)).toBeInTheDocument(); - const container = screen.getByLabelText('short-answer-input'); - const inputElement = within(container).getByRole('textbox') as HTMLInputElement; + const inputElement = screen.getByRole('textbox') as HTMLInputElement; expect(inputElement).toBeInTheDocument(); expect(screen.getByText('Répondre')).toBeInTheDocument(); }); it('handles input change correctly', () => { - const container = screen.getByLabelText('short-answer-input'); - const inputElement = within(container).getByRole('textbox') as HTMLInputElement; + const inputElement = screen.getByRole('textbox') as HTMLInputElement; fireEvent.change(inputElement, { target: { value: 'User Input' } }); expect(inputElement.value).toBe('User Input'); }); - it('Submit button should be disable if nothing is entered', () => { + it('Submit button should be disabled if nothing is entered', () => { const submitButton = screen.getByText('Répondre'); expect(submitButton).toBeDisabled(); }); - it('not submitted answer if nothing is entered', () => { + it('does not submit answer if nothing is entered', () => { const submitButton = screen.getByText('Répondre'); fireEvent.click(submitButton); @@ -49,17 +47,51 @@ describe('ShortAnswerQuestion Component', () => { expect(mockHandleSubmitAnswer).not.toHaveBeenCalled(); }); - it('submits answer correctly', () => { - const container = screen.getByLabelText('short-answer-input'); - const inputElement = within(container).getByRole('textbox') as HTMLInputElement; + it('renders correctly with the correct answer shown', () => { + render(); + expect(screen.getByText('Réponse(s) accepté(es):')).toBeInTheDocument(); + expect(screen.getByText('Correct Answer')).toBeInTheDocument(); + }); + + it('handles input change and checks if the answer is correct', () => { + const inputElement = screen.getByRole('textbox') as HTMLInputElement; + + fireEvent.change(inputElement, { target: { value: 'Correct Answer' } }); + + expect(inputElement.value).toBe('Correct Answer'); - // const inputElement = screen.getByRole('textbox', { name: 'short-answer-input'}) as HTMLInputElement; const submitButton = screen.getByText('Répondre'); - - fireEvent.change(inputElement, { target: { value: 'User Input' } }); - fireEvent.click(submitButton); - expect(mockHandleSubmitAnswer).toHaveBeenCalledWith('User Input'); + expect(mockHandleSubmitAnswer).toHaveBeenCalledWith('Correct Answer'); }); -}); + + it('submits the correct answer', () => { + const inputElement = screen.getByRole('textbox') as HTMLInputElement; + + fireEvent.change(inputElement, { target: { value: 'Correct Answer' } }); + + const submitButton = screen.getByText('Répondre'); + fireEvent.click(submitButton); + + expect(mockHandleSubmitAnswer).toHaveBeenCalledWith('Correct Answer'); + }); + + it('submits an incorrect answer', () => { + const inputElement = screen.getByRole('textbox') as HTMLInputElement; + + fireEvent.change(inputElement, { target: { value: 'Incorrect Answer' } }); + + const submitButton = screen.getByText('Répondre'); + fireEvent.click(submitButton); + + expect(mockHandleSubmitAnswer).toHaveBeenCalledWith('Incorrect Answer'); + }); + + it('displays feedback when the answer is shown', () => { + render(); + expect(screen.getByText('❌ Incorrect!')).toBeInTheDocument(); + expect(screen.getByText('Réponse(s) accepté(es):')).toBeInTheDocument(); + expect(screen.getByText('Incorrect Answer')).toBeInTheDocument(); + }); +}); \ No newline at end of file diff --git a/client/src/__tests__/pages/Student/TeacherModeQuiz/TeacherModeQuiz.test.tsx b/client/src/__tests__/pages/Student/TeacherModeQuiz/TeacherModeQuiz.test.tsx index 6a4ec59..90c963a 100644 --- a/client/src/__tests__/pages/Student/TeacherModeQuiz/TeacherModeQuiz.test.tsx +++ b/client/src/__tests__/pages/Student/TeacherModeQuiz/TeacherModeQuiz.test.tsx @@ -66,6 +66,18 @@ describe('TeacherModeQuiz', () => { expect(mockSubmitAnswer).toHaveBeenCalledWith('Option A', 1); }); + + test('handles shows feedback for answered question', () => { + act(() => { + fireEvent.click(screen.getByText('Option B')); + }); + act(() => { + fireEvent.click(screen.getByText('Répondre')); + }); + expect(mockSubmitAnswer).toHaveBeenCalledWith('Option B', 1) + expect(screen.getByText('❌ Incorrect!')).toBeInTheDocument(); + }); + test('handles shows feedback for an already answered question', () => { // Answer the first question act(() => { @@ -106,7 +118,7 @@ describe('TeacherModeQuiz', () => { }); // Check if the feedback dialog is shown again - expect(screen.getByText('Rétroaction')).toBeInTheDocument(); + expect(screen.getByText('❌ Incorrect!')).toBeInTheDocument(); }); test('handles disconnect button click', () => { diff --git a/client/src/components/QuestionsDisplay/ShortAnswerQuestionDisplay/ShortAnswerQuestionDisplay.tsx b/client/src/components/QuestionsDisplay/ShortAnswerQuestionDisplay/ShortAnswerQuestionDisplay.tsx index 03be9ff..2f82736 100644 --- a/client/src/components/QuestionsDisplay/ShortAnswerQuestionDisplay/ShortAnswerQuestionDisplay.tsx +++ b/client/src/components/QuestionsDisplay/ShortAnswerQuestionDisplay/ShortAnswerQuestionDisplay.tsx @@ -31,7 +31,7 @@ const ShortAnswerQuestionDisplay: React.FC = (props) => { }, [answer]); const checkAnswer = () => { - const isCorrect = question.choices.some((choice) => choice.text.toLowerCase() === (answer as String).toLowerCase()); + const isCorrect = question.choices.some((choice) => String(choice.text).toLowerCase() === String(answer).toLowerCase()); setisGoodAnswer(isCorrect); };