diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index 9c3a1d27..cc705895 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -200,10 +200,8 @@ const Game = () => { button.onmouse = colorOnMousePreguntas; }); - incrementQuestion(); - - - + setQuestionCounter(qc => qc + 1); + }catch (error){ console.error('Error:', error); @@ -227,7 +225,7 @@ const Game = () => { const correctButton = document.getElementById(buttonId); if (correctButton) { correctButton.style.backgroundColor = "rgba(79, 141, 18, 0.726)"; - incrementCorrect(); + setCorrectCounter(correct => correct + 1); } }else{ const buttonId = `button_${index}`; @@ -244,7 +242,7 @@ const Game = () => { } } - incrementIncorrect(); + setIncorrectCounter(incorrect => incorrect + 1); } const buttons = document.querySelectorAll('button[title="btnsPreg"]'); @@ -253,7 +251,7 @@ const Game = () => { button.onmouse = null; }); - decrementQuestionsToAnswer(); + setQuestionsToAnswer(toAnswer => toAnswer - 1); if (!isGameFinished()) { setTimeout(() => { @@ -314,14 +312,6 @@ const getQuestions = () => { correctAnswers: correctCounter, incorrectAnswers: numberOfQuestions-correctCounter }; - //console.log("Se va a guardar la siguiente partida:"); - //console.log("Username:", newGame.username); - //console.log("Duración:", newGame.duration); - //console.log("Preguntas:", newGame.questions); - //console.log("Porcentaje de Aciertos:", newGame.percentage); - //console.log("Número Total de Preguntas:", newGame.totalQuestions); - //console.log("Número de Respuestas Correctas:", newGame.correctAnswers); - //console.log("Número de Respuestas Incorrectas:", newGame.incorrectAnswers); setGameData(newGame); @@ -334,24 +324,6 @@ const getQuestions = () => { }); } - const incrementCorrect = () => { - setCorrectCounter(correct => correct + 1); - }; - - const incrementIncorrect = () => { - setIncorrectCounter(incorrect => incorrect + 1); - } - - const decrementQuestionsToAnswer = () => { - setQuestionsToAnswer(toAnswer => toAnswer - 1); - } - - const incrementQuestion = () => { - setQuestionCounter(qc => qc + 1); - } - - - useEffect(() => { if (isTimedOut && !isFinished) { // mostrar la respuesta correcta @@ -364,8 +336,8 @@ const getQuestions = () => { } } - incrementIncorrect(); - decrementQuestionsToAnswer(); + setIncorrectCounter(incorrect => incorrect + 1); + setQuestionsToAnswer(toAnswer => toAnswer - 1); setTimeout(() => { if (!isGameFinished()) { @@ -417,7 +389,7 @@ const getQuestions = () => { -
+
{time}
diff --git a/webapp/src/components/Game.test.js b/webapp/src/components/Game.test.js index 72c0a533..54c42726 100644 --- a/webapp/src/components/Game.test.js +++ b/webapp/src/components/Game.test.js @@ -1,20 +1,26 @@ import React from 'react'; -import { render, fireEvent, screen, waitFor } from '@testing-library/react'; +import { render, fireEvent, screen, act, waitFor } from '@testing-library/react'; import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; import Game from './Game'; import { MemoryRouter } from 'react-router-dom'; // Importa MemoryRouter +import MainPage from './MainPage'; +import { BrowserRouter as Router } from 'react-router-dom'; + + const mockAxios = new MockAdapter(axios); -const renderGameComponent = () => { +const renderGameComponent = (numQuestions, timePerQuestion) => { render( - + ); }; + + const mockQuestionData = { responseQuestionObject: 'What is 2 + 2?', responseCorrectOption: '4', @@ -22,16 +28,56 @@ const mockQuestionData = { }; describe('Game component', () => { + let consoleErrorSpy; + + beforeEach(() => { mockAxios.reset(); jest.useFakeTimers(); jest.clearAllMocks(); localStorage.clear(); + consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => { }); }); + + afterEach(() => { + // Restaurar console.error después de cada test + consoleErrorSpy.mockRestore(); + }); + + it('should handle API error correctly', async () => { + renderGameComponent(); + + mockAxios.onGet('http://localhost:8000/createquestion').reply(500); // Simular error de servidor + + await waitFor(() => { + // Verificar que console.error fue llamado con el mensaje de error esperado + expect(consoleErrorSpy).toHaveBeenCalledWith('Error:', expect.anything()); + }); + }); + + + it('muestra la página principal correctamente', async () => { + renderGameComponent(); + + // Open the confirmation dialog + fireEvent.click(screen.getByText('Volver al menú principal')); + + // Simulate clicking the confirm button + fireEvent.click(screen.getByText('Confirmar')); + + // Wait for the component to unmount (indicating the redirection) + await waitFor(() => { + expect(screen.queryByText('Game')).not.toBeInTheDocument(); + + }); + + }); + + it('should display initial elements correctly', () => { renderGameComponent(); - + // Verificar que elementos iniciales se muestren correctamente expect(screen.getByText('Saber y Ganar Juego')).toBeInTheDocument(); expect(screen.getByText('Preguntas restantes: 5')).toBeInTheDocument(); // Depende de la configuración del juego @@ -43,9 +89,9 @@ describe('Game component', () => { it('should display question and answer options', async () => { renderGameComponent(); - + mockAxios.onGet('http://localhost:8000/createquestion').reply(200, { data: mockQuestionData }); - + await waitFor(() => { // Esperar a que el texto de la pregunta cambie a "Pregunta 1" if (screen.queryByText(/Pregunta 1:/i)) { @@ -62,9 +108,9 @@ describe('Game component', () => { it('should handle correct answer click', async () => { renderGameComponent(); - + mockAxios.onGet('http://localhost:8000/createquestion').reply(200, { data: mockQuestionData }); - + // Esperar hasta que se muestre "Pregunta 1" await waitFor(() => { if (screen.queryByText(/Pregunta 1:/i)) { @@ -77,12 +123,12 @@ describe('Game component', () => { } }); }); - + it('should handle incorrect answer click', async () => { renderGameComponent(); - + mockAxios.onGet('http://localhost:8000/createquestion').reply(200, { data: mockQuestionData }); - + // Esperar hasta que se muestre "Pregunta 1" await waitFor(() => { if (screen.queryByText(/Pregunta 1:/i)) { @@ -112,26 +158,27 @@ describe('Game component', () => { it('should redirect to main page after confirmation', async () => { renderGameComponent(); - + // Open the confirmation dialog fireEvent.click(screen.getByText('Volver al menú principal')); - + // Simulate clicking the confirm button fireEvent.click(screen.getByText('Confirmar')); - + // Wait for the component to unmount (indicating the redirection) await waitFor(() => { expect(screen.queryByText('Game')).not.toBeInTheDocument(); + }); }); - + it('should display end game message and enable "Back to Main Menu" button when game is finished', async () => { renderGameComponent(); - + for (let i = 1; i <= 5; i++) { mockAxios.onGet('http://localhost:8000/createquestion').reply(200, { data: mockQuestionData }); - + await waitFor(() => { if (screen.queryByText(`Pregunta ${i}:`)) { fireEvent.click(screen.getByText('4')); @@ -143,17 +190,17 @@ describe('Game component', () => { } // Verificar que la partida haya finalizado correctamente - await waitFor(() => { - if (screen.queryByText(/Partida finalizada/i)) { - expect(screen.getByText(/Partida finalizada/i)).toBeInTheDocument(); - expect(screen.getByText(/Gracias por jugar/i)).toBeInTheDocument(); - expect(screen.getByText(/Puntuación/i)).toBeInTheDocument(); - expect(screen.getByText(/Volver al menú principal/i)).toBeInTheDocument(); - } - }); + await waitFor(() => { + if (screen.queryByText(/Partida finalizada/i)) { + expect(screen.getByText(/Partida finalizada/i)).toBeInTheDocument(); + expect(screen.getByText(/Gracias por jugar/i)).toBeInTheDocument(); + expect(screen.getByText(/Puntuación/i)).toBeInTheDocument(); + expect(screen.getByText(/Volver al menú principal/i)).toBeInTheDocument(); + } + }); + + - - }); @@ -161,14 +208,14 @@ describe('Game component', () => { it('should disable buttons when time runs out', async () => { renderGameComponent(); - + mockAxios.onGet('http://localhost:8000/createquestion').reply(200, { data: mockQuestionData }); - + // Esperar hasta que se muestre "Pregunta 1" await waitFor(() => { if (screen.queryByText(/Pregunta 1:/i)) { jest.advanceTimersByTime(10000); // Avanzar el temporizador por 10 segundos - + // Verificar que los botones estén deshabilitados const buttons = screen.getAllByRole('button', { name: /answer/i }); buttons.forEach(button => { @@ -177,32 +224,56 @@ describe('Game component', () => { } }); }); - + it('should handle timeout correctly', async () => { // Define una función simulada para handleShowQuestion const handleShowQuestion = jest.fn(); - + renderGameComponent({ handleShowQuestion }); // Pasa la función simulada como propiedad - + await waitFor(() => { mockAxios.onGet('http://localhost:8000/createquestion').reply(200, { data: mockQuestionData }); }); - + await waitFor(() => { if (screen.queryByText(/Pregunta 1:/i)) { - jest.advanceTimersByTime(10000); + jest.advanceTimersByTime(10000); expect(screen.getByText(correctOption)).toHaveStyle({ backgroundColor: 'rgba(79, 141, 18, 0.726)' }); expect(incrementIncorrect).toHaveBeenCalledTimes(1); expect(decrementQuestionsToAnswer).toHaveBeenCalledTimes(1); } }); - + await waitFor(() => { expect(handleShowQuestion).toHaveBeenCalledTimes(0); // Verifica que handleShowQuestion se llame una vez }); }); - + + + + it('should decrement questions to answer when question is answered', async () => { + renderGameComponent(5, 10); // Configuración inicial con 5 preguntas y 10 segundos por pregunta + + mockAxios.onGet('http://localhost:8000/createquestion').reply(200, { data: mockQuestionData }); + + // Iterar sobre las preguntas y respuestas + for (let i = 1; i <= 5; i++) { + // Esperar hasta que se muestre la pregunta i + await waitFor(() => { + if (screen.queryByText(`Pregunta ${i}:`)) { + // Una vez que se muestre la pregunta, hacer clic en una respuesta + fireEvent.click(screen.getByText('4')); + + // Verificar que el número de preguntas restantes se haya decrementado correctamente + expect(screen.getByText(`Preguntas restantes: ${5 - i}`)).toBeInTheDocument(); + } + }); + } + }); + + + it('should handle dialog open and close', async () => { renderGameComponent(); @@ -259,12 +330,12 @@ describe('Game component', () => { } await waitFor(() => { - if (screen.queryByText('Partida finalizada')) { - expect(screen.getByText('Partida finalizada')).toBeInTheDocument(); - expect(screen.getByText('Gracias por jugar')).toBeInTheDocument(); - expect(screen.getByText('Puntuación')).toBeInTheDocument(); - expect(screen.getByText('Volver al menú principal')).toBeInTheDocument(); - } + if (screen.queryByText('Partida finalizada')) { + expect(screen.getByText('Partida finalizada')).toBeInTheDocument(); + expect(screen.getByText('Gracias por jugar')).toBeInTheDocument(); + expect(screen.getByText('Puntuación')).toBeInTheDocument(); + expect(screen.getByText('Volver al menú principal')).toBeInTheDocument(); + } }); }); @@ -303,14 +374,14 @@ describe('Game component', () => { it('should display the timer correctly', async () => { renderGameComponent(); - + expect(screen.getByText('10')).toBeInTheDocument(); // Comprobar el valor inicial del temporizador - + // Esperar a que el temporizador llegue a cero await waitFor(() => { - if (screen.queryByText('0')) { - expect(screen.queryByText('0')).toBeInTheDocument(); // Comprobar que el temporizador llega a cero - } + if (screen.queryByText('0')) { + expect(screen.queryByText('0')).toBeInTheDocument(); // Comprobar que el temporizador llega a cero + } }); }); @@ -320,16 +391,38 @@ describe('Game component', () => { // Verificar que el temporizador comience con el valor correcto expect(screen.getByText('10')).toBeInTheDocument(); - for(let i = 9; i >= 0; i--){ - await waitFor(() => { - if (screen.queryByText(String(i))) { - expect(screen.queryByText(String(i))).toBeInTheDocument(); - } - }); + for (let i = 9; i >= 0; i--) { + await waitFor(() => { + if (screen.queryByText(String(i))) { + expect(screen.queryByText(String(i))).toBeInTheDocument(); + } + }); } // Verificar que el temporizador no sea negativo expect(screen.queryByText('-1')).not.toBeInTheDocument(); -}); + }); + + + + it('should display loading spinner while fetching questions', async () => { + renderGameComponent(); + + + await waitFor(() => { + // Verifica si se muestra el spinner de carga al principio + expect(screen.getByTestId('Timer')).toBeInTheDocument(); + }); + + + + // Simula una respuesta exitosa del servidor después de un breve retraso + await waitFor(() => { + mockAxios.onGet('http://localhost:8000/createquestion').reply(200, { data: mockQuestionData }); + }); + }); + + + });