const request = require('supertest'); const express = require('express'); const authRoutes = require('../../routes/auth'); const User = require('../../models/User'); const { createTestUser } = require('../utils/testHelpers'); // Create Express app for testing const app = express(); app.use(express.json()); app.use('/api/auth', authRoutes); describe('Auth Routes', () => { describe('POST /api/auth/register', () => { it('should register a new user and return a token', async () => { const userData = { name: 'John Doe', email: 'john@example.com', password: 'password123', }; const response = await request(app) .post('/api/auth/register') .send(userData) .expect(200); expect(response.body).toHaveProperty('token'); expect(typeof response.body.token).toBe('string'); // Verify user was created in database const user = await User.findOne({ email: userData.email }); expect(user).toBeTruthy(); expect(user.name).toBe(userData.name); expect(user.email).toBe(userData.email); expect(user.password).not.toBe(userData.password); // Password should be hashed }); it('should not register a user with an existing email', async () => { // Create a user first await createTestUser({ email: 'existing@example.com' }); const userData = { name: 'Jane Doe', email: 'existing@example.com', password: 'password123', }; const response = await request(app) .post('/api/auth/register') .send(userData) .expect(400); expect(response.body).toHaveProperty('msg', 'User already exists'); }); it('should handle missing required fields', async () => { const response = await request(app) .post('/api/auth/register') .send({ email: 'test@example.com' }) .expect(500); expect(response.body).toBeDefined(); }); }); describe('POST /api/auth/login', () => { beforeEach(async () => { // Create a test user before each login test await createTestUser({ email: 'login@example.com', password: 'password123', }); }); it('should login with valid credentials and return a token', async () => { const loginData = { email: 'login@example.com', password: 'password123', }; const response = await request(app) .post('/api/auth/login') .send(loginData) .expect(200); expect(response.body).toHaveProperty('token'); expect(typeof response.body.token).toBe('string'); }); it('should not login with invalid email', async () => { const loginData = { email: 'nonexistent@example.com', password: 'password123', }; const response = await request(app) .post('/api/auth/login') .send(loginData) .expect(400); expect(response.body).toHaveProperty('msg', 'Invalid credentials'); }); it('should not login with invalid password', async () => { const loginData = { email: 'login@example.com', password: 'wrongpassword', }; const response = await request(app) .post('/api/auth/login') .send(loginData) .expect(400); expect(response.body).toHaveProperty('msg', 'Invalid credentials'); }); it('should handle missing email or password', async () => { const response = await request(app) .post('/api/auth/login') .send({ email: 'test@example.com' }) .expect(500); expect(response.body).toBeDefined(); }); }); describe('GET /api/auth', () => { it('should get authenticated user with valid token', async () => { const { user, token } = await createTestUser(); const response = await request(app) .get('/api/auth') .set('x-auth-token', token) .expect(200); expect(response.body).toHaveProperty('_id', user.id); expect(response.body).toHaveProperty('name', user.name); expect(response.body).toHaveProperty('email', user.email); expect(response.body).not.toHaveProperty('password'); }); it('should reject request without token', async () => { const response = await request(app) .get('/api/auth') .expect(401); expect(response.body).toHaveProperty('msg', 'No token, authorization denied'); }); it('should reject request with invalid token', async () => { const response = await request(app) .get('/api/auth') .set('x-auth-token', 'invalid-token') .expect(401); expect(response.body).toHaveProperty('msg', 'Token is not valid'); }); }); });