This commit is contained in:
JubaAzul 2025-03-07 16:33:57 -05:00
parent ec2de888ec
commit 22482592cd
4 changed files with 115 additions and 18 deletions

View file

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { render, screen, fireEvent, act } from '@testing-library/react'; import { render, screen, fireEvent, act, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom'; import '@testing-library/jest-dom';
import { MemoryRouter } from 'react-router-dom'; import { MemoryRouter } from 'react-router-dom';
import StudentModeQuiz from 'src/components/StudentModeQuiz/StudentModeQuiz'; import StudentModeQuiz from 'src/components/StudentModeQuiz/StudentModeQuiz';
@ -15,13 +15,16 @@ const mockQuestions: QuestionType[] = mockGiftQuestions.map((question, index) =>
if (question.type !== "Category") if (question.type !== "Category")
question.id = (index + 1).toString(); question.id = (index + 1).toString();
const newMockQuestion = question; const newMockQuestion = question;
return {question : newMockQuestion as BaseQuestion}; return { question: newMockQuestion as BaseQuestion };
}); });
const mockSubmitAnswer = jest.fn(); const mockSubmitAnswer = jest.fn();
const mockDisconnectWebSocket = jest.fn(); const mockDisconnectWebSocket = jest.fn();
beforeEach(() => { beforeEach(() => {
// Clear local storage before each test
localStorage.clear();
render( render(
<MemoryRouter> <MemoryRouter>
<StudentModeQuiz <StudentModeQuiz
@ -29,7 +32,8 @@ beforeEach(() => {
submitAnswer={mockSubmitAnswer} submitAnswer={mockSubmitAnswer}
disconnectWebSocket={mockDisconnectWebSocket} disconnectWebSocket={mockDisconnectWebSocket}
/> />
</MemoryRouter>); </MemoryRouter>
);
}); });
describe('StudentModeQuiz', () => { describe('StudentModeQuiz', () => {
@ -49,6 +53,47 @@ describe('StudentModeQuiz', () => {
}); });
expect(mockSubmitAnswer).toHaveBeenCalledWith('Option A', 1); expect(mockSubmitAnswer).toHaveBeenCalledWith('Option A', 1);
// await waitFor(() => {
// expect(localStorage.getItem('Answer1')).toBe(JSON.stringify('Option A'));
// });
});
test.skip('handles shows feedback for an already answered question', async () => {
// Answer the first question
act(() => {
fireEvent.click(screen.getByText('Option A'));
});
act(() => {
fireEvent.click(screen.getByText('Répondre'));
});
expect(mockSubmitAnswer).toHaveBeenCalledWith('Option A', 1);
await waitFor(() => {
expect(localStorage.getItem('Answer1')).toBe(JSON.stringify('Option A'));
});
expect(screen.queryByText('Répondre')).not.toBeInTheDocument();
// Simulate feedback display (e.g., a checkmark or feedback message)
// This part depends on how feedback is displayed in your component
// For example, if you display a checkmark, you can check for it:
expect(screen.getByText('✅')).toBeInTheDocument();
// Navigate to the next question
act(() => {
fireEvent.click(screen.getByText('Question suivante'));
});
expect(screen.getByText('Sample Question 2')).toBeInTheDocument();
expect(screen.getByText('Répondre')).toBeInTheDocument();
// Navigate back to the first question
act(() => {
fireEvent.click(screen.getByText('Question précédente'));
});
expect(screen.getByText('Sample Question 1')).toBeInTheDocument();
// Check if feedback is shown again
expect(screen.getByText('✅')).toBeInTheDocument();
}); });
test('handles quit button click', async () => { test('handles quit button click', async () => {
@ -70,11 +115,7 @@ describe('StudentModeQuiz', () => {
fireEvent.click(screen.getByText('Question suivante')); fireEvent.click(screen.getByText('Question suivante'));
}); });
const sampleQuestionElements = screen.queryAllByText(/Sample question 2/i); expect(screen.getByText('Sample Question 2')).toBeInTheDocument();
expect(sampleQuestionElements.length).toBeGreaterThan(0); expect(screen.getByText('Répondre')).toBeInTheDocument();
expect(screen.getByText('V')).toBeInTheDocument();
}); });
}); });

View file

