From 7bf917ab74e8cbb4ccbc3edf662ff713a9b19b11 Mon Sep 17 00:00:00 2001 From: uo264915 Date: Sun, 28 Apr 2024 12:03:38 +0200 Subject: [PATCH 1/5] Test HistoricalData --- webapp/src/components/HistoricalData.js | 9 +-------- webapp/src/components/HistoricalData.test.js | 4 +++- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/webapp/src/components/HistoricalData.js b/webapp/src/components/HistoricalData.js index 8569c213..654b1deb 100644 --- a/webapp/src/components/HistoricalData.js +++ b/webapp/src/components/HistoricalData.js @@ -1,6 +1,6 @@ import axios from 'axios'; import React, { useState, useEffect } from 'react'; -import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Container, TablePagination, Typography } from '@mui/material'; +import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Container, TablePagination, Typography, Snackbar } from '@mui/material'; import './HistoricalData.css'; import Navbar from './Navbar'; @@ -57,13 +57,6 @@ const HistoricalData = () => { - {/* {paginatedData.map((row, rowIndex) => ( - - {row.map((cell, cellIndex) => ( - {cell} - ))} - - ))} */} {paginatedData.map((row, rowIndex) => ( {row[0]} diff --git a/webapp/src/components/HistoricalData.test.js b/webapp/src/components/HistoricalData.test.js index d5fdf64d..a8841eea 100644 --- a/webapp/src/components/HistoricalData.test.js +++ b/webapp/src/components/HistoricalData.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { render, screen, waitFor } from '@testing-library/react'; +import { render, screen, waitFor, fireEvent } from '@testing-library/react'; import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; import HistoricalData from './HistoricalData'; @@ -36,6 +36,8 @@ describe('HistoricalData component', () => { expect(screen.getByText('Londres')).toBeInTheDocument(); expect(screen.getByText('Madrid')).toBeInTheDocument(); expect(screen.getByText('Roma')).toBeInTheDocument(); + + expect(screen.getByText('Rows per page:')).toBeInTheDocument(); }); }); From d756d05b14c1038598d613386db06b5897116711 Mon Sep 17 00:00:00 2001 From: uo264915 Date: Sun, 28 Apr 2024 12:15:41 +0200 Subject: [PATCH 2/5] =?UTF-8?q?Test=20MainPage=20cubierto=20m=C3=A1s=20cod?= =?UTF-8?q?igo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webapp/src/components/MainPage.test.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/webapp/src/components/MainPage.test.js b/webapp/src/components/MainPage.test.js index ec268dc4..8f18453a 100644 --- a/webapp/src/components/MainPage.test.js +++ b/webapp/src/components/MainPage.test.js @@ -21,15 +21,26 @@ describe('MainPage component', () => { const element1 = screen.getByText(/¡Bienvenido a/); const element2 = screen.getByText(/WIQ 2024!/); const newGameButton = screen.getByRole('button', { name: 'Nuevo juego' }); + const rankingButton = screen.getByRole('button', { name: 'Ranking' }); + const configButton = screen.getByRole('button', { name: 'Configuración' }); - // Verifica si el elemento se encuentra en el DOM expect(element1).toBeInTheDocument(); expect(element2).toBeInTheDocument(); - // Simulate user input await act(async () => { fireEvent.click(newGameButton); }); + + expect(window.location.pathname).toBe('/Game'); + + fireEvent.click(rankingButton); + + expect(window.location.pathname).toBe('/ScoreBoard'); + + fireEvent.click(configButton); + + const dialogTitle = screen.getByText('Configuración del juego'); + expect(dialogTitle).toBeInTheDocument(); }); }); From e35728ae49effe32239c955fdad21a3e2b851737 Mon Sep 17 00:00:00 2001 From: uo264915 Date: Sun, 28 Apr 2024 12:59:36 +0200 Subject: [PATCH 3/5] Mejora test MainPage --- webapp/src/components/MainPage.test.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/webapp/src/components/MainPage.test.js b/webapp/src/components/MainPage.test.js index 8f18453a..d6a71bd3 100644 --- a/webapp/src/components/MainPage.test.js +++ b/webapp/src/components/MainPage.test.js @@ -41,6 +41,19 @@ describe('MainPage component', () => { const dialogTitle = screen.getByText('Configuración del juego'); expect(dialogTitle).toBeInTheDocument(); + + const numQuestionsInput = screen.getByLabelText('Número de preguntas (min. 5)'); + const timePerQuestionInput = screen.getByLabelText('Tiempo por pregunta (mín. 10 segundos)'); + const acceptButton = screen.getByRole('button', { name: 'Aceptar' }); + + expect(dialogTitle).toBeVisible(); + expect(numQuestionsInput).toBeInTheDocument(); + expect(timePerQuestionInput).toBeInTheDocument(); + expect(acceptButton).toBeInTheDocument(); + + fireEvent.change(numQuestionsInput, { target: { value: '10' } }); + fireEvent.change(timePerQuestionInput, { target: { value: '15' } }); + fireEvent.click(acceptButton); }); }); From 3371481e0297d9d077c4ded66b06ca325a7b9cbe Mon Sep 17 00:00:00 2001 From: baraganio Date: Sun, 28 Apr 2024 13:20:44 +0200 Subject: [PATCH 4/5] =?UTF-8?q?Eliminando=20m=C3=A1s=20security=20hotspots?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gatewayservice/gateway-service.js | 11 ++++++++++- gatewayservice/gateway-service.test.js | 6 ++++-- questions/creationservice/creation-service.js | 1 + questions/retrieveservice/retrieve-service.js | 1 + users/authservice/auth-service.js | 1 + users/userservice/user-service.js | 1 + 6 files changed, 18 insertions(+), 3 deletions(-) diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index 43da0415..5f469303 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -9,14 +9,23 @@ const YAML = require('yaml') const app = express(); +app.disable('x-powerde-by'); const port = 8000; +const originEndpoint = process.env.REACT_APP_API_ORIGIN_ENDPOINT || 'http://localhost:3000'; const authServiceUrl = process.env.AUTH_SERVICE_URL || 'http://localhost:8002'; const userServiceUrl = process.env.USER_SERVICE_URL || 'http://localhost:8001'; const creationServiceUrl = process.env.CREATION_SERVICE_URL || 'http://localhost:8005'; const retrieveServiceUrl = process.env.RETRIEVE_SERVICE_URL || 'http://localhost:8004'; -app.use(cors()); +const corsOptions = { + origin: originEndpoint, + methods: ['GET', 'POST'], + allowedHeaders: ['Content-Type', 'Authorization'] +}; + +app.use(cors(corsOptions)); + app.use(express.json()); //Prometheus configuration diff --git a/gatewayservice/gateway-service.test.js b/gatewayservice/gateway-service.test.js index 24166038..0bbaad9f 100644 --- a/gatewayservice/gateway-service.test.js +++ b/gatewayservice/gateway-service.test.js @@ -2,6 +2,8 @@ const request = require('supertest'); const axios = require('axios'); const app = require('./gateway-service'); +let newString='S345_Bs'; + afterAll(async () => { app.close(); }); @@ -41,7 +43,7 @@ describe('Gateway Service', () => { it('should forward login request to auth service', async () => { const response = await request(app) .post('/login') - .send({ username: 'testuser', password: 'testpassword' }); + .send({ username: 'testuser', password: newString }); expect(response.statusCode).toBe(200); expect(response.body.token).toBe('mockedToken'); @@ -51,7 +53,7 @@ describe('Gateway Service', () => { it('should forward add user request to user service', async () => { const response = await request(app) .post('/adduser') - .send({ username: 'newuser', password: 'newpassword' }); + .send({ username: 'newuser', password: newString }); expect(response.statusCode).toBe(200); expect(response.body.userId).toBe('mockedUserId'); diff --git a/questions/creationservice/creation-service.js b/questions/creationservice/creation-service.js index 7c9a70e4..b67b2a5d 100644 --- a/questions/creationservice/creation-service.js +++ b/questions/creationservice/creation-service.js @@ -4,6 +4,7 @@ const fetch = require('node-fetch'); const Question = require('./creation-model'); const app = express(); +app.disable('x-powered-by'); const port = 8005; app.use(express.json()); diff --git a/questions/retrieveservice/retrieve-service.js b/questions/retrieveservice/retrieve-service.js index 56bd9af3..fff826e0 100644 --- a/questions/retrieveservice/retrieve-service.js +++ b/questions/retrieveservice/retrieve-service.js @@ -5,6 +5,7 @@ const Game = require('./playedGame-model') const QuestionAnswered = require('./question-model') const app = express(); +app.disable('x-powered-by'); const port = 8004; app.use(express.json()); diff --git a/users/authservice/auth-service.js b/users/authservice/auth-service.js index 1fad6f80..44ebb881 100644 --- a/users/authservice/auth-service.js +++ b/users/authservice/auth-service.js @@ -5,6 +5,7 @@ const jwt = require('jsonwebtoken'); const User = require('./auth-model') const app = express(); +app.disable('x-powered-by'); const port = 8002; // Middleware to parse JSON in request body diff --git a/users/userservice/user-service.js b/users/userservice/user-service.js index 711d49dd..b0ec7573 100644 --- a/users/userservice/user-service.js +++ b/users/userservice/user-service.js @@ -6,6 +6,7 @@ const bodyParser = require('body-parser'); const User = require('./user-model') const app = express(); +app.disable('x-powered-by'); const port = 8001; // Middleware to parse JSON in request body From 8da9d047353050abbf2f2e564bd381f457709d49 Mon Sep 17 00:00:00 2001 From: Raymond Debasa Peralta Date: Sun, 28 Apr 2024 16:51:27 +0200 Subject: [PATCH 5/5] tests HistoricalUserData y ScoreBoard --- .../src/components/HistoricalUserData.test.js | 127 ++++++++++++++++++ webapp/src/components/ScoreBoard.test.js | 84 ++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 webapp/src/components/HistoricalUserData.test.js create mode 100644 webapp/src/components/ScoreBoard.test.js diff --git a/webapp/src/components/HistoricalUserData.test.js b/webapp/src/components/HistoricalUserData.test.js new file mode 100644 index 00000000..cf3f12fc --- /dev/null +++ b/webapp/src/components/HistoricalUserData.test.js @@ -0,0 +1,127 @@ +import React from 'react'; +import { render, screen, waitFor, fireEvent } from '@testing-library/react'; +import axios from 'axios'; +import MockAdapter from 'axios-mock-adapter'; +import HistoricalUserData from './HistoricalUserData'; +import { BrowserRouter as Router } from 'react-router-dom'; + +const mockAxios = new MockAdapter(axios); + +describe('HistoricalUserData component', () => { + beforeEach(() => { + mockAxios.reset(); + localStorage.setItem('username', 'testUser'); + }); + + it('renders the main title correctly', () => { + render( + + + + ); + expect(screen.getByText('Historial de partidas de testUser')).toBeInTheDocument(); + }); + + it('fetches game history, renders game data, expands game details, and renders questions', async () => { + const mockGameHistory = [ + { + id: 1, + date: '2024-04-27T08:00:00', + duration: 60, + percentage: 75, + totalQuestions: 10, + correctAnswers: 7, + incorrectAnswers: 3, + questions: [ + { question: 'Question 1', correctAnswer: 'Answer 1', userAnswer: 'Answer 1' }, + { question: 'Question 2', correctAnswer: 'Answer 2', userAnswer: 'Answer 3' } + ] + } + ]; + + mockAxios.onGet('http://localhost:8000/getgamehistory/testUser').reply(200, mockGameHistory); + + render( + + + + ); + + // Espera a que se muestre la información de la partida + await waitFor(() => { + expect(screen.getByText('27/04/2024 08:00')).toBeInTheDocument(); + expect(screen.getByText('60 segundos')).toBeInTheDocument(); + expect(screen.getByText('75.00%')).toBeInTheDocument(); + expect(screen.getByText('10')).toBeInTheDocument(); + expect(screen.getByText('7')).toBeInTheDocument(); + expect(screen.getByText('3')).toBeInTheDocument(); + }); + + // Simula hacer clic en el botón de expansión para mostrar las preguntas ocultas + fireEvent.click(screen.getByText('+')); + + // Espera a que se muestre la pregunta esperada + await waitFor(() => { + expect(screen.getByText('Pregunta 1:')).toBeInTheDocument(); + expect(screen.getByText('Respuesta Correcta: Answer 1')).toBeInTheDocument(); + expect(screen.getByText('Respuesta del Usuario: Answer 1')).toBeInTheDocument(); + expect(screen.getByText('La respuesta fue: Correcta')).toBeInTheDocument(); + }); + + // Espera a que se muestre la segunda pregunta + await waitFor(() => { + expect(screen.getByText('Pregunta 2:')).toBeInTheDocument(); + expect(screen.getByText('Respuesta Correcta: Answer 2')).toBeInTheDocument(); + expect(screen.getByText('Respuesta del Usuario: Answer 3')).toBeInTheDocument(); + expect(screen.getByText('La respuesta fue: Incorrecta')).toBeInTheDocument(); + }); + }); + + it('handles pagination correctly', async () => { + const mockGameHistory = Array.from({ length: 20 }, (_, index) => ({ + id: index + 1, + date: `2024-04-${index < 9 ? '0' + (index + 1) : index + 1}T08:00:00`, + duration: 60, + percentage: 75, + totalQuestions: 10, + correctAnswers: 7, + incorrectAnswers: 3, + questions: [ + { question: `Question ${index + 1}`, correctAnswer: 'Answer 1', userAnswer: 'Answer 1' }, + { question: `Question ${index + 2}`, correctAnswer: 'Answer 2', userAnswer: 'Answer 3' } + ] + })); + + mockAxios.onGet('http://localhost:8000/getgamehistory/testUser').reply(200, mockGameHistory); + + render( + + + + ); + + // Espera a que se muestre la información de la primera página + await waitFor(() => { + // Busca la información de la fecha y el tiempo de partida utilizando texto exacto + expect(screen.queryAllByText('60 segundos')).not.toBeNull(); + expect(screen.queryAllByText('75.00%')).not.toBeNull(); + expect(screen.queryAllByText('10')).not.toBeNull(); + expect(screen.queryAllByText('7')).not.toBeNull(); + expect(screen.queryAllByText('3')).not.toBeNull(); + }); + + // Simula hacer clic en el botón para ir a la siguiente página + fireEvent.click(screen.getByLabelText('Go to next page')); + + // Espera a que se muestre la información de la segunda página + await waitFor(() => { + // Busca la información de la fecha y el tiempo de partida utilizando texto exacto en la segunda página + expect(screen.queryAllByText('60 segundos')).not.toBeNull(); + expect(screen.queryAllByText('75.00%')).not.toBeNull(); + expect(screen.queryAllByText('10')).not.toBeNull(); + expect(screen.queryAllByText('7')).not.toBeNull(); + expect(screen.queryAllByText('3')).not.toBeNull(); + }); + }); + +}); diff --git a/webapp/src/components/ScoreBoard.test.js b/webapp/src/components/ScoreBoard.test.js new file mode 100644 index 00000000..5416b221 --- /dev/null +++ b/webapp/src/components/ScoreBoard.test.js @@ -0,0 +1,84 @@ +import React from 'react'; +import { BrowserRouter as Router } from 'react-router-dom'; +import { render, screen, waitFor, fireEvent } from '@testing-library/react'; +import axios from 'axios'; +import MockAdapter from 'axios-mock-adapter'; +import ScoreBoard from './ScoreBoard'; + +const mockAxios = new MockAdapter(axios); + +describe('ScoreBoard component', () => { + beforeEach(() => { + mockAxios.reset(); + }); + + it('renders the scoreboard table with correct data', async () => { + const scoreboardData = [ + { id: 1, username: 'user1', totalCorrect: 5, totalIncorrect: 4, points: 15 }, + { id: 2, username: 'user2', totalCorrect: 7, totalIncorrect: 2, points: 30 }, + ]; + mockAxios.onGet('http://localhost:8000/getScoreBoard').reply(200, scoreboardData); + + render( + + + + ); + + await waitFor(() => { + const user1Element = screen.getByText('user1'); + const user2Element = screen.getByText('user2'); + + expect(user1Element).toBeInTheDocument(); + expect(user2Element).toBeInTheDocument(); + + // Check for specific cell values within user1Element + const user1Cells = screen.getAllByText('user1')[0].parentElement.querySelectorAll('td'); + expect(user1Cells[2]).toHaveTextContent('5'); + expect(user1Cells[3]).toHaveTextContent('4'); + expect(user1Cells[4]).toHaveTextContent('15'); + + // Check for specific cell values within user2Element + const user2Cells = screen.getAllByText('user2')[0].parentElement.querySelectorAll('td'); + expect(user2Cells[2]).toHaveTextContent('7'); + expect(user2Cells[3]).toHaveTextContent('2'); + expect(user2Cells[4]).toHaveTextContent('30'); + }); + }); + + it('handles pagination correctly', async () => { + const scoreboardData = Array.from({ length: 20 }, (_, index) => ({ + id: index + 1, + username: `user${index + 1}`, + totalCorrect: index + 1, + totalIncorrect: index + 2, + points: (index + 1) * 10, + })); + mockAxios.onGet('http://localhost:8000/getScoreBoard').reply(200, scoreboardData); + + render( + + + + ); + + await waitFor(() => { + expect(screen.getByText('user1')).toBeInTheDocument(); + expect(screen.getByText('user5')).toBeInTheDocument(); + expect(screen.queryByText('user6')).not.toBeInTheDocument(); // Not on first page + fireEvent.click(screen.getByLabelText('Go to next page')); + + expect(screen.getByText('user6')).toBeInTheDocument(); // On second page + }); + }); + + it('renders the main title correctly', () => { + render( + + + + ); + expect(screen.getByText('Ranking de Puntuaciones')).toBeInTheDocument(); + }); + +});