refactorings of users.js

This commit is contained in:
C. Fuhrman 2024-10-01 11:30:26 -04:00
parent 1f78c44be2
commit a175718eec
10 changed files with 154 additions and 17 deletions

1
.gitignore vendored
View file

@ -128,3 +128,4 @@ dist
.yarn/build-state.yml .yarn/build-state.yml
.yarn/install-state.gz .yarn/install-state.gz
.pnp.* .pnp.*
db-backup/

View file

@ -0,0 +1,8 @@
class AppError extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
}
}
module.exports = AppError;

View file

@ -0,0 +1,6 @@
const mockBcrypt = {
hash: jest.fn().mockResolvedValue('hashedPassword'),
compare: jest.fn().mockResolvedValue(true),
};
module.exports = mockBcrypt;

20
server/__mocks__/db.js Normal file
View file

@ -0,0 +1,20 @@
class MockDBConnection {
constructor() {
this.db = jest.fn().mockReturnThis();
this.collection = jest.fn().mockReturnThis();
this.insertOne = jest.fn();
this.findOne = jest.fn();
this.updateOne = jest.fn();
this.deleteOne = jest.fn();
}
async connect() {
// Simulate successful connection
}
getConnection() {
return this;
}
}
module.exports = MockDBConnection;

View file

@ -0,0 +1,8 @@
const mockFolders = {
create: jest.fn(),
find: jest.fn(),
update: jest.fn(),
delete: jest.fn(),
};
module.exports = mockFolders;

View file

@ -0,0 +1,82 @@
const Users = require('../models/users');
const bcrypt = require('bcrypt');
const AppError = require('../middleware/AppError');
const Folders = require('../models/folders');
const { ObjectId } = require('mongodb');
jest.mock('bcrypt');
jest.mock('../middleware/AppError');
jest.mock('../models/folders');
describe('Users', () => {
let users;
let db;
beforeEach(() => {
jest.clearAllMocks(); // Clear any previous mock calls
// Mock the database connection
db = {
connect: jest.fn(),
getConnection: jest.fn().mockReturnThis(), // Add getConnection method
collection: jest.fn().mockReturnThis(),
findOne: jest.fn(),
insertOne: jest.fn().mockResolvedValue({ _id: new ObjectId() }), // Mock insertOne to return an ObjectId
updateOne: jest.fn(),
deleteOne: jest.fn(),
};
users = new Users(db);
});
it('should register a new user', async () => {
db.collection().findOne.mockResolvedValue(null); // No user found
db.collection().insertOne.mockResolvedValue({ _id: new ObjectId() });
bcrypt.hash.mockResolvedValue('hashedPassword');
Folders.create.mockResolvedValue(true);
const email = 'test@example.com';
const password = 'password123';
const result = await users.register(email, password);
expect(db.connect).toHaveBeenCalled();
expect(db.collection().findOne).toHaveBeenCalledWith({ email });
expect(bcrypt.hash).toHaveBeenCalledWith(password, 10);
expect(db.collection().insertOne).toHaveBeenCalledWith({
email,
password: 'hashedPassword',
created_at: expect.any(Date),
});
expect(Folders.create).toHaveBeenCalledWith('Dossier par Défaut', expect.any(String));
expect(result._id).toBeDefined(); // Ensure result has _id
});
// it('should update the user password', async () => {
// db.collection().updateOne.mockResolvedValue({ modifiedCount: 1 });
// bcrypt.hash.mockResolvedValue('hashedPassword');
// const email = 'test@example.com';
// const newPassword = 'newPassword123';
// const result = await users.updatePassword(email, newPassword);
// expect(db.connect).toHaveBeenCalled();
// expect(db.collection().updateOne).toHaveBeenCalledWith(
// { email },
// { $set: { password: 'hashedPassword' } }
// );
// expect(result).toEqual(newPassword);
// });
// it('should delete a user', async () => {
// db.collection().deleteOne.mockResolvedValue({ deletedCount: 1 });
// const email = 'test@example.com';
// const result = await users.delete(email);
// expect(db.connect).toHaveBeenCalled();
// expect(db.collection().deleteOne).toHaveBeenCalledWith({ email });
// expect(result).toBe(true);
// });
// Add more tests as needed
});

View file

