diff --git a/LogArtApp/backend/Seeders/dropDatabase.js b/LogArtApp/backend/Seeders/dropDatabase.js index 5f9a4fd..0093e59 100644 --- a/LogArtApp/backend/Seeders/dropDatabase.js +++ b/LogArtApp/backend/Seeders/dropDatabase.js @@ -16,4 +16,4 @@ const dropDatabase = async () => { } }; -module.exports = dropDatabase; \ No newline at end of file +module.exports = dropDatabase; diff --git a/LogArtApp/backend/Seeders/seedAdmins.js b/LogArtApp/backend/Seeders/seedAdmins.js index 3add446..cdc2095 100644 --- a/LogArtApp/backend/Seeders/seedAdmins.js +++ b/LogArtApp/backend/Seeders/seedAdmins.js @@ -1,50 +1,48 @@ -const mongoose = require('mongoose'); -const User = require('../models/user.model'); -const bcrypt = require('bcrypt'); +const mongoose = require("mongoose"); +const User = require("../models/user.model"); +const bcrypt = require("bcrypt"); const seedAdmins = async () => { try { const admins = [ { - username: 'admin_one', - password: 'admin123', - email: 'admin@gmail.com', - firstName: 'Admin', - lastName: 'One', - bio: 'Administrador principal.', - role: 'admin', + username: "admin_one", + password: "admin123", + email: "admin@gmail.com", + firstName: "Admin", + lastName: "One", + bio: "Administrador principal.", + role: "admin", isVerified: true, verificationToken: null, }, { - username: 'admin_two', - password: 'admin123', - email: 'admin2@example.com', - firstName: 'Admin', - lastName: 'Two', - bio: 'Administrador secundario.', - role: 'admin', + username: "admin_two", + password: "admin123", + email: "admin2@example.com", + firstName: "Admin", + lastName: "Two", + bio: "Administrador secundario.", + role: "admin", isVerified: true, verificationToken: null, }, ]; - for (const adminData of admins) { const exist = await User.findOne({ email: adminData.email }); if (!exist) { const salt = await bcrypt.genSalt(10); const hashedPassword = await bcrypt.hash(adminData.password, salt); adminData.password = hashedPassword; - await User.create(adminData); console.log(`Admin created: ${adminData.email}`); } else { console.log(`Admin ${adminData.email} already exists`); } } - console.log('Admins seeded successfully'); + console.log("Admins seeded successfully"); } catch (error) { - console.error('Error seeding admins:', error); + console.error("Error seeding admins:", error); process.exit(1); } }; diff --git a/LogArtApp/backend/Seeders/seedComments.js b/LogArtApp/backend/Seeders/seedComments.js index 11e83e0..6587110 100644 --- a/LogArtApp/backend/Seeders/seedComments.js +++ b/LogArtApp/backend/Seeders/seedComments.js @@ -1,79 +1,84 @@ -const mongoose = require('mongoose'); -const Comment = require('../models/comment.model'); -const ObjectModel = require('../models/object.model'); -const User = require('../models/user.model'); +const mongoose = require("mongoose"); +const Comment = require("../models/comment.model"); +const ObjectModel = require("../models/object.model"); +const User = require("../models/user.model"); const seedComments = async () => { try { const objects = await ObjectModel.find({}); - const users = await User.find({ role: 'user' }); - const admins = await User.find({ role: 'admin' }); - + const users = await User.find({ role: "user" }); + const admins = await User.find({ role: "admin" }); if (objects.length === 0 || users.length === 0 || admins.length === 0) { - console.log('Ensure that objects and users are seeded before seeding comments.'); + console.log( + "Ensure that objects and users are seeded before seeding comments." + ); return; } - const comments = [ { - content: '¡Me encantó este libro!', - object: objects.find(o => o.name === 'Cien Años de Soledad')._id, + content: "¡Me encantó este libro!", + object: objects.find((o) => o.name === "Cien Años de Soledad")._id, user: users[0]._id, }, { - content: 'Bohemian Rhapsody es una obra maestra.', - object: objects.find(o => o.name === 'Bohemian Rhapsody')._id, + content: "Bohemian Rhapsody es una obra maestra.", + object: objects.find((o) => o.name === "Bohemian Rhapsody")._id, user: users[1]._id, }, { - content: 'The Legend of Zelda siempre me ha fascinado.', - object: objects.find(o => o.name === 'The Legend of Zelda')._id, + content: "The Legend of Zelda siempre me ha fascinado.", + object: objects.find((o) => o.name === "The Legend of Zelda")._id, user: users[0]._id, }, { - content: '¡Controla tu lenguage!', - object: objects.find(o => o.name === 'The Legend of Zelda')._id, + content: "¡Controla tu lenguage!", + object: objects.find((o) => o.name === "The Legend of Zelda")._id, user: admins[0]._id, }, { - content: 'Intenta respetar las normas de la comunidad.', - object: objects.find(o => o.name === 'Bohemian Rhapsody')._id, + content: "Intenta respetar las normas de la comunidad.", + object: objects.find((o) => o.name === "Bohemian Rhapsody")._id, user: admins[1]._id, }, { - content: '¡Perdón!', - object: objects.find(o => o.name === 'The Legend of Zelda')._id, + content: "¡Perdón!", + object: objects.find((o) => o.name === "The Legend of Zelda")._id, user: users[0]._id, }, { - content: 'Este es un aviso para que no lo olvides.', - object: objects.find(o => o.name === 'Cien Años de Soledad')._id, + content: "Este es un aviso para que no lo olvides.", + object: objects.find((o) => o.name === "Cien Años de Soledad")._id, user: admins[0]._id, }, { - content: '¡Soy admin, y me encanta este juego!', - object: objects.find(o => o.name === 'The Legend of Zelda 2')._id, + content: "¡Soy admin, y me encanta este juego!", + object: objects.find((o) => o.name === "The Legend of Zelda 2")._id, user: admins[0]._id, }, { - content: '¡Me encantó este juego!', - object: objects.find(o => o.name === 'The Legend of Zelda 3')._id, + content: "¡Me encantó este juego!", + object: objects.find((o) => o.name === "The Legend of Zelda 3")._id, user: admins[1]._id, }, ]; - for (const commentData of comments) { - const exist = await Comment.findOne({ content: commentData.content, object: commentData.object, user: commentData.user }); + const exist = await Comment.findOne({ + content: commentData.content, + object: commentData.object, + user: commentData.user, + }); if (!exist) { await Comment.create(commentData); console.log(`Comment created for object ID: ${commentData.object}`); } else { - console.log(`Comment for object ID: ${commentData.object} already exists`); + console.log( + `Comment for object ID: ${commentData.object} already exists` + ); } } - console.log('Comments seeded successfully'); + console.log("Comments seeded successfully"); } catch (error) { - console.error('Error seeding comments:', error); + console.error("Error seeding comments:", error); process.exit(1); } }; diff --git a/LogArtApp/backend/Seeders/seedDB.js b/LogArtApp/backend/Seeders/seedDB.js index 7a99d73..5993333 100644 --- a/LogArtApp/backend/Seeders/seedDB.js +++ b/LogArtApp/backend/Seeders/seedDB.js @@ -1,11 +1,10 @@ -const mongoose = require('mongoose'); - -const seedDisciplines = require('./seedDisciplines'); -const seedUsers = require('./seedUsers'); -const seedAdmins = require('./seedAdmins'); -const seedObjects = require('./seedObjects'); -const seedComments = require('./seedComments'); -const dropDatabase = require('./dropDatabase'); +const mongoose = require("mongoose"); +const seedDisciplines = require("./seedDisciplines"); +const seedUsers = require("./seedUsers"); +const seedAdmins = require("./seedAdmins"); +const seedObjects = require("./seedObjects"); +const seedComments = require("./seedComments"); +const dropDatabase = require("./dropDatabase"); const seedDB = async () => { try { @@ -15,9 +14,8 @@ const seedDB = async () => { await seedAdmins(); await seedObjects(); await seedComments(); - } catch (error) { - console.error('Error seeding the database:', error); + console.error("Error seeding the database:", error); process.exit(1); } }; diff --git a/LogArtApp/backend/Seeders/seedDisciplines.js b/LogArtApp/backend/Seeders/seedDisciplines.js index d5da9cc..eec77db 100644 --- a/LogArtApp/backend/Seeders/seedDisciplines.js +++ b/LogArtApp/backend/Seeders/seedDisciplines.js @@ -1,14 +1,13 @@ -const mongoose = require('mongoose'); -const Discipline = require('../models/discipline.model'); +const mongoose = require("mongoose"); +const Discipline = require("../models/discipline.model"); const seedDisciplines = async () => { try { const disciplines = [ - { name: 'Libros', description: 'Libros que has leído' }, - { name: 'Canciones', description: 'Canciones que has escuchado' }, - { name: 'Videojuegos', description: 'Videojuegos que has jugado' }, + { name: "Libros", description: "Libros que has leído" }, + { name: "Canciones", description: "Canciones que has escuchado" }, + { name: "Videojuegos", description: "Videojuegos que has jugado" }, ]; - for (const discipline of disciplines) { const exist = await Discipline.findOne({ name: discipline.name }); if (!exist) { @@ -18,9 +17,9 @@ const seedDisciplines = async () => { console.log(`Discipline ${discipline.name} already exists`); } } - console.log('Disciplines seeded successfully'); + console.log("Disciplines seeded successfully"); } catch (error) { - console.error('Error seeding disciplines:', error); + console.error("Error seeding disciplines:", error); process.exit(1); } }; diff --git a/LogArtApp/backend/Seeders/seedObjects.js b/LogArtApp/backend/Seeders/seedObjects.js index 0d21d40..8472d88 100644 --- a/LogArtApp/backend/Seeders/seedObjects.js +++ b/LogArtApp/backend/Seeders/seedObjects.js @@ -1,57 +1,56 @@ -const mongoose = require('mongoose'); -const ObjectModel = require('../models/object.model'); -const Discipline = require('../models/discipline.model'); -const User = require('../models/user.model'); +const mongoose = require("mongoose"); +const ObjectModel = require("../models/object.model"); +const Discipline = require("../models/discipline.model"); +const User = require("../models/user.model"); const seedObjects = async () => { try { const disciplines = await Discipline.find({}); - const users = await User.find({ role: 'user' }); - const admins = await User.find({ role: 'admin' }); - + const users = await User.find({ role: "user" }); + const admins = await User.find({ role: "admin" }); if (disciplines.length === 0 || users.length === 0) { - console.log('Ensure that disciplines and users are seeded before seeding objects.'); + console.log( + "Ensure that disciplines and users are seeded before seeding objects." + ); return; } - const objects = [ { - name: 'Cien Años de Soledad', - description: 'Una novela clásica de Gabriel García Márquez.', - imageUrl: 'public/images/objects/cien_años.jpg', - discipline: disciplines.find(d => d.name === 'Libros')._id, + name: "Cien Años de Soledad", + description: "Una novela clásica de Gabriel García Márquez.", + imageUrl: "public/images/objects/cien_años.jpg", + discipline: disciplines.find((d) => d.name === "Libros")._id, createdBy: users[0]._id, }, { - name: 'Bohemian Rhapsody', - description: 'Canción icónica de Queen.', - imageUrl: 'public/images/objects/bohemian_rhapsody.jpg', - discipline: disciplines.find(d => d.name === 'Canciones')._id, + name: "Bohemian Rhapsody", + description: "Canción icónica de Queen.", + imageUrl: "public/images/objects/bohemian_rhapsody.jpg", + discipline: disciplines.find((d) => d.name === "Canciones")._id, createdBy: users[1]._id, }, { - name: 'The Legend of Zelda', - description: 'Un famoso videojuego de aventura.', - imageUrl: 'public/images/objects/zelda.jpg', - discipline: disciplines.find(d => d.name === 'Videojuegos')._id, + name: "The Legend of Zelda", + description: "Un famoso videojuego de aventura.", + imageUrl: "public/images/objects/zelda.jpg", + discipline: disciplines.find((d) => d.name === "Videojuegos")._id, createdBy: users[0]._id, }, { - name: 'The Legend of Zelda 2', - description: 'Un famoso videojuego de aventura.', - imageUrl: 'public/images/objects/zelda.jpg', - discipline: disciplines.find(d => d.name === 'Videojuegos')._id, + name: "The Legend of Zelda 2", + description: "Un famoso videojuego de aventura.", + imageUrl: "public/images/objects/zelda.jpg", + discipline: disciplines.find((d) => d.name === "Videojuegos")._id, createdBy: admins[0]._id, }, { - name: 'The Legend of Zelda 3', - description: 'Un famoso videojuego de aventura.', - imageUrl: 'public/images/objects/zelda.jpg', - discipline: disciplines.find(d => d.name === 'Videojuegos')._id, + name: "The Legend of Zelda 3", + description: "Un famoso videojuego de aventura.", + imageUrl: "public/images/objects/zelda.jpg", + discipline: disciplines.find((d) => d.name === "Videojuegos")._id, createdBy: admins[1]._id, }, ]; - for (const objectData of objects) { const exist = await ObjectModel.findOne({ name: objectData.name }); if (!exist) { @@ -61,9 +60,9 @@ const seedObjects = async () => { console.log(`Object ${objectData.name} already exists`); } } - console.log('Objects seeded successfully'); + console.log("Objects seeded successfully"); } catch (error) { - console.error('Error seeding objects:', error); + console.error("Error seeding objects:", error); process.exit(1); } }; diff --git a/LogArtApp/backend/Seeders/seedUsers.js b/LogArtApp/backend/Seeders/seedUsers.js index 5b04c2c..45fabb2 100644 --- a/LogArtApp/backend/Seeders/seedUsers.js +++ b/LogArtApp/backend/Seeders/seedUsers.js @@ -1,61 +1,59 @@ -const mongoose = require('mongoose'); -const User = require('../models/user.model'); -const bcrypt = require('bcrypt'); +const mongoose = require("mongoose"); +const User = require("../models/user.model"); +const bcrypt = require("bcrypt"); const seedUsers = async () => { try { const users = [ { - username: 'john_doe', - password: 'hola123', - email: 'pepe@gmail.com', - firstName: 'John', - lastName: 'Doe', - bio: 'Apasionado por los libros y la música.', - role: 'user', + username: "john_doe", + password: "hola123", + email: "pepe@gmail.com", + firstName: "John", + lastName: "Doe", + bio: "Apasionado por los libros y la música.", + role: "user", isVerified: true, verificationToken: null, }, { - username: 'jane_smith', - password: 'hola123', - email: 'pepa@gmail.com', - firstName: 'Jane', - lastName: 'Smith', - bio: 'Amante de los videojuegos y la tecnología.', - role: 'user', + username: "jane_smith", + password: "hola123", + email: "pepa@gmail.com", + firstName: "Jane", + lastName: "Smith", + bio: "Amante de los videojuegos y la tecnología.", + role: "user", isVerified: true, verificationToken: null, }, { - username: 'notverified', - password: 'hola123', - email: 'notverified@gmail.com', - firstName: 'Bob', - lastName: 'Jones', - bio: 'Amante de la moda y la moda.', - role: 'user', + username: "notverified", + password: "hola123", + email: "notverified@gmail.com", + firstName: "Bob", + lastName: "Jones", + bio: "Amante de la moda y la moda.", + role: "user", isVerified: false, verificationToken: null, }, ]; - for (const userData of users) { const exist = await User.findOne({ email: userData.email }); if (!exist) { const salt = await bcrypt.genSalt(10); const hashedPassword = await bcrypt.hash(userData.password, salt); userData.password = hashedPassword; - await User.create(userData); console.log(`User created: ${userData.email}`); } else { console.log(`User ${userData.email} already exists`); } } - console.log('Users seeded successfully'); + console.log("Users seeded successfully"); } catch (error) { - console.error('Error seeding users:', error); + console.error("Error seeding users:", error); process.exit(1); } }; diff --git a/LogArtApp/backend/__test__/dbtest.js b/LogArtApp/backend/__test__/dbtest.js index 32a0984..4da71c6 100644 --- a/LogArtApp/backend/__test__/dbtest.js +++ b/LogArtApp/backend/__test__/dbtest.js @@ -1,20 +1,17 @@ -const mongoose = require('mongoose'); -const { MongoMemoryServer } = require('mongodb-memory-server'); +const mongoose = require("mongoose"); +const { MongoMemoryServer } = require("mongodb-memory-server"); let mongoServer; - const connect = async () => { mongoServer = await MongoMemoryServer.create(); const uri = mongoServer.getUri(); await mongoose.connect(uri); }; - const closeDatabase = async () => { await mongoose.connection.dropDatabase(); await mongoose.connection.close(); await mongoServer.stop(); }; - const clearDatabase = async () => { const collections = mongoose.connection.collections; for (const key in collections) { diff --git a/LogArtApp/backend/__test__/integration/auth.test.js b/LogArtApp/backend/__test__/integration/auth.test.js index f503efc..b4663db 100644 --- a/LogArtApp/backend/__test__/integration/auth.test.js +++ b/LogArtApp/backend/__test__/integration/auth.test.js @@ -17,11 +17,9 @@ describe("Pruebas de Autenticación", () => { email: "juan.perez@example.com", password: "SecurePassword123", }; - const response = await request(app) .post("/api/v1/users") .send(newUserData); - expect(response.statusCode).toBe(201); expect(response.body).toHaveProperty("user"); expect(response.body.user.email).toBe(newUserData.email); @@ -30,7 +28,6 @@ describe("Pruebas de Autenticación", () => { "User registered, please check your email to verify your account" ); expect(response.headers).toHaveProperty("location"); - const userInDb = await User.findOne({ email: newUserData.email }); expect(userInDb).not.toBeNull(); expect(userInDb.isVerified).toBe(false); @@ -44,17 +41,14 @@ describe("Pruebas de Autenticación", () => { email: "juan.repetido@example.com", password: "SecurePassword123", }; - await User.create({ ...existingUserData, password: await bcrypt.hash("SecurePassword123", 10), isVerified: true, }); - const response = await request(app) .post("/api/v1/users") .send(existingUserData); - expect(response.statusCode).toBe(409); expect(response.body).toHaveProperty("error", true); expect(response.body.message).toBe("User already exists"); @@ -66,11 +60,9 @@ describe("Pruebas de Autenticación", () => { email: "falta.campos@example.com", password: "SecurePassword123", }; - const response = await request(app) .post("/api/v1/users") .send(incompleteUserData); - expect(response.statusCode).toBe(400); expect(response.body).toHaveProperty("error", true); expect(response.body.message).toBe("All fields are required"); @@ -90,7 +82,6 @@ describe("Pruebas de Autenticación", () => { isVerified: true, hastoken: false, }); - loginData = { email: "pepe@gmail.com", password: "hola123", @@ -102,11 +93,9 @@ describe("Pruebas de Autenticación", () => { email: "pepe@gmail.com", password: "WrongPassword", }; - const response = await request(app) .post("/api/v1/auth/") .send(invalidLoginData); - expect(response.statusCode).toBe(401); expect(response.body).toHaveProperty("error", true); expect(response.body.message).toBe("Invalid credentials"); @@ -114,12 +103,10 @@ describe("Pruebas de Autenticación", () => { it("debería iniciar sesión con credenciales válidas", async () => { const response = await request(app).post("/api/v1/auth/").send(loginData); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty("accessToken"); expect(response.body.user).toHaveProperty("email", loginData.email); expect(response.body).toHaveProperty("message", "Login successful"); - const user = await User.findOne({ email: loginData.email }); expect(user.hastoken).toBe(true); }); @@ -129,11 +116,9 @@ describe("Pruebas de Autenticación", () => { email: "nonexistent@example.com", password: "SomePassword", }; - const response = await request(app) .post("/api/v1/auth/") .send(noUserData); - expect(response.statusCode).toBe(401); expect(response.body).toHaveProperty("error", true); expect(response.body.message).toBe("User not found"); @@ -144,7 +129,6 @@ describe("Pruebas de Autenticación", () => { const response = await request(app) .post("/api/v1/auth/") .send(incompleteLoginData); - expect(response.statusCode).toBe(400); expect(response.body).toHaveProperty("error", true); expect(response.body.message).toBe("Both fields are required"); @@ -161,16 +145,13 @@ describe("Pruebas de Autenticación", () => { isVerified: false, hastoken: false, }); - const unverifiedData = { email: "juan.perez2@example.com", password: "AnotherPassword123", }; - const response = await request(app) .post("/api/v1/auth/") .send(unverifiedData); - expect(response.statusCode).toBe(401); expect(response.body).toHaveProperty("error", true); expect(response.body.message).toBe( @@ -182,7 +163,6 @@ describe("Pruebas de Autenticación", () => { describe("POST /api/v1/logout/", () => { it("debería cerrar la sesión correctamente", async () => { const hashedPassword = await bcrypt.hash("hola123", 10); - const userDB = await User.create({ username: "pepeuser", email: "pepe3@gmail.com", @@ -192,19 +172,15 @@ describe("Pruebas de Autenticación", () => { isVerified: true, hastoken: false, }); - const { accessToken } = await authService.login( "pepe3@gmail.com", "hola123" ); - const response = await request(app) .post("/api/v1/logout") .set("Authorization", `Bearer ${accessToken}`); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty("message", "Logout successful"); - const userAfterLogout = await User.findOne({ email: "pepe3@gmail.com" }); expect(userAfterLogout.hastoken).toBe(false); }); @@ -224,7 +200,6 @@ describe("Pruebas de Autenticación", () => { "pepe2@gmail.com", "hola123" ); - const extendedExpirationDate = new Date( Date.now() + 7 * 24 * 60 * 60 * 1000 ); @@ -232,11 +207,9 @@ describe("Pruebas de Autenticación", () => { accessToken, extendedExpirationDate ); - const response = await request(app) .post("/api/v1/logout") .set("Authorization", `Bearer ${accessToken}`); - expect(response.statusCode).toBe(401); expect(response.body).toHaveProperty("error", true); expect(response.body.message).toBe( @@ -248,7 +221,6 @@ describe("Pruebas de Autenticación", () => { const response = await request(app) .post("/api/v1/logout") .set("Authorization", "Bearer invalidToken"); - expect(response.statusCode).toBe(403); expect(response.body).toHaveProperty("error", true); expect(response.body.message).toBe("Invalid token"); diff --git a/LogArtApp/backend/__test__/integration/comment.test.js b/LogArtApp/backend/__test__/integration/comment.test.js index 69c5636..b8d8a3b 100644 --- a/LogArtApp/backend/__test__/integration/comment.test.js +++ b/LogArtApp/backend/__test__/integration/comment.test.js @@ -1,43 +1,38 @@ -const request = require('supertest'); -const app = require('../../app'); -const User = require('../../models/user.model'); -const Discipline = require('../../models/discipline.model'); -const ObjectModel = require('../../models/object.model'); -const Comment = require('../../models/comment.model'); -const mongoose = require('mongoose'); -const path = require('path'); -const bcrypt = require('bcrypt'); +const request = require("supertest"); +const app = require("../../app"); +const User = require("../../models/user.model"); +const Discipline = require("../../models/discipline.model"); +const ObjectModel = require("../../models/object.model"); +const Comment = require("../../models/comment.model"); +const mongoose = require("mongoose"); +const path = require("path"); +const bcrypt = require("bcrypt"); const createUser = async (overrides = {}) => { const timestamp = Date.now(); const defaultData = { - firstName: 'Usuario', - lastName: 'Prueba', + firstName: "Usuario", + lastName: "Prueba", username: `usuario${timestamp}`, email: `usuario${timestamp}@example.com`, - password: 'Password123', + password: "Password123", isVerified: true, hastoken: false, - role: 'user', - + role: "user", }; - const userData = { ...defaultData, ...overrides }; const hashedPassword = await bcrypt.hash(userData.password, 10); - const user = await User.create({ ...userData, password: hashedPassword, }); - return user; }; const loginUser = async (email, password) => { const response = await request(app) - .post('/api/v1/auth/') + .post("/api/v1/auth/") .send({ email, password }); - return response.body.accessToken; }; @@ -45,13 +40,10 @@ const createDiscipline = async (overrides = {}) => { const timestamp = Date.now(); const defaultData = { name: `Libros${timestamp}`, - description: 'Disciplina relacionada con libros', + description: "Disciplina relacionada con libros", }; - const disciplineData = { ...defaultData, ...overrides }; - const discipline = await Discipline.create(disciplineData); - return discipline; }; @@ -59,31 +51,24 @@ const createObject = async (overrides = {}) => { const timestamp = Date.now(); const defaultData = { name: `Objeto${timestamp}`, - description: 'Descripción del objeto', + description: "Descripción del objeto", imageUrl: `/public/images/objects/objeto${timestamp}.jpg`, }; - const objectData = { ...defaultData, ...overrides }; - const object = await ObjectModel.create(objectData); - return object; }; const createComment = async (overrides = {}) => { const defaultData = { - content: 'Este es un comentario de prueba', + content: "Este es un comentario de prueba", }; - const commentData = { ...defaultData, ...overrides }; - const comment = await Comment.create(commentData); - return comment; }; -describe('Pruebas de Comentarios', () => { - +describe("Pruebas de Comentarios", () => { beforeEach(async () => { await User.deleteMany({}); await Discipline.deleteMany({}); @@ -91,786 +76,731 @@ describe('Pruebas de Comentarios', () => { await Comment.deleteMany({}); }); - - describe('POST /api/v1/comments/', () => { - it('debería crear un comentario exitosamente como propietario', async () => { + describe("POST /api/v1/comments/", () => { + it("debería crear un comentario exitosamente como propietario", async () => { const user = await createUser({ - email: 'usuario1@example.com', - password: 'password123', + email: "usuario1@example.com", + password: "password123", }); - const userToken = await loginUser(user.email, 'password123'); - + const userToken = await loginUser(user.email, "password123"); const discipline = await createDiscipline({ - name: 'Libros', - description: 'Disciplina relacionada con libros', + name: "Libros", + description: "Disciplina relacionada con libros", }); - const object = await ObjectModel.create({ - name: 'Objeto1', - description: 'Descripción del objeto 1', + name: "Objeto1", + description: "Descripción del objeto 1", discipline: discipline._id, createdBy: user._id, - imageUrl: '/public/images/objects/objeto1.jpg', + imageUrl: "/public/images/objects/objeto1.jpg", }); - const newCommentData = { - content: 'Este es un comentario de prueba', + content: "Este es un comentario de prueba", objectId: object._id.toString(), }; - const response = await request(app) - .post('/api/v1/comments/') - .set('Authorization', `Bearer ${userToken}`) + .post("/api/v1/comments/") + .set("Authorization", `Bearer ${userToken}`) .send(newCommentData); - expect(response.statusCode).toBe(201); - expect(response.body).toHaveProperty('comment'); + expect(response.body).toHaveProperty("comment"); expect(response.body.comment.content).toBe(newCommentData.content); - expect(response.body.comment.object.toString()).toBe(object._id.toString()); + expect(response.body.comment.object.toString()).toBe( + object._id.toString() + ); expect(response.body.comment.user.toString()).toBe(user._id.toString()); - expect(response.body).toHaveProperty('message', 'Comment created successfully'); - expect(response.headers).toHaveProperty('location'); - - const commentInDb = await Comment.findOne({ content: newCommentData.content }); + expect(response.body).toHaveProperty( + "message", + "Comment created successfully" + ); + expect(response.headers).toHaveProperty("location"); + const commentInDb = await Comment.findOne({ + content: newCommentData.content, + }); expect(commentInDb).not.toBeNull(); expect(commentInDb.object.toString()).toBe(object._id.toString()); expect(commentInDb.user.toString()).toBe(user._id.toString()); }); - it('debería crear un comentario exitosamente como admin en objeto de otro usuario', async () => { + it("debería crear un comentario exitosamente como admin en objeto de otro usuario", async () => { const ownerUser = await createUser({ - email: 'owner1@example.com', - password: 'password123', + email: "owner1@example.com", + password: "password123", }); - const ownerToken = await loginUser(ownerUser.email, 'password123'); - + const ownerToken = await loginUser(ownerUser.email, "password123"); const adminUser = await createUser({ - email: 'admin1@example.com', - password: 'adminpass123', - role: 'admin', + email: "admin1@example.com", + password: "adminpass123", + role: "admin", }); - const adminToken = await loginUser(adminUser.email, 'adminpass123'); - + const adminToken = await loginUser(adminUser.email, "adminpass123"); const discipline = await createDiscipline({ - name: 'Canciones', - description: 'Disciplina relacionada con canciones', + name: "Canciones", + description: "Disciplina relacionada con canciones", }); - const object = await ObjectModel.create({ - name: 'Objeto2', - description: 'Descripción del objeto 2', + name: "Objeto2", + description: "Descripción del objeto 2", discipline: discipline._id, createdBy: ownerUser._id, - imageUrl: '/public/images/objects/objeto2.jpg', + imageUrl: "/public/images/objects/objeto2.jpg", }); - const newCommentData = { - content: 'Comentario realizado por admin', + content: "Comentario realizado por admin", objectId: object._id.toString(), }; - const response = await request(app) - .post('/api/v1/comments/') - .set('Authorization', `Bearer ${adminToken}`) + .post("/api/v1/comments/") + .set("Authorization", `Bearer ${adminToken}`) .send(newCommentData); - expect(response.statusCode).toBe(201); - expect(response.body).toHaveProperty('comment'); + expect(response.body).toHaveProperty("comment"); expect(response.body.comment.content).toBe(newCommentData.content); - expect(response.body.comment.object.toString()).toBe(object._id.toString()); - expect(response.body.comment.user.toString()).toBe(adminUser._id.toString()); - expect(response.body).toHaveProperty('message', 'Comment created successfully'); - expect(response.headers).toHaveProperty('location'); - - const commentInDb = await Comment.findOne({ content: newCommentData.content }); + expect(response.body.comment.object.toString()).toBe( + object._id.toString() + ); + expect(response.body.comment.user.toString()).toBe( + adminUser._id.toString() + ); + expect(response.body).toHaveProperty( + "message", + "Comment created successfully" + ); + expect(response.headers).toHaveProperty("location"); + const commentInDb = await Comment.findOne({ + content: newCommentData.content, + }); expect(commentInDb).not.toBeNull(); expect(commentInDb.object.toString()).toBe(object._id.toString()); expect(commentInDb.user.toString()).toBe(adminUser._id.toString()); }); - it('debería fallar al crear un comentario sin contenido', async () => { + it("debería fallar al crear un comentario sin contenido", async () => { const user = await createUser({ - email: 'usuario2@example.com', - password: 'password123', + email: "usuario2@example.com", + password: "password123", }); - const userToken = await loginUser(user.email, 'password123'); - + const userToken = await loginUser(user.email, "password123"); const discipline = await createDiscipline({ - name: 'Videojuegos', - description: 'Disciplina relacionada con videojuegos', + name: "Videojuegos", + description: "Disciplina relacionada con videojuegos", }); - const object = await ObjectModel.create({ - name: 'Objeto3', - description: 'Descripción del objeto 3', + name: "Objeto3", + description: "Descripción del objeto 3", discipline: discipline._id, createdBy: user._id, - imageUrl: '/public/images/objects/objeto3.jpg', + imageUrl: "/public/images/objects/objeto3.jpg", }); - const newCommentData = { objectId: object._id.toString(), }; - const response = await request(app) - .post('/api/v1/comments/') - .set('Authorization', `Bearer ${userToken}`) + .post("/api/v1/comments/") + .set("Authorization", `Bearer ${userToken}`) .send(newCommentData); - expect(response.statusCode).toBe(400); - expect(response.body).toHaveProperty('error', true); - expect(response.body).toHaveProperty('message', 'Both content and object Id are required'); - + expect(response.body).toHaveProperty("error", true); + expect(response.body).toHaveProperty( + "message", + "Both content and object Id are required" + ); const commentInDb = await Comment.findOne({ object: object._id }); expect(commentInDb).toBeNull(); }); - it('debería fallar al crear un comentario con un objectId inválido', async () => { + it("debería fallar al crear un comentario con un objectId inválido", async () => { const user = await createUser({ - email: 'usuario3@example.com', - password: 'password123', + email: "usuario3@example.com", + password: "password123", }); - const userToken = await loginUser(user.email, 'password123'); - + const userToken = await loginUser(user.email, "password123"); const newCommentData = { - content: 'Comentario con objectId inválido', - objectId: '12345', + content: "Comentario con objectId inválido", + objectId: "12345", }; - const response = await request(app) - .post('/api/v1/comments/') - .set('Authorization', `Bearer ${userToken}`) + .post("/api/v1/comments/") + .set("Authorization", `Bearer ${userToken}`) .send(newCommentData); - expect(response.statusCode).toBe(400); - expect(response.body).toHaveProperty('error', true); - expect(response.body).toHaveProperty('message', 'Invalid object ID format'); - - const commentInDb = await Comment.findOne({ content: newCommentData.content }); + expect(response.body).toHaveProperty("error", true); + expect(response.body).toHaveProperty( + "message", + "Invalid object ID format" + ); + const commentInDb = await Comment.findOne({ + content: newCommentData.content, + }); expect(commentInDb).toBeNull(); }); - it('debería fallar al crear un comentario en un objeto inexistente', async () => { + it("debería fallar al crear un comentario en un objeto inexistente", async () => { const user = await createUser({ - email: 'usuario4@example.com', - password: 'password123', + email: "usuario4@example.com", + password: "password123", }); - const userToken = await loginUser(user.email, 'password123'); - + const userToken = await loginUser(user.email, "password123"); const nonExistentObjectId = new mongoose.Types.ObjectId(); - const newCommentData = { - content: 'Comentario en objeto inexistente', + content: "Comentario en objeto inexistente", objectId: nonExistentObjectId.toString(), }; - const response = await request(app) - .post('/api/v1/comments/') - .set('Authorization', `Bearer ${userToken}`) + .post("/api/v1/comments/") + .set("Authorization", `Bearer ${userToken}`) .send(newCommentData); - expect(response.statusCode).toBe(404); - expect(response.body).toHaveProperty('error', true); - expect(response.body).toHaveProperty('message', 'Object not found'); - - const commentInDb = await Comment.findOne({ content: newCommentData.content }); + expect(response.body).toHaveProperty("error", true); + expect(response.body).toHaveProperty("message", "Object not found"); + const commentInDb = await Comment.findOne({ + content: newCommentData.content, + }); expect(commentInDb).toBeNull(); }); - it('debería fallar al crear un comentario como usuario no autorizado (no propietario ni admin)', async () => { + it("debería fallar al crear un comentario como usuario no autorizado (no propietario ni admin)", async () => { const ownerUser = await createUser({ - email: 'owner2@example.com', - password: 'password123', + email: "owner2@example.com", + password: "password123", }); - const ownerToken = await loginUser(ownerUser.email, 'password123'); - + const ownerToken = await loginUser(ownerUser.email, "password123"); const anotherUser = await createUser({ - email: 'usuario5@example.com', - password: 'password123', + email: "usuario5@example.com", + password: "password123", }); - const anotherToken = await loginUser(anotherUser.email, 'password123'); - + const anotherToken = await loginUser(anotherUser.email, "password123"); const discipline = await createDiscipline({ - name: 'Libros', - description: 'Disciplina relacionada con libros', + name: "Libros", + description: "Disciplina relacionada con libros", }); - const object = await ObjectModel.create({ - name: 'Objeto4', - description: 'Descripción del objeto 4', + name: "Objeto4", + description: "Descripción del objeto 4", discipline: discipline._id, createdBy: ownerUser._id, - imageUrl: '/public/images/objects/objeto4.jpg', + imageUrl: "/public/images/objects/objeto4.jpg", }); - const newCommentData = { - content: 'Comentario no autorizado', + content: "Comentario no autorizado", objectId: object._id.toString(), }; - const response = await request(app) - .post('/api/v1/comments/') - .set('Authorization', `Bearer ${anotherToken}`) + .post("/api/v1/comments/") + .set("Authorization", `Bearer ${anotherToken}`) .send(newCommentData); - expect(response.statusCode).toBe(403); - expect(response.body).toHaveProperty('error', true); - expect(response.body).toHaveProperty('message', 'You are not authorized to comment on this object'); - - const commentInDb = await Comment.findOne({ content: newCommentData.content }); + expect(response.body).toHaveProperty("error", true); + expect(response.body).toHaveProperty( + "message", + "You are not authorized to comment on this object" + ); + const commentInDb = await Comment.findOne({ + content: newCommentData.content, + }); expect(commentInDb).toBeNull(); }); }); - describe('PUT /api/v1/comments/:commentId', () => { - it('debería actualizar un comentario exitosamente como propietario', async () => { + describe("PUT /api/v1/comments/:commentId", () => { + it("debería actualizar un comentario exitosamente como propietario", async () => { const user = await createUser({ - email: 'usuario6@example.com', - password: 'password123', + email: "usuario6@example.com", + password: "password123", }); - const userToken = await loginUser(user.email, 'password123'); - + const userToken = await loginUser(user.email, "password123"); const discipline = await createDiscipline({ - name: 'Canciones', - description: 'Disciplina relacionada con canciones', + name: "Canciones", + description: "Disciplina relacionada con canciones", }); - const object = await ObjectModel.create({ - name: 'Objeto5', - description: 'Descripción del objeto 5', + name: "Objeto5", + description: "Descripción del objeto 5", discipline: discipline._id, createdBy: user._id, - imageUrl: '/public/images/objects/objeto5.jpg', + imageUrl: "/public/images/objects/objeto5.jpg", }); - const comment = await Comment.create({ - content: 'Comentario original', + content: "Comentario original", object: object._id, user: user._id, }); - const updatedCommentData = { - content: 'Comentario actualizado por propietario', + content: "Comentario actualizado por propietario", }; - const response = await request(app) .put(`/api/v1/comments/${comment._id}`) - .set('Authorization', `Bearer ${userToken}`) + .set("Authorization", `Bearer ${userToken}`) .send(updatedCommentData); - expect(response.statusCode).toBe(200); - expect(response.body).toHaveProperty('comment'); + expect(response.body).toHaveProperty("comment"); expect(response.body.comment.content).toBe(updatedCommentData.content); - expect(response.body).toHaveProperty('message', 'Comment updated successfully'); - + expect(response.body).toHaveProperty( + "message", + "Comment updated successfully" + ); const commentInDb = await Comment.findById(comment._id); expect(commentInDb.content).toBe(updatedCommentData.content); expect(commentInDb.isEditedByAdmin).toBe(false); expect(commentInDb.editedBy).toBeNull(); }); - it('debería actualizar un comentario exitosamente como admin', async () => { + it("debería actualizar un comentario exitosamente como admin", async () => { const ownerUser = await createUser({ - email: 'owner3@example.com', - password: 'password123', + email: "owner3@example.com", + password: "password123", }); - const ownerToken = await loginUser(ownerUser.email, 'password123'); - + const ownerToken = await loginUser(ownerUser.email, "password123"); const adminUser = await createUser({ - email: 'admin2@example.com', - password: 'adminpass123', - role: 'admin', + email: "admin2@example.com", + password: "adminpass123", + role: "admin", }); - const adminToken = await loginUser(adminUser.email, 'adminpass123'); - + const adminToken = await loginUser(adminUser.email, "adminpass123"); const discipline = await createDiscipline({ - name: 'Videojuegos', - description: 'Disciplina relacionada con videojuegos', + name: "Videojuegos", + description: "Disciplina relacionada con videojuegos", }); - const object = await ObjectModel.create({ - name: 'Objeto6', - description: 'Descripción del objeto 6', + name: "Objeto6", + description: "Descripción del objeto 6", discipline: discipline._id, createdBy: ownerUser._id, - imageUrl: '/public/images/objects/objeto6.jpg', + imageUrl: "/public/images/objects/objeto6.jpg", }); - const comment = await Comment.create({ - content: 'Comentario original del propietario', + content: "Comentario original del propietario", object: object._id, user: ownerUser._id, }); - const updatedCommentData = { - content: 'Comentario actualizado por admin', + content: "Comentario actualizado por admin", }; - const response = await request(app) .put(`/api/v1/comments/${comment._id}`) - .set('Authorization', `Bearer ${adminToken}`) + .set("Authorization", `Bearer ${adminToken}`) .send(updatedCommentData); - expect(response.statusCode).toBe(200); - expect(response.body).toHaveProperty('comment'); + expect(response.body).toHaveProperty("comment"); expect(response.body.comment.content).toBe(updatedCommentData.content); expect(response.body.comment.isEditedByAdmin).toBe(true); - expect(response.body.comment.editedBy.toString()).toBe(adminUser._id.toString()); - expect(response.body).toHaveProperty('message', 'Comment updated successfully'); - + expect(response.body.comment.editedBy.toString()).toBe( + adminUser._id.toString() + ); + expect(response.body).toHaveProperty( + "message", + "Comment updated successfully" + ); const commentInDb = await Comment.findById(comment._id); expect(commentInDb.content).toBe(updatedCommentData.content); expect(commentInDb.isEditedByAdmin).toBe(true); expect(commentInDb.editedBy.toString()).toBe(adminUser._id.toString()); }); - it('debería fallar al actualizar un comentario sin autenticación', async () => { + it("debería fallar al actualizar un comentario sin autenticación", async () => { const user = await createUser({ - email: 'usuario7@example.com', - password: 'password123', + email: "usuario7@example.com", + password: "password123", }); - const userToken = await loginUser(user.email, 'password123'); - + const userToken = await loginUser(user.email, "password123"); const discipline = await createDiscipline({ - name: 'Libros', - description: 'Disciplina relacionada con libros', + name: "Libros", + description: "Disciplina relacionada con libros", }); - const object = await ObjectModel.create({ - name: 'Objeto7', - description: 'Descripción del objeto 7', + name: "Objeto7", + description: "Descripción del objeto 7", discipline: discipline._id, createdBy: user._id, - imageUrl: '/public/images/objects/objeto7.jpg', + imageUrl: "/public/images/objects/objeto7.jpg", }); - const comment = await Comment.create({ - content: 'Comentario original sin autenticación', + content: "Comentario original sin autenticación", object: object._id, user: user._id, }); - const updatedCommentData = { - content: 'Intento de actualización sin autenticación', + content: "Intento de actualización sin autenticación", }; - const response = await request(app) .put(`/api/v1/comments/${comment._id}`) .send(updatedCommentData); - expect(response.statusCode).toBe(401); - expect(response.body).toHaveProperty('error', true); - expect(response.body).toHaveProperty('message', 'Necesitas estar logueado y un token válido para realizar esta acción'); - + expect(response.body).toHaveProperty("error", true); + expect(response.body).toHaveProperty( + "message", + "Necesitas estar logueado y un token válido para realizar esta acción" + ); const commentInDb = await Comment.findById(comment._id); - expect(commentInDb.content).toBe('Comentario original sin autenticación'); + expect(commentInDb.content).toBe("Comentario original sin autenticación"); }); - it('debería fallar al actualizar un comentario con un commentId inválido', async () => { + it("debería fallar al actualizar un comentario con un commentId inválido", async () => { const user = await createUser({ - email: 'usuario8@example.com', - password: 'password123', + email: "usuario8@example.com", + password: "password123", }); - const userToken = await loginUser(user.email, 'password123'); - - const invalidCommentId = '12345'; + const userToken = await loginUser(user.email, "password123"); + const invalidCommentId = "12345"; const updatedCommentData = { - content: 'Intento de actualización con ID inválido', + content: "Intento de actualización con ID inválido", }; - const response = await request(app) .put(`/api/v1/comments/${invalidCommentId}`) - .set('Authorization', `Bearer ${userToken}`) + .set("Authorization", `Bearer ${userToken}`) .send(updatedCommentData); - expect(response.statusCode).toBe(400); - expect(response.body).toHaveProperty('error', true); - expect(response.body).toHaveProperty('message', 'Invalid comment ID format'); + expect(response.body).toHaveProperty("error", true); + expect(response.body).toHaveProperty( + "message", + "Invalid comment ID format" + ); }); - it('debería fallar al actualizar un comentario que no existe', async () => { + it("debería fallar al actualizar un comentario que no existe", async () => { const user = await createUser({ - email: 'usuario9@example.com', - password: 'password123', + email: "usuario9@example.com", + password: "password123", }); - const userToken = await loginUser(user.email, 'password123'); - + const userToken = await loginUser(user.email, "password123"); const nonExistentCommentId = new mongoose.Types.ObjectId(); const updatedCommentData = { - content: 'Intento de actualización en comentario inexistente', + content: "Intento de actualización en comentario inexistente", }; - const response = await request(app) .put(`/api/v1/comments/${nonExistentCommentId}`) - .set('Authorization', `Bearer ${userToken}`) + .set("Authorization", `Bearer ${userToken}`) .send(updatedCommentData); - expect(response.statusCode).toBe(404); - expect(response.body).toHaveProperty('error', true); - expect(response.body).toHaveProperty('message', 'Comment not found'); + expect(response.body).toHaveProperty("error", true); + expect(response.body).toHaveProperty("message", "Comment not found"); }); - it('debería fallar al actualizar un comentario como usuario no autorizado', async () => { + it("debería fallar al actualizar un comentario como usuario no autorizado", async () => { const ownerUser = await createUser({ - email: 'owner4@example.com', - password: 'password123', + email: "owner4@example.com", + password: "password123", }); - const ownerToken = await loginUser(ownerUser.email, 'password123'); - + const ownerToken = await loginUser(ownerUser.email, "password123"); const anotherUser = await createUser({ - email: 'usuario10@example.com', - password: 'password123', + email: "usuario10@example.com", + password: "password123", }); - const anotherToken = await loginUser(anotherUser.email, 'password123'); - + const anotherToken = await loginUser(anotherUser.email, "password123"); const discipline = await createDiscipline({ - name: 'Videojuegos', - description: 'Disciplina relacionada con videojuegos', + name: "Videojuegos", + description: "Disciplina relacionada con videojuegos", }); - const object = await ObjectModel.create({ - name: 'Objeto8', - description: 'Descripción del objeto 8', + name: "Objeto8", + description: "Descripción del objeto 8", discipline: discipline._id, createdBy: ownerUser._id, - imageUrl: '/public/images/objects/objeto8.jpg', + imageUrl: "/public/images/objects/objeto8.jpg", }); - const comment = await Comment.create({ - content: 'Comentario del propietario', + content: "Comentario del propietario", object: object._id, user: ownerUser._id, }); - const updatedCommentData = { - content: 'Intento de actualización por usuario no autorizado', + content: "Intento de actualización por usuario no autorizado", }; - const response = await request(app) .put(`/api/v1/comments/${comment._id}`) - .set('Authorization', `Bearer ${anotherToken}`) + .set("Authorization", `Bearer ${anotherToken}`) .send(updatedCommentData); - expect(response.statusCode).toBe(403); - expect(response.body).toHaveProperty('error', true); - expect(response.body).toHaveProperty('message', 'You are not authorized to update this comment'); - + expect(response.body).toHaveProperty("error", true); + expect(response.body).toHaveProperty( + "message", + "You are not authorized to update this comment" + ); const commentInDb = await Comment.findById(comment._id); - expect(commentInDb.content).toBe('Comentario del propietario'); + expect(commentInDb.content).toBe("Comentario del propietario"); }); }); - describe('DELETE /api/v1/comments/:commentId', () => { - it('debería eliminar un comentario exitosamente como propietario', async () => { + describe("DELETE /api/v1/comments/:commentId", () => { + it("debería eliminar un comentario exitosamente como propietario", async () => { const user = await createUser({ - email: 'usuario11@example.com', - password: 'password123', + email: "usuario11@example.com", + password: "password123", }); - const userToken = await loginUser(user.email, 'password123'); - + const userToken = await loginUser(user.email, "password123"); const discipline = await createDiscipline({ - name: 'Libros', - description: 'Disciplina relacionada con libros', + name: "Libros", + description: "Disciplina relacionada con libros", }); - const object = await ObjectModel.create({ - name: 'Objeto9', - description: 'Descripción del objeto 9', + name: "Objeto9", + description: "Descripción del objeto 9", discipline: discipline._id, createdBy: user._id, - imageUrl: '/public/images/objects/objeto9.jpg', + imageUrl: "/public/images/objects/objeto9.jpg", }); - const comment = await Comment.create({ - content: 'Comentario a eliminar', + content: "Comentario a eliminar", object: object._id, user: user._id, }); - const response = await request(app) .delete(`/api/v1/comments/${comment._id}`) - .set('Authorization', `Bearer ${userToken}`); - + .set("Authorization", `Bearer ${userToken}`); expect(response.statusCode).toBe(200); - expect(response.body).toHaveProperty('message', 'Comment deleted successfully'); - + expect(response.body).toHaveProperty( + "message", + "Comment deleted successfully" + ); const commentInDb = await Comment.findById(comment._id); expect(commentInDb).toBeNull(); }); - it('debería eliminar un comentario exitosamente como admin', async () => { + it("debería eliminar un comentario exitosamente como admin", async () => { const ownerUser = await createUser({ - email: 'owner5@example.com', - password: 'password123', + email: "owner5@example.com", + password: "password123", }); - const ownerToken = await loginUser(ownerUser.email, 'password123'); - + const ownerToken = await loginUser(ownerUser.email, "password123"); const adminUser = await createUser({ - email: 'admin3@example.com', - password: 'adminpass123', - role: 'admin', + email: "admin3@example.com", + password: "adminpass123", + role: "admin", }); - const adminToken = await loginUser(adminUser.email, 'adminpass123'); - + const adminToken = await loginUser(adminUser.email, "adminpass123"); const discipline = await createDiscipline({ - name: 'Canciones', - description: 'Disciplina relacionada con canciones', + name: "Canciones", + description: "Disciplina relacionada con canciones", }); - const object = await ObjectModel.create({ - name: 'Objeto10', - description: 'Descripción del objeto 10', + name: "Objeto10", + description: "Descripción del objeto 10", discipline: discipline._id, createdBy: ownerUser._id, - imageUrl: '/public/images/objects/objeto10.jpg', + imageUrl: "/public/images/objects/objeto10.jpg", }); - const comment = await Comment.create({ - content: 'Comentario a eliminar por admin', + content: "Comentario a eliminar por admin", object: object._id, user: ownerUser._id, }); - const response = await request(app) .delete(`/api/v1/comments/${comment._id}`) - .set('Authorization', `Bearer ${adminToken}`); - + .set("Authorization", `Bearer ${adminToken}`); expect(response.statusCode).toBe(200); - expect(response.body).toHaveProperty('message', 'Comment deleted successfully'); - + expect(response.body).toHaveProperty( + "message", + "Comment deleted successfully" + ); const commentInDb = await Comment.findById(comment._id); expect(commentInDb).toBeNull(); }); - it('debería fallar al eliminar un comentario sin autenticación', async () => { + it("debería fallar al eliminar un comentario sin autenticación", async () => { const user = await createUser({ - email: 'usuario12@example.com', - password: 'password123', + email: "usuario12@example.com", + password: "password123", }); - const userToken = await loginUser(user.email, 'password123'); - + const userToken = await loginUser(user.email, "password123"); const discipline = await createDiscipline({ - name: 'Videojuegos', - description: 'Disciplina relacionada con videojuegos', + name: "Videojuegos", + description: "Disciplina relacionada con videojuegos", }); - - const object = await ObjectModel.create({ - name: 'Objeto11', - description: 'Descripción del objeto 11', + name: "Objeto11", + description: "Descripción del objeto 11", discipline: discipline._id, createdBy: user._id, - imageUrl: '/public/images/objects/objeto11.jpg', + imageUrl: "/public/images/objects/objeto11.jpg", }); - const comment = await Comment.create({ - content: 'Comentario sin autenticación', + content: "Comentario sin autenticación", object: object._id, user: user._id, }); - - const response = await request(app) - .delete(`/api/v1/comments/${comment._id}`); - + const response = await request(app).delete( + `/api/v1/comments/${comment._id}` + ); expect(response.statusCode).toBe(401); - expect(response.body).toHaveProperty('error', true); - expect(response.body).toHaveProperty('message', 'Necesitas estar logueado y un token válido para realizar esta acción'); - + expect(response.body).toHaveProperty("error", true); + expect(response.body).toHaveProperty( + "message", + "Necesitas estar logueado y un token válido para realizar esta acción" + ); const commentInDb = await Comment.findById(comment._id); expect(commentInDb).not.toBeNull(); }); - it('debería fallar al eliminar un comentario con un commentId inválido', async () => { + it("debería fallar al eliminar un comentario con un commentId inválido", async () => { const user = await createUser({ - email: 'usuario13@example.com', - password: 'password123', + email: "usuario13@example.com", + password: "password123", }); - const userToken = await loginUser(user.email, 'password123'); - - const invalidCommentId = '12345'; - + const userToken = await loginUser(user.email, "password123"); + const invalidCommentId = "12345"; const response = await request(app) .delete(`/api/v1/comments/${invalidCommentId}`) - .set('Authorization', `Bearer ${userToken}`); - + .set("Authorization", `Bearer ${userToken}`); expect(response.statusCode).toBe(400); - expect(response.body).toHaveProperty('error', true); - expect(response.body).toHaveProperty('message', 'Invalid comment ID format'); + expect(response.body).toHaveProperty("error", true); + expect(response.body).toHaveProperty( + "message", + "Invalid comment ID format" + ); }); - it('debería fallar al eliminar un comentario que no existe', async () => { + it("debería fallar al eliminar un comentario que no existe", async () => { const adminUser = await createUser({ - email: 'admin4@example.com', - password: 'adminpass123', - role: 'admin', + email: "admin4@example.com", + password: "adminpass123", + role: "admin", }); - const adminToken = await loginUser(adminUser.email, 'adminpass123'); - + const adminToken = await loginUser(adminUser.email, "adminpass123"); const nonExistentCommentId = new mongoose.Types.ObjectId(); - const response = await request(app) .delete(`/api/v1/comments/${nonExistentCommentId}`) - .set('Authorization', `Bearer ${adminToken}`); - + .set("Authorization", `Bearer ${adminToken}`); expect(response.statusCode).toBe(404); - expect(response.body).toHaveProperty('error', true); - expect(response.body).toHaveProperty('message', 'Comment not found'); + expect(response.body).toHaveProperty("error", true); + expect(response.body).toHaveProperty("message", "Comment not found"); }); - it('debería fallar al eliminar un comentario como usuario no autorizado (no propietario ni admin)', async () => { + it("debería fallar al eliminar un comentario como usuario no autorizado (no propietario ni admin)", async () => { const ownerUser = await createUser({ - email: 'owner6@example.com', - password: 'password123', + email: "owner6@example.com", + password: "password123", }); - const ownerToken = await loginUser(ownerUser.email, 'password123'); - + const ownerToken = await loginUser(ownerUser.email, "password123"); const anotherUser = await createUser({ - email: 'usuario14@example.com', - password: 'password123', + email: "usuario14@example.com", + password: "password123", }); - const anotherToken = await loginUser(anotherUser.email, 'password123'); - + const anotherToken = await loginUser(anotherUser.email, "password123"); const discipline = await createDiscipline({ - name: 'Libros', - description: 'Disciplina relacionada con libros', + name: "Libros", + description: "Disciplina relacionada con libros", }); - const object = await ObjectModel.create({ - name: 'Objeto12', - description: 'Descripción del objeto 12', + name: "Objeto12", + description: "Descripción del objeto 12", discipline: discipline._id, createdBy: ownerUser._id, - imageUrl: '/public/images/objects/objeto12.jpg', + imageUrl: "/public/images/objects/objeto12.jpg", }); - const comment = await Comment.create({ - content: 'Comentario protegido', + content: "Comentario protegido", object: object._id, user: ownerUser._id, }); - const response = await request(app) .delete(`/api/v1/comments/${comment._id}`) - .set('Authorization', `Bearer ${anotherToken}`); - + .set("Authorization", `Bearer ${anotherToken}`); expect(response.statusCode).toBe(403); - expect(response.body).toHaveProperty('error', true); - expect(response.body).toHaveProperty('message', 'You are not authorized to delete this comment'); - + expect(response.body).toHaveProperty("error", true); + expect(response.body).toHaveProperty( + "message", + "You are not authorized to delete this comment" + ); const commentInDb = await Comment.findById(comment._id); expect(commentInDb).not.toBeNull(); }); }); - describe('GET /api/v1/comments/:objectId', () => { - it('debería obtener todos los comentarios de un objeto exitosamente como propietario', async () => { + describe("GET /api/v1/comments/:objectId", () => { + it("debería obtener todos los comentarios de un objeto exitosamente como propietario", async () => { const user = await createUser({ - email: 'usuario15@example.com', - password: 'password123', + email: "usuario15@example.com", + password: "password123", }); - const userToken = await loginUser(user.email, 'password123'); - + const userToken = await loginUser(user.email, "password123"); const discipline = await createDiscipline({ - name: 'Canciones', - description: 'Disciplina relacionada con canciones', + name: "Canciones", + description: "Disciplina relacionada con canciones", }); - const object = await ObjectModel.create({ - name: 'Objeto13', - description: 'Descripción del objeto 13', + name: "Objeto13", + description: "Descripción del objeto 13", discipline: discipline._id, createdBy: user._id, - imageUrl: '/public/images/objects/objeto13.jpg', + imageUrl: "/public/images/objects/objeto13.jpg", }); - const commentsData = [ - { content: 'Comentario 1', object: object._id, user: user._id }, - { content: 'Comentario 2', object: object._id, user: user._id }, - { content: 'Comentario 3', object: object._id, user: user._id }, + { content: "Comentario 1", object: object._id, user: user._id }, + { content: "Comentario 2", object: object._id, user: user._id }, + { content: "Comentario 3", object: object._id, user: user._id }, ]; - await Comment.insertMany(commentsData); - const response = await request(app) .get(`/api/v1/comments/${object._id}`) - .set('Authorization', `Bearer ${userToken}`) + .set("Authorization", `Bearer ${userToken}`) .query({ page: 1, limit: 2 }); - expect(response.statusCode).toBe(200); - expect(response.body).toHaveProperty('comments'); + expect(response.body).toHaveProperty("comments"); expect(Array.isArray(response.body.comments)).toBe(true); expect(response.body.comments.length).toBe(2); - expect(response.body).toHaveProperty('totalComments', 3); - expect(response.body).toHaveProperty('currentPage', 1); - expect(response.body).toHaveProperty('totalPages', 2); + expect(response.body).toHaveProperty("totalComments", 3); + expect(response.body).toHaveProperty("currentPage", 1); + expect(response.body).toHaveProperty("totalPages", 2); }); - it('debería obtener comentarios específicos por commentId', async () => { + it("debería obtener comentarios específicos por commentId", async () => { const user = await createUser({ - email: 'usuario16@example.com', - password: 'password123', + email: "usuario16@example.com", + password: "password123", }); - const userToken = await loginUser(user.email, 'password123'); - + const userToken = await loginUser(user.email, "password123"); const discipline = await createDiscipline({ - name: 'Videojuegos', - description: 'Disciplina relacionada con videojuegos', + name: "Videojuegos", + description: "Disciplina relacionada con videojuegos", }); - const object = await ObjectModel.create({ - name: 'Objeto14', - description: 'Descripción del objeto 14', + name: "Objeto14", + description: "Descripción del objeto 14", discipline: discipline._id, createdBy: user._id, - imageUrl: '/public/images/objects/objeto14.jpg', + imageUrl: "/public/images/objects/objeto14.jpg", }); - const comment1 = await Comment.create({ - content: 'Comentario 1', + content: "Comentario 1", object: object._id, user: user._id, }); const comment2 = await Comment.create({ - content: 'Comentario 2', + content: "Comentario 2", object: object._id, user: user._id, }); - const response = await request(app) .get(`/api/v1/comments/${object._id}`) - .set('Authorization', `Bearer ${userToken}`) + .set("Authorization", `Bearer ${userToken}`) .query({ commentId: comment1._id.toString() }); - expect(response.statusCode).toBe(200); - expect(response.body).toHaveProperty('comments'); + expect(response.body).toHaveProperty("comments"); expect(Array.isArray(response.body.comments)).toBe(true); expect(response.body.comments.length).toBe(1); - expect(response.body.comments[0].content).toBe('Comentario 1'); - expect(response.body).toHaveProperty('totalComments', 1); - expect(response.body).toHaveProperty('currentPage', 1); - expect(response.body).toHaveProperty('totalPages', 1); + expect(response.body.comments[0].content).toBe("Comentario 1"); + expect(response.body).toHaveProperty("totalComments", 1); + expect(response.body).toHaveProperty("currentPage", 1); + expect(response.body).toHaveProperty("totalPages", 1); }); - it('debería obtener comentarios con paginación', async () => { + it("debería obtener comentarios con paginación", async () => { const user = await createUser({ - email: 'usuario17@example.com', - password: 'password123', + email: "usuario17@example.com", + password: "password123", }); - const userToken = await loginUser(user.email, 'password123'); - + const userToken = await loginUser(user.email, "password123"); const discipline = await createDiscipline({ - name: 'Libros', - description: 'Disciplina relacionada con libros', + name: "Libros", + description: "Disciplina relacionada con libros", }); - const object = await ObjectModel.create({ - name: 'Objeto15', - description: 'Descripción del objeto 15', + name: "Objeto15", + description: "Descripción del objeto 15", discipline: discipline._id, createdBy: user._id, - imageUrl: '/public/images/objects/objeto15.jpg', + imageUrl: "/public/images/objects/objeto15.jpg", }); - const commentsData = []; for (let i = 1; i <= 5; i++) { commentsData.push({ @@ -880,120 +810,110 @@ describe('Pruebas de Comentarios', () => { }); } await Comment.insertMany(commentsData); - const response = await request(app) .get(`/api/v1/comments/${object._id}`) - .set('Authorization', `Bearer ${userToken}`) + .set("Authorization", `Bearer ${userToken}`) .query({ page: 2, limit: 2 }); - expect(response.statusCode).toBe(200); - expect(response.body).toHaveProperty('comments'); + expect(response.body).toHaveProperty("comments"); expect(Array.isArray(response.body.comments)).toBe(true); expect(response.body.comments.length).toBe(2); - expect(response.body).toHaveProperty('totalComments', 5); - expect(response.body).toHaveProperty('currentPage', 2); - expect(response.body).toHaveProperty('totalPages', 3); + expect(response.body).toHaveProperty("totalComments", 5); + expect(response.body).toHaveProperty("currentPage", 2); + expect(response.body).toHaveProperty("totalPages", 3); }); - it('debería fallar al obtener comentarios sin autenticación', async () => { + it("debería fallar al obtener comentarios sin autenticación", async () => { const discipline = await createDiscipline({ - name: 'Canciones', - description: 'Disciplina relacionada con canciones', + name: "Canciones", + description: "Disciplina relacionada con canciones", }); - const object = await ObjectModel.create({ - name: 'Objeto16', - description: 'Descripción del objeto 16', + name: "Objeto16", + description: "Descripción del objeto 16", discipline: discipline._id, createdBy: new mongoose.Types.ObjectId(), - imageUrl: '/public/images/objects/objeto16.jpg', + imageUrl: "/public/images/objects/objeto16.jpg", }); - - const response = await request(app) - .get(`/api/v1/comments/${object._id}`); - + const response = await request(app).get(`/api/v1/comments/${object._id}`); expect(response.statusCode).toBe(401); - expect(response.body).toHaveProperty('error', true); - expect(response.body).toHaveProperty('message', 'Necesitas estar logueado y un token válido para realizar esta acción'); + expect(response.body).toHaveProperty("error", true); + expect(response.body).toHaveProperty( + "message", + "Necesitas estar logueado y un token válido para realizar esta acción" + ); }); - it('debería fallar al obtener comentarios con un objectId inválido', async () => { + it("debería fallar al obtener comentarios con un objectId inválido", async () => { const user = await createUser({ - email: 'usuario18@example.com', - password: 'password123', + email: "usuario18@example.com", + password: "password123", }); - const userToken = await loginUser(user.email, 'password123'); - - const invalidObjectId = '12345'; - + const userToken = await loginUser(user.email, "password123"); + const invalidObjectId = "12345"; const response = await request(app) .get(`/api/v1/comments/${invalidObjectId}`) - .set('Authorization', `Bearer ${userToken}`); - + .set("Authorization", `Bearer ${userToken}`); expect(response.statusCode).toBe(400); - expect(response.body).toHaveProperty('error', true); - expect(response.body).toHaveProperty('message', 'Invalid object ID format'); + expect(response.body).toHaveProperty("error", true); + expect(response.body).toHaveProperty( + "message", + "Invalid object ID format" + ); }); - it('debería fallar al obtener comentarios de un objeto inexistente', async () => { + it("debería fallar al obtener comentarios de un objeto inexistente", async () => { const adminUser = await createUser({ - email: 'admin5@example.com', - password: 'adminpass123', - role: 'admin', + email: "admin5@example.com", + password: "adminpass123", + role: "admin", }); - const adminToken = await loginUser(adminUser.email, 'adminpass123'); - + const adminToken = await loginUser(adminUser.email, "adminpass123"); const nonExistentObjectId = new mongoose.Types.ObjectId(); - const response = await request(app) .get(`/api/v1/comments/${nonExistentObjectId}`) - .set('Authorization', `Bearer ${adminToken}`); - + .set("Authorization", `Bearer ${adminToken}`); expect(response.statusCode).toBe(404); - expect(response.body).toHaveProperty('error', true); - expect(response.body).toHaveProperty('message', 'Object not found'); + expect(response.body).toHaveProperty("error", true); + expect(response.body).toHaveProperty("message", "Object not found"); }); - it('debería fallar al obtener comentarios como usuario no autorizado (no propietario ni admin)', async () => { + it("debería fallar al obtener comentarios como usuario no autorizado (no propietario ni admin)", async () => { const ownerUser = await createUser({ - email: 'owner7@example.com', - password: 'password123', + email: "owner7@example.com", + password: "password123", }); - const ownerToken = await loginUser(ownerUser.email, 'password123'); - + const ownerToken = await loginUser(ownerUser.email, "password123"); const anotherUser = await createUser({ - email: 'usuario19@example.com', - password: 'password123', + email: "usuario19@example.com", + password: "password123", }); - const anotherToken = await loginUser(anotherUser.email, 'password123'); - + const anotherToken = await loginUser(anotherUser.email, "password123"); const discipline = await createDiscipline({ - name: 'Libros', - description: 'Disciplina relacionada con libros', + name: "Libros", + description: "Disciplina relacionada con libros", }); - const object = await ObjectModel.create({ - name: 'Objeto17', - description: 'Descripción del objeto 17', + name: "Objeto17", + description: "Descripción del objeto 17", discipline: discipline._id, createdBy: ownerUser._id, - imageUrl: '/public/images/objects/objeto17.jpg', + imageUrl: "/public/images/objects/objeto17.jpg", }); - const comment = await Comment.create({ - content: 'Comentario protegido', + content: "Comentario protegido", object: object._id, user: ownerUser._id, }); - const response = await request(app) .get(`/api/v1/comments/${object._id}`) - .set('Authorization', `Bearer ${anotherToken}`); - + .set("Authorization", `Bearer ${anotherToken}`); expect(response.statusCode).toBe(403); - expect(response.body).toHaveProperty('error', true); - expect(response.body).toHaveProperty('message', 'You are not authorized to view comments for this object'); + expect(response.body).toHaveProperty("error", true); + expect(response.body).toHaveProperty( + "message", + "You are not authorized to view comments for this object" + ); }); }); - }); diff --git a/LogArtApp/backend/__test__/integration/discipline.test.js b/LogArtApp/backend/__test__/integration/discipline.test.js index 859258c..ac9fb8c 100644 --- a/LogArtApp/backend/__test__/integration/discipline.test.js +++ b/LogArtApp/backend/__test__/integration/discipline.test.js @@ -20,16 +20,12 @@ describe("Pruebas de Disciplinas", () => { description: "Disciplina relacionada con videojuegos", }, ]; - await Discipline.insertMany(disciplinesData); - const response = await request(app).get("/api/v1/disciplines/").send(); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty("disciplines"); expect(Array.isArray(response.body.disciplines)).toBe(true); expect(response.body.disciplines.length).toBe(3); - const returnedNames = response.body.disciplines.map((d) => d.name).sort(); const expectedNames = disciplinesData.map((d) => d.name).sort(); expect(returnedNames).toEqual(expectedNames); @@ -37,7 +33,6 @@ describe("Pruebas de Disciplinas", () => { it("debería obtener un array vacío si no hay disciplinas", async () => { const response = await request(app).get("/api/v1/disciplines/").send(); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty("disciplines"); expect(Array.isArray(response.body.disciplines)).toBe(true); @@ -49,16 +44,13 @@ describe("Pruebas de Disciplinas", () => { Discipline.find = jest.fn().mockImplementation(() => { throw new Error("Error de base de datos"); }); - const response = await request(app).get("/api/v1/disciplines/").send(); - expect(response.statusCode).toBe(500); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty( "message", "Error obteniendo disciplinas" ); - Discipline.find = originalFind; }); }); diff --git a/LogArtApp/backend/__test__/integration/object.test.js b/LogArtApp/backend/__test__/integration/object.test.js index 13dc3e6..c512ea3 100644 --- a/LogArtApp/backend/__test__/integration/object.test.js +++ b/LogArtApp/backend/__test__/integration/object.test.js @@ -18,15 +18,12 @@ const createUser = async (overrides = {}) => { hastoken: false, role: "user", }; - const userData = { ...defaultData, ...overrides }; const hashedPassword = await bcrypt.hash(userData.password, 10); - const user = await User.create({ ...userData, password: hashedPassword, }); - return user; }; @@ -34,20 +31,15 @@ const loginUser = async (email, password) => { const response = await request(app) .post("/api/v1/auth/") .send({ email, password }); - return response.body.accessToken; }; - const createDiscipline = async (overrides = {}) => { const defaultData = { name: "Libros", description: "Libros que has leído", }; - const disciplineData = { ...defaultData, ...overrides }; - const discipline = await Discipline.create(disciplineData); - return discipline; }; @@ -65,18 +57,15 @@ describe("Pruebas de Objetos", () => { password: "password123", }); const userToken = await loginUser(user.email, "password123"); - const discipline = await createDiscipline({ name: "Libros", description: "Libros que has leído", }); - const newObjectData = { name: "Objeto1", description: "Descripción del objeto 1", disciplineName: "Libros", }; - const response = await request(app) .post("/api/v1/objects/") .set("Authorization", `Bearer ${userToken}`) @@ -87,7 +76,6 @@ describe("Pruebas de Objetos", () => { "imageUrl", path.join(__dirname, "imagesTest", "test-image.jpg") ); - expect(response.statusCode).toBe(201); expect(response.body).toHaveProperty("object"); expect(response.body.object.name).toBe(newObjectData.name); @@ -102,23 +90,19 @@ describe("Pruebas de Objetos", () => { password: "password123", }); const userToken = await loginUser(user.email, "password123"); - const discipline = await createDiscipline({ name: "Canciones", description: "Canciones que has escuchado", }); - const newObjectData = { name: "Objeto2", description: "Descripción del objeto 2", disciplineName: "Canciones", }; - const response = await request(app) .post("/api/v1/objects/") .set("Authorization", `Bearer ${userToken}`) .send(newObjectData); - expect(response.statusCode).toBe(400); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty("message", "Image is required"); @@ -130,17 +114,14 @@ describe("Pruebas de Objetos", () => { password: "password123", }); const userToken = await loginUser(user.email, "password123"); - const discipline = await createDiscipline({ name: "Videojuegos", description: "Videojuegos que has jugado", }); - const newObjectData = { name: "Objeto3", description: "Descripción del objeto 3", }; - const response = await request(app) .post("/api/v1/objects/") .set("Authorization", `Bearer ${userToken}`) @@ -150,7 +131,6 @@ describe("Pruebas de Objetos", () => { "imageUrl", path.join(__dirname, "imagesTest", "test-image.jpg") ); - expect(response.statusCode).toBe(400); expect(response.body).toHaveProperty("error", true); expect(response.body.message).toBe( @@ -164,13 +144,11 @@ describe("Pruebas de Objetos", () => { password: "password123", }); const userToken = await loginUser(user.email, "password123"); - const newObjectData = { name: "Objeto4", description: "Descripción del objeto 4", disciplineName: "Fotografía", }; - const response = await request(app) .post("/api/v1/objects/") .set("Authorization", `Bearer ${userToken}`) @@ -181,7 +159,6 @@ describe("Pruebas de Objetos", () => { "imageUrl", path.join(__dirname, "imagesTest", "test-image.jpg") ); - expect(response.statusCode).toBe(404); expect(response.body).toHaveProperty("error", true); expect(response.body.message).toBe("Discipline not found"); @@ -195,12 +172,10 @@ describe("Pruebas de Objetos", () => { password: "password123", }); const userToken = await loginUser(user.email, "password123"); - const discipline = await createDiscipline({ name: "Canciones", description: "Canciones que has escuchado", }); - const object = await ObjectModel.create({ name: "Objeto6", description: "Descripción del objeto 6", @@ -208,18 +183,15 @@ describe("Pruebas de Objetos", () => { createdBy: user._id, imageUrl: "/public/images/objects/test-image.jpg", }); - const updatedData = { name: "Objeto6 Actualizado", description: "Descripción actualizada del objeto 6", disciplineName: "Canciones", }; - const response = await request(app) .put(`/api/v1/objects/${object._id}`) .set("Authorization", `Bearer ${userToken}`) .send(updatedData); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty("object"); expect(response.body.object.name).toBe(updatedData.name); @@ -239,12 +211,10 @@ describe("Pruebas de Objetos", () => { password: "password123", }); const userToken = await loginUser(user.email, "password123"); - const discipline = await createDiscipline({ name: "Videojuegos", description: "Videojuegos que has jugado", }); - const object = await ObjectModel.create({ name: "Objeto7", description: "Descripción del objeto 7", @@ -252,13 +222,11 @@ describe("Pruebas de Objetos", () => { createdBy: user._id, imageUrl: "/public/images/objects/test-image.jpg", }); - const updatedData = { name: "Objeto7 Actualizado", description: "Descripción actualizada del objeto 7", disciplineName: "Videojuegos", }; - const response = await request(app) .put(`/api/v1/objects/${object._id}`) .set("Authorization", `Bearer ${userToken}`) @@ -269,7 +237,6 @@ describe("Pruebas de Objetos", () => { "imageUrl", path.join(__dirname, "imagesTest", "test-image-2.jpg") ); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty("object"); expect(response.body.object.name).toBe(updatedData.name); @@ -288,7 +255,6 @@ describe("Pruebas de Objetos", () => { name: "Libros", description: "Libros que has leído", }); - const object = await ObjectModel.create({ name: "Objeto8", description: "Descripción del objeto 8", @@ -296,17 +262,14 @@ describe("Pruebas de Objetos", () => { createdBy: new mongoose.Types.ObjectId(), imageUrl: "/public/images/objects/test-image.jpg", }); - const updatedData = { name: "Objeto8 Actualizado", description: "Descripción actualizada del objeto 8", disciplineName: "Libros", }; - const response = await request(app) .put(`/api/v1/objects/${object._id}`) .send(updatedData); - expect(response.statusCode).toBe(401); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty( @@ -321,19 +284,16 @@ describe("Pruebas de Objetos", () => { password: "password123", }); const userToken = await loginUser(user.email, "password123"); - const invalidId = "12345"; const updatedData = { name: "Objeto9 Actualizado", description: "Descripción actualizada del objeto 9", disciplineName: "Libros", }; - const response = await request(app) .put(`/api/v1/objects/${invalidId}`) .set("Authorization", `Bearer ${userToken}`) .send(updatedData); - expect(response.statusCode).toBe(400); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty( @@ -348,19 +308,16 @@ describe("Pruebas de Objetos", () => { password: "password123", }); const userToken = await loginUser(user.email, "password123"); - const nonExistentId = new mongoose.Types.ObjectId(); const updatedData = { name: "Objeto10 Actualizado", description: "Descripción actualizada del objeto 10", disciplineName: "Libros", }; - const response = await request(app) .put(`/api/v1/objects/${nonExistentId}`) .set("Authorization", `Bearer ${userToken}`) .send(updatedData); - expect(response.statusCode).toBe(404); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty("message", "Object not found"); @@ -372,18 +329,15 @@ describe("Pruebas de Objetos", () => { password: "password123", }); const ownerToken = await loginUser(ownerUser.email, "password123"); - const anotherUser = await createUser({ email: "another@example.com", password: "password123", }); const anotherToken = await loginUser(anotherUser.email, "password123"); - const discipline = await createDiscipline({ name: "Canciones", description: "Canciones que has escuchado", }); - const object = await ObjectModel.create({ name: "Objeto11", description: "Descripción del objeto 11", @@ -391,18 +345,15 @@ describe("Pruebas de Objetos", () => { createdBy: ownerUser._id, imageUrl: "/public/images/objects/test-image.jpg", }); - const updatedData = { name: "Objeto11 Actualizado", description: "Descripción actualizada del objeto 11", disciplineName: "Canciones", }; - const response = await request(app) .put(`/api/v1/objects/${object._id}`) .set("Authorization", `Bearer ${anotherToken}`) .send(updatedData); - expect(response.statusCode).toBe(403); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty( @@ -420,12 +371,10 @@ describe("Pruebas de Objetos", () => { role: "admin", }); const adminToken = await loginUser(adminUser.email, "adminpass123"); - const discipline = await createDiscipline({ name: "Videojuegos", description: "Videojuegos que has jugado", }); - const object = await ObjectModel.create({ name: "Objeto12", description: "Descripción del objeto 12", @@ -433,11 +382,9 @@ describe("Pruebas de Objetos", () => { createdBy: new mongoose.Types.ObjectId(), imageUrl: "/public/images/objects/test-image.jpg", }); - const response = await request(app) .delete(`/api/v1/objects/${object._id}`) .set("Authorization", `Bearer ${adminToken}`); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty( "message", @@ -451,18 +398,15 @@ describe("Pruebas de Objetos", () => { password: "password123", }); const ownerToken = await loginUser(ownerUser.email, "password123"); - const anotherUser = await createUser({ email: "another2@example.com", password: "password123", }); const anotherToken = await loginUser(anotherUser.email, "password123"); - const discipline = await createDiscipline({ name: "Libros", description: "Libros que has leído", }); - const object = await ObjectModel.create({ name: "Objeto13", description: "Descripción del objeto 13", @@ -470,11 +414,9 @@ describe("Pruebas de Objetos", () => { createdBy: ownerUser._id, imageUrl: "/public/images/objects/test-image.jpg", }); - const response = await request(app) .delete(`/api/v1/objects/${object._id}`) .set("Authorization", `Bearer ${anotherToken}`); - expect(response.statusCode).toBe(403); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty( @@ -490,12 +432,10 @@ describe("Pruebas de Objetos", () => { role: "admin", }); const adminToken = await loginUser(adminUser.email, "adminpass123"); - const nonExistentId = new mongoose.Types.ObjectId(); const response = await request(app) .delete(`/api/v1/objects/${nonExistentId}`) .set("Authorization", `Bearer ${adminToken}`); - expect(response.statusCode).toBe(404); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty("message", "Object not found"); @@ -508,12 +448,10 @@ describe("Pruebas de Objetos", () => { role: "admin", }); const adminToken = await loginUser(adminUser.email, "adminpass123"); - const invalidId = "12345"; const response = await request(app) .delete(`/api/v1/objects/${invalidId}`) .set("Authorization", `Bearer ${adminToken}`); - expect(response.statusCode).toBe(400); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty( @@ -528,12 +466,10 @@ describe("Pruebas de Objetos", () => { password: "password123", }); const ownerToken = await loginUser(ownerUser.email, "password123"); - const discipline = await createDiscipline({ name: "Canciones", description: "Canciones que has escuchado", }); - const object = await ObjectModel.create({ name: "Objeto14", description: "Descripción del objeto 14", @@ -541,11 +477,9 @@ describe("Pruebas de Objetos", () => { createdBy: ownerUser._id, imageUrl: "/public/images/objects/test-image.jpg", }); - const response = await request(app) .delete(`/api/v1/objects/${object._id}`) .set("Authorization", `Bearer ${ownerToken}`); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty( "message", @@ -561,12 +495,10 @@ describe("Pruebas de Objetos", () => { password: "password123", }); const userToken = await loginUser(user.email, "password123"); - const discipline = await createDiscipline({ name: "Libros", description: "Libros que has leído", }); - for (let i = 1; i <= 5; i++) { await ObjectModel.create({ name: `Objeto${i}`, @@ -576,12 +508,10 @@ describe("Pruebas de Objetos", () => { imageUrl: `/public/images/objects/objeto${i}.jpg`, }); } - const response = await request(app) .get(`/api/v1/objects/${discipline.name}`) .set("Authorization", `Bearer ${userToken}`) .query({ page: 1, limit: 3 }); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty("discipline"); expect(response.body.discipline.name).toBe("Libros"); @@ -599,16 +529,13 @@ describe("Pruebas de Objetos", () => { password: "password123", }); const userToken = await loginUser(user.email, "password123"); - const discipline = await createDiscipline({ name: "Canciones", description: "Canciones que has escuchado", }); - const response = await request(app) .get(`/api/v1/objects/${discipline.name}`) .set("Authorization", `Bearer ${userToken}`); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty("discipline"); expect(response.body.discipline.name).toBe("Canciones"); @@ -626,13 +553,10 @@ describe("Pruebas de Objetos", () => { password: "password123", }); const userToken = await loginUser(user.email, "password123"); - const nonExistentDiscipline = "Cocina"; - const response = await request(app) .get(`/api/v1/objects/${nonExistentDiscipline}`) .set("Authorization", `Bearer ${userToken}`); - expect(response.statusCode).toBe(404); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty("message", "Discipline not found"); @@ -649,12 +573,10 @@ describe("Pruebas de Objetos", () => { password: "password123", }); const userToken = await loginUser(user.email, "password123"); - const discipline = await createDiscipline({ name: "Canciones", description: "Canciones que has escuchado", }); - const object = await ObjectModel.create({ name: "Objeto15", description: "Descripción del objeto 15", @@ -662,11 +584,9 @@ describe("Pruebas de Objetos", () => { createdBy: user._id, imageUrl: "/public/images/objects/test-image.jpg", }); - const response = await request(app) .get(`/api/v1/objects/details/${object._id}`) .set("Authorization", `Bearer ${userToken}`); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty("object"); expect(response.body.object.name).toBe("Objeto15"); @@ -684,12 +604,10 @@ describe("Pruebas de Objetos", () => { role: "admin", }); const adminToken = await loginUser(adminUser.email, "adminpass123"); - const discipline = await createDiscipline({ name: "Videojuegos", description: "Videojuegos que has jugado", }); - const ownerUser = await createUser({ username: "owner", firstName: "Owner", @@ -704,11 +622,9 @@ describe("Pruebas de Objetos", () => { createdBy: ownerUser._id, imageUrl: "/public/images/objects/test-image.jpg", }); - const response = await request(app) .get(`/api/v1/objects/details/${object._id}`) .set("Authorization", `Bearer ${adminToken}`); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty("object"); expect(response.body.object.name).toBe("Objeto16"); @@ -725,18 +641,15 @@ describe("Pruebas de Objetos", () => { password: "password123", }); const ownerToken = await loginUser(ownerUser.email, "password123"); - const anotherUser = await createUser({ email: "another3@example.com", password: "password123", }); const anotherToken = await loginUser(anotherUser.email, "password123"); - const discipline = await createDiscipline({ name: "Libros", description: "Libros que has leído", }); - const object = await ObjectModel.create({ name: "Objeto17", description: "Descripción del objeto 17", @@ -744,11 +657,9 @@ describe("Pruebas de Objetos", () => { createdBy: ownerUser._id, imageUrl: "/public/images/objects/test-image.jpg", }); - const response = await request(app) .get(`/api/v1/objects/details/${object._id}`) .set("Authorization", `Bearer ${anotherToken}`); - expect(response.statusCode).toBe(403); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty( @@ -763,12 +674,10 @@ describe("Pruebas de Objetos", () => { password: "password123", }); const userToken = await loginUser(user.email, "password123"); - const invalidId = "12345"; const response = await request(app) .get(`/api/v1/objects/details/${invalidId}`) .set("Authorization", `Bearer ${userToken}`); - expect(response.statusCode).toBe(400); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty( @@ -784,12 +693,10 @@ describe("Pruebas de Objetos", () => { role: "admin", }); const adminToken = await loginUser(adminUser.email, "adminpass123"); - const nonExistentId = new mongoose.Types.ObjectId(); const response = await request(app) .get(`/api/v1/objects/details/${nonExistentId}`) .set("Authorization", `Bearer ${adminToken}`); - expect(response.statusCode).toBe(404); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty("message", "Object not found"); diff --git a/LogArtApp/backend/__test__/integration/user.test.js b/LogArtApp/backend/__test__/integration/user.test.js index 87a5403..f48d0ef 100644 --- a/LogArtApp/backend/__test__/integration/user.test.js +++ b/LogArtApp/backend/__test__/integration/user.test.js @@ -12,7 +12,6 @@ describe("Pruebas de Usuarios", () => { let adminToken; let userId; let adminId; - beforeAll(async () => { const user = await User.create({ firstName: "Usuario", @@ -29,7 +28,6 @@ describe("Pruebas de Usuarios", () => { "password123" ); userToken = userLogin.accessToken; - const admin = await User.create({ firstName: "Administrador", lastName: "Principal", @@ -60,12 +58,10 @@ describe("Pruebas de Usuarios", () => { role: "user", }); } - const response = await request(app) .get("/api/v1/users") .set("Authorization", `Bearer ${adminToken}`) .query({ page: 2, limit: 5 }); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty("users"); expect(response.body.users.length).toBe(5); @@ -76,7 +72,6 @@ describe("Pruebas de Usuarios", () => { it("debería retornar 401 si no está autenticado", async () => { const response = await request(app).get("/api/v1/users"); - expect(response.statusCode).toBe(401); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty( @@ -106,7 +101,6 @@ describe("Pruebas de Usuarios", () => { const response = await request(app) .get("/api/v1/users/profile") .set("Authorization", `Bearer ${accessToken}`); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty("user"); expect(response.body.user.email).toBe("pepe3@gmail.com"); @@ -114,7 +108,6 @@ describe("Pruebas de Usuarios", () => { it("debería retornar 401 si no está autenticado", async () => { const response = await request(app).get("/api/v1/users/profile"); - expect(response.statusCode).toBe(401); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty( @@ -145,12 +138,10 @@ describe("Pruebas de Usuarios", () => { "pepe3@gmail.com", "hola123" ); - const response = await request(app) .put("/api/v1/users/profile") .set("Authorization", `Bearer ${accessToken}`) .send(updateData); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty("user"); expect(response.body.user.firstName).toBe("UsuarioActualizado"); @@ -186,7 +177,6 @@ describe("Pruebas de Usuarios", () => { `El archivo de imagen no existe en la ruta: ${imagePath}` ); } - const response = await request(app) .put("/api/v1/users/profile") .set("Authorization", `Bearer ${accessToken}`) @@ -195,7 +185,6 @@ describe("Pruebas de Usuarios", () => { "profileImage", path.join(__dirname, "imagesTest", "test-image.jpg") ); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty("user"); expect(response.body.user.firstName).toBe("UsuarioConImagen"); @@ -212,11 +201,9 @@ describe("Pruebas de Usuarios", () => { const updateData = { firstName: "SinAutenticacion", }; - const response = await request(app) .put("/api/v1/users/profile") .send(updateData); - expect(response.statusCode).toBe(401); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty( @@ -228,7 +215,6 @@ describe("Pruebas de Usuarios", () => { describe("GET /api/v1/users/:userId", () => { let targetUserId; - beforeEach(async () => { const targetUser = await User.create({ firstName: "Target", @@ -262,7 +248,6 @@ describe("Pruebas de Usuarios", () => { const response = await request(app) .get(`/api/v1/users/${userIddb}`) .set("Authorization", `Bearer ${accessToken}`); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty("user"); expect(response.body.user.email).toBe("pepe3@gmail.com"); @@ -288,7 +273,6 @@ describe("Pruebas de Usuarios", () => { const response = await request(app) .get(`/api/v1/users/${targetUserId}`) .set("Authorization", `Bearer ${accessToken}`); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty("user"); expect(response.body.user.email).toBe("target@example.com"); @@ -314,7 +298,6 @@ describe("Pruebas de Usuarios", () => { const response = await request(app) .get(`/api/v1/users/${targetUserId}`) .set("Authorization", `Bearer ${accessToken}`); - expect(response.statusCode).toBe(401); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty("message", "Unauthorized"); @@ -325,7 +308,6 @@ describe("Pruebas de Usuarios", () => { const response = await request(app) .get(`/api/v1/users/${nonExistentId}`) .set("Authorization", `Bearer ${adminToken}`); - expect(response.statusCode).toBe(404); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty("message", "User not found"); @@ -351,7 +333,6 @@ describe("Pruebas de Usuarios", () => { const response = await request(app) .get(`/api/v1/users/${invalidId}`) .set("Authorization", `Bearer ${accessToken}`); - expect(response.statusCode).toBe(400); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty("message", "Invalid user ID format"); @@ -362,7 +343,6 @@ describe("Pruebas de Usuarios", () => { let targetUserId; let accessTokenAdmin; let hashedPassword; - beforeEach(async () => { const targetUser = await User.create({ firstName: "Delete", @@ -395,13 +375,11 @@ describe("Pruebas de Usuarios", () => { const response = await request(app) .delete(`/api/v1/users/${targetUserId}`) .set("Authorization", `Bearer ${accessToken}`); - expect(response.statusCode).toBe(200); expect(response.body).toHaveProperty( "message", "User and Data deleted successfully" ); - const userInDb = await User.findById(targetUserId); expect(userInDb).toBeNull(); }); @@ -425,7 +403,6 @@ describe("Pruebas de Usuarios", () => { const response = await request(app) .delete(`/api/v1/users/${targetUserId}`) .set("Authorization", `Bearer ${accessToken}`); - expect(response.statusCode).toBe(401); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty("message", "Access denied"); @@ -451,7 +428,6 @@ describe("Pruebas de Usuarios", () => { const response = await request(app) .delete(`/api/v1/users/${Id}`) .set("Authorization", `Bearer ${accessToken}`); - expect(response.statusCode).toBe(401); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty( @@ -480,7 +456,6 @@ describe("Pruebas de Usuarios", () => { const response = await request(app) .delete(`/api/v1/users/${nonExistentId}`) .set("Authorization", `Bearer ${accessToken}`); - expect(response.statusCode).toBe(404); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty("message", "User not found"); @@ -506,7 +481,6 @@ describe("Pruebas de Usuarios", () => { const response = await request(app) .delete(`/api/v1/users/${invalidId}`) .set("Authorization", `Bearer ${accessToken}`); - expect(response.statusCode).toBe(400); expect(response.body).toHaveProperty("error", true); expect(response.body).toHaveProperty("message", "Invalid user ID format"); diff --git a/LogArtApp/backend/__test__/setup.js b/LogArtApp/backend/__test__/setup.js index ce1b56c..081afa7 100644 --- a/LogArtApp/backend/__test__/setup.js +++ b/LogArtApp/backend/__test__/setup.js @@ -1,13 +1,11 @@ -const { connect, closeDatabase, clearDatabase } = require('./dbtest'); +const { connect, closeDatabase, clearDatabase } = require("./dbtest"); beforeAll(async () => { await connect(); }); - afterEach(async () => { await clearDatabase(); }); - afterAll(async () => { await closeDatabase(); }); diff --git a/LogArtApp/backend/app.js b/LogArtApp/backend/app.js index b2ac10d..c8bf113 100644 --- a/LogArtApp/backend/app.js +++ b/LogArtApp/backend/app.js @@ -1,41 +1,40 @@ -const express = require('express'); -const path = require('path'); -const authRoutes = require('./routes/authRoutes'); -const userRoutes = require('./routes/userRoutes'); -const objectRoutes = require('./routes/objectRoutes'); -const commentRoutes = require('./routes/commentRoutes'); -const disciplineRoutes = require('./routes/disciplineRoutes'); -const connectDB = require('./config/db'); -const cors = require('cors'); -const seedDB = require('./Seeders/seedDB'); - +const express = require("express"); +const path = require("path"); +const authRoutes = require("./routes/authRoutes"); +const userRoutes = require("./routes/userRoutes"); +const objectRoutes = require("./routes/objectRoutes"); +const commentRoutes = require("./routes/commentRoutes"); +const disciplineRoutes = require("./routes/disciplineRoutes"); +const connectDB = require("./config/db"); +const cors = require("cors"); +const seedDB = require("./Seeders/seedDB"); const app = express(); - - -app.use(cors({ - origin: ['https://localhost:5173', 'https://editor.swagger.io', 'https://codeurjc-students.github.io'], - methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], - allowedHeaders: ['Content-Type', 'Authorization'], - credentials: true -})); - -app.use('/public', express.static(path.join(__dirname, 'public'))); +app.use( + cors({ + origin: [ + "https://localhost:5173", + "https://editor.swagger.io", + "https://codeurjc-students.github.io", + ], + methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"], + allowedHeaders: ["Content-Type", "Authorization"], + credentials: true, + }) +); +app.use("/public", express.static(path.join(__dirname, "public"))); app.use(express.json()); -app.use('/api/v1/', authRoutes); -app.use('/api/v1/users', userRoutes); -app.use('/api/v1/objects', objectRoutes); -app.use('/api/v1/comments', commentRoutes); -app.use('/api/v1/disciplines', disciplineRoutes); - -app.get('/health', (req, res) => { - res.status(200).send('OK'); +app.use("/api/v1/", authRoutes); +app.use("/api/v1/users", userRoutes); +app.use("/api/v1/objects", objectRoutes); +app.use("/api/v1/comments", commentRoutes); +app.use("/api/v1/disciplines", disciplineRoutes); +app.get("/health", (req, res) => { + res.status(200).send("OK"); }); -app.use(express.static(path.join(__dirname, 'public'))); -app.get('*', (req, res) => { - res.sendFile(path.join(__dirname, 'public', 'index.html')); +app.use(express.static(path.join(__dirname, "public"))); +app.get("*", (req, res) => { + res.sendFile(path.join(__dirname, "public", "index.html")); }); - - module.exports = app; diff --git a/LogArtApp/backend/config/db.js b/LogArtApp/backend/config/db.js index d55491c..8e4761e 100644 --- a/LogArtApp/backend/config/db.js +++ b/LogArtApp/backend/config/db.js @@ -1,13 +1,14 @@ -const mongoose = require('mongoose') -const { dbConnectionString } = require('./environment') +const mongoose = require("mongoose"); +const { dbConnectionString } = require("./environment"); + const connectDB = async () => { try { await mongoose.connect(dbConnectionString); - console.log('MongoDB connected') + console.log("MongoDB connected"); } catch (error) { - console.error('Error connecting to MongoDB:', error); - process.exit(1) + console.error("Error connecting to MongoDB:", error); + process.exit(1); } }; -module.exports = connectDB \ No newline at end of file +module.exports = connectDB; diff --git a/LogArtApp/backend/controllers/authController.js b/LogArtApp/backend/controllers/authController.js index 8db4e5c..d3201a9 100644 --- a/LogArtApp/backend/controllers/authController.js +++ b/LogArtApp/backend/controllers/authController.js @@ -1,6 +1,5 @@ const authService = require("../services/authService"); - /** * @swagger * tags: @@ -37,9 +36,7 @@ const authService = require("../services/authService"); const login = async (req, res) => { try { const { email, password } = req.body; - const { accessToken, user } = await authService.login(email, password); - return res .status(200) .json({ accessToken, user, message: "Login successful" }); @@ -92,9 +89,7 @@ const login = async (req, res) => { const register = async (req, res) => { try { const registrationData = req.body; - const { user, message } = await authService.register(registrationData); - return res .status(201) .location(`/api/v1/users/${user._id}`) @@ -112,13 +107,10 @@ const register = async (req, res) => { } }; - const verifyUser = async (req, res) => { try { const { token } = req.params; - const result = await authService.verifyUser(token); - return res.status(200).json(result); } catch (error) { console.error("Error en verifyUser:", error); @@ -160,9 +152,7 @@ const logout = async (req, res) => { const authHeader = req.headers["authorization"]; const token = authHeader && authHeader.split(" ")[1]; const userId = req.user.userId; - const result = await authService.logout(token, userId); - return res.status(200).json(result); } catch (error) { console.error("Error en logout:", error); diff --git a/LogArtApp/backend/controllers/commentController.js b/LogArtApp/backend/controllers/commentController.js index a002292..de915da 100644 --- a/LogArtApp/backend/controllers/commentController.js +++ b/LogArtApp/backend/controllers/commentController.js @@ -46,13 +46,11 @@ const createComment = async (req, res) => { try { const { content, objectId } = req.body; const userId = req.user.userId; - const newComment = await commentService.createComment( content, objectId, userId ); - return res .status(201) .location(`/api/v1/comments/${objectId}/${newComment._id}`) @@ -112,19 +110,15 @@ const updateComment = async (req, res) => { const { commentId } = req.params; const { content } = req.body; const userId = req.user.userId; - const updatedComment = await commentService.updateComment( commentId, content, userId ); - - return res - .status(200) - .json({ - comment: updatedComment, - message: "Comment updated successfully", - }); + return res.status(200).json({ + comment: updatedComment, + message: "Comment updated successfully", + }); } catch (error) { console.error("Error en updateComment:", error); if (error.statusCode) { @@ -173,9 +167,7 @@ const deleteComment = async (req, res) => { try { const { commentId } = req.params; const userId = req.user.userId; - const result = await commentService.deleteComment(commentId, userId); - return res.status(200).json(result); } catch (error) { console.error("Error en deleteComment:", error); @@ -243,13 +235,11 @@ const getCommentsByObjectId = async (req, res) => { const { objectId } = req.params; const query = req.query; const userId = req.user.userId; - const commentsData = await commentService.getCommentsByObjectId( objectId, query, userId ); - return res.status(200).json(commentsData); } catch (error) { console.error("Error en getCommentsByObjectId:", error); diff --git a/LogArtApp/backend/controllers/objectController.js b/LogArtApp/backend/controllers/objectController.js index 90f23cf..7c411b4 100644 --- a/LogArtApp/backend/controllers/objectController.js +++ b/LogArtApp/backend/controllers/objectController.js @@ -59,21 +59,17 @@ const createObject = async (req, res) => { const { name, description, disciplineName } = req.body; const userId = req.user.userId; const baseUrl = process.env.BASE_URL; - if (!req.file) { return res .status(400) .json({ error: true, message: "Image is required" }); } - const imageUrl = `${baseUrl}/public/images/objects/${req.file.filename}`; - const newObject = await objectService.createObject( { name, description, disciplineName, imageUrl }, userId, baseUrl ); - return res .status(201) .location(`/api/v1/objects/${newObject._id}`) @@ -147,18 +143,15 @@ const updateObject = async (req, res) => { const { objectId } = req.params; const { name, description, disciplineName } = req.body; const userId = req.user.userId; - let imageUrl; if (req.file) { imageUrl = `${process.env.BASE_URL}/public/images/objects/${req.file.filename}`; } - const updatedObject = await objectService.updateObject( objectId, { name, description, disciplineName, imageUrl }, userId ); - return res .status(200) .json({ object: updatedObject, message: "Object updated successfully" }); @@ -210,9 +203,7 @@ const deleteObject = async (req, res) => { try { const { objectId } = req.params; const userId = req.user.userId; - const result = await objectService.deleteObject(objectId, userId); - return res.status(200).json(result); } catch (error) { console.error("Error en deleteObject:", error); @@ -280,12 +271,10 @@ const getGalleryByDiscipline = async (req, res) => { try { const { disciplineName } = req.params; const query = req.query; - const gallery = await objectService.getGalleryByDiscipline( disciplineName, query ); - return res.status(200).json(gallery); } catch (error) { console.error("Error en getGalleryByDiscipline:", error); @@ -335,9 +324,7 @@ const getObjectById = async (req, res) => { try { const { objectId } = req.params; const userId = req.user.userId; - const object = await objectService.getObjectById(objectId, userId); - return res.status(200).json({ object }); } catch (error) { console.error("Error en getObjectById:", error); diff --git a/LogArtApp/backend/controllers/userController.js b/LogArtApp/backend/controllers/userController.js index b82e1d9..c58d827 100644 --- a/LogArtApp/backend/controllers/userController.js +++ b/LogArtApp/backend/controllers/userController.js @@ -95,16 +95,13 @@ const findUserById = async (req, res) => { try { const targetUserId = req.params.userId; const requestingUserId = req.user.userId; - const requestingUserProfile = await userService.getUserProfile( requestingUserId ); const userRole = requestingUserProfile.user.role; - if (targetUserId !== requestingUserId && userRole !== "admin") { return res.status(401).json({ error: true, message: "Unauthorized" }); } - const user = await userService.getUserById(targetUserId); return res.status(200).json({ user, message: "User found" }); } catch (error) { @@ -160,29 +157,22 @@ const deleteUser = async (req, res) => { try { const { userId } = req.params; const requestingUserId = req.user.userId; - const requestingUserProfile = await userService.getUserProfile( requestingUserId ); const userRole = requestingUserProfile.user.role; - if (userRole !== "admin") { - return res - .status(403) - .json({ - error: true, - message: "Forbidden: Only admin can delete users", - }); + return res.status(403).json({ + error: true, + message: "Forbidden: Only admin can delete users", + }); } - if (requestingUserId === userId) { - return res - .status(401) - .json({ - error: true, - message: - "You cannot delete your own account, contact the system administrator", - }); + return res.status(401).json({ + error: true, + message: + "You cannot delete your own account, contact the system administrator", + }); } const result = await userService.deleteUser(userId, requestingUserId); @@ -301,7 +291,6 @@ const updateUserProfile = async (req, res) => { const userId = req.user.userId; const updateData = req.body; const file = req.file; - const result = await userService.updateUserProfile( userId, updateData, diff --git a/LogArtApp/backend/middlewares/authMiddleware.js b/LogArtApp/backend/middlewares/authMiddleware.js index f7ff0ba..5bbd96e 100644 --- a/LogArtApp/backend/middlewares/authMiddleware.js +++ b/LogArtApp/backend/middlewares/authMiddleware.js @@ -1,31 +1,43 @@ -const jwt = require ('jsonwebtoken'); -const BlacklistedToken = require('../models/blacklist.model'); -const { accessTokenSecret } = require('../config/environment'); +const jwt = require("jsonwebtoken"); +const BlacklistedToken = require("../models/blacklist.model"); +const { accessTokenSecret } = require("../config/environment"); async function verifyToken(req, res, next) { - const authHeader = req.headers['authorization']; - const token = authHeader && authHeader.split(' ')[1]; - if (!token){ - return res.status(401).json({ error: true, message: 'Necesitas estar logueado y un token válido para realizar esta acción' }); + const authHeader = req.headers["authorization"]; + const token = authHeader && authHeader.split(" ")[1]; + if (!token) { + return res + .status(401) + .json({ + error: true, + message: + "Necesitas estar logueado y un token válido para realizar esta acción", + }); } try { - const blacklistedToken = await BlacklistedToken.findOne({ token }); - if (blacklistedToken) { - return res.status(401).json({ error: true, message: 'Su token ha está en la lista negra, por favor inicie sesión nuevamente' }); - - } - jwt.verify(token, accessTokenSecret, (err, user) => { - if (err){ - return res.status(403).json({ error: true, message: 'Invalid token' }); + const blacklistedToken = await BlacklistedToken.findOne({ token }); + if (blacklistedToken) { + return res + .status(401) + .json({ + error: true, + message: + "Su token ha está en la lista negra, por favor inicie sesión nuevamente", + }); } - req.user = user; - next(); - }); -} -catch (error) { - console.error(error); - return res.status(500).json({ error: true, message: 'Internal server error' }); -} + jwt.verify(token, accessTokenSecret, (err, user) => { + if (err) { + return res.status(403).json({ error: true, message: "Invalid token" }); + } + req.user = user; + next(); + }); + } catch (error) { + console.error(error); + return res + .status(500) + .json({ error: true, message: "Internal server error" }); + } } -module.exports = { verifyToken }; \ No newline at end of file +module.exports = { verifyToken }; diff --git a/LogArtApp/backend/middlewares/checkRole.js b/LogArtApp/backend/middlewares/checkRole.js index da3c440..53568a5 100644 --- a/LogArtApp/backend/middlewares/checkRole.js +++ b/LogArtApp/backend/middlewares/checkRole.js @@ -1,4 +1,4 @@ -const User = require('../models/user.model'); +const User = require("../models/user.model"); const checkRole = (roles) => { return async (req, res, next) => { @@ -6,15 +6,16 @@ const checkRole = (roles) => { const userIdFromToken = req.user?.userId; const user = await User.findById(userIdFromToken); if (!user || !roles.includes(user.role)) { - return res.status(401).json({ error: true, message: 'Access denied' }); - } - + return res.status(401).json({ error: true, message: "Access denied" }); + } next(); } catch (error) { console.error(error); - return res.status(500).json({ error: true, message: 'Internal server error' }); + return res + .status(500) + .json({ error: true, message: "Internal server error" }); } }; }; -module.exports = checkRole; \ No newline at end of file +module.exports = checkRole; diff --git a/LogArtApp/backend/middlewares/uploadImgMiddleware.js b/LogArtApp/backend/middlewares/uploadImgMiddleware.js index c6c9f72..0d387a9 100644 --- a/LogArtApp/backend/middlewares/uploadImgMiddleware.js +++ b/LogArtApp/backend/middlewares/uploadImgMiddleware.js @@ -1,5 +1,5 @@ -const multer = require('multer'); -const path = require('path'); +const multer = require("multer"); +const path = require("path"); const createStorage = (folder) => { return multer.diskStorage({ @@ -7,26 +7,27 @@ const createStorage = (folder) => { cb(null, `public/images/${folder}`); }, filename: (req, file, cb) => { - const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9); + const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9); cb(null, Date.now() + path.extname(file.originalname)); }, }); -} +}; const fileFilter = (req, file, cb) => { const allowedTypes = /jpeg|jpg|png|gif/; - const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase()); + const extname = allowedTypes.test( + path.extname(file.originalname).toLowerCase() + ); const mimetype = allowedTypes.test(file.mimetype); - if (mimetype && extname) { return cb(null, true); } else { - cb(new Error('Solo se permiten imágenes (jpeg, jpg, png, gif)')); + cb(new Error("Solo se permiten imágenes (jpeg, jpg, png, gif)")); } }; const uploadObject = multer({ - storage: createStorage('objects'), + storage: createStorage("objects"), fileFilter: fileFilter, limits: { fileSize: 1024 * 1024 * 5, // 5MB @@ -34,12 +35,11 @@ const uploadObject = multer({ }); const uploadProfile = multer({ - storage: createStorage('profiles'), + storage: createStorage("profiles"), fileFilter: fileFilter, limits: { fileSize: 1024 * 1024 * 5, // 5MB }, }); - -module.exports = { uploadObject, uploadProfile }; \ No newline at end of file +module.exports = { uploadObject, uploadProfile }; diff --git a/LogArtApp/backend/models/blacklist.model.js b/LogArtApp/backend/models/blacklist.model.js index a68762d..9943781 100644 --- a/LogArtApp/backend/models/blacklist.model.js +++ b/LogArtApp/backend/models/blacklist.model.js @@ -1,19 +1,21 @@ -const mongoose = require('mongoose'); +const mongoose = require("mongoose"); const Schema = mongoose.Schema; const blacklistedTokenSchema = new Schema({ token: { type: String, - required: true + required: true, }, expiresAt: { type: Date, - required: true - } + required: true, + }, }); blacklistedTokenSchema.index({ expiresAt: 1 }, { expireAfterSeconds: 0 }); +const BlacklistedToken = mongoose.model( + "BlacklistedToken", + blacklistedTokenSchema +); -const BlacklistedToken = mongoose.model('BlacklistedToken', blacklistedTokenSchema); - -module.exports = BlacklistedToken; \ No newline at end of file +module.exports = BlacklistedToken; diff --git a/LogArtApp/backend/models/comment.model.js b/LogArtApp/backend/models/comment.model.js index 7b1e138..675eb6a 100644 --- a/LogArtApp/backend/models/comment.model.js +++ b/LogArtApp/backend/models/comment.model.js @@ -1,4 +1,4 @@ -const mongoose = require('mongoose'); +const mongoose = require("mongoose"); const Schema = mongoose.Schema; const commentSchema = new Schema({ @@ -9,30 +9,30 @@ const commentSchema = new Schema({ }, object: { type: Schema.Types.ObjectId, - ref: 'Object', - required: true + ref: "Object", + required: true, }, user: { type: Schema.Types.ObjectId, - ref: 'User', - required: true + ref: "User", + required: true, }, isEditedByAdmin: { type: Boolean, - default: false + default: false, }, editedBy: { type: Schema.Types.ObjectId, - ref: 'User', - default: null + ref: "User", + default: null, }, createdAt: { type: Date, - default: Date.now + default: Date.now, }, updatedAt: { type: Date, }, }); -module.exports = mongoose.model('Comment', commentSchema); \ No newline at end of file +module.exports = mongoose.model("Comment", commentSchema); diff --git a/LogArtApp/backend/models/discipline.model.js b/LogArtApp/backend/models/discipline.model.js index 0248457..5c00c83 100644 --- a/LogArtApp/backend/models/discipline.model.js +++ b/LogArtApp/backend/models/discipline.model.js @@ -1,4 +1,4 @@ -const mongoose = require('mongoose'); +const mongoose = require("mongoose"); const Schema = mongoose.Schema; const DisciplineSchema = new Schema({ @@ -6,12 +6,12 @@ const DisciplineSchema = new Schema({ type: String, required: true, unique: true, - enum: ['Libros', 'Canciones', 'Videojuegos'] + enum: ["Libros", "Canciones", "Videojuegos"], }, description: { type: String, - default: '' + default: "", }, - }); +}); - module.exports = mongoose.model('Discipline', DisciplineSchema); \ No newline at end of file +module.exports = mongoose.model("Discipline", DisciplineSchema); diff --git a/LogArtApp/backend/models/object.model.js b/LogArtApp/backend/models/object.model.js index 980f54e..68b54cd 100644 --- a/LogArtApp/backend/models/object.model.js +++ b/LogArtApp/backend/models/object.model.js @@ -1,4 +1,4 @@ -const mongoose = require('mongoose'); +const mongoose = require("mongoose"); const Schema = mongoose.Schema; const ObjectSchema = new Schema({ @@ -8,26 +8,26 @@ const ObjectSchema = new Schema({ }, description: { type: String, - default: '' + default: "", }, imageUrl: { type: String, - default: '' + default: "", }, discipline: { type: Schema.Types.ObjectId, - ref: 'Discipline', - required: true + ref: "Discipline", + required: true, }, createdBy: { type: Schema.Types.ObjectId, - ref: 'User', - required: true + ref: "User", + required: true, }, createdAt: { type: Date, - default: Date.now - } + default: Date.now, + }, }); -module.exports = mongoose.model('Object', ObjectSchema); \ No newline at end of file +module.exports = mongoose.model("Object", ObjectSchema); diff --git a/LogArtApp/backend/models/user.model.js b/LogArtApp/backend/models/user.model.js index fd80ff2..633af17 100644 --- a/LogArtApp/backend/models/user.model.js +++ b/LogArtApp/backend/models/user.model.js @@ -1,59 +1,57 @@ -const mongoose = require('mongoose'); +const mongoose = require("mongoose"); const Schema = mongoose.Schema; const userSchema = new Schema({ username: { type: String, - required: true + required: true, }, password: { type: String, - required: true + required: true, }, email: { type: String, required: true, - lowercase: true + lowercase: true, }, firstName: { type: String, - required: true + required: true, }, lastName: { type: String, - required: true + required: true, }, createdAt: { type: Date, - default: Date.now + default: Date.now, }, hastoken: { type: Boolean, - default: false + default: false, }, role: { type: String, - enum: ['user', 'admin', 'guest'], - default: 'user' + enum: ["user", "admin", "guest"], + default: "user", }, bio: { type: String, - maxlength: [250, 'Bio cannot be more than 250 characters'], - default: '' + maxlength: [250, "Bio cannot be more than 250 characters"], + default: "", }, profileImage: { type: String, - default: '/public/images/profiles/default-profile.png' + default: "/public/images/profiles/default-profile.png", }, isVerified: { type: Boolean, - default: false + default: false, }, verificationToken: { - type: String - - } + type: String, + }, }); - -module.exports = mongoose.model('User', userSchema); \ No newline at end of file +module.exports = mongoose.model("User", userSchema); diff --git a/LogArtApp/backend/repositories/authRepository.js b/LogArtApp/backend/repositories/authRepository.js index 25a8b83..359a495 100644 --- a/LogArtApp/backend/repositories/authRepository.js +++ b/LogArtApp/backend/repositories/authRepository.js @@ -4,25 +4,20 @@ const BlacklistedToken = require("../models/blacklist.model"); const findUserByEmail = (email) => { return User.findOne({ email }); }; - const findUserById = (userId) => { return User.findById(userId); }; - const createUser = (data) => { const newUser = new User(data); return newUser.save(); }; - const updateUserById = (userId, updateData) => { return User.findByIdAndUpdate(userId, updateData, { new: true }); }; - const addTokenToBlacklist = (token, expiresAt) => { const blacklistedToken = new BlacklistedToken({ token, expiresAt }); return blacklistedToken.save(); }; - const isTokenBlacklisted = async (token) => { const blacklisted = await BlacklistedToken.findOne({ token }); return !!blacklisted; diff --git a/LogArtApp/backend/repositories/commentRepository.js b/LogArtApp/backend/repositories/commentRepository.js index 1dc0cc3..e10973e 100644 --- a/LogArtApp/backend/repositories/commentRepository.js +++ b/LogArtApp/backend/repositories/commentRepository.js @@ -4,20 +4,16 @@ const createComment = (data) => { const newComment = new Comment(data); return newComment.save(); }; - const findById = (commentId) => { return Comment.findById(commentId); }; - const findCommentsByObjectId = (objectId, options) => { const { skip, limit, commentId } = options; - if (commentId) { return Comment.find({ _id: commentId, object: objectId }) .populate("user", "username email") .exec(); } - return Comment.find({ object: objectId }) .populate("user", "username email role _id") .sort({ createdAt: -1 }) @@ -25,19 +21,15 @@ const findCommentsByObjectId = (objectId, options) => { .limit(limit) .exec(); }; - const countCommentsByObjectId = (objectId) => { return Comment.countDocuments({ object: objectId }); }; - const updateCommentById = (commentId, updateData) => { return Comment.findByIdAndUpdate(commentId, updateData, { new: true }); }; - const deleteCommentById = (commentId) => { return Comment.findByIdAndDelete(commentId); }; - const deleteCommentsByObjectIds = (objectIds) => { return Comment.deleteMany({ object: { $in: objectIds } }); }; diff --git a/LogArtApp/backend/repositories/disciplineRepository.js b/LogArtApp/backend/repositories/disciplineRepository.js index cb40e74..688831d 100644 --- a/LogArtApp/backend/repositories/disciplineRepository.js +++ b/LogArtApp/backend/repositories/disciplineRepository.js @@ -3,20 +3,16 @@ const Discipline = require("../models/discipline.model"); const findAllDisciplines = () => { return Discipline.find(); }; - const findByName = (name) => { return Discipline.findOne({ name }); }; - const createDiscipline = (data) => { const newDiscipline = new Discipline(data); return newDiscipline.save(); }; - const updateById = (disciplineId, updateData) => { return Discipline.findByIdAndUpdate(disciplineId, updateData, { new: true }); }; - const deleteById = (disciplineId) => { return Discipline.findByIdAndDelete(disciplineId); }; diff --git a/LogArtApp/backend/repositories/objectRepository.js b/LogArtApp/backend/repositories/objectRepository.js index 353d972..ed25b8d 100644 --- a/LogArtApp/backend/repositories/objectRepository.js +++ b/LogArtApp/backend/repositories/objectRepository.js @@ -4,23 +4,18 @@ const createObject = (data) => { const newObject = new ObjectModel(data); return newObject.save(); }; - const findById = (objectId) => { return ObjectModel.findById(objectId); }; - const findByName = (name) => { return ObjectModel.findOne({ name }); }; - const updateById = (objectId, updateData) => { return ObjectModel.findByIdAndUpdate(objectId, updateData, { new: true }); }; - const deleteById = (objectId) => { return ObjectModel.findByIdAndDelete(objectId); }; - const findObjects = (filter, skip, limit) => { return ObjectModel.find(filter) .populate("createdBy", "firstName lastName username") @@ -28,11 +23,9 @@ const findObjects = (filter, skip, limit) => { .skip(skip) .limit(limit); }; - const countObjects = (filter) => { return ObjectModel.countDocuments(filter); }; - const findObjectsByUserId = (userId) => { return ObjectModel.find({ createdBy: userId }); }; diff --git a/LogArtApp/backend/repositories/userRepository.js b/LogArtApp/backend/repositories/userRepository.js index 4392437..8344769 100644 --- a/LogArtApp/backend/repositories/userRepository.js +++ b/LogArtApp/backend/repositories/userRepository.js @@ -6,23 +6,18 @@ const findAllUsers = (page, limit) => { const skip = (page - 1) * limit; return User.find().skip(skip).limit(limit); }; - const countUsers = () => { return User.countDocuments(); }; - const findById = (userId) => { return User.findById(userId); }; - const deleteManyCommentsByUserId = (userId) => { return Comment.deleteMany({ user: userId }); }; - const deleteManyObjectsByUserId = (userId) => { return ObjectModel.deleteMany({ createdBy: userId }); }; - const deleteById = (userId) => { return User.findByIdAndDelete(userId); }; diff --git a/LogArtApp/backend/routes/authRoutes.js b/LogArtApp/backend/routes/authRoutes.js index 3066996..619586d 100644 --- a/LogArtApp/backend/routes/authRoutes.js +++ b/LogArtApp/backend/routes/authRoutes.js @@ -1,11 +1,17 @@ -const express = require('express'); -const { register, login, logout, verifyUser } = require('../controllers/authController'); -const { verifyToken } = require('../middlewares/authMiddleware'); +const express = require("express"); +const { + register, + login, + logout, + verifyUser, +} = require("../controllers/authController"); +const { verifyToken } = require("../middlewares/authMiddleware"); const router = express.Router(); -router.post('/users', register); -router.post('/auth', login); -router.post('/logout', verifyToken , logout); -router.get('/verify/:token', verifyUser); +router.post("/users", register); -module.exports = router; \ No newline at end of file +router.post("/auth", login); +router.post("/logout", verifyToken, logout); +router.get("/verify/:token", verifyUser); + +module.exports = router; diff --git a/LogArtApp/backend/routes/commentRoutes.js b/LogArtApp/backend/routes/commentRoutes.js index d715f1b..07e64b8 100644 --- a/LogArtApp/backend/routes/commentRoutes.js +++ b/LogArtApp/backend/routes/commentRoutes.js @@ -1,11 +1,16 @@ -const express = require('express'); +const express = require("express"); const router = express.Router(); -const { createComment, updateComment, deleteComment, getCommentsByObjectId } = require('../controllers/commentController'); -const { verifyToken } = require('../middlewares/authMiddleware'); +const { + createComment, + updateComment, + deleteComment, + getCommentsByObjectId, +} = require("../controllers/commentController"); +const { verifyToken } = require("../middlewares/authMiddleware"); -router.post('/', verifyToken, createComment); -router.put('/:commentId', verifyToken, updateComment); -router.delete('/:commentId', verifyToken, deleteComment); -router.get('/:objectId', verifyToken, getCommentsByObjectId); +router.post("/", verifyToken, createComment); +router.put("/:commentId", verifyToken, updateComment); +router.delete("/:commentId", verifyToken, deleteComment); +router.get("/:objectId", verifyToken, getCommentsByObjectId); -module.exports = router; \ No newline at end of file +module.exports = router; diff --git a/LogArtApp/backend/routes/disciplineRoutes.js b/LogArtApp/backend/routes/disciplineRoutes.js index ec78377..ff36036 100644 --- a/LogArtApp/backend/routes/disciplineRoutes.js +++ b/LogArtApp/backend/routes/disciplineRoutes.js @@ -1,7 +1,7 @@ -const express = require('express'); +const express = require("express"); const router = express.Router(); -const { getAllDisciplines } = require('../controllers/disciplineController'); +const { getAllDisciplines } = require("../controllers/disciplineController"); -router.get('/', getAllDisciplines); +router.get("/", getAllDisciplines); module.exports = router; diff --git a/LogArtApp/backend/routes/objectRoutes.js b/LogArtApp/backend/routes/objectRoutes.js index 74d5c24..13f0128 100644 --- a/LogArtApp/backend/routes/objectRoutes.js +++ b/LogArtApp/backend/routes/objectRoutes.js @@ -1,15 +1,28 @@ -const express = require('express'); -const { createObject, updateObject, deleteObject, getGalleryByDiscipline, getObjectById } = require('../controllers/objectController'); -const { verifyToken } = require('../middlewares/authMiddleware'); -const { uploadObject, uploadProfile } = require('../middlewares/uploadImgMiddleware'); +const express = require("express"); +const { + createObject, + updateObject, + deleteObject, + getGalleryByDiscipline, + getObjectById, +} = require("../controllers/objectController"); +const { verifyToken } = require("../middlewares/authMiddleware"); +const { + uploadObject, + uploadProfile, +} = require("../middlewares/uploadImgMiddleware"); const router = express.Router(); -router.post('/', verifyToken, uploadObject.single('imageUrl') , createObject); -router.put('/:objectId', verifyToken, uploadObject.single('imageUrl') ,updateObject); -router.delete('/:objectId', verifyToken, deleteObject); -router.get('/details/:objectId', verifyToken, getObjectById); -router.get('/:disciplineName', verifyToken, getGalleryByDiscipline); -router.get('/details/:objectId', verifyToken, getObjectById); +router.post("/", verifyToken, uploadObject.single("imageUrl"), createObject); +router.put( + "/:objectId", + verifyToken, + uploadObject.single("imageUrl"), + updateObject +); +router.delete("/:objectId", verifyToken, deleteObject); +router.get("/details/:objectId", verifyToken, getObjectById); +router.get("/:disciplineName", verifyToken, getGalleryByDiscipline); +router.get("/details/:objectId", verifyToken, getObjectById); - -module.exports = router; \ No newline at end of file +module.exports = router; diff --git a/LogArtApp/backend/routes/userRoutes.js b/LogArtApp/backend/routes/userRoutes.js index ed1ed93..6daed97 100644 --- a/LogArtApp/backend/routes/userRoutes.js +++ b/LogArtApp/backend/routes/userRoutes.js @@ -1,15 +1,25 @@ -const express = require('express'); +const express = require("express"); const router = express.Router(); -const { allUsers, findUserById, deleteUser, getUserProfile, updateUserProfile } = require('../controllers/userController'); -const { verifyToken } = require('../middlewares/authMiddleware'); -const checkRole = require('../middlewares/checkRole'); -const { uploadProfile } = require('../middlewares/uploadImgMiddleware'); +const { + allUsers, + findUserById, + deleteUser, + getUserProfile, + updateUserProfile, +} = require("../controllers/userController"); +const { verifyToken } = require("../middlewares/authMiddleware"); +const checkRole = require("../middlewares/checkRole"); +const { uploadProfile } = require("../middlewares/uploadImgMiddleware"); -router.get('/', verifyToken, allUsers); -router.get('/profile', verifyToken, getUserProfile); -router.put('/profile', verifyToken, uploadProfile.single('profileImage') ,updateUserProfile); -router.get('/:userId', verifyToken, findUserById); -router.delete('/:userId', verifyToken, checkRole(['admin']), deleteUser); +router.get("/", verifyToken, allUsers); +router.get("/profile", verifyToken, getUserProfile); +router.put( + "/profile", + verifyToken, + uploadProfile.single("profileImage"), + updateUserProfile +); +router.get("/:userId", verifyToken, findUserById); +router.delete("/:userId", verifyToken, checkRole(["admin"]), deleteUser); - -module.exports = router; \ No newline at end of file +module.exports = router; diff --git a/LogArtApp/backend/server.js b/LogArtApp/backend/server.js index 81f6093..762459e 100644 --- a/LogArtApp/backend/server.js +++ b/LogArtApp/backend/server.js @@ -1,28 +1,22 @@ -const app = require('./app'); -const https = require('https'); -const fs = require('fs'); -const path = require('path'); -const { sslKeyPath, sslCertPath, port } = require('./config/environment'); -const connectDB = require('./config/db'); -const seedDB = require('./Seeders/seedDB'); +const app = require("./app"); +const https = require("https"); +const fs = require("fs"); +const path = require("path"); +const { sslKeyPath, sslCertPath, port } = require("./config/environment"); +const connectDB = require("./config/db"); +const seedDB = require("./Seeders/seedDB"); const sslOptions = { key: fs.readFileSync(path.resolve(__dirname, sslKeyPath)), cert: fs.readFileSync(path.resolve(__dirname, sslCertPath)), }; - async function startServer() { - if (process.env.NODE_ENV !== 'test') { + if (process.env.NODE_ENV !== "test") { await connectDB(); await seedDB(); } - - -https.createServer(sslOptions, app).listen(port, () => { - console.log(`Servidor HTTPS corriendo en https://localhost:${port}`); -}); - + https.createServer(sslOptions, app).listen(port, () => { + console.log(`Servidor HTTPS corriendo en https://localhost:${port}`); + }); } - startServer(); - diff --git a/LogArtApp/backend/services/authService.js b/LogArtApp/backend/services/authService.js index 6256f78..ae1a66b 100644 --- a/LogArtApp/backend/services/authService.js +++ b/LogArtApp/backend/services/authService.js @@ -13,52 +13,44 @@ const login = async (email, password) => { error.statusCode = 400; throw error; } - const user = await authRepository.findUserByEmail(email); if (!user) { const error = new Error("User not found"); error.statusCode = 401; throw error; } - if (!user.isVerified) { const error = new Error("Please verify your email before logging in"); error.statusCode = 401; throw error; } - if (user.hastoken) { const error = new Error("User already logged in"); error.statusCode = 401; throw error; } - const isPasswordValid = await bcrypt.compare(password, user.password); if (!isPasswordValid) { const error = new Error("Invalid credentials"); error.statusCode = 401; throw error; } - const accessToken = jwt.sign({ userId: user._id }, accessTokenSecret, { expiresIn: "24h", }); user.hastoken = true; await user.save(); - return { accessToken, user }; }; const register = async (data) => { const { password, email, firstName, lastName, username } = data; - const loggedUser = await User.findOne({ hastoken: true }); if (loggedUser) { const error = new Error("You are already logged in"); error.statusCode = 401; throw error; } - if ( !password || !email || @@ -75,16 +67,13 @@ const register = async (data) => { error.statusCode = 400; throw error; } - const existingUser = await authRepository.findUserByEmail(email); if (existingUser) { const error = new Error("User already exists"); error.statusCode = 409; throw error; } - const verificationToken = crypto.randomBytes(32).toString("hex"); - const hashedPassword = await bcrypt.hash(password, 10); const user = await authRepository.createUser({ password: hashedPassword, @@ -94,10 +83,8 @@ const register = async (data) => { username, verificationToken, }); - const verificationLink = `${url}/api/v1/verify/${verificationToken}`; await sendVerificationEmail(email, verificationLink); - return { user: { firstName: user.firstName, @@ -108,35 +95,29 @@ const register = async (data) => { message: "User registered, please check your email to verify your account", }; }; - const verifyUser = async (token) => { if (!token || token.trim() === "") { const error = new Error("Verification token is required"); error.statusCode = 400; throw error; } - const user = await User.findOne({ verificationToken: token }); if (!user) { const error = new Error("Invalid or expired token"); error.statusCode = 404; throw error; } - user.isVerified = true; user.verificationToken = null; await user.save(); - return { message: "User verified successfully" }; }; - const logout = async (token, userId) => { if (!token) { const error = new Error("No token provided"); error.statusCode = 401; throw error; } - try { const decoded = jwt.verify(token, accessTokenSecret); const originalExpirationDate = new Date(decoded.exp * 1000); @@ -144,15 +125,12 @@ const logout = async (token, userId) => { const extendedExpirationDate = new Date( originalExpirationDate.getTime() + ADDITIONAL_TOKEN_EXP_TIME ); - await authRepository.addTokenToBlacklist(token, extendedExpirationDate); - const user = await authRepository.findUserById(userId); if (user) { user.hastoken = false; await user.save(); } - return { message: "Logout successful" }; } catch (error) { console.error("Error during logout:", error); diff --git a/LogArtApp/backend/services/commentService.js b/LogArtApp/backend/services/commentService.js index 91b61b5..02bb3ff 100644 --- a/LogArtApp/backend/services/commentService.js +++ b/LogArtApp/backend/services/commentService.js @@ -9,151 +9,126 @@ const createComment = async (content, objectId, userId) => { error.statusCode = 400; throw error; } - if (!isValidMongoId(objectId)) { const error = new Error("Invalid object ID format"); error.statusCode = 400; throw error; } - const object = await objectRepository.findById(objectId); if (!object) { const error = new Error("Object not found"); error.statusCode = 404; throw error; } - const user = await userRepository.findById(userId); if (!user) { const error = new Error("User not found"); error.statusCode = 404; throw error; } - const userRole = user.role; if (object.createdBy.toString() !== userId && userRole !== "admin") { const error = new Error("You are not authorized to comment on this object"); error.statusCode = 403; throw error; } - const newComment = await commentRepository.createComment({ content, object: objectId, user: userId, }); - return newComment; }; - const updateComment = async (commentId, content, userId) => { if (!content || content.trim() === "") { const error = new Error("Content is required"); error.statusCode = 400; throw error; } - if (!isValidMongoId(commentId)) { const error = new Error("Invalid comment ID format"); error.statusCode = 400; throw error; } - const comment = await commentRepository.findById(commentId); if (!comment) { const error = new Error("Comment not found"); error.statusCode = 404; throw error; } - const user = await userRepository.findById(userId); if (!user) { const error = new Error("User not found"); error.statusCode = 404; throw error; } - const userRole = user.role; if (comment.user.toString() !== userId && userRole !== "admin") { const error = new Error("You are not authorized to update this comment"); error.statusCode = 403; throw error; } - const updateData = { content, updatedAt: Date.now(), }; - if (userRole === "admin" && comment.user.toString() !== userId) { updateData.isEditedByAdmin = true; updateData.editedBy = userId; } - const updatedComment = await commentRepository.updateCommentById( commentId, updateData ); return updatedComment; }; - const deleteComment = async (commentId, userId) => { if (!isValidMongoId(commentId)) { const error = new Error("Invalid comment ID format"); error.statusCode = 400; throw error; } - const comment = await commentRepository.findById(commentId); if (!comment) { const error = new Error("Comment not found"); error.statusCode = 404; throw error; } - const user = await userRepository.findById(userId); if (!user) { const error = new Error("User not found"); error.statusCode = 404; throw error; } - const userRole = user.role; if (comment.user.toString() !== userId && userRole !== "admin") { const error = new Error("You are not authorized to delete this comment"); error.statusCode = 403; throw error; } - await commentRepository.deleteCommentById(commentId); - return { message: "Comment deleted successfully" }; }; - const getCommentsByObjectId = async (objectId, query, userId) => { const { page = 1, limit = 3, commentId } = query; const skip = (page - 1) * limit; - if (!isValidMongoId(objectId)) { const error = new Error("Invalid object ID format"); error.statusCode = 400; throw error; } - const object = await objectRepository.findById(objectId); if (!object) { const error = new Error("Object not found"); error.statusCode = 404; throw error; } - const user = await userRepository.findById(userId); if (!user) { const error = new Error("User not found"); error.statusCode = 404; throw error; } - const userRole = user.role; const userIdFromObject = object.createdBy.toString(); if (userId !== userIdFromObject && userRole !== "admin") { @@ -163,14 +138,12 @@ const getCommentsByObjectId = async (objectId, query, userId) => { error.statusCode = 403; throw error; } - if (commentId) { if (!isValidMongoId(commentId)) { const error = new Error("Invalid comment ID format"); error.statusCode = 400; throw error; } - const comment = await commentRepository.findCommentsByObjectId(objectId, { commentId, }); @@ -179,7 +152,6 @@ const getCommentsByObjectId = async (objectId, query, userId) => { error.statusCode = 404; throw error; } - return { comments: comment, totalComments: 1, @@ -187,16 +159,13 @@ const getCommentsByObjectId = async (objectId, query, userId) => { totalPages: 1, }; } - const totalComments = await commentRepository.countCommentsByObjectId( objectId ); - const comments = await commentRepository.findCommentsByObjectId(objectId, { skip, limit, }); - return { comments, totalComments, diff --git a/LogArtApp/backend/services/disciplineService.js b/LogArtApp/backend/services/disciplineService.js index b96c166..71f0d8d 100644 --- a/LogArtApp/backend/services/disciplineService.js +++ b/LogArtApp/backend/services/disciplineService.js @@ -5,41 +5,34 @@ const getAllDisciplines = async () => { const disciplines = await disciplineRepository.findAllDisciplines(); return disciplines; }; - const createDiscipline = async (data) => { const { name } = data; - if (!name || name.trim() === "") { const error = new Error("Discipline name is required"); error.statusCode = 400; throw error; } - const existingDiscipline = await disciplineRepository.findByName(name); if (existingDiscipline) { const error = new Error("Discipline already exists"); error.statusCode = 400; throw error; } - const newDiscipline = await disciplineRepository.createDiscipline(data); return newDiscipline; }; - const updateDiscipline = async (disciplineId, updateData) => { if (!isValidMongoId(disciplineId)) { const error = new Error("Invalid discipline ID format"); error.statusCode = 400; throw error; } - const discipline = await disciplineRepository.findById(disciplineId); if (!discipline) { const error = new Error("Discipline not found"); error.statusCode = 404; throw error; } - if (updateData.name && updateData.name !== discipline.name) { const existingDiscipline = await disciplineRepository.findByName( updateData.name @@ -52,28 +45,24 @@ const updateDiscipline = async (disciplineId, updateData) => { throw error; } } - const updatedDiscipline = await disciplineRepository.updateById( disciplineId, updateData ); return updatedDiscipline; }; - const deleteDiscipline = async (disciplineId) => { if (!isValidMongoId(disciplineId)) { const error = new Error("Invalid discipline ID format"); error.statusCode = 400; throw error; } - const discipline = await disciplineRepository.findById(disciplineId); if (!discipline) { const error = new Error("Discipline not found"); error.statusCode = 404; throw error; } - const ObjectModel = require("../models/object.model"); const objects = await ObjectModel.find({ discipline: disciplineId }); if (objects.length > 0) { @@ -81,7 +70,6 @@ const deleteDiscipline = async (disciplineId) => { error.statusCode = 400; throw error; } - await disciplineRepository.deleteById(disciplineId); return { message: "Discipline deleted successfully" }; }; diff --git a/LogArtApp/backend/services/objectService.js b/LogArtApp/backend/services/objectService.js index dc85cbf..24fa3b9 100644 --- a/LogArtApp/backend/services/objectService.js +++ b/LogArtApp/backend/services/objectService.js @@ -8,27 +8,22 @@ const isValidMongoId = require("../utils/validId"); const createObject = async (data, userId, baseUrl) => { const { name, description, disciplineName } = data; - if (!name || !disciplineName || name.trim() === "") { const error = new Error("Both name and discipline are required"); error.statusCode = 400; throw error; } - const discipline = await disciplineRepository.findByName(disciplineName); if (!discipline) { const error = new Error("Discipline not found"); error.statusCode = 404; throw error; } - - if (!data.imageUrl) { const error = new Error("Image is required"); error.statusCode = 400; throw error; } - const newObject = await objectRepository.createObject({ name, description, @@ -36,32 +31,26 @@ const createObject = async (data, userId, baseUrl) => { createdBy: userId, imageUrl: data.imageUrl, }); - return newObject; }; - const updateObject = async (objectId, data, userId) => { const { name, description, disciplineName, imageUrl } = data; - if (!name || !disciplineName || name.trim() === "") { const error = new Error("Both name and discipline are required"); error.statusCode = 400; throw error; } - if (!isValidMongoId(objectId)) { const error = new Error("Invalid object ID format"); error.statusCode = 400; throw error; } - const object = await objectRepository.findById(objectId); if (!object) { const error = new Error("Object not found"); error.statusCode = 404; throw error; } - if (object.createdBy.toString() !== userId) { const user = await User.findById(userId); if (user.role !== "admin") { @@ -70,14 +59,12 @@ const updateObject = async (objectId, data, userId) => { throw error; } } - const discipline = await disciplineRepository.findByName(disciplineName); if (!discipline) { const error = new Error("Discipline not found"); error.statusCode = 404; throw error; } - if (name !== object.name) { const existingObject = await objectRepository.findByName(name); if (existingObject) { @@ -88,18 +75,16 @@ const updateObject = async (objectId, data, userId) => { throw error; } } - const updateData = { name, description, discipline: discipline._id, updatedAt: Date.now(), }; - if (imageUrl) { if ( object.imageUrl && - object.imageUrl !== "public/images/objects/zelda.jpg" && + object.imageUrl !== "public/images/objects/zelda.jpg" && object.imageUrl !== "public/images/objects/bohemian_rhapsody.jpg" && object.imageUrl !== "public/images/objects/cien_años.jpg" ) { @@ -121,25 +106,21 @@ const updateObject = async (objectId, data, userId) => { } updateData.imageUrl = imageUrl; } - const updatedObject = await objectRepository.updateById(objectId, updateData); return updatedObject; }; - const deleteObject = async (objectId, userId) => { if (!isValidMongoId(objectId)) { const error = new Error("Invalid object ID format"); error.statusCode = 400; throw error; } - const object = await objectRepository.findById(objectId); if (!object) { const error = new Error("Object not found"); error.statusCode = 404; throw error; } - if (object.createdBy.toString() !== userId) { const user = await User.findById(userId); if (user.role !== "admin") { @@ -148,8 +129,12 @@ const deleteObject = async (objectId, userId) => { throw error; } } - - if (object.imageUrl && object.imageUrl !== "public/images/objects/zelda.jpg" && object.imageUrl !== "public/images/objects/bohemian_rhapsody.jpg" && object.imageUrl !== "public/images/objects/cien_años.jpg") { + if ( + object.imageUrl && + object.imageUrl !== "public/images/objects/zelda.jpg" && + object.imageUrl !== "public/images/objects/bohemian_rhapsody.jpg" && + object.imageUrl !== "public/images/objects/cien_años.jpg" + ) { const imagePath = path.join( __dirname, "..", @@ -166,25 +151,19 @@ const deleteObject = async (objectId, userId) => { } } } - await commentRepository.deleteCommentsByObjectIds([objectId]); - await objectRepository.deleteById(objectId); - return { message: "Object deleted successfully" }; }; - const getGalleryByDiscipline = async (disciplineName, query) => { const { userId, page = 1, limit = 3, objectName } = query; const skip = (page - 1) * limit; - const discipline = await disciplineRepository.findByName(disciplineName); if (!discipline) { const error = new Error("Discipline not found"); error.statusCode = 404; throw error; } - const filter = { discipline: discipline._id }; if (userId) { filter.createdBy = userId; @@ -192,11 +171,8 @@ const getGalleryByDiscipline = async (disciplineName, query) => { if (objectName) { filter.name = { $regex: new RegExp(objectName, "i") }; } - const totalObjects = await objectRepository.countObjects(filter); - const objects = await objectRepository.findObjects(filter, skip, limit); - return { discipline: { id: discipline._id, @@ -208,25 +184,21 @@ const getGalleryByDiscipline = async (disciplineName, query) => { totalPages: Math.ceil(totalObjects / limit), }; }; - const getObjectById = async (objectId, userId) => { if (!isValidMongoId(objectId)) { const error = new Error("Invalid object ID format"); error.statusCode = 400; throw error; } - const object = await objectRepository .findById(objectId) .populate("discipline", "name") .populate("createdBy", "firstName lastName username"); - if (!object) { const error = new Error("Object not found"); error.statusCode = 404; throw error; } - if (object.createdBy._id.toString() !== userId) { const user = await User.findById(userId); const userRole = user.role; @@ -236,7 +208,6 @@ const getObjectById = async (objectId, userId) => { throw error; } } - return object; }; diff --git a/LogArtApp/backend/services/userService.js b/LogArtApp/backend/services/userService.js index c3c0378..864385f 100644 --- a/LogArtApp/backend/services/userService.js +++ b/LogArtApp/backend/services/userService.js @@ -8,34 +8,26 @@ const commentRepository = require("../repositories/commentRepository"); const getAllUsers = async (page, limit) => { const users = await userRepository.findAllUsers(page, limit); const totalUsers = await userRepository.countUsers(); - const currentPage = parseInt(page); const totalPages = Math.ceil(totalUsers / limit); - return { users, totalUsers, currentPage, totalPages }; }; - const getUserById = async (userId) => { if (!isValidMongoId(userId)) { throw new Error("Invalid user ID format"); } - const user = await userRepository.findById(userId); - if (!user) { throw new Error("User not found"); } - return user; }; - const deleteUser = async (userId, requestingUserId) => { if (!isValidMongoId(userId)) { const error = new Error("Invalid user ID format"); error.statusCode = 400; throw error; } - if (requestingUserId === userId) { const error = new Error( "You cannot delete your own account, contact the system administrator" @@ -43,52 +35,49 @@ const deleteUser = async (userId, requestingUserId) => { error.statusCode = 401; throw error; } - const user = await userRepository.findById(userId); - if (!user) { const error = new Error("User not found"); error.statusCode = 404; throw error; } - const userObjects = await objectRepository.findObjectsByUserId(userId); - if (Array.isArray(userObjects) && userObjects.length > 0) { const objectIds = userObjects.map((object) => object._id); - await commentRepository.deleteCommentsByObjectIds(objectIds); - for (const object of userObjects) { - if (object.imageUrl && object.imageUrl !== "public/images/objects/zelda.jpg" && object.imageUrl !== "public/images/objects/bohemian_rhapsody.jpg" && object.imageUrl !== "public/images/objects/cien_años.jpg") { - const imagePath = path.join( - __dirname, - "..", - "public", - "images", - "objects", - path.basename(object.imageUrl) - ); - if (fs.existsSync(imagePath)) { - try { - fs.unlinkSync(imagePath); - } catch (err) { - console.error("Error al eliminar la imagen del objeto:", err); + if ( + object.imageUrl && + object.imageUrl !== "public/images/objects/zelda.jpg" && + object.imageUrl !== "public/images/objects/bohemian_rhapsody.jpg" && + object.imageUrl !== "public/images/objects/cien_años.jpg" + ) { + const imagePath = path.join( + __dirname, + "..", + "public", + "images", + "objects", + path.basename(object.imageUrl) + ); + if (fs.existsSync(imagePath)) { + try { + fs.unlinkSync(imagePath); + } catch (err) { + console.error("Error al eliminar la imagen del objeto:", err); + } + } } } - } - } - - - await userRepository.deleteManyObjectsByUserId(userId); } else { console.warn(`No se encontraron objetos para el usuario con ID: ${userId}`); } - await userRepository.deleteManyCommentsByUserId(userId); - - if (user.profileImage && user.profileImage !== "public/images/users/default.png") { + if ( + user.profileImage && + user.profileImage !== "public/images/users/default.png" + ) { const imagePath = path.join( __dirname, "..", @@ -105,48 +94,37 @@ const deleteUser = async (userId, requestingUserId) => { } } } - await userRepository.deleteById(userId); - return { message: "User and Data deleted successfully" }; }; - const getUserProfile = async (userId) => { if (!isValidMongoId(userId)) { throw new Error("Invalid user ID format"); } - const user = await userRepository .findById(userId) .select( "-password -createdAt -hasToken -isVerified -verificationToken -__v" ); - if (!user) { throw new Error("User not found"); } - return { user }; }; - const updateUserProfile = async (userId, updateData, file) => { if (!isValidMongoId(userId)) { throw new Error("Invalid user ID format"); } - const user = await userRepository.findById(userId); - if (!user) { throw new Error("User not found"); } - const { firstName, lastName, email, username, bio } = updateData; if (username) user.username = username; if (firstName) user.firstName = firstName; if (lastName) user.lastName = lastName; if (email) user.email = email; if (bio) user.bio = bio; - if (file) { if ( user.profileImage && @@ -170,9 +148,7 @@ const updateUserProfile = async (userId, updateData, file) => { } user.profileImage = `/public/images/profiles/${file.filename}`; } - await user.save(); - return { user, message: "User updated successfully" }; }; diff --git a/LogArtApp/backend/utils/emailService.js b/LogArtApp/backend/utils/emailService.js index e387825..6f1aa74 100644 --- a/LogArtApp/backend/utils/emailService.js +++ b/LogArtApp/backend/utils/emailService.js @@ -1,25 +1,22 @@ -const nodemailer = require('nodemailer'); -const { email } = require('../config/environment'); -const { password } = require('../config/environment'); +const nodemailer = require("nodemailer"); +const { email } = require("../config/environment"); +const { password } = require("../config/environment"); const sendVerificationEmail = async (to, link) => { const transporter = nodemailer.createTransport({ - service: 'gmail', + service: "gmail", auth: { user: email, pass: password, }, }); - const mailOptions = { from: email, to, - subject: 'Verify your LogArt email', + subject: "Verify your LogArt email", html: `

Click the link below to verify your email:

${link}`, }; - - const info = await transporter.sendMail(mailOptions); - + const info = await transporter.sendMail(mailOptions); }; -module.exports = sendVerificationEmail; \ No newline at end of file +module.exports = sendVerificationEmail; diff --git a/LogArtApp/backend/utils/validId.js b/LogArtApp/backend/utils/validId.js index 5018fab..167c7db 100644 --- a/LogArtApp/backend/utils/validId.js +++ b/LogArtApp/backend/utils/validId.js @@ -1,18 +1,13 @@ const mongoose = require("mongoose"); - function isValidMongoId(id) { - if (typeof id !== 'string') { + if (typeof id !== "string") { return false; } - - // Verificar si la longitud es correcta para un ObjectId if (id.length !== 24) { return false; } - - // Verificar si solo contiene caracteres hexadecimales return /^[0-9a-fA-F]{24}$/.test(id); } -module.exports = isValidMongoId \ No newline at end of file +module.exports = isValidMongoId; diff --git a/LogArtApp/docker/Dockerfile b/LogArtApp/docker/Dockerfile index c9273e4..f751224 100644 --- a/LogArtApp/docker/Dockerfile +++ b/LogArtApp/docker/Dockerfile @@ -7,25 +7,17 @@ RUN npm run build FROM node:20-alpine AS backend-build WORKDIR /app/backend - RUN apk add --no-cache make gcc g++ python3 - COPY backend/package*.json ./ RUN npm install --legacy-peer-deps - COPY backend/ ./ - RUN npm rebuild bcrypt --build-from-source - RUN npm prune --production - RUN npm cache clean --force - RUN apk del make gcc g++ python3 FROM node:20-alpine AS production WORKDIR /app/backend - COPY --from=backend-build /app/backend ./ COPY --from=frontend-build /app/frontend/dist ./public diff --git a/LogArtApp/docker/docker-compose.yml b/LogArtApp/docker/docker-compose.yml index eda8103..aa9a492 100644 --- a/LogArtApp/docker/docker-compose.yml +++ b/LogArtApp/docker/docker-compose.yml @@ -1,5 +1,4 @@ -version: '3.8' - +version: "3.8" services: mongo: image: mongo:latest @@ -8,7 +7,19 @@ services: MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME} MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD} healthcheck: - test: ["CMD", "mongo", "--username", "${MONGO_INITDB_ROOT_USERNAME}", "--password", "${MONGO_INITDB_ROOT_PASSWORD}", "--authenticationDatabase", "admin", "--eval", "db.adminCommand('ping')"] + test: + [ + "CMD", + "mongo", + "--username", + "${MONGO_INITDB_ROOT_USERNAME}", + "--password", + "${MONGO_INITDB_ROOT_PASSWORD}", + "--authenticationDatabase", + "admin", + "--eval", + "db.adminCommand('ping')", + ] interval: 10s timeout: 5s retries: 5 @@ -16,7 +27,6 @@ services: ports: - "27017:27017" restart: unless-stopped - app: image: davidmorenoo/logartapp:latest17 ports: diff --git a/LogArtApp/frontend/LogArt-frontend/src/App.jsx b/LogArtApp/frontend/LogArt-frontend/src/App.jsx index 5dc03e1..c4f4291 100644 --- a/LogArtApp/frontend/LogArt-frontend/src/App.jsx +++ b/LogArtApp/frontend/LogArt-frontend/src/App.jsx @@ -1,5 +1,10 @@ -import {BrowserRouter as Router, Routes, Route, Navigate } from "react-router-dom"; -import React from 'react' +import { + BrowserRouter as Router, + Routes, + Route, + Navigate, +} from "react-router-dom"; +import React from "react"; import Login from "./pages/Login"; import Register from "./pages/Register"; import Profile from "./pages/Profile"; @@ -12,12 +17,10 @@ import Hero from "./pages/Hero"; import { ModalProvider } from "./context/ModalContext"; import ErrorPage from "./components/ErrorPage"; - const App = () => { return ( - - +
@@ -25,31 +28,29 @@ const App = () => { } /> } /> - - - } - /> - - - - } - /> - } /> - } /> - } /> + path="/profile" + element={ + + + + } + /> + + + + } + /> + } /> + } /> + } />
- {/*