yatra-x-admin / __tests__ /auth.controller.test.js
imkrish's picture
Upload folder using huggingface_hub
abdeed6 verified
Raw History Blame Contribute Delete
8.14 kB
'use strict';
/**
* Admin Auth Controller Unit Tests
* Tests for admin authentication endpoints
*/
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
process.env.ADMIN_JWT_SECRET = 'test-secret-for-unit-tests';
// Mock dependencies before requiring the controller
const mockPool = {
query: jest.fn(),
connect: jest.fn(() => ({
query: jest.fn(),
release: jest.fn()
}))
};
jest.mock('../db', () => ({
getPool: jest.fn(() => mockPool)
}));
const authController = require('../controllers/auth.controller');
const { getPool } = require('../db');
describe('Admin Auth Controller', () => {
let mockReq;
let mockRes;
let mockPool;
beforeEach(() => {
mockReq = {
body: {},
user: {}
};
mockRes = {
status: jest.fn().mockReturnThis(),
json: jest.fn().mockReturnThis()
};
mockPool = getPool();
jest.clearAllMocks();
});
describe('register', () => {
it('should register a new admin successfully', async () => {
mockReq.body = {
username: 'admin1',
email: 'admin@example.com',
password: 'SecurePass123!',
name: 'Admin User'
};
// No existing admin
mockPool.query.mockResolvedValueOnce({ rows: [] });
// Insert returns new admin
const newAdmin = {
id: 'admin-id-1',
username: 'admin1',
email: 'admin@example.com',
name: 'Admin User',
permissions: ['all']
};
mockPool.query.mockResolvedValueOnce({ rows: [newAdmin] });
await authController.register(mockReq, mockRes);
expect(mockRes.status).toHaveBeenCalledWith(201);
expect(mockRes.json).toHaveBeenCalledWith(
expect.objectContaining({
admin: expect.objectContaining({
email: 'admin@example.com',
username: 'admin1'
}),
tokens: expect.objectContaining({
accessToken: expect.any(String),
refreshToken: expect.any(String)
})
})
);
});
it('should return 400 if admin already exists by email', async () => {
mockReq.body = {
username: 'newadmin',
email: 'existing@example.com',
password: 'pass123',
name: 'New Admin'
};
mockPool.query.mockResolvedValueOnce({ rows: [{ id: 'existing-id' }] });
await authController.register(mockReq, mockRes);
expect(mockRes.status).toHaveBeenCalledWith(400);
expect(mockRes.json).toHaveBeenCalledWith({ error: 'Admin already exists' });
});
it('should return 400 if admin already exists by username', async () => {
mockReq.body = {
username: 'existingadmin',
email: 'new@example.com',
password: 'pass123',
name: 'New Admin'
};
mockPool.query.mockResolvedValueOnce({ rows: [{ id: 'existing-id' }] });
await authController.register(mockReq, mockRes);
expect(mockRes.status).toHaveBeenCalledWith(400);
expect(mockRes.json).toHaveBeenCalledWith({ error: 'Admin already exists' });
});
it('should return 500 if database is not connected', async () => {
mockReq.body = { username: 'admin', email: 'a@b.com', password: 'pass', name: 'Admin' };
require('../db').getPool.mockReturnValueOnce(null);
await authController.register(mockReq, mockRes);
expect(mockRes.status).toHaveBeenCalledWith(500);
expect(mockRes.json).toHaveBeenCalledWith({ error: 'Database not connected' });
});
it('should return 500 on database error', async () => {
mockReq.body = { username: 'admin', email: 'a@b.com', password: 'pass', name: 'Admin' };
mockPool.query.mockRejectedValueOnce(new Error('DB error'));
await authController.register(mockReq, mockRes);
expect(mockRes.status).toHaveBeenCalledWith(500);
expect(mockRes.json).toHaveBeenCalledWith({ error: 'Failed to register admin' });
});
});
describe('login', () => {
it('should login admin with valid credentials', async () => {
const password = 'SecurePass123!';
const hashedPassword = await bcrypt.hash(password, 12);
mockReq.body = {
email: 'admin@example.com',
password: password
};
const admin = {
id: 'admin-id-1',
username: 'admin1',
email: 'admin@example.com',
password_hash: hashedPassword,
name: 'Admin User',
permissions: ['all']
};
mockPool.query.mockResolvedValueOnce({ rows: [admin] });
await authController.login(mockReq, mockRes);
expect(mockRes.json).toHaveBeenCalledWith(
expect.objectContaining({
admin: expect.objectContaining({
email: 'admin@example.com'
}),
tokens: expect.objectContaining({
accessToken: expect.any(String),
refreshToken: expect.any(String)
})
})
);
// Password hash should be removed from response
expect(mockRes.json.mock.calls[0][0].admin.password_hash).toBeUndefined();
});
it('should return 401 if admin not found', async () => {
mockReq.body = {
email: 'nonexistent@example.com',
password: 'password123'
};
mockPool.query.mockResolvedValueOnce({ rows: [] });
await authController.login(mockReq, mockRes);
expect(mockRes.status).toHaveBeenCalledWith(401);
expect(mockRes.json).toHaveBeenCalledWith({ error: 'Invalid credentials' });
});
it('should return 401 for invalid password', async () => {
mockReq.body = {
email: 'admin@example.com',
password: 'wrongpassword'
};
const admin = {
id: 'admin-id-1',
email: 'admin@example.com',
password_hash: await bcrypt.hash('correctpassword', 12)
};
mockPool.query.mockResolvedValueOnce({ rows: [admin] });
await authController.login(mockReq, mockRes);
expect(mockRes.status).toHaveBeenCalledWith(401);
expect(mockRes.json).toHaveBeenCalledWith({ error: 'Invalid credentials' });
});
it('should return 500 if database is not connected', async () => {
mockReq.body = { email: 'admin@example.com', password: 'pass' };
require('../db').getPool.mockReturnValueOnce(null);
await authController.login(mockReq, mockRes);
expect(mockRes.status).toHaveBeenCalledWith(500);
expect(mockRes.json).toHaveBeenCalledWith({ error: 'Database not connected' });
});
it('should return 500 on database error', async () => {
mockReq.body = { email: 'admin@example.com', password: 'pass' };
mockPool.query.mockRejectedValueOnce(new Error('DB error'));
await authController.login(mockReq, mockRes);
expect(mockRes.status).toHaveBeenCalledWith(500);
expect(mockRes.json).toHaveBeenCalledWith({ error: 'Login failed' });
});
});
describe('getMe', () => {
it('should return current admin profile', async () => {
mockReq.user = { id: 'admin-id-1' };
const admin = {
id: 'admin-id-1',
username: 'admin1',
email: 'admin@example.com',
name: 'Admin User',
permissions: ['all']
};
mockPool.query.mockResolvedValueOnce({ rows: [admin] });
await authController.getMe(mockReq, mockRes);
expect(mockRes.json).toHaveBeenCalledWith({ admin });
});
it('should return 404 if admin not found', async () => {
mockReq.user = { id: 'nonexistent-id' };
mockPool.query.mockResolvedValueOnce({ rows: [] });
await authController.getMe(mockReq, mockRes);
expect(mockRes.status).toHaveBeenCalledWith(404);
expect(mockRes.json).toHaveBeenCalledWith({ error: 'Admin not found' });
});
it('should return 500 on database error', async () => {
mockReq.user = { id: 'admin-id-1' };
mockPool.query.mockRejectedValueOnce(new Error('DB error'));
await authController.getMe(mockReq, mockRes);
expect(mockRes.status).toHaveBeenCalledWith(500);
expect(mockRes.json).toHaveBeenCalledWith({ error: 'Failed to fetch profile' });
});
});
});