From 0513d23edb01a4a1cd16734600ec90a088c9efec Mon Sep 17 00:00:00 2001 From: danimsix Date: Mon, 13 Jan 2025 14:39:44 -0600 Subject: [PATCH] fix the test --- controllers/products.js | 51 ++++--- controllers/users.js | 33 ++++- package-lock.json | 5 +- package.json | 4 +- routes/users.js | 2 +- server.js | 15 +- .../get_products_offered_product.test.js | 118 +++++++++++----- .../products/get_statistics_product.test.js | 77 ++++++---- .../users/update_availability_user.test.js | 133 ++++++++---------- 9 files changed, 262 insertions(+), 176 deletions(-) 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 08c1f72..636e509 100644 --- a/tests/controllers/products/get_products_offered_product.test.js +++ b/tests/controllers/products/get_products_offered_product.test.js @@ -1,43 +1,95 @@ -describe('Pruebas para la ruta /offered/:idSeller', () => { - let token = ''; - - beforeAll(async () => { +const request = require('supertest'); +const app = require('../../../server'); + +describe('GET /offered/:idSeller', () => { + let validTokenSuccess; + + beforeAll(async () => { + try { const loginResponse = await request(app) - .post('/auth/login') + .post('/auth/login') .send({ - correo: 'test@uv.mx', - contrasenia: 'test123', + correo: 'dms19-@hotmail.com', + contrasenia: '123456', }); - - token = loginResponse.headers['x-token']; - expect(token).not.toBeUndefined(); + + expect(loginResponse.status).toBe(200); + expect(loginResponse.headers).toHaveProperty('x-token'); + + validTokenSuccess = loginResponse.headers['x-token']; + console.log('Token generado por autenticación:', validTokenSuccess); + + if (!validTokenSuccess) { + throw new Error('Token no recibido'); + } + } catch (error) { + console.error('Error al autenticar al cliente:', error); + throw error; + } + }); + + it('Debe devolver todos los productos ofrecidos por un vendedor', async () => { + const sellerId = 1; + const response = await request(app) + .get(`/products/offered/${sellerId}`) + .set('x-token', validTokenSuccess); + + 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); + + response.body.productos.forEach(producto => { + expect(producto).toHaveProperty('idProducto'); + expect(producto).toHaveProperty('nombreProducto'); + expect(producto).toHaveProperty('descripcion'); + expect(producto).toHaveProperty('precio'); + expect(producto).toHaveProperty('cantidadDisponible'); + expect(producto).toHaveProperty('disponible'); + expect(producto).toHaveProperty('categoria'); + expect(producto).toHaveProperty('nombreVendedor'); + expect(producto).toHaveProperty('correoVendedor'); + expect(producto).toHaveProperty('ubicacionVendedor'); + expect(producto).toHaveProperty('fotoVendedor'); }); + }); + + it('Debe devolver un error 404 si no se encuentran productos ofrecidos', async () => { + let validTokenNoProducts; - it('Debe retornar los productos ofrecidos por un vendedor', async () => { - const idSeller = 1; - - const response = await request(app) - .get(`/offered/${idSeller}`) - .set('x-token', token); + try { + const loginResponse = await request(app) + .post('/auth/login') + .send({ + correo: 'juan@example.com', + contrasenia: 'password123', + }); - expect(response.status).toBe(200); - expect(response.body).toHaveProperty('productos'); - }); + expect(loginResponse.status).toBe(200); + expect(loginResponse.headers).toHaveProperty('x-token'); + + validTokenNoProducts = loginResponse.headers['x-token']; - it('Debe retornar un error si el token es inválido', async () => { - const response = await request(app) - .get(`/offered/1`) - .set('x-token', 'token-invalido'); + if (!validTokenNoProducts) { + throw new Error('Token no recibido'); + } + } catch (error) { + console.error('Error al autenticar al usuario sin productos:', error); + throw error; + } - expect(response.status).toBe(401); - expect(response.body).toHaveProperty('mensaje', 'Token inválido o expirado'); - }); + const sellerId = 4; + const response = await request(app) + .get(`/products/offered/${sellerId}`) + .set('x-token', validTokenNoProducts); - it('Debe retornar un error si no se proporciona el token', async () => { - const response = await request(app) - .get(`/offered/1`); + console.log('Respuesta de error:', response.body); - expect(response.status).toBe(401); - expect(response.body).toHaveProperty('mensaje', 'No se proporcionó el token'); - }); - }); \ No newline at end of file + 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.productos.length).toBe(0); + }); +}); \ No newline at end of file diff --git a/tests/controllers/products/get_statistics_product.test.js b/tests/controllers/products/get_statistics_product.test.js index d58a26c..819e0dc 100644 --- a/tests/controllers/products/get_statistics_product.test.js +++ b/tests/controllers/products/get_statistics_product.test.js @@ -1,49 +1,64 @@ const request = require('supertest'); -const app = require('../../../server'); +const app = require('../../../server'); +const { generarJWT } = require('../../../helpers/generar-jwt'); // Importa la función de JWT -describe('Pruebas para la ruta /statistics/:idSeller/:year/:month', () => { - let token = ''; +let validToken; - beforeAll(async () => { - const loginResponse = await request(app) - .post('/auth/login') - .send({ - correo: 'test@uv.mx', - contrasenia: 'test123', - }); +async function obtenerTokenValido() { + const token = await generarJWT(1); // Suponiendo que el idUsuario sea 1 + return token; +} - token = loginResponse.headers['x-token']; - expect(token).not.toBeUndefined(); +beforeAll(async () => { + validToken = await obtenerTokenValido(); +}); + +describe('GET /statistics/:year/:month', () => { + it('Debe devolver estadísticas de productos vendidos', async () => { + const year = 2025; + const month = 1; + + const response = await request(app) + .get(`/products/statistics/${year}/${month}`) + .set('x-token', validToken); + + expect(response.status).toBe(200); + expect(response.body).toHaveProperty('productos'); + expect(Array.isArray(response.body.productos)).toBe(true); }); - it('Debe retornar las estadísticas de productos vendidos para un vendedor en un mes y año específico', async () => { - const idSeller = 1; - const year = 2024; - const month = 5; + it('Debe devolver un error 401 si no se proporciona un token', async () => { + const year = 2023; + const month = 5; const response = await request(app) - .get(`/statistics/${idSeller}/${year}/${month}`) - .set('x-token', token); + .get(`/products/statistics/${year}/${month}`); - expect(response.status).toBe(200); - expect(response.body).toHaveProperty('productos'); + expect(response.status).toBe(401); + expect(response.body).toHaveProperty('mensaje', 'No hay token en la petición'); }); - it('Debe retornar un error si faltan parámetros', async () => { + it('Debe devolver un error 400 si el año o mes no son válidos', async () => { + const invalidYear = 'invalid'; + const invalidMonth = 'invalid'; + const response = await request(app) - .get(`/statistics/1/2024`) - .set('x-token', token); + .get(`/products/statistics/${invalidYear}/${invalidMonth}`) + .set('x-token', validToken); - expect(response.status).toBe(400); - expect(response.body).toHaveProperty('mensaje', 'Faltan parámetros requeridos: idSeller, year, month'); + expect(response.status).toBe(400); + expect(response.body).toHaveProperty('mensaje', 'El año y mes deben ser valores numéricos válidos y el mes debe estar entre 1 y 12.'); }); - it('Debe retornar un error si el token es inválido', async () => { + it('Debe devolver un error 404 si no se encuentran productos vendidos en el mes y año especificados', async () => { + const year = 2023; + const month = 5; + const response = await request(app) - .get(`/statistics/1/2024/5`) - .set('x-token', 'token-invalido'); + .get(`/products/statistics/${year}/${month}`) + .set('x-token', validToken); - expect(response.status).toBe(401); - expect(response.body).toHaveProperty('mensaje', 'Token inválido o expirado'); + expect(response.status).toBe(404); + expect(response.body).toHaveProperty('mensaje', 'No se encontraron productos vendidos para este vendedor en el mes y año especificados.'); }); -}); \ No newline at end of file +}); diff --git a/tests/controllers/users/update_availability_user.test.js b/tests/controllers/users/update_availability_user.test.js index 6530924..3cf8fd2 100644 --- a/tests/controllers/users/update_availability_user.test.js +++ b/tests/controllers/users/update_availability_user.test.js @@ -1,96 +1,79 @@ const request = require('supertest'); const app = require('../../../server'); +const path = require('path'); -describe('Pruebas para la ruta PUT /availability/:idUsuario', () => { - let token = ''; +describe('PUT /users/availability/:idUsuario', () => { + let validTokenSuccess; beforeAll(async () => { - const loginResponse = await request(app) - .post('/auth/login') - .send({ - correo: 'test@uv.mx', - contrasenia: 'test123', - }); - - token = loginResponse.headers['x-token']; - expect(token).not.toBeUndefined(); + try { + const loginResponse = await request(app) + .post('/auth/login') + .send({ + 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); + if (!validTokenSuccess) { + throw new Error('Token no recibido'); + } + } catch (error) { + console.error('Error al autenticar al cliente:', error); + throw error; + } }); - it('Debe actualizar la disponibilidad y la ubicación de un usuario', async () => { - const idUsuario = 1; - const requestBody = { - disponibilidad: 'true', - ubicacion: 'Ciudad de México', - }; + // Test 1: Actualizar la disponibilidad y ubicación de un usuario + it('Debe actualizar la disponibilidad y ubicación de un usuario', async () => { + const userId = '1'; // ID del usuario + const availability = 1; // Disponibilidad ahora es 1, como en Postman + const location = 'Nueva ubicación'; // Nueva ubicación const response = await request(app) - .put(`/availability/${idUsuario}`) - .set('x-token', token) - .send(requestBody); - - expect(response.status).toBe(200); - expect(response.body).toHaveProperty('mensaje', 'Usuario actualizado correctamente'); - expect(response.body).toHaveProperty('disponibilidad', true); - expect(response.body).toHaveProperty('ubicacion', 'Ciudad de México'); - }); + .put(`/users/availability/${userId}`) // Ruta actualizada + .set('x-token', validTokenSuccess) // Usamos el token obtenido + .send({ disponibilidad: availability, ubicacion: location }); - it('Debe retornar un error si no se proporciona ningún campo para actualizar', async () => { - const idUsuario = 1; - const requestBody = {}; + console.log('Respuesta de actualización de disponibilidad:', response.body); // Imprime la respuesta para depuración - const response = await request(app) - .put(`/availability/${idUsuario}`) - .set('x-token', token) - .send(requestBody); - - expect(response.status).toBe(400); - expect(response.body).toHaveProperty('error', 'Se debe proporcionar al menos un campo para actualizar'); + expect(response.status).toBe(200); // Esperamos un código de estado 200 (OK) + expect(response.body).toHaveProperty('mensaje', 'Usuario actualizado correctamente'); }); - it('Debe retornar un error si el usuario no existe', async () => { - const idUsuario = 9999; - const requestBody = { - disponibilidad: 'true', - ubicacion: 'Guadalajara', - }; + // Test 2: Error 401 si no se proporciona un token + it('Debe devolver un error 401 si no se proporciona un token', async () => { + const userId = '1'; + const availability = 1; + const location = 'Nueva ubicación'; const response = await request(app) - .put(`/availability/${idUsuario}`) - .set('x-token', token) - .send(requestBody); - - expect(response.status).toBe(404); - expect(response.body).toHaveProperty('mensaje', 'Usuario no encontrado'); - }); - - it('Debe retornar un error si el token es inválido', async () => { - const idUsuario = 1; - const requestBody = { - disponibilidad: 'true', - ubicacion: 'Monterrey', - }; + .put(`/users/availability/${userId}`) // Ruta actualizada + .send({ disponibilidad: availability, ubicacion: location }); - const response = await request(app) - .put(`/availability/${idUsuario}`) - .set('x-token', 'token-invalido') - .send(requestBody); + console.log('Respuesta de error 401:', response.body); // Imprime la respuesta para depuración - expect(response.status).toBe(401); - expect(response.body).toHaveProperty('mensaje', 'Token inválido o expirado'); + expect(response.status).toBe(401); // Esperamos un error 401 + expect(response.body).toHaveProperty('mensaje', 'No se proporcionó el token'); }); - it('Debe retornar un error si no se proporciona el token', async () => { - const idUsuario = 1; - const requestBody = { - disponibilidad: 'true', - ubicacion: 'Querétaro', - }; - + // Test 3: Error 400 si los datos no son válidos + it('Debe devolver un error 400 si los datos no son válidos', async () => { + const availability = 'no'; // Disponibilidad no válida (esto debe ser un valor 1 o 0) + const location = ''; // Ubicación no proporcionada + const response = await request(app) - .put(`/availability/${idUsuario}`) - .send(requestBody); - - expect(response.status).toBe(401); - expect(response.body).toHaveProperty('mensaje', 'No se proporcionó el token'); - }); + .put(`/users/availability/123`) // Ruta actualizada + .set('x-token', validTokenSuccess) // Usamos el token válido + .send({ disponibilidad: availability, ubicacion: location }); + + console.log('Respuesta de error 400:', response.body); // Depuración + + expect(response.status).toBe(400); // Código de estado esperado + expect(response.body).toHaveProperty('mensaje', 'El valor de disponibilidad no es válido'); // Validar mensaje correcto + }); }); \ No newline at end of file