From 3f8d9315359baf7c16fca45ac19760c3033b5e55 Mon Sep 17 00:00:00 2001 From: Fernando Jose Gonzalez Sierra Date: Sun, 28 Apr 2024 12:17:51 +0200 Subject: [PATCH 01/14] =?UTF-8?q?OpenAPI=20update=20y=20bot=C3=B3n=20final?= =?UTF-8?q?izar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gatewayservice/gateway-service.js | 4 +- gatewayservice/openapi.yaml | 125 ++++++++------------------- webapp/src/components/Pages/Juego.js | 3 +- 3 files changed, 39 insertions(+), 93 deletions(-) diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index 918b9df..363400a 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -93,7 +93,7 @@ app.get('/getUserData', async (req, res) => { const { username } = req.query; try{ const getUserDataResponse = await axios.get(userServiceUrl+ `/getUserData?username=${username}`) - res.json(getUserDataResponse.data); + res.status(200).json(getUserDataResponse.data); }catch(error){ res.status(error.response.status).json({error: error.response.data.error}); } @@ -102,7 +102,7 @@ app.get('/getUserData', async (req, res) => { app.get('/getUsernames', async (req, res) => { try{ const getUserDataResponse = await axios.get(userServiceUrl+ `/getUsernames`) - res.json(getUserDataResponse.data); + res.status(200).json(getUserDataResponse.data); }catch(error){ res.status(error.response.status).json({error: error.response.data.error}); } diff --git a/gatewayservice/openapi.yaml b/gatewayservice/openapi.yaml index 31a02ff..aec74e7 100644 --- a/gatewayservice/openapi.yaml +++ b/gatewayservice/openapi.yaml @@ -183,21 +183,23 @@ paths: type: string description: Error information. example: Internal Server Error - /updateCorrectAnswers: + /updateStats: get: summary: Updates the data of the user, increasing his number of correct answers. - operationId: updateCorrectAnswers + operationId: updateStats parameters: in: path name: params required: true - description: Parameters for the update (username and numAnswers) + description: Parameters for the update (username, numRespuestsasCorrectas, numRespuestasIncorrectas) schema: type: object properties: username: type: string - numAnswers: + numRespuestsasCorrectas: + type: integer + numRespuestasIncorrectas: type: integer responses: '200': @@ -213,63 +215,16 @@ paths: message: type: string example: Respuestas correctas actualizada con éxito - '404': - description: The user is not found. - content: - application/json: - schema: - type: object - properties: - success: - type: boolean - example: false - message: - type: string - example: Usuario no encontrado - '500': - description: Internal server error. - content: - application/json: - schema: - type: object - properties: - success: - type: boolean - example: false - message: - type: string - description: Error information. - example: Error al actualizar las respuestas correctas - /updateIncorrectAnswers: - get: - summary: Updates the data of the user, increasing his number of incorrect answers. - operationId: updateIncorrectAnswers - parameters: - in: path - name: params - required: true - description: Parameters for the update (username and numAnswers) - schema: - type: object - properties: - username: - type: string - numAnswers: - type: integer - responses: - '200': - description: Updates the data correctly. + '401': + description: Params needed for the get action. content: application/json: schema: type: object properties: - success: - type: boolean - example: true - message: + error: type: string - example: Respuestas incorrectas actualizada con éxito + example: Faltan parámetros en la solicitud. '404': description: The user is not found. content: @@ -296,16 +251,16 @@ paths: message: type: string description: Error information. - example: Error al actualizar las respuestas incorrectas - /updateCompletedGames: + example: Error al actualizar las respuestas correctas + /getUserData: get: - summary: Update the number of completed games by the user. - operationId: updateCompletedGames + summary: Gets the data of an user. + operationId: getUserData parameters: in: path name: username required: true - description: Username for the update of data + description: Username for the search of data schema: type: string responses: @@ -316,12 +271,22 @@ paths: schema: type: user properties: - success: - type: boolean - example: true - message: + username: type: string - example: Juegos completados actualizado con éxito + example: Pablo + password: + type: integer + example: pass + createdAt: + type: date + correctAnswers: + type: integer + incorrectAnswers: + type: integer + completedGames: + type: integer + averageTime: + type: integer '404': description: The user is not found. content: @@ -348,21 +313,14 @@ paths: message: type: string description: Error information. - example: Error al actualizar Juegos completados - /getUserData: + example: Error al obtener los datos de usuario + /getUsernames: get: - summary: Gets the data of an user. - operationId: getUserData - parameters: - in: path - name: username - required: true - description: Username for the search of data - schema: - type: string + summary: Gets all the usernames. + operationId: getUsernames responses: '200': - description: Finds the data of the user correctly. + description: Finds the data of the user correctly (or no users). content: application/json: schema: @@ -384,19 +342,6 @@ paths: type: integer averageTime: type: integer - '404': - description: The user is not found. - content: - application/json: - schema: - type: object - properties: - success: - type: boolean - example: false - message: - type: string - example: Usuario no encontrado '500': description: Internal server error. content: diff --git a/webapp/src/components/Pages/Juego.js b/webapp/src/components/Pages/Juego.js index 025cfaf..a8c2818 100644 --- a/webapp/src/components/Pages/Juego.js +++ b/webapp/src/components/Pages/Juego.js @@ -224,7 +224,8 @@ const Juego = ({isLogged, username, numPreguntas}) => { {finishGame ? <>

PARTIDA FINALIZADA

ACERTADAS: {numRespuestasCorrectas} FALLADAS: {numRespuestasIncorrectas}

- + { !disableFinish ? + : <> } : <>} { disableFinish ? (

Comience nueva partida o visite sus estadísticas!!

) From 130b2ac293e42bf4c9842cb3f74278dd25c0c5c1 Mon Sep 17 00:00:00 2001 From: Fernando Jose Gonzalez Sierra Date: Sun, 28 Apr 2024 12:21:55 +0200 Subject: [PATCH 02/14] Update Juego.test.js --- webapp/src/components/tests/Juego.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/webapp/src/components/tests/Juego.test.js b/webapp/src/components/tests/Juego.test.js index 2ddf3a2..b446439 100644 --- a/webapp/src/components/tests/Juego.test.js +++ b/webapp/src/components/tests/Juego.test.js @@ -95,9 +95,9 @@ describe('Juego component', () => { const { container, getByText } = render(); await waitFor(() => getByText(mockData.question)); fireEvent.click(getByText('SIGUIENTE')); - fireEvent.click(getByText('FINALIZAR PARTIDA')); - expect(getByText('FINALIZAR PARTIDA')).toBeDisabled(); - console.log(container.numRespuestasCorrectas) + fireEvent.click(getByText('GUARDAR ESTADÍSTICAS')); + //expect(getByText('GUARDAR ESTADÍSTICAS')).toBeDisabled(); + expect(getByText('Comience nueva partida o visite sus estadísticas!!')).toBeInTheDocument() //expect(axios.get).toHaveBeenCalledWith('http://localhost:8000/updateStats?username=test&numRespuestasCorrectas=0&numRespuestasIncorrectas=0'); }); From 5bd50ae689c232328142543e3074136bea78e005 Mon Sep 17 00:00:00 2001 From: Lara Date: Sun, 28 Apr 2024 13:10:15 +0200 Subject: [PATCH 03/14] descomentando e2e --- .github/workflows/release.yml | 40 +++++++------- webapp/e2e/steps/01-register-form.steps.js | 52 ------------------- .../steps/{03-home.steps.js => home.steps.js} | 0 .../{02-login.steps.js => login.steps.js} | 0 4 files changed, 20 insertions(+), 72 deletions(-) delete mode 100644 webapp/e2e/steps/01-register-form.steps.js rename webapp/e2e/steps/{03-home.steps.js => home.steps.js} (100%) rename webapp/e2e/steps/{02-login.steps.js => login.steps.js} (100%) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 628c986..9e4a6a3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,28 +27,28 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} -# e2e-tests: -# needs: [unit-tests] -# runs-on: ubuntu-latest -# steps: -# - uses: actions/checkout@v4 -# - uses: actions/setup-node@v4 -# with: -# node-version: 20 -# - run: npm --prefix userservice/authservice install -# - run: npm --prefix userservice/userservice install -# - run: npm --prefix gatewayservice install -# - run: npm --prefix questionservice install -# - run: npm --prefix webapp install -# - run: npm --prefix webapp run build -# - run: npm --prefix webapp run test:e2e + e2e-tests: + needs: [unit-tests] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20 + - run: npm --prefix userservice/authservice install + - run: npm --prefix userservice/userservice install + - run: npm --prefix gatewayservice install + - run: npm --prefix questionservice install + - run: npm --prefix webapp install + - run: npm --prefix webapp run build + - run: npm --prefix webapp run test:e2e docker-push-webapp: name: Push webapp Docker Image to GitHub Packages runs-on: ubuntu-latest permissions: contents: read packages: write -# needs: [e2e-tests] + needs: [e2e-tests] steps: - uses: actions/checkout@v4 - name: Publish to Registry @@ -68,7 +68,7 @@ jobs: permissions: contents: read packages: write -# needs: [e2e-tests] + needs: [e2e-tests] steps: - uses: actions/checkout@v4 - name: Publish to Registry @@ -85,7 +85,7 @@ jobs: permissions: contents: read packages: write -# needs: [e2e-tests] + needs: [e2e-tests] steps: - uses: actions/checkout@v4 - name: Publish to Registry @@ -102,7 +102,7 @@ jobs: permissions: contents: read packages: write -# needs: [e2e-tests] + needs: [e2e-tests] steps: - uses: actions/checkout@v4 - name: Update OpenAPI configuration @@ -123,7 +123,7 @@ jobs: permissions: contents: read packages: write -# needs: [e2e-tests] + needs: [e2e-tests] steps: - uses: actions/checkout@v4 - name: Publish to Registry diff --git a/webapp/e2e/steps/01-register-form.steps.js b/webapp/e2e/steps/01-register-form.steps.js deleted file mode 100644 index e54df87..0000000 --- a/webapp/e2e/steps/01-register-form.steps.js +++ /dev/null @@ -1,52 +0,0 @@ -const puppeteer = require('puppeteer'); -const { defineFeature, loadFeature }=require('jest-cucumber'); -const setDefaultOptions = require('expect-puppeteer').setDefaultOptions -const feature = loadFeature('./features/register-form.feature'); - -let page; -let browser; - -defineFeature(feature, test => { - - beforeAll(async () => { - browser = process.env.GITHUB_ACTIONS - ? await puppeteer.launch() - : await puppeteer.launch({ headless: false, slowMo: 100 }); - page = await browser.newPage(); - //Way of setting up the timeout - setDefaultOptions({ timeout: 10000 }) - - await page - .goto("http://localhost:3000", { - waitUntil: "networkidle0", - }) - .catch(() => {}); - }); - - test('The user is not registered in the site', ({given,when,then}) => { - - let username; - let password; - - given('An unregistered user', async () => { - username = "pablo@gmail.com" - password = "pabloasw1" - await expect(page).toClick("button", { text: "REGÍSTRATE" }); - }); - - when('I fill the data in the form and press submit', async () => { - await expect(page).toFill('input[name="username"]', username); - await expect(page).toFill('input[name="password"]', password); - await expect(page).toClick('button', { text: 'Crear' }) - }); - - then('A confirmation message should be shown in the screen', async () => { - await expect(page).toMatchElement("div", { text: "Usuario creado correctamente" }); - }); - }) - - afterAll(async ()=>{ - browser.close() - }) - -}); \ No newline at end of file diff --git a/webapp/e2e/steps/03-home.steps.js b/webapp/e2e/steps/home.steps.js similarity index 100% rename from webapp/e2e/steps/03-home.steps.js rename to webapp/e2e/steps/home.steps.js diff --git a/webapp/e2e/steps/02-login.steps.js b/webapp/e2e/steps/login.steps.js similarity index 100% rename from webapp/e2e/steps/02-login.steps.js rename to webapp/e2e/steps/login.steps.js From d691733f18b98a453627a1b8dbaac7fa4fe943f6 Mon Sep 17 00:00:00 2001 From: Lara Date: Sun, 28 Apr 2024 13:56:01 +0200 Subject: [PATCH 04/14] quitando tiempo de estadisticas --- webapp/e2e/steps/home.steps.js | 2 +- webapp/src/components/Pages/Estadisticas.js | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/webapp/e2e/steps/home.steps.js b/webapp/e2e/steps/home.steps.js index 35cd730..6f83e6b 100644 --- a/webapp/e2e/steps/home.steps.js +++ b/webapp/e2e/steps/home.steps.js @@ -47,7 +47,7 @@ defineFeature(feature, test => { then('I should be able to interact with the app', async () => { await expect(page).toMatchElement("button", { text: "JUGAR" }); await expect(page).toMatchElement("button", { text: "ESTADÍSTICAS" }); - }); + }); }) afterAll(async ()=>{ diff --git a/webapp/src/components/Pages/Estadisticas.js b/webapp/src/components/Pages/Estadisticas.js index dcaa63f..99d6902 100644 --- a/webapp/src/components/Pages/Estadisticas.js +++ b/webapp/src/components/Pages/Estadisticas.js @@ -12,7 +12,7 @@ const Estadisticas = ({isLogged, username}) => { const [correctAnswers, setCorrectAnswers] = useState(0); const [incorrectAnswers, setIncorrectAnswers] = useState(0); const [completedGames, setCompletedGames] = useState(0); - const [averageTime, setAverageTime] = useState(0); + //const [averageTime, setAverageTime] = useState(0); const [firstRender, setFirstRender] = useState(false); useEffect(() => { @@ -30,7 +30,7 @@ const Estadisticas = ({isLogged, username}) => { setCorrectAnswers(datos.user.correctAnswers); setIncorrectAnswers(datos.user.incorrectAnswers); setCompletedGames(datos.user.completedGames); - setAverageTime(datos.user.averageTime); + //setAverageTime(datos.user.averageTime); } catch (error) { setError('Error al cargar la información'); } @@ -54,10 +54,6 @@ const Estadisticas = ({isLogged, username}) => { Nº Juegos completados: {completedGames} - - Tiempo medio por juego: - {averageTime} - From c01fb6bbca3a30f8c5bf18c48a6a09c0f8060b2b Mon Sep 17 00:00:00 2001 From: Lara Date: Sun, 28 Apr 2024 14:00:10 +0200 Subject: [PATCH 05/14] linea cambio --- webapp/src/components/tests/Estadisticas.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webapp/src/components/tests/Estadisticas.test.js b/webapp/src/components/tests/Estadisticas.test.js index bfd3def..8c8828d 100644 --- a/webapp/src/components/tests/Estadisticas.test.js +++ b/webapp/src/components/tests/Estadisticas.test.js @@ -36,8 +36,8 @@ describe('Estadisticas Component', () => { expect(getByText('Nº Juegos completados:')).toBeInTheDocument(); expect(getByText('20')).toBeInTheDocument(); // Verifica que el número de juegos completados sea 20 - expect(getByText('Tiempo medio por juego:')).toBeInTheDocument(); - expect(getByText('30')).toBeInTheDocument(); // Verifica que el tiempo medio por juego sea 30 + //expect(getByText('Tiempo medio por juego:')).toBeInTheDocument(); + //expect(getByText('30')).toBeInTheDocument(); // Verifica que el tiempo medio por juego sea 30 }); }); From 5b1fa3841a805fcc8a8cd83303d743100a243c41 Mon Sep 17 00:00:00 2001 From: Lara Date: Sun, 28 Apr 2024 14:25:50 +0200 Subject: [PATCH 06/14] Mas pruebas para userservice --- userservice/userservice/user-service.test.js | 58 +++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/userservice/userservice/user-service.test.js b/userservice/userservice/user-service.test.js index 8dd8ea1..04c536f 100644 --- a/userservice/userservice/user-service.test.js +++ b/userservice/userservice/user-service.test.js @@ -16,6 +16,7 @@ afterAll(async () => { await mongoServer.stop(); }); + describe('User Service', () => { it('should add a new user on POST /adduser', async () => { const newUser = { @@ -27,4 +28,59 @@ describe('User Service', () => { expect(response.status).toBe(200); expect(response.body).toHaveProperty('username', 'testuser'); }); -}); + + it('Debería devolver una lista de nombres de usuario cuando hay usuarios en la base de datos', async () => { + const response = await request(app).get('/getUsernames'); + expect(response.status).toBe(200); + expect(response.body.usernames).toBeDefined(); + expect(response.body.usernames.length).toBeGreaterThan(0); + }); + + it('Debería actualizar las estadísticas del usuario correctamente', async () => { + const username = 'testuser'; + const numRespuestasCorrectas = 5; + const numRespuestasIncorrectas = 3; + + const response = await request(app) + .get('/updateStats') + .query({ username, numRespuestasCorrectas, numRespuestasIncorrectas }); + + expect(response.status).toBe(200); + expect(response.body.success).toBe(true); + expect(response.body.message).toBe('Estadísticas actualizadas con éxito'); + + }); + + it('Debería devolver un mensaje de error cuando el usuario no se encuentra en la base de datos al actualizar estadisticas', async () => { + const username = 'usuario_inexistente'; + const numRespuestasCorrectas = 5; + const numRespuestasIncorrectas = 3; + + const response = await request(app) + .get('/updateStats') + .query({ username, numRespuestasCorrectas, numRespuestasIncorrectas }); + + expect(response.status).toBe(404); + expect(response.body.success).toBe(false); + expect(response.body.message).toBe('Usuario no encontrado'); + }); + + it('Debería devolver un mensaje de error cuando el usuario no se encuentra en la base de datos al obtener sus datos', async () => { + const username = 'usuario_inexistente'; + + const response = await request(app) + .get('/getUserData') + .query({ username }); + + expect(response.status).toBe(404); + expect(response.body.success).toBe(false); + expect(response.body.message).toBe('Usuario no encontrado'); + }); + + + +} + +); + + From aedfdeeece87bed0af291c77e42ec838c79d793e Mon Sep 17 00:00:00 2001 From: Lara Date: Sun, 28 Apr 2024 14:48:23 +0200 Subject: [PATCH 07/14] =?UTF-8?q?A=C3=B1adido=20test=20que=20faltaba=20de?= =?UTF-8?q?=20gateway?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gatewayservice/gateway-service.test.js | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/gatewayservice/gateway-service.test.js b/gatewayservice/gateway-service.test.js index c3e55c5..b76f343 100644 --- a/gatewayservice/gateway-service.test.js +++ b/gatewayservice/gateway-service.test.js @@ -194,23 +194,7 @@ describe('Gateway Service', () => { expect(response.status).toBe(401); // Esperamos un error de solicitud incorrecta }); - /* - it('debería manejar correctamente la carga excesiva', async () => { - // Realizar múltiples solicitudes simultáneas a endpoints diferentes - const promises = []; - for (let i = 0; i < 100; i++) { - promises.push(request(app).post('/login').send({ username: `user${i}`, password: 'password' })); - } - - // Esperar a que se completen todas las solicitudes - const responses = await Promise.all(promises); - - // Verificar que todas las respuestas tengan el código de estado esperado (200) - responses.forEach(response => { - expect(response.status).toBe(200); - }); - }); - */ + it('debería devolver un estado de salud "OK"', async () => { const response = await request(app).get('/health'); @@ -219,4 +203,10 @@ describe('Gateway Service', () => { expect(response.status).toBe(200); expect(response.body).toEqual({ status: 'OK' }); }); + + it('Debería devolver una lista de nombres de usuario cuando hay usuarios en la base de datos', async () => { + const response = await request(app).get('/getUsernames'); + expect(response.status).toBe(200); + }); + }); \ No newline at end of file From 07d8fa7f47369379c876b7461ebb500250f96d83 Mon Sep 17 00:00:00 2001 From: Lara Date: Sun, 28 Apr 2024 16:02:32 +0200 Subject: [PATCH 08/14] =?UTF-8?q?Coverafe=20para=20metodos=20de=20validar?= =?UTF-8?q?=20de=20a=C3=B1adir=20usuarios=20comentados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webapp/src/components/tests/AddUser.test.js | 41 +++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/webapp/src/components/tests/AddUser.test.js b/webapp/src/components/tests/AddUser.test.js index 8af0338..49cf88b 100644 --- a/webapp/src/components/tests/AddUser.test.js +++ b/webapp/src/components/tests/AddUser.test.js @@ -56,4 +56,45 @@ describe('AddUser component', () => { expect(screen.getByText(/Error: Internal Server Error/i)).toBeInTheDocument(); }); }); + + + + + + // it('should display error message for short password', async () => { + // render(); + + // const usernameInput = screen.getByLabelText(/Usuario/i); + // const passwordInput = screen.getByLabelText(/Contraseña/i); + // const createUserButton = screen.getByRole('button', { name: /Crear/i }); + + // fireEvent.change(usernameInput, { target: { value: 'newusername' } }); + // fireEvent.change(passwordInput, { target: { value: 'err' } }); + + // fireEvent.click(createUserButton); + + // expect(await screen.findByText(/Error: Credenciales incorrectas. La contraseña debe contener al menos 8 caracteres/i)).toBeInTheDocument(); + // }); + + + // it('should display error message for repeated username', async () => { + // const mockAxios = new MockAdapter(axios); + // const mockedUsernames = ['existingUser']; + // mockAxios.onGet(`http://localhost:8000/getUsernames`).reply(200, { usernames: mockedUsernames }); + + // render(); + + // const usernameInput = screen.getByLabelText(/Usuario/i); + // const passwordInput = screen.getByLabelText(/Contraseña/i); + // const createUserButton = screen.getByRole('button', { name: /Crear/i }); + + // fireEvent.change(usernameInput, { target: { value: 'existingUser' } }); + // fireEvent.change(passwordInput, { target: { value: 'short123456' } }); + + // fireEvent.click(createUserButton); + + // expect(await screen.findByText(/Usuario creado correctamente/i)).toBeInTheDocument(); + // }); + }); + From 81137f6d633f5266887aa15bc7262a16c8fcd4b7 Mon Sep 17 00:00:00 2001 From: Lara Date: Sun, 28 Apr 2024 16:25:35 +0200 Subject: [PATCH 09/14] Cambio de codigo comentado pero sigue sin funcionar correctamente --- webapp/src/components/tests/AddUser.test.js | 52 ++++++++++++++------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/webapp/src/components/tests/AddUser.test.js b/webapp/src/components/tests/AddUser.test.js index 49cf88b..2994019 100644 --- a/webapp/src/components/tests/AddUser.test.js +++ b/webapp/src/components/tests/AddUser.test.js @@ -57,44 +57,60 @@ describe('AddUser component', () => { }); }); - - - - - // it('should display error message for short password', async () => { + // it('should show error of password too short', async () => { // render(); + // const mockAxios = new MockAdapter(axios); + // const mockedUsernames = ['existingUser']; + // mockAxios.onGet(`http://localhost:8000/getUsernames`).reply(200, { usernames: mockedUsernames }); + // const usernameInput = screen.getByLabelText(/Usuario/i); // const passwordInput = screen.getByLabelText(/Contraseña/i); - // const createUserButton = screen.getByRole('button', { name: /Crear/i }); + // const addUserButton = screen.getByRole('button', { name: /Crear/i }); - // fireEvent.change(usernameInput, { target: { value: 'newusername' } }); - // fireEvent.change(passwordInput, { target: { value: 'err' } }); + // // Mock the axios.post request to simulate a successful response + // mockAxios.onPost('http://localhost:8000/adduser').reply(200); - // fireEvent.click(createUserButton); + // // Simulate user input + // fireEvent.change(usernameInput, { target: { value: 'testUser' } }); + // fireEvent.change(passwordInput, { target: { value: 'sh' } }); - // expect(await screen.findByText(/Error: Credenciales incorrectas. La contraseña debe contener al menos 8 caracteres/i)).toBeInTheDocument(); + // // Trigger the add user button click + // fireEvent.click(addUserButton); + + // // Wait for the Snackbar to be open + // await waitFor(() => { + // expect(screen.getByText(/Error: Credenciales incorrectas. La contraseña debe contener al menos 8 caracteres/i)).toBeInTheDocument(); + // }); // }); + // it('should show error of repeated user', async () => { + // render(); - // it('should display error message for repeated username', async () => { // const mockAxios = new MockAdapter(axios); // const mockedUsernames = ['existingUser']; // mockAxios.onGet(`http://localhost:8000/getUsernames`).reply(200, { usernames: mockedUsernames }); - // render(); - // const usernameInput = screen.getByLabelText(/Usuario/i); // const passwordInput = screen.getByLabelText(/Contraseña/i); - // const createUserButton = screen.getByRole('button', { name: /Crear/i }); + // const addUserButton = screen.getByRole('button', { name: /Crear/i }); + // // Mock the axios.post request to simulate a successful response + // mockAxios.onPost('http://localhost:8000/adduser').reply(200); + + // // Simulate user input // fireEvent.change(usernameInput, { target: { value: 'existingUser' } }); - // fireEvent.change(passwordInput, { target: { value: 'short123456' } }); + // fireEvent.change(passwordInput, { target: { value: 'passwordCorrect' } }); - // fireEvent.click(createUserButton); + // // Trigger the add user button click + // fireEvent.click(addUserButton); - // expect(await screen.findByText(/Usuario creado correctamente/i)).toBeInTheDocument(); + // // Wait for the Snackbar to be open + // await waitFor(() => { + // expect(screen.getByText(/Error: Credenciales incorrectas. El nombre de usuario esta en uso/i)).toBeInTheDocument(); + // }); // }); - + + }); From 41772848c4646d80f63ea4b62d5f02b84c8ccb66 Mon Sep 17 00:00:00 2001 From: Lara Date: Sun, 28 Apr 2024 16:38:57 +0200 Subject: [PATCH 10/14] Coverage de test de validacion de usuarios --- webapp/src/components/AddUser.js | 2 + webapp/src/components/tests/AddUser.test.js | 80 ++++++++++----------- 2 files changed, 42 insertions(+), 40 deletions(-) diff --git a/webapp/src/components/AddUser.js b/webapp/src/components/AddUser.js index f6eedb8..689d884 100644 --- a/webapp/src/components/AddUser.js +++ b/webapp/src/components/AddUser.js @@ -30,10 +30,12 @@ const AddUser = () => { const usernames = response.data.usernames; if (usernames.includes(username)){ setMensajeError('Credenciales incorrectas. El nombre de usuario esta en uso') + setError('Credenciales incorrectas. El nombre de usuario esta en uso') return false; } if (password.length < 8) { setMensajeError('Credenciales incorrectas. La contraseña debe contener al menos 8 caracteres') + setError('Credenciales incorrectas. La contraseña debe contener al menos 8 caracteres') return false; } return true; diff --git a/webapp/src/components/tests/AddUser.test.js b/webapp/src/components/tests/AddUser.test.js index 2994019..a08f0e2 100644 --- a/webapp/src/components/tests/AddUser.test.js +++ b/webapp/src/components/tests/AddUser.test.js @@ -57,59 +57,59 @@ describe('AddUser component', () => { }); }); - // it('should show error of password too short', async () => { - // render(); + it('should show error of password too short', async () => { + render(); - // const mockAxios = new MockAdapter(axios); - // const mockedUsernames = ['existingUser']; - // mockAxios.onGet(`http://localhost:8000/getUsernames`).reply(200, { usernames: mockedUsernames }); + const mockAxios = new MockAdapter(axios); + const mockedUsernames = ['existingUser']; + mockAxios.onGet(`http://localhost:8000/getUsernames`).reply(200, { usernames: mockedUsernames }); - // const usernameInput = screen.getByLabelText(/Usuario/i); - // const passwordInput = screen.getByLabelText(/Contraseña/i); - // const addUserButton = screen.getByRole('button', { name: /Crear/i }); + const usernameInput = screen.getByLabelText(/Usuario/i); + const passwordInput = screen.getByLabelText(/Contraseña/i); + const addUserButton = screen.getByRole('button', { name: /Crear/i }); - // // Mock the axios.post request to simulate a successful response - // mockAxios.onPost('http://localhost:8000/adduser').reply(200); + // Mock the axios.post request to simulate a successful response + mockAxios.onPost('http://localhost:8000/adduser').reply(200); - // // Simulate user input - // fireEvent.change(usernameInput, { target: { value: 'testUser' } }); - // fireEvent.change(passwordInput, { target: { value: 'sh' } }); + // Simulate user input + fireEvent.change(usernameInput, { target: { value: 'testUser' } }); + fireEvent.change(passwordInput, { target: { value: 'sh' } }); - // // Trigger the add user button click - // fireEvent.click(addUserButton); + // Trigger the add user button click + fireEvent.click(addUserButton); - // // Wait for the Snackbar to be open - // await waitFor(() => { - // expect(screen.getByText(/Error: Credenciales incorrectas. La contraseña debe contener al menos 8 caracteres/i)).toBeInTheDocument(); - // }); - // }); + // Wait for the Snackbar to be open + await waitFor(() => { + expect(screen.getByText(/Error: Credenciales incorrectas. La contraseña debe contener al menos 8 caracteres/i)).toBeInTheDocument(); + }); + }); - // it('should show error of repeated user', async () => { - // render(); + it('should show error of repeated user', async () => { + render(); - // const mockAxios = new MockAdapter(axios); - // const mockedUsernames = ['existingUser']; - // mockAxios.onGet(`http://localhost:8000/getUsernames`).reply(200, { usernames: mockedUsernames }); + const mockAxios = new MockAdapter(axios); + const mockedUsernames = ['existingUser']; + mockAxios.onGet(`http://localhost:8000/getUsernames`).reply(200, { usernames: mockedUsernames }); - // const usernameInput = screen.getByLabelText(/Usuario/i); - // const passwordInput = screen.getByLabelText(/Contraseña/i); - // const addUserButton = screen.getByRole('button', { name: /Crear/i }); + const usernameInput = screen.getByLabelText(/Usuario/i); + const passwordInput = screen.getByLabelText(/Contraseña/i); + const addUserButton = screen.getByRole('button', { name: /Crear/i }); - // // Mock the axios.post request to simulate a successful response - // mockAxios.onPost('http://localhost:8000/adduser').reply(200); + // Mock the axios.post request to simulate a successful response + mockAxios.onPost('http://localhost:8000/adduser').reply(200); - // // Simulate user input - // fireEvent.change(usernameInput, { target: { value: 'existingUser' } }); - // fireEvent.change(passwordInput, { target: { value: 'passwordCorrect' } }); + // Simulate user input + fireEvent.change(usernameInput, { target: { value: 'existingUser' } }); + fireEvent.change(passwordInput, { target: { value: 'passwordCorrect' } }); - // // Trigger the add user button click - // fireEvent.click(addUserButton); + // Trigger the add user button click + fireEvent.click(addUserButton); - // // Wait for the Snackbar to be open - // await waitFor(() => { - // expect(screen.getByText(/Error: Credenciales incorrectas. El nombre de usuario esta en uso/i)).toBeInTheDocument(); - // }); - // }); + // Wait for the Snackbar to be open + await waitFor(() => { + expect(screen.getByText(/Error: Credenciales incorrectas. El nombre de usuario esta en uso/i)).toBeInTheDocument(); + }); + }); }); From 8899ce10f73e638cdc96aaff59e7693563ed5150 Mon Sep 17 00:00:00 2001 From: Lara Date: Sun, 28 Apr 2024 16:47:16 +0200 Subject: [PATCH 11/14] Quitando codigo repetido --- webapp/src/components/tests/AddUser.test.js | 36 ++++----------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/webapp/src/components/tests/AddUser.test.js b/webapp/src/components/tests/AddUser.test.js index a08f0e2..2613dd5 100644 --- a/webapp/src/components/tests/AddUser.test.js +++ b/webapp/src/components/tests/AddUser.test.js @@ -4,7 +4,13 @@ import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; import AddUser from '../AddUser'; -const mockAxios = new MockAdapter(axios); + const mockAxios = new MockAdapter(axios); + const mockedUsernames = ['existingUser']; + mockAxios.onGet(`http://localhost:8000/getUsernames`).reply(200, { usernames: mockedUsernames }); + + const usernameInput = screen.getByLabelText(/Usuario/i); + const passwordInput = screen.getByLabelText(/Contraseña/i); + const addUserButton = screen.getByRole('button', { name: /Crear/i }); describe('AddUser component', () => { beforeEach(() => { @@ -13,11 +19,6 @@ describe('AddUser component', () => { it('should add user successfully', async () => { render(); - - const usernameInput = screen.getByLabelText(/Usuario/i); - const passwordInput = screen.getByLabelText(/Contraseña/i); - const addUserButton = screen.getByRole('button', { name: /Crear/i }); - // Mock the axios.post request to simulate a successful response mockAxios.onPost('http://localhost:8000/adduser').reply(200); @@ -36,11 +37,6 @@ describe('AddUser component', () => { it('should handle error when adding user', async () => { render(); - - const usernameInput = screen.getByLabelText(/Usuario/i); - const passwordInput = screen.getByLabelText(/Contraseña/i); - const addUserButton = screen.getByRole('button', { name: /Crear/i }); - // Mock the axios.post request to simulate an error response mockAxios.onPost('http://localhost:8000/adduser').reply(500, { error: 'Internal Server Error' }); @@ -59,15 +55,6 @@ describe('AddUser component', () => { it('should show error of password too short', async () => { render(); - - const mockAxios = new MockAdapter(axios); - const mockedUsernames = ['existingUser']; - mockAxios.onGet(`http://localhost:8000/getUsernames`).reply(200, { usernames: mockedUsernames }); - - const usernameInput = screen.getByLabelText(/Usuario/i); - const passwordInput = screen.getByLabelText(/Contraseña/i); - const addUserButton = screen.getByRole('button', { name: /Crear/i }); - // Mock the axios.post request to simulate a successful response mockAxios.onPost('http://localhost:8000/adduser').reply(200); @@ -86,15 +73,6 @@ describe('AddUser component', () => { it('should show error of repeated user', async () => { render(); - - const mockAxios = new MockAdapter(axios); - const mockedUsernames = ['existingUser']; - mockAxios.onGet(`http://localhost:8000/getUsernames`).reply(200, { usernames: mockedUsernames }); - - const usernameInput = screen.getByLabelText(/Usuario/i); - const passwordInput = screen.getByLabelText(/Contraseña/i); - const addUserButton = screen.getByRole('button', { name: /Crear/i }); - // Mock the axios.post request to simulate a successful response mockAxios.onPost('http://localhost:8000/adduser').reply(200); From 0bceae4469814b119e734e32ac2333a4f06d2f84 Mon Sep 17 00:00:00 2001 From: Lara Date: Sun, 28 Apr 2024 16:53:25 +0200 Subject: [PATCH 12/14] Quitando codigo repetido --- webapp/src/components/tests/AddUser.test.js | 100 +++++++++----------- 1 file changed, 44 insertions(+), 56 deletions(-) diff --git a/webapp/src/components/tests/AddUser.test.js b/webapp/src/components/tests/AddUser.test.js index 2613dd5..fe76461 100644 --- a/webapp/src/components/tests/AddUser.test.js +++ b/webapp/src/components/tests/AddUser.test.js @@ -4,91 +4,79 @@ import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; import AddUser from '../AddUser'; - const mockAxios = new MockAdapter(axios); - const mockedUsernames = ['existingUser']; - mockAxios.onGet(`http://localhost:8000/getUsernames`).reply(200, { usernames: mockedUsernames }); - - const usernameInput = screen.getByLabelText(/Usuario/i); - const passwordInput = screen.getByLabelText(/Contraseña/i); - const addUserButton = screen.getByRole('button', { name: /Crear/i }); +const mockAxios = new MockAdapter(axios); describe('AddUser component', () => { beforeEach(() => { mockAxios.reset(); }); - it('should add user successfully', async () => { - render(); - // Mock the axios.post request to simulate a successful response + const renderComponent = () => render(); + + const setupMockedUsernames = (usernames) => { + mockAxios.onGet(`http://localhost:8000/getUsernames`).reply(200, { usernames }); + }; + + const setupSuccessfulResponse = () => { mockAxios.onPost('http://localhost:8000/adduser').reply(200); + }; - // Simulate user input - fireEvent.change(usernameInput, { target: { value: 'testUser' } }); - fireEvent.change(passwordInput, { target: { value: 'testPassword' } }); + const setupErrorResponse = (statusCode, errorMessage) => { + mockAxios.onPost('http://localhost:8000/adduser').reply(statusCode, { error: errorMessage }); + }; - // Trigger the add user button click - fireEvent.click(addUserButton); + const typeUsernameAndPassword = (username, password) => { + const usernameInput = screen.getByLabelText(/Usuario/i); + const passwordInput = screen.getByLabelText(/Contraseña/i); + fireEvent.change(usernameInput, { target: { value: username } }); + fireEvent.change(passwordInput, { target: { value: password } }); + }; + + const clickCreateUserButton = () => { + const createUserButton = screen.getByRole('button', { name: /Crear/i }); + fireEvent.click(createUserButton); + }; - // Wait for the Snackbar to be open + it('should add user successfully', async () => { + renderComponent(); + setupSuccessfulResponse(); + typeUsernameAndPassword('testUser', 'testPassword'); + clickCreateUserButton(); await waitFor(() => { expect(screen.getByText(/Usuario creado correctamente/i)).toBeInTheDocument(); }); }); it('should handle error when adding user', async () => { - render(); - // Mock the axios.post request to simulate an error response - mockAxios.onPost('http://localhost:8000/adduser').reply(500, { error: 'Internal Server Error' }); - - // Simulate user input - fireEvent.change(usernameInput, { target: { value: 'testUser' } }); - fireEvent.change(passwordInput, { target: { value: 'testPassword' } }); - - // Trigger the add user button click - fireEvent.click(addUserButton); - - // Wait for the error Snackbar to be open + renderComponent(); + setupErrorResponse(500, 'Internal Server Error'); + typeUsernameAndPassword('testUser', 'testPassword'); + clickCreateUserButton(); await waitFor(() => { expect(screen.getByText(/Error: Internal Server Error/i)).toBeInTheDocument(); }); }); - it('should show error of password too short', async () => { - render(); - // Mock the axios.post request to simulate a successful response - mockAxios.onPost('http://localhost:8000/adduser').reply(200); - - // Simulate user input - fireEvent.change(usernameInput, { target: { value: 'testUser' } }); - fireEvent.change(passwordInput, { target: { value: 'sh' } }); - - // Trigger the add user button click - fireEvent.click(addUserButton); - - // Wait for the Snackbar to be open + it('should show error message for short password', async () => { + renderComponent(); + setupMockedUsernames([]); + setupSuccessfulResponse(); + typeUsernameAndPassword('testUser', 'sh'); + clickCreateUserButton(); await waitFor(() => { expect(screen.getByText(/Error: Credenciales incorrectas. La contraseña debe contener al menos 8 caracteres/i)).toBeInTheDocument(); }); }); - it('should show error of repeated user', async () => { - render(); - // Mock the axios.post request to simulate a successful response - mockAxios.onPost('http://localhost:8000/adduser').reply(200); - - // Simulate user input - fireEvent.change(usernameInput, { target: { value: 'existingUser' } }); - fireEvent.change(passwordInput, { target: { value: 'passwordCorrect' } }); - - // Trigger the add user button click - fireEvent.click(addUserButton); - - // Wait for the Snackbar to be open + it('should show error message for repeated username', async () => { + renderComponent(); + setupMockedUsernames(['existingUser']); + setupSuccessfulResponse(); + typeUsernameAndPassword('existingUser', 'passwordCorrect'); + clickCreateUserButton(); await waitFor(() => { expect(screen.getByText(/Error: Credenciales incorrectas. El nombre de usuario esta en uso/i)).toBeInTheDocument(); }); }); - }); - From add7c77a5191e31e77ae3f1fffb6c2b5a632f7d3 Mon Sep 17 00:00:00 2001 From: Lara Date: Sun, 28 Apr 2024 17:10:28 +0200 Subject: [PATCH 13/14] Fixing issues de Sonar --- gatewayservice/gateway-service.js | 2 +- webapp/src/components/AddUser.js | 2 +- webapp/src/components/Pages/Estadisticas.js | 2 -- webapp/src/components/tests/Estadisticas.test.js | 2 -- webapp/src/components/tests/Juego.test.js | 2 -- 5 files changed, 2 insertions(+), 8 deletions(-) diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index 363400a..899b55b 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -39,7 +39,7 @@ app.post('/login', async (req, res) => { app.post('/adduser', async (req, res) => { try { - const { username, password, valido, mensajeError } = req.body; + const { valido, mensajeError } = req.body; if (!valido) { // Si las credenciales son inválidas, devuelve un error 401 diff --git a/webapp/src/components/AddUser.js b/webapp/src/components/AddUser.js index 689d884..0f99681 100644 --- a/webapp/src/components/AddUser.js +++ b/webapp/src/components/AddUser.js @@ -14,7 +14,7 @@ const AddUser = () => { const addUser = async () => { try { - var valido = await validateCredentials(username, password); + let valido = await validateCredentials(username, password); await axios.post(`${apiEndpoint}/adduser`, { username, password, valido, mensajeError }); setOpenSnackbar(true); } catch (error) { diff --git a/webapp/src/components/Pages/Estadisticas.js b/webapp/src/components/Pages/Estadisticas.js index 99d6902..cf46249 100644 --- a/webapp/src/components/Pages/Estadisticas.js +++ b/webapp/src/components/Pages/Estadisticas.js @@ -12,7 +12,6 @@ const Estadisticas = ({isLogged, username}) => { const [correctAnswers, setCorrectAnswers] = useState(0); const [incorrectAnswers, setIncorrectAnswers] = useState(0); const [completedGames, setCompletedGames] = useState(0); - //const [averageTime, setAverageTime] = useState(0); const [firstRender, setFirstRender] = useState(false); useEffect(() => { @@ -30,7 +29,6 @@ const Estadisticas = ({isLogged, username}) => { setCorrectAnswers(datos.user.correctAnswers); setIncorrectAnswers(datos.user.incorrectAnswers); setCompletedGames(datos.user.completedGames); - //setAverageTime(datos.user.averageTime); } catch (error) { setError('Error al cargar la información'); } diff --git a/webapp/src/components/tests/Estadisticas.test.js b/webapp/src/components/tests/Estadisticas.test.js index 8c8828d..60526ad 100644 --- a/webapp/src/components/tests/Estadisticas.test.js +++ b/webapp/src/components/tests/Estadisticas.test.js @@ -36,8 +36,6 @@ describe('Estadisticas Component', () => { expect(getByText('Nº Juegos completados:')).toBeInTheDocument(); expect(getByText('20')).toBeInTheDocument(); // Verifica que el número de juegos completados sea 20 - //expect(getByText('Tiempo medio por juego:')).toBeInTheDocument(); - //expect(getByText('30')).toBeInTheDocument(); // Verifica que el tiempo medio por juego sea 30 }); }); diff --git a/webapp/src/components/tests/Juego.test.js b/webapp/src/components/tests/Juego.test.js index b446439..1a981bc 100644 --- a/webapp/src/components/tests/Juego.test.js +++ b/webapp/src/components/tests/Juego.test.js @@ -96,9 +96,7 @@ describe('Juego component', () => { await waitFor(() => getByText(mockData.question)); fireEvent.click(getByText('SIGUIENTE')); fireEvent.click(getByText('GUARDAR ESTADÍSTICAS')); - //expect(getByText('GUARDAR ESTADÍSTICAS')).toBeDisabled(); expect(getByText('Comience nueva partida o visite sus estadísticas!!')).toBeInTheDocument() - //expect(axios.get).toHaveBeenCalledWith('http://localhost:8000/updateStats?username=test&numRespuestasCorrectas=0&numRespuestasIncorrectas=0'); }); it('el temporizador llega a 0 y se desvelan las respuestas ademas de bloquearse los botones', async () => { From 34453cfcb12707bea7bc577015f8bbaadcca9674 Mon Sep 17 00:00:00 2001 From: Lara Date: Sun, 28 Apr 2024 17:17:03 +0200 Subject: [PATCH 14/14] Otra issue --- webapp/src/components/tests/Juego.test.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/webapp/src/components/tests/Juego.test.js b/webapp/src/components/tests/Juego.test.js index 1a981bc..26422aa 100644 --- a/webapp/src/components/tests/Juego.test.js +++ b/webapp/src/components/tests/Juego.test.js @@ -34,7 +34,7 @@ describe('Juego component', () => { }); it('obtiene las preguntas y respuestas', async () => { - const { container, getByText } = render(); + const { getByText } = render(); await waitFor(() => getByText('CARGANDO...')); @@ -49,7 +49,7 @@ describe('Juego component', () => { }); it('responde la pregunta correctamente', async () => { - const { container, getByText } = render(); + const { getByText } = render(); await waitFor(() => getByText(mockData.question)); @@ -63,7 +63,7 @@ describe('Juego component', () => { }); it('responde la pregunta incorrectamente y despinta al hacer click en Siguiente', async () => { - const { container, getByText } = render(); + const { getByText } = render(); await waitFor(() => getByText(mockData.question)); @@ -92,7 +92,7 @@ describe('Juego component', () => { }); it('finalizar Juego', async () => { - const { container, getByText } = render(); + const { getByText } = render(); await waitFor(() => getByText(mockData.question)); fireEvent.click(getByText('SIGUIENTE')); fireEvent.click(getByText('GUARDAR ESTADÍSTICAS')); @@ -100,7 +100,7 @@ describe('Juego component', () => { }); it('el temporizador llega a 0 y se desvelan las respuestas ademas de bloquearse los botones', async () => { - const { container, getByText } = render(); + const { getByText } = render(); await waitFor(() => getByText(mockData.question)); act(() => {