@ -3,23 +3,36 @@ import React from 'react';
import { render, fireEvent, act } from '@testing-library/react'; import { render, fireEvent, act } from '@testing-library/react';
import { screen } from '@testing-library/dom'; import { screen } from '@testing-library/dom';
import '@testing-library/jest-dom'; import '@testing-library/jest-dom';
import { MultipleChoiceQuestion, parse } from 'gift-pegjs'; import { BaseQuestion, MultipleChoiceQuestion, parse } from 'gift-pegjs';
import TeacherModeQuiz from 'src/components/TeacherModeQuiz/TeacherModeQuiz'; import TeacherModeQuiz from 'src/components/TeacherModeQuiz/TeacherModeQuiz';
import { MemoryRouter } from 'react-router-dom'; import { MemoryRouter } from 'react-router-dom';
import { QuestionType } from 'src/Types/QuestionType';
const mockGiftQuestions = parse( const mockGiftQuestions = parse(
`::Question:: Sample Question {=Option A ~Option B}`); `::Sample Question 1:: Sample Question 1 {=Option A ~Option B}
::Sample Question 2:: Sample Question 2 {=Option A ~Option B}`);
const mockQuestions: QuestionType[] = mockGiftQuestions.map((question, index) => {
if (question.type !== "Category")
question.id = (index + 1).toString();
const newMockQuestion = question;
return {question : newMockQuestion as BaseQuestion};
});
describe('TeacherModeQuiz', () => { describe('TeacherModeQuiz', () => {
const mockQuestion = mockGiftQuestions[0] as MultipleChoiceQuestion;
let mockQuestion = mockQuestions[0].question as MultipleChoiceQuestion;
mockQuestion.id = '1'; mockQuestion.id = '1';
const mockSubmitAnswer = jest.fn(); const mockSubmitAnswer = jest.fn();
const mockDisconnectWebSocket = jest.fn(); const mockDisconnectWebSocket = jest.fn();
let rerender: (ui: React.ReactElement) => void;
beforeEach(async () => { beforeEach(async () => {
render( const utils = render(
<MemoryRouter> <MemoryRouter>
<TeacherModeQuiz <TeacherModeQuiz
questionInfos={{ question: mockQuestion }} questionInfos={{ question: mockQuestion }}
@ -27,12 +40,13 @@ describe('TeacherModeQuiz', () => {
disconnectWebSocket={mockDisconnectWebSocket} /> disconnectWebSocket={mockDisconnectWebSocket} />
</MemoryRouter> </MemoryRouter>
); );
rerender = utils.rerender;
}); });
test('renders the initial question', () => { test('renders the initial question', () => {
expect(screen.getByText('Question 1')).toBeInTheDocument(); expect(screen.getByText('Question 1')).toBeInTheDocument();
expect(screen.getByText('Sample Question')).toBeInTheDocument(); expect(screen.getByText('Sample Question 1')).toBeInTheDocument();
expect(screen.getByText('Option A')).toBeInTheDocument(); expect(screen.getByText('Option A')).toBeInTheDocument();
expect(screen.getByText('Option B')).toBeInTheDocument(); expect(screen.getByText('Option B')).toBeInTheDocument();
expect(screen.getByText('Quitter')).toBeInTheDocument(); expect(screen.getByText('Quitter')).toBeInTheDocument();
@ -50,6 +64,47 @@ describe('TeacherModeQuiz', () => {
expect(mockSubmitAnswer).toHaveBeenCalledWith('Option A', 1); expect(mockSubmitAnswer).toHaveBeenCalledWith('Option A', 1);
}); });
test('handles shows feedback for an already answered question', () => {
// Answer the first question
act(() => {
fireEvent.click(screen.getByText('Option A'));
});
act(() => {
fireEvent.click(screen.getByText('Répondre'));
});
expect(mockSubmitAnswer).toHaveBeenCalledWith('Option A', 1);
mockQuestion = mockQuestions[1].question as MultipleChoiceQuestion;
// Navigate to the next question by re-rendering with new props
act(() => {
rerender(
<MemoryRouter>
<TeacherModeQuiz
questionInfos={{ question: mockQuestion }}
submitAnswer={mockSubmitAnswer}
disconnectWebSocket={mockDisconnectWebSocket}
/>
</MemoryRouter>
);
});
mockQuestion = mockQuestions[0].question as MultipleChoiceQuestion;
act(() => {
rerender(
<MemoryRouter>
<TeacherModeQuiz
questionInfos={{ question: mockQuestion }}
submitAnswer={mockSubmitAnswer}
disconnectWebSocket={mockDisconnectWebSocket}
/>
</MemoryRouter>
);
});
// Check if the feedback dialog is shown again
expect(screen.getByText('Rétroaction')).toBeInTheDocument();
});
test('handles disconnect button click', () => { test('handles disconnect button click', () => {
act(() => { act(() => {
fireEvent.click(screen.getByText('Quitter')); fireEvent.click(screen.getByText('Quitter'));

View file

@ -22,12 +22,13 @@ const TrueFalseQuestionDisplay: React.FC<Props> = (props) => {
} }
useEffect(() => { useEffect(() => {
console.log("passedAnswer", answer);
if (passedAnswer === true || passedAnswer === false) { if (passedAnswer === true || passedAnswer === false) {
setAnswer(passedAnswer); setAnswer(passedAnswer);
} else { } else {
setAnswer(undefined); setAnswer(undefined);
} }
}, [passedAnswer]); }, [passedAnswer, question.id]);
const [answer, setAnswer] = useState<boolean | undefined>(() => { const [answer, setAnswer] = useState<boolean | undefined>(() => {
@ -94,6 +95,7 @@ const TrueFalseQuestionDisplay: React.FC<Props> = (props) => {
variant="contained" variant="contained"
onClick={() => onClick={() =>
answer !== undefined && handleOnSubmitAnswer && handleOnSubmitAnswer(answer) answer !== undefined && handleOnSubmitAnswer && handleOnSubmitAnswer(answer)
} }
disabled={answer === undefined} disabled={answer === undefined}
> >

View file

@ -28,7 +28,6 @@ const TeacherModeQuiz: React.FC<TeacherModeQuizProps> = ({
handleFeedbackDialogClose(); handleFeedbackDialogClose();
setIsAnswerSubmitted(false); setIsAnswerSubmitted(false);
setAnswer(JSON.parse(localStorage.getItem(`Answer${questionInfos.question.id}`)||'null')); setAnswer(JSON.parse(localStorage.getItem(`Answer${questionInfos.question.id}`)||'null'));
console.log("LA REP",typeof answer);
if (typeof answer !== "object" && typeof answer !== "undefined") { if (typeof answer !== "object" && typeof answer !== "undefined") {
setIsAnswerSubmitted(true); setIsAnswerSubmitted(true);
setIsFeedbackDialogOpen(true); setIsFeedbackDialogOpen(true);