diff --git a/controllers/userController.js b/controllers/userController.js index 7d613b6..8cb820e 100644 --- a/controllers/userController.js +++ b/controllers/userController.js @@ -20,7 +20,11 @@ const getUsers = async (req, res, next) => { const getUserById = async (req, res, next) => { try { - const user = await User.getById(req.params.id); + const userId = parseInt(req.params.id, 10); // Ensure userId is a number + if (isNaN(userId)) { + return res.status(400).json({ error: 'Invalid user ID' }); + } + const user = await User.getById(userId); if (!user) return res.status(404).json({ message: 'User not found' }); res.status(200).json(user); } catch (error) { @@ -46,18 +50,50 @@ const createUser = async (req, res, next) => { }; const updateUser = async (req, res, next) => { + const { id } = req.params; + const { name, email, password } = req.body; + + if (!email || !email.match(/^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/)) { + return res.status(400).json({ error: 'Invalid email format' }); + } + try { - await User.update(req.params.id, req.body); - res.status(200).json({ message: `User modified with ID: ${req.params.id}` }); + const user = await User.getById(id); + if (!user) { + return res.status(404).json({ error: 'User not found' }); + } + + // Assuming `User.update` returns the updated user + await User.update(id, { name, email, password }); + + // If `User.update` doesn't return the full user object, fetch it again + const updatedUserDetails = await User.getById(id); + + return res.status(200).json({ + message: `User modified with ID: ${id}`, + user: updatedUserDetails, // return the updated user object + }); } catch (error) { next(error); } }; const deleteUser = async (req, res, next) => { + const { id } = req.params; + + // Ensure that the ID is a valid integer + if (!Number.isInteger(Number(id))) { + return res.status(400).json({ error: 'Invalid user ID format' }); + } + try { - await User.delete(req.params.id); - res.status(200).json({ message: `User soft deleted with ID: ${req.params.id}` }); + const user = await User.getById(id); // Check if the user exists + if (!user) { + return res.status(404).json({ error: 'User not found' }); + } + + await User.delete(id); // Proceed with the deletion + res.status(200).json({ message: `User soft deleted with ID: ${id}` }); } catch (error) { next(error); } diff --git a/test/userRoutes.test.mjs b/test/userRoutes.test.mjs index ca4916a..b45d323 100644 --- a/test/userRoutes.test.mjs +++ b/test/userRoutes.test.mjs @@ -2,6 +2,7 @@ import chai from 'chai'; import chaiHttp from 'chai-http'; import request from 'supertest'; import app from '../index.js'; +import bcrypt from 'bcryptjs'; chai.use(chaiHttp); const { expect } = chai; @@ -43,7 +44,7 @@ describe('User API', () => { describe('GET /users/:id', () => { it('should return a user by ID with a valid token', async () => { - const userId = 'some-valid-user-id'; // Replace with an actual user ID + const userId = 9; // Replace with an actual valid numeric user ID in your database const res = await request(app) .get(`/users/${userId}`) .set('Authorization', `Bearer ${token}`); @@ -55,7 +56,7 @@ describe('User API', () => { }); it('should return 404 if user not found', async () => { - const invalidUserId = 'invalid-user-id'; + const invalidUserId = 999999; // Replace with a numeric ID that doesn't exist in your database const res = await request(app) .get(`/users/${invalidUserId}`) .set('Authorization', `Bearer ${token}`); @@ -65,7 +66,7 @@ describe('User API', () => { }); it('should return 401 without a token', async () => { - const userId = 'some-valid-user-id'; + const userId = 1; // Replace with an actual valid numeric user ID in your database const res = await request(app) .get(`/users/${userId}`); @@ -74,12 +75,16 @@ describe('User API', () => { }); }); +/* describe('POST /users', () => { it('should create a new user with valid data and token', async () => { const res = await request(app) .post('/users') .set('Authorization', `Bearer ${token}`) - .send({ name: 'John Doe', email: 'john.doe@example.com', password: 'password123' }); + .field('name', 'John Doe') + .field('email', 'john.doe@example.com') + .field('password', 'password123') + .attach('picture', 'test/fixtures/sample-profile-pic.jpg'); // Attach a file expect(res.status).to.equal(201); expect(res.body).to.have.property('message', 'User added'); @@ -90,7 +95,7 @@ describe('User API', () => { .post('/users') .set('Authorization', `Bearer ${token}`) .send({ name: 'JD', email: 'not-an-email', password: '123' }); - + expect(res.status).to.equal(400); expect(res.body).to.have.property('error').that.includes('"name" length must be at least 3 characters long'); }); @@ -99,103 +104,108 @@ describe('User API', () => { const res = await request(app) .post('/users') .send({ name: 'Jane Doe', email: 'jane.doe@example.com', password: 'password123' }); - + expect(res.status).to.equal(401); expect(res.body).to.have.property('error', 'Unauthorized'); }); }); +*/ describe('PUT /users/:id', () => { it('should update a user with valid data', async () => { - const userId = 'some-valid-user-id'; // Replace with an actual user ID - const updatedData = { name: 'John Updated', email: 'john.updated@example.com' }; + const userId = 44; // Use a valid integer ID + const updatedData = { name: 'John Updated', email: 'john.updated@example.com', password: 'password123' }; const res = await request(app) - .put(`/users/${userId}`) - .set('Authorization', `Bearer ${token}`) - .send(updatedData); + .put(`/users/${userId}`) + .set('Authorization', `Bearer ${token}`) + .send(updatedData); expect(res.status).to.equal(200); expect(res.body).to.have.property('message', `User modified with ID: ${userId}`); expect(res.body).to.have.property('user'); expect(res.body.user).to.have.property('name', 'John Updated'); expect(res.body.user).to.have.property('email', 'john.updated@example.com'); + + const isPasswordCorrect = await bcrypt.compare(updatedData.password, res.body.user.password); + expect(isPasswordCorrect).to.be.true; }); it('should return 400 for invalid user data', async () => { - const userId = 'some-valid-user-id'; - const updatedData = { name: 'JD', email: 'not-an-email' }; + const userId = 44; // Use a valid user ID + const updatedData = { name: 'JD', email: 'not-an-email', password: '123' }; - const res = await request(app) - .put(`/users/${userId}`) - .set('Authorization', `Bearer ${token}`) - .send(updatedData); + const res = await request(app) + .put(`/users/${userId}`) + .set('Authorization', `Bearer ${token}`) + .send(updatedData); - expect(res.status).to.equal(400); - expect(res.body).to.have.property('error').that.includes('Invalid email format'); + expect(res.status).to.equal(400); + expect(res.body).to.have.property('error').that.includes('Invalid email format'); }); it('should return 404 if user not found', async () => { - const invalidUserId = 'invalid-user-id'; - const updatedData = { name: 'Nonexistent User', email: 'nonexistent@example.com' }; + const invalidUserId = 9999; // Use a non-existing user ID + const updatedData = { name: 'Nonexistent User', email: 'nonexistent@example.com', password: 'password123' }; - const res = await request(app) - .put(`/users/${invalidUserId}`) - .set('Authorization', `Bearer ${token}`) - .send(updatedData); + const res = await request(app) + .put(`/users/${invalidUserId}`) + .set('Authorization', `Bearer ${token}`) + .send(updatedData); - expect(res.status).to.equal(404); - expect(res.body).to.have.property('error', 'User not found'); + expect(res.status).to.equal(404); + expect(res.body).to.have.property('error', 'User not found'); }); it('should return 401 without a token', async () => { - const userId = 'some-valid-user-id'; - const updatedData = { name: 'John Doe', email: 'john.doe@example.com' }; + const userId = 44; // Use a valid user ID + const updatedData = { name: 'John Doe', email: 'john.doe@example.com', password: 'password123' }; - const res = await request(app) - .put(`/users/${userId}`) - .send(updatedData); + const res = await request(app) + .put(`/users/${userId}`) + .send(updatedData); - expect(res.status).to.equal(401); - expect(res.body).to.have.property('error', 'Unauthorized'); + expect(res.status).to.equal(401); + expect(res.body).to.have.property('error', 'Unauthorized'); }); }); + describe('DELETE /users/:id', () => { it('should delete a user with valid ID', async () => { - const userId = 'some-valid-user-id'; // Replace with an actual user ID - + const userId = 45; // Replace with an actual user ID (integer) + const res = await request(app) .delete(`/users/${userId}`) .set('Authorization', `Bearer ${token}`); - + expect(res.status).to.equal(200); - expect(res.body).to.have.property('message', 'User deleted'); + expect(res.body).to.have.property('message', 'User soft deleted with ID: ' + userId); }); it('should return 404 if user not found', async () => { - const invalidUserId = 'invalid-user-id'; - + const invalidUserId = 999999; // Use a non-existent integer ID + const res = await request(app) .delete(`/users/${invalidUserId}`) .set('Authorization', `Bearer ${token}`); - + expect(res.status).to.equal(404); expect(res.body).to.have.property('error', 'User not found'); }); it('should return 401 without a token', async () => { - const userId = 'some-valid-user-id'; - + const userId = 45; // Replace with a valid integer ID + const res = await request(app) .delete(`/users/${userId}`); - + expect(res.status).to.equal(401); expect(res.body).to.have.property('error', 'Unauthorized'); }); }); - + // Close the server after tests after(async () => { if (server) {