diff --git a/controllers/products.js b/controllers/products.js index 3b44839..11dfaa4 100644 --- a/controllers/products.js +++ b/controllers/products.js @@ -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, @@ -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, @@ -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'); diff --git a/controllers/users.js b/controllers/users.js index 7276f1e..4c0b62f 100644 --- a/controllers/users.js +++ b/controllers/users.js @@ -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) { @@ -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 @@ -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] ); @@ -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", @@ -319,6 +339,7 @@ const update_availability = async (req, res = response) => { } }; + module.exports = { save_user, update_user, diff --git a/package-lock.json b/package-lock.json index 052cde8..d99e885 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3217,7 +3217,6 @@ "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, - "license": "MIT", "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -4214,8 +4213,7 @@ "version": "3.0.5", "resolved": "https://registry.npmjs.org/mockdate/-/mockdate-3.0.5.tgz", "integrity": "sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/ms": { "version": "2.0.0", @@ -5259,7 +5257,6 @@ "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.0.0.tgz", "integrity": "sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA==", "dev": true, - "license": "MIT", "dependencies": { "methods": "^1.1.2", "superagent": "^9.0.1" diff --git a/package.json b/package.json index f3d0d4c..10c12a7 100644 --- a/package.json +++ b/package.json @@ -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" } } diff --git a/routes/users.js b/routes/users.js index f84907f..ce798fa 100644 --- a/routes/users.js +++ b/routes/users.js @@ -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; diff --git a/server.js b/server.js index 7031333..f5888d7 100644 --- a/server.js +++ b/server.js @@ -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}`); -}); \ No newline at end of file +module.exports = app; // Exporta la app para las pruebas diff --git a/tests/controllers/products/get_products_offered_product.test.js b/tests/controllers/products/get_products_offered_product.test.js index 15221f0..71ad20c 100644 --- a/tests/controllers/products/get_products_offered_product.test.js +++ b/tests/controllers/products/get_products_offered_product.test.js @@ -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'); @@ -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); }); -}); +}); \ No newline at end of file