Skip to content
Merged

Dani #37

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 33 additions & 18 deletions controllers/products.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,14 @@ const get_statistics_products = async (req, res = response) => {

const { year, month } = req.params;


if (!uid || !year || !month) {
console.log("Faltan parámetros requeridos.");
return res.status(400).json({ mensaje: "Faltan parámetros requeridos: idSeller, year, month" });
if (!year || !month) {
return res.status(400).json({ mensaje: "Faltan parámetros requeridos: year, month" });
}

if (isNaN(year) || isNaN(month)) {
console.log("Año o mes no son valores numéricos válidos.");
return res.status(400).json({ mensaje: "El año y mes deben ser valores numéricos." });
if (isNaN(year) || isNaN(month) || month < 1 || month > 12) {
return res.status(400).json({ mensaje: "El año y mes deben ser valores numéricos válidos y el mes debe estar entre 1 y 12." });
}

console.log("Ejecutando consulta SQL...");
const [productos] = await connection.execute(
`SELECT
p.nombre AS producto,
Expand Down Expand Up @@ -70,6 +66,22 @@ const get_statistics_products = async (req, res = response) => {

const get_products_offered = async (req, res = response) => {
try {
// Validación del token
const token = req.header('x-token');
if (!token) {
return res.status(401).json({ mensaje: 'No se proporcionó el token' });
}

// Verifica el token
let uid;
try {
({ uid } = jwt.verify(token, SECRET_KEY));
} catch (error) {
console.error("Error al verificar el token:", error.message);
return res.status(401).json({ mensaje: `Token inválido o expirado: ${error.message}` });
}

// Si el token es válido, obtenemos los productos
const [productos] = await connection.execute(`
SELECT
p.idProducto,
Expand All @@ -85,24 +97,27 @@ const get_products_offered = async (req, res = response) => {
u.foto AS fotoVendedor
FROM productos p
JOIN categoriaProducto c ON p.idcategoriaProducto = c.idcategoriaProducto
JOIN usuarios u ON p.idVendedor = u.idUsuario;
`);
JOIN usuarios u ON p.idVendedor = u.idUsuario
WHERE p.idVendedor = ?;
`, [uid]);

if (productos.length === 0) {
return res
.status(404)
.json({ mensaje: "No se encontraron productos registrados" });
if (!productos || productos.length === 0) {
return res.status(404).json({
mensaje: 'No se encontraron productos registrados',
productos: []
});
}

// Si hay productos, los retornamos con un código 200
return res.status(200).json({ productos });

} catch (error) {
console.error("Error al obtener todos los productos:", error);
res
.status(500)
.json({ mensaje: "Error interno del servidor al obtener los productos" });
console.error("Error al obtener los productos:", error);
return res.status(500).json({ mensaje: "Error interno del servidor al obtener los productos" });
}
};


const add_product = async (req, res = response) => {
const token = req.header('x-token');

Expand Down
33 changes: 27 additions & 6 deletions controllers/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,26 +260,45 @@ const change_disponibility = async (req, res = response) => {
};

const update_availability = async (req, res = response) => {

try {
const token = req.header("x-token");

if (!token) {
return res.status(401).json({ mensaje: "No se proporcionó el token" });
}

const { idUsuario } = req.params;
const { disponibilidad, ubicacion } = req.body;

console.log(req.body);

// Validar si se proporcionan datos para actualizar
if (disponibilidad === undefined && ubicacion === undefined) {
return res
.status(400)
.json({ error: "Se debe proporcionar al menos un campo para actualizar" });
.json({ mensaje: "Faltan parámetros requeridos: disponibilidad, ubicacion" });
}

// Validar que disponibilidad sea 1 o 0
if (
disponibilidad !== undefined &&
disponibilidad !== 1 &&
disponibilidad !== 0
) {
return res.status(400).json({ mensaje: "El valor de disponibilidad no es válido" });
}

// Validar que la ubicación no sea una cadena vacía si está presente
if (ubicacion !== undefined && ubicacion.trim() === "") {
return res.status(400).json({ mensaje: "El valor de ubicación no es válido" });
}

const updates = [];
const values = [];

if (disponibilidad !== undefined) {
const disponibilidadBool = disponibilidad === 'true' || disponibilidad === true; // Asegura que el valor sea booleano
updates.push("disponibilidad = ?");
values.push(disponibilidadBool);
values.push(disponibilidad);
}

if (ubicacion !== undefined) {
Expand All @@ -289,6 +308,7 @@ const update_availability = async (req, res = response) => {

values.push(idUsuario);

// Intentar actualizar el usuario
const [resultado] = await connection.execute(
`UPDATE usuarios SET ${updates.join(", ")} WHERE idUsuario = ?`,
values
Expand All @@ -298,8 +318,9 @@ const update_availability = async (req, res = response) => {
return res.status(404).json({ mensaje: "Usuario no encontrado" });
}

// Obtener los datos actualizados del usuario
const [usuarioActualizado] = await connection.execute(
"SELECT idUsuario, nombre, correo, contrasenia, tipo, disponibilidad, ubicacion FROM usuarios WHERE idUsuario = ?",
"SELECT idUsuario, nombre, correo, contrasenia, disponibilidad, ubicacion FROM usuarios WHERE idUsuario = ?",
[idUsuario]
);

Expand All @@ -308,7 +329,6 @@ const update_availability = async (req, res = response) => {
nombre: usuarioActualizado[0].nombre,
correo: usuarioActualizado[0].correo,
contrasenia: usuarioActualizado[0].contrasenia,
tipo: usuarioActualizado[0].tipo,
disponibilidad: usuarioActualizado[0].disponibilidad,
ubicacion: usuarioActualizado[0].ubicacion,
mensaje: "Usuario actualizado correctamente",
Expand All @@ -319,6 +339,7 @@ const update_availability = async (req, res = response) => {
}
};


module.exports = {
save_user,
update_user,
Expand Down
5 changes: 1 addition & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
"test:saveUser": "jest tests/controllers/users/save_user.test.js",
"test:updateUser": "jest tests/controllers/users/update_user.test.js",
"test:deleteUser": "jest tests/controllers/users/delete_user.test.js",
"test:getProductsoffered": "jest tests/controllers/users/get_products_offered_product.test.js",
"test:getStaticsGraph": "jest tests/controllers/users/get_statistics_product.test.js",
"test:getProductsoffered": "jest tests/controllers/products/get_products_offered_product.test.js",
"test:getStaticsGraph": "jest tests/controllers/products/get_statistics_product.test.js",
"test:updateAvailability": "jest tests/controllers/users/update_availability_user.test.js"
}
}
2 changes: 1 addition & 1 deletion routes/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const router = Router();
router.post('/', upload.single('foto'), save_user);
router.put('/', upload.single('foto'), validarJWT, update_user);
router.delete('/', validarJWT, delete_usuario);
router.put('/availability/:idUsuario', validarJWT, update_availability);
router.put('/availability/:idUsuario', update_availability);

module.exports = router;

15 changes: 9 additions & 6 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,14 @@ app.use('/auth', require('./routes/auth'));
app.use('/products', require('./routes/products'));
app.use('/utils', require('./routes/utils'));
app.use('/users', require('./routes/users'));
app.use('/orders',require('./routes/orders'))
app.use('/orders', require('./routes/orders'));

module.exports = app;
// Solo iniciar el servidor si no estamos en el entorno de pruebas
if (process.env.NODE_ENV !== 'test') {
const PORT = 3000;
app.listen(PORT, () => {
console.log(`\nServidor está escuchando en puerto ${PORT}`);
});
}

const PORT = 3000;
app.listen(PORT, () => {
console.log(`\nServidor está escuchando en puerto ${PORT}`);
});
module.exports = app; // Exporta la app para las pruebas
100 changes: 49 additions & 51 deletions tests/controllers/products/get_products_offered_product.test.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,67 @@
const request = require('supertest');
const app = require('../../../server');
const app = require('../../../server');

describe('GET /offered/:idSeller', () => {
let validTokenSuccess;
let validTokenSuccess;
let validTokenNoProducts;

beforeAll(async () => {
// Generar token para un usuario con productos
try {
const loginResponse = await request(app)
.post('/auth/login')
.send({
correo: 'dms19-@hotmail.com',
contrasenia: '123456',
correo: 'dms19-@hotmail.com',
contrasenia: '123456',
});

expect(loginResponse.status).toBe(200);
expect(loginResponse.headers).toHaveProperty('x-token');

validTokenSuccess = loginResponse.headers['x-token'];
console.log('Token generado por autenticación:', validTokenSuccess);
validTokenSuccess = loginResponse.headers['x-token'];

if (!validTokenSuccess) {
throw new Error('Token no recibido');
throw new Error('Token no recibido para usuario con productos');
}
} catch (error) {
console.error('Error al autenticar al usuario con productos:', error);
throw error;
}

// Generar token para un usuario sin productos
try {
const loginResponse = await request(app)
.post('/auth/login')
.send({
correo: 'juan@example.com',
contrasenia: 'password123',
});

expect(loginResponse.status).toBe(200);
expect(loginResponse.headers).toHaveProperty('x-token');
validTokenNoProducts = loginResponse.headers['x-token'];

if (!validTokenNoProducts) {
throw new Error('Token no recibido para usuario sin productos');
}
} catch (error) {
console.error('Error al autenticar al cliente:', error);
throw error;
console.error('Error al autenticar al usuario sin productos:', error);
throw error;
}
});

it('Debe devolver todos los productos ofrecidos por un vendedor', async () => {
const sellerId = 1;
const sellerId = 1; // ID de un vendedor con productos
const response = await request(app)
.get(`/products/offered/${sellerId}`)
.set('x-token', validTokenSuccess);
.get(`/products/offered/${sellerId}`)
.set('x-token', validTokenSuccess);

console.log('Respuesta de productos:', response.body);
console.log('Respuesta de productos:', response.body);

expect(response.status).toBe(200);
expect(response.body).toHaveProperty('productos');
expect(Array.isArray(response.body.productos)).toBe(true);
expect(response.status).toBe(200);
expect(response.body).toHaveProperty('productos');
expect(Array.isArray(response.body.productos)).toBe(true);

response.body.productos.forEach(producto => {
response.body.productos.forEach((producto) => {
expect(producto).toHaveProperty('idProducto');
expect(producto).toHaveProperty('nombreProducto');
expect(producto).toHaveProperty('descripcion');
Expand All @@ -56,40 +77,17 @@ describe('GET /offered/:idSeller', () => {
});

it('Debe devolver un error 404 si no se encuentran productos ofrecidos', async () => {
let validTokenNoProducts;

try {
const loginResponse = await request(app)
.post('/auth/login')
.send({
correo: 'juan@example.com',
contrasenia: 'password123',
});

expect(loginResponse.status).toBe(200);
expect(loginResponse.headers).toHaveProperty('x-token');

validTokenNoProducts = loginResponse.headers['x-token'];

if (!validTokenNoProducts) {
throw new Error('Token no recibido');
}
} catch (error) {
console.error('Error al autenticar al usuario sin productos:', error);
throw error;
}

const sellerId = 4;
const sellerId = 4; // ID de un vendedor sin productos
const response = await request(app)
.get(`/products/offered/${sellerId}`)
.set('x-token', validTokenNoProducts);
console.log('Respuesta de error:', response.body);
expect(response.status).toBe(404);
.get(`/products/offered/${sellerId}`)
.set('x-token', validTokenNoProducts);

console.log('Respuesta de error:', response.body);

expect(response.status).toBe(404);
expect(response.body).toHaveProperty('mensaje', 'No se encontraron productos registrados');
expect(response.body).toHaveProperty('productos');
expect(Array.isArray(response.body.productos)).toBe(true);
expect(response.body).toHaveProperty('productos');
expect(Array.isArray(response.body.productos)).toBe(true);
expect(response.body.productos.length).toBe(0);
});
});
});
Loading