diff --git a/webiu-server/__tests__/authController.test.js b/webiu-server/__tests__/authController.test.js index 1517edfc..426edf94 100644 --- a/webiu-server/__tests__/authController.test.js +++ b/webiu-server/__tests__/authController.test.js @@ -1,9 +1,12 @@ const request = require('supertest'); const express = require('express'); const User = require('../models/User'); +const { sendVerificationEmail } = require('../services/emailServices'); const { signToken } = require('../utils/jwt'); +const crypto = require('crypto'); const authController = require('../controllers/authController'); +jest.mock('../services/emailServices'); // Mock email service jest.mock('../utils/jwt', () => ({ signToken: jest.fn().mockReturnValue('mockedToken'), })); @@ -12,43 +15,14 @@ const app = express(); app.use(express.json()); app.post('/register', authController.register); app.post('/login', authController.login); +app.get('/verify-email', authController.verifyEmail); // GET method to verify email describe('Auth Controller Tests', () => { beforeEach(() => { - jest.clearAllMocks(); - }); - - // Test successful user registration - it('should register a user successfully', async () => { - const mockUser = { - _id: '60d6f96a9b1f8f001c8f27c5', - name: 'John Doe', - email: 'johndoe@example.com', - password: 'password123', - }; - - User.findOne = jest.fn().mockResolvedValue(null); - User.prototype.save = jest.fn().mockResolvedValue(mockUser); - - const response = await request(app).post('/register').send({ - name: 'John Doe', - email: 'johndoe@example.com', - password: 'password123', - confirmPassword: 'password123', - }); - - response.body.data.user.id = mockUser._id; - - expect(response.status).toBe(201); - expect(response.body.status).toBe('success'); - expect(response.body.data.user).toEqual({ - id: mockUser._id, - name: mockUser.name, - email: mockUser.email, - }); - expect(response.body.data.token).toBe('mockedToken'); + jest.clearAllMocks(); // Clear mocks before each test }); + // Test failed user registration - email already exists it('should return an error when email already exists during registration', async () => { const mockUser = { @@ -86,6 +60,21 @@ describe('Auth Controller Tests', () => { expect(response.body.message).toBe('Passwords do not match'); }); + // Test failed user registration - invalid email format + it('should return an error for invalid email format during registration', async () => { + const response = await request(app).post('/register').send({ + name: 'John Doe', + email: 'invalid-email', + password: 'password123', + confirmPassword: 'password123', + }); + + expect(response.status).toBe(400); + expect(response.body.status).toBe('error'); + expect(response.body.message).toBe('Invalid email format'); + }); + + // Test successful user login it('should login a user successfully', async () => { const mockUser = { @@ -94,6 +83,7 @@ describe('Auth Controller Tests', () => { password: 'password123', matchPassword: jest.fn().mockResolvedValue(true), githubId: 'john-github', + isVerified: true, }; User.findOne = jest.fn().mockResolvedValue(mockUser); @@ -105,6 +95,7 @@ describe('Auth Controller Tests', () => { expect(response.status).toBe(200); expect(response.body.status).toBe('success'); + expect(response.body.message).toBe('Login successful'); expect(response.body.data.user).toEqual({ id: mockUser._id, name: mockUser.name, @@ -120,7 +111,7 @@ describe('Auth Controller Tests', () => { _id: '60d6f96a9b1f8f001c8f27c5', email: 'johndoe@example.com', password: 'password123', - matchPassword: jest.fn().mockResolvedValue(false), + matchPassword: jest.fn().mockResolvedValue(false), }; User.findOne = jest.fn().mockResolvedValue(mockUser); @@ -137,7 +128,7 @@ describe('Auth Controller Tests', () => { // Test failed user login - user not found it('should return an error if user is not found during login', async () => { - User.findOne = jest.fn().mockResolvedValue(null); + User.findOne = jest.fn().mockResolvedValue(null); const response = await request(app).post('/login').send({ email: 'nonexistentuser@example.com', @@ -149,28 +140,25 @@ describe('Auth Controller Tests', () => { expect(response.body.message).toBe('User not found'); }); - // Test failed user registration - invalid email format - it('should return an error for invalid email format during registration', async () => { - const response = await request(app).post('/register').send({ - name: 'John Doe', - email: 'invalid-email', + // Test failed user login - email not verified + it('should return an error if email is not verified during login', async () => { + const mockUser = { + _id: '60d6f96a9b1f8f001c8f27c5', + email: 'johndoe@example.com', password: 'password123', - confirmPassword: 'password123', - }); + matchPassword: jest.fn().mockResolvedValue(true), + isVerified: false, + }; - expect(response.status).toBe(400); - expect(response.body.status).toBe('error'); - expect(response.body.message).toBe('Invalid email format'); - }); + User.findOne = jest.fn().mockResolvedValue(mockUser); - // Test failed user login - missing fields - it('should return an error if required fields are missing during login', async () => { const response = await request(app).post('/login').send({ - email: 'johndoe@example.com', + email: 'johndoe@example.com', + password: 'password123', }); expect(response.status).toBe(401); expect(response.body.status).toBe('error'); - expect(response.body.message).toBe('User not found'); + expect(response.body.message).toBe('Please verify your email to login'); }); }); diff --git a/webiu-server/package-lock.json b/webiu-server/package-lock.json index 3fcaf981..7d571de0 100644 --- a/webiu-server/package-lock.json +++ b/webiu-server/package-lock.json @@ -15,10 +15,12 @@ "colors": "^1.4.0", "cookie-parser": "^1.4.6", "cors": "^2.8.5", + "crypto": "^1.0.1", "dotenv": "^16.4.5", "express": "^4.21.1", "jsonwebtoken": "^9.0.2", "mongoose": "^8.8.1", + "nodemailer": "^6.9.16", "nodemon": "^3.1.4", "path": "^0.12.7" }, @@ -2078,6 +2080,13 @@ "node": ">= 8" } }, + "node_modules/crypto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", + "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==", + "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in.", + "license": "ISC" + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -4652,6 +4661,15 @@ "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true }, + "node_modules/nodemailer": { + "version": "6.9.16", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.16.tgz", + "integrity": "sha512-psAuZdTIRN08HKVd/E8ObdV6NO7NTBY3KsC30F7M4H1OnmLCUNaS56FpYxyb26zWLSyYF9Ozch9KYHhHegsiOQ==", + "license": "MIT-0", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/nodemon": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.4.tgz",