Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/Arquisoft/wiq_es05a into…
Browse files Browse the repository at this point in the history
… develop
  • Loading branch information
uo289432 committed Apr 25, 2024
2 parents 4ccab80 + abf2c34 commit 7e84dee
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 37 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
- develop
- LaraFMz
- Pablo-Arreglos
- Jota
pull_request:
types: [opened, synchronize, reopened]
jobs:
Expand Down
Binary file added docs/images/07_DiagramaDespliegue3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 14 additions & 10 deletions gatewayservice/gateway-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,6 @@ app.get('/health', (_req, res) => {
});

app.post('/login', async (req, res) => {
const isValidUser = validateCredentials(req.body.username, req.body.password);

if (!isValidUser) {
// Si las credenciales son inválidas, devuelve un error 401
res.status(401).json({ error: 'Credenciales incorrectas' });
return; // Termina la ejecución de la función para evitar ejecutar el código restante
}

try {
// Forward the login request to the authentication service
const authResponse = await axios.post(authServiceUrl+'/login', req.body);
Expand All @@ -45,14 +37,26 @@ app.post('/login', async (req, res) => {
}
});


function validateCredentials(username, password) {
// Verifica si la contraseña es erronea
const invalidPassword = 'no';
if (password.length < 8) {
return false;
}

return !(password === invalidPassword);
return true;
}

app.post('/adduser', async (req, res) => {

const isValidUser = validateCredentials(req.body.username, req.body.password);

if (!isValidUser) {
// Si las credenciales son inválidas, devuelve un error 401
res.status(401).json({ error: 'Credenciales incorrectas. La contraseña debe contener al menos 8 caracteres' });
return; // Termina la ejecución de la función para evitar ejecutar el código restante
}

try {
// Forward the add user request to the user service
const userResponse = await axios.post(userServiceUrl+'/adduser', req.body);
Expand Down
26 changes: 5 additions & 21 deletions gatewayservice/gateway-service.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,15 @@ describe('Gateway Service', () => {
return Promise.resolve({ data: { userId: 'mockedUserId' } });
}
});

/*
// Test /login endpoint
it('deberia iniciar sesión correctamente', async () => {
const response = await request(app)
.post('/login')
.send({ username: 'testuser', password: 'testpassword' });
expect(response.statusCode).toBe(200);
expect(response.body.token).toBe('mockedToken');
});
*/

// Prueba de manejo de errores para el endpoint /login
it('deberia devolver error al iniciar sesion', async () => {
// Datos de prueba para iniciar sesión (incorrectos)
const invalidLoginData = {
username: 'userInvalido',
password: 'no'
};
// Prueba de manejo de errores para el endpoint /adduser
it('deberia devolver error al registrate', async () => {

// Realizamos una solicitud POST al endpoint /login con datos incorrectos
const response = await request(app)
.post('/login')
.send(invalidLoginData);
.post('/adduser')
.send({ username: 'userInvalido', password: 'no' });


// Verificamos que la respuesta tenga un código de estado 401 (Unauthorized)
expect(response.statusCode).toBe(401);
Expand Down
2 changes: 1 addition & 1 deletion webapp/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ RUN npm install serve

#Execute npm run prod to run the server
CMD [ "npm", "run", "prod" ]
#CMD ["npm", "start"]
#CMD ["npm", "start"]
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ defineFeature(feature, test => {

given('An unregistered user', async () => {
username = "[email protected]"
password = "pabloasw"
password = "pabloasw1"
await expect(page).toClick("button", { text: "REGÍSTRATE" });
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ defineFeature(feature, test => {

given('A user that is logged in the application', async () => {
username = "[email protected]"
password = "pabloasw"
password = "pabloasw1"
await expect(page).toClick("button", { text: "INICIA SESIÓN" });
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ defineFeature(feature, test => {

given('A user that is logged in the application', async () => {
username = "[email protected]"
password = "pabloasw"
password = "pabloasw1"
await expect(page).toClick("button", { text: "INICIA SESIÓN" });
});

Expand Down
68 changes: 68 additions & 0 deletions webapp/src/App.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { render, screen } from '@testing-library/react';
import App from './App';

/*test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/Welcome to the 2024 edition of the Software Architecture course/i);
expect(linkElement).toBeInTheDocument();
});
*/

describe('App', () => {

it('renders login page when not logged in', () => {
render(
<MemoryRouter>
<App />
</MemoryRouter>
);

expect(screen.getByText(/Login/i)).toBeInTheDocument();
});

it('renders home page when logged in', () => {
// Mock local storage to simulate being logged in
const mockLocalStorage = {
getItem: jest.fn(() => 'true'),
setItem: jest.fn(),
clear: jest.fn()
};
global.localStorage = mockLocalStorage;

render(
<MemoryRouter>
<App />
</MemoryRouter>
);

expect(screen.getByText(/Home/i)).toBeInTheDocument();
});

it('redirects to login when trying to access stats page without logging in', () => {
render(
<MemoryRouter initialEntries={['/stats']}>
<App />
</MemoryRouter>
);

expect(screen.getByText(/Login/i)).toBeInTheDocument();
});

it('renders stats page when logged in and trying to access stats page', () => {
// Mock local storage to simulate being logged in
const mockLocalStorage = {
getItem: jest.fn(() => 'true'),
setItem: jest.fn(),
clear: jest.fn()
};
global.localStorage = mockLocalStorage;

render(
<MemoryRouter initialEntries={['/stats']}>
<App />
</MemoryRouter>
);

expect(screen.getByText(/Estadisticas/i)).toBeInTheDocument();
});
});
4 changes: 2 additions & 2 deletions webapp/src/components/Pages/Juego.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const Juego = ({isLogged, username, numPreguntas}) => {
const [numRespuestasIncorrectas, setNumRespuestasIncorrectas] = useState(0)
const [disableFinish, setDisableFinish] = useState(false)

//const navigate= useNavigate()
const navigate= useNavigate()

//Variables para la obtencion y modificacion de estadisticas del usuario y de preguntas
const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000';
Expand Down Expand Up @@ -201,7 +201,7 @@ const Juego = ({isLogged, username, numPreguntas}) => {
const clickFinalizar = () => {
updateStats();
setDisableFinish(true)
//navigate('/')
navigate('/')
}

const handleRestart = () => {
Expand Down
6 changes: 6 additions & 0 deletions webapp/src/components/Pages/Layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import React from 'react';
import {Container, Nav, Navbar} from 'react-bootstrap';
import PropTypes from 'prop-types'

const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000';

const Layout = ({ isLogged, setIsLogged }) => {

function onLogout(){
Expand All @@ -22,8 +24,12 @@ import PropTypes from 'prop-types'
<Nav.Link href="stats">Estadísticas</Nav.Link>
}
</Nav>
<Nav>
<Nav.Link href={`${apiEndpoint}/api-doc`} target="_blanck">API</Nav.Link>
</Nav>
<Nav>
{isLogged ? (

<Nav.Link onClick={onLogout}>Cerrar sesión</Nav.Link>
) : (
<>
Expand Down
49 changes: 49 additions & 0 deletions webapp/src/components/Temporizador.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import Temporizador from './Temporizador';

describe('Temporizador', () => {
it('renders the initial countdown time', () => {
const tiempoInicial = 60;
render(<Temporizador tiempoInicial={tiempoInicial} />);
const countdownElement = screen.getByText(tiempoInicial);
expect(countdownElement).toBeInTheDocument();
});

it('decreases countdown time when not paused', () => {
jest.useFakeTimers();
const tiempoInicial = 60;
render(<Temporizador tiempoInicial={tiempoInicial} />);
jest.advanceTimersByTime(1000);
const updatedCountdownElement = screen.getByText(tiempoInicial - 1);
expect(updatedCountdownElement).toBeInTheDocument();
jest.useRealTimers();
});

it('stops countdown time when paused', () => {
jest.useFakeTimers();
const tiempoInicial = 60;
render(<Temporizador tiempoInicial={tiempoInicial} pausa={true} />);
jest.advanceTimersByTime(1000);
const updatedCountdownElement = screen.getByText(tiempoInicial);
expect(updatedCountdownElement).toBeInTheDocument();
jest.useRealTimers();
});

it('restarts countdown time when restart prop changes', () => {
jest.useFakeTimers();
const tiempoInicial = 60;
const { rerender } = render(<Temporizador tiempoInicial={tiempoInicial} />);
jest.advanceTimersByTime(1000);
const updatedCountdownElement = screen.getByText(tiempoInicial - 1);
expect(updatedCountdownElement).toBeInTheDocument();

// Simulate restart by changing the restart prop
rerender(<Temporizador tiempoInicial={tiempoInicial} restart={true} />);

// Countdown should restart
const restartedCountdownElement = screen.getByText(tiempoInicial);
expect(restartedCountdownElement).toBeInTheDocument();
jest.useRealTimers();
});
});

0 comments on commit 7e84dee

Please sign in to comment.