@ -1,12 +1,18 @@
const emailer = require('../config/email.js'); const emailer = require('../config/email.js');
const model = require('../models/users.js'); const model = require('../models/users.js');
const jwt = require('../middleware/jwtToken.js'); const jwt = require('../middleware/jwtToken.js');
const db = require('../config/db.js');
const AppError = require('../middleware/AppError.js'); const AppError = require('../middleware/AppError.js');
const { MISSING_REQUIRED_PARAMETER, LOGIN_CREDENTIALS_ERROR, GENERATE_PASSWORD_ERROR, UPDATE_PASSWORD_ERROR, DELETE_USER_ERROR } = require('../constants/errorCodes'); const { MISSING_REQUIRED_PARAMETER, LOGIN_CREDENTIALS_ERROR, GENERATE_PASSWORD_ERROR, UPDATE_PASSWORD_ERROR, DELETE_USER_ERROR } = require('../constants/errorCodes');
class UsersController { class UsersController {
constructor() {
this.db = db;
this.users = new model(this.db);
}
async register(req, res, next) { async register(req, res, next) {
try { try {
const { email, password } = req.body; const { email, password } = req.body;
@ -143,4 +149,4 @@ class UsersController {
} }
module.exports = new UsersController; module.exports = new UsersController;

View file

@ -1,11 +1,15 @@
//user //user
const db = require('../config/db.js'); // const db = require('../config/db.js');
const bcrypt = require('bcrypt'); const bcrypt = require('bcrypt');
const AppError = require('../middleware/AppError.js'); const AppError = require('../middleware/AppError.js');
const { USER_ALREADY_EXISTS } = require('../constants/errorCodes'); const { USER_ALREADY_EXISTS } = require('../constants/errorCodes');
const Folders = require('../models/folders.js'); const Folders = require('../models/folders.js');
class Users { class Users {
constructor(db) {
console.log("Users constructor: db", db)
this.db = db;
}
async hashPassword(password) { async hashPassword(password) {
return await bcrypt.hash(password, 10) return await bcrypt.hash(password, 10)
@ -20,8 +24,8 @@ class Users {
} }
async register(email, password) { async register(email, password) {
await db.connect() await this.db.connect()
const conn = db.getConnection(); const conn = this.db.getConnection();
const userCollection = conn.collection('users'); const userCollection = conn.collection('users');
@ -37,18 +41,18 @@ class Users {
created_at: new Date() created_at: new Date()
}; };
await userCollection.insertOne(newUser); const result = await userCollection.insertOne(newUser);
const userId = result._id.toString();
const folderTitle = 'Dossier par Défaut'; const folderTitle = 'Dossier par Défaut';
const userId = newUser._id.toString();
await Folders.create(folderTitle, userId); await Folders.create(folderTitle, userId);
// TODO: verif if inserted properly... return result;
} }
async login(email, password) { async login(email, password) {
await db.connect() await this.db.connect()
const conn = db.getConnection(); const conn = this.db.getConnection();
const userCollection = conn.collection('users'); const userCollection = conn.collection('users');
@ -74,8 +78,8 @@ class Users {
} }
async changePassword(email, newPassword) { async changePassword(email, newPassword) {
await db.connect() await this.db.connect()
const conn = db.getConnection(); const conn = this.db.getConnection();
const userCollection = conn.collection('users'); const userCollection = conn.collection('users');
@ -89,8 +93,8 @@ class Users {
} }
async delete(email) { async delete(email) {
await db.connect() await this.db.connect()
const conn = db.getConnection(); const conn = this.db.getConnection();
const userCollection = conn.collection('users'); const userCollection = conn.collection('users');
@ -102,8 +106,8 @@ class Users {
} }
async getId(email) { async getId(email) {
await db.connect() await this.db.connect()
const conn = db.getConnection(); const conn = this.db.getConnection();
const userCollection = conn.collection('users'); const userCollection = conn.collection('users');
@ -118,4 +122,4 @@ class Users {
} }
module.exports = new Users; module.exports = Users;

View file

@ -22,6 +22,7 @@
}, },
"devDependencies": { "devDependencies": {
"jest": "^29.7.0", "jest": "^29.7.0",
"jest-mock": "^29.7.0",
"nodemon": "^3.0.1", "nodemon": "^3.0.1",
"supertest": "^6.3.4" "supertest": "^6.3.4"
}, },

View file

@ -7,7 +7,7 @@
"build": "webpack --config webpack.config.js", "build": "webpack --config webpack.config.js",
"start": "node app.js", "start": "node app.js",
"dev": "nodemon app.js", "dev": "nodemon app.js",
"test": "jest" "test": "jest --colors"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "",
@ -26,6 +26,7 @@
}, },
"devDependencies": { "devDependencies": {
"jest": "^29.7.0", "jest": "^29.7.0",
"jest-mock": "^29.7.0",
"nodemon": "^3.0.1", "nodemon": "^3.0.1",
"supertest": "^6.3.4" "supertest": "^6.3.4"
}, },