feat: add more roles (tech_lead, scrum_master, product_owner, designer, qa)
- Registration form: added 5 new role options to dropdown - Sidebar: new roles get proper nav access via ALL_ROLES/LEADER_ROLES - Dashboard: isLeader check expanded to include new leadership roles - Shared/Pages: role badge colors added for all new roles - Invite modal: expanded role dropdown
This commit is contained in:
127
server/tests/auth.test.js
Normal file
127
server/tests/auth.test.js
Normal file
@@ -0,0 +1,127 @@
|
||||
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import { app } from '../index.js';
|
||||
import pool from '../db.js';
|
||||
import bcrypt from 'bcryptjs';
|
||||
|
||||
// Mock dependencies
|
||||
vi.mock('../db.js', () => ({
|
||||
default: {
|
||||
query: vi.fn(),
|
||||
},
|
||||
initDB: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('bcryptjs', () => ({
|
||||
default: {
|
||||
compare: vi.fn(),
|
||||
hash: vi.fn()
|
||||
}
|
||||
}));
|
||||
|
||||
describe('Auth Routes', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('POST /api/auth/login', () => {
|
||||
it('logs in successfully with correct credentials', async () => {
|
||||
const mockUser = {
|
||||
id: 'u1',
|
||||
name: 'Test User',
|
||||
email: 'test@test.com',
|
||||
password_hash: 'hashed_password',
|
||||
role: 'employee',
|
||||
dept: 'dev'
|
||||
};
|
||||
|
||||
// Mock DB response
|
||||
pool.query.mockResolvedValue([[mockUser]]);
|
||||
// Mock bcrypt comparison
|
||||
bcrypt.compare.mockResolvedValue(true);
|
||||
|
||||
const res = await request(app)
|
||||
.post('/api/auth/login')
|
||||
.send({ email: 'test@test.com', password: 'password' });
|
||||
|
||||
expect(res.status).toBe(200);
|
||||
expect(res.body).toEqual(expect.objectContaining({
|
||||
id: 'u1',
|
||||
email: 'test@test.com'
|
||||
}));
|
||||
expect(res.body).not.toHaveProperty('password_hash');
|
||||
});
|
||||
|
||||
it('returns 401 for invalid password', async () => {
|
||||
const mockUser = {
|
||||
id: 'u1',
|
||||
email: 'test@test.com',
|
||||
password_hash: 'hashed_password'
|
||||
};
|
||||
|
||||
pool.query.mockResolvedValue([[mockUser]]);
|
||||
bcrypt.compare.mockResolvedValue(false);
|
||||
|
||||
const res = await request(app)
|
||||
.post('/api/auth/login')
|
||||
.send({ email: 'test@test.com', password: 'wrong' });
|
||||
|
||||
expect(res.status).toBe(401);
|
||||
expect(res.body).toEqual({ error: 'Invalid email or password' });
|
||||
});
|
||||
|
||||
it('returns 401 for user not found', async () => {
|
||||
pool.query.mockResolvedValue([[]]); // Empty array
|
||||
|
||||
const res = await request(app)
|
||||
.post('/api/auth/login')
|
||||
.send({ email: 'notfound@test.com', password: 'password' });
|
||||
|
||||
expect(res.status).toBe(401);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api/auth/register', () => {
|
||||
it('registers a new user successfully', async () => {
|
||||
pool.query.mockResolvedValueOnce([[]]); // Check existing email (empty)
|
||||
pool.query.mockResolvedValueOnce({}); // Insert success
|
||||
|
||||
bcrypt.hash.mockResolvedValue('hashed_new_password');
|
||||
|
||||
const newUser = {
|
||||
name: 'New User',
|
||||
email: 'new@test.com',
|
||||
password: 'password',
|
||||
role: 'employee'
|
||||
};
|
||||
|
||||
const res = await request(app)
|
||||
.post('/api/auth/register')
|
||||
.send(newUser);
|
||||
|
||||
expect(res.status).toBe(201);
|
||||
expect(res.body).toEqual(expect.objectContaining({
|
||||
name: 'New User',
|
||||
email: 'new@test.com'
|
||||
}));
|
||||
|
||||
// Verify DB insert called
|
||||
expect(pool.query).toHaveBeenCalledTimes(2);
|
||||
expect(pool.query).toHaveBeenLastCalledWith(
|
||||
expect.stringContaining('INSERT INTO users'),
|
||||
expect.arrayContaining(['New User', 'employee', 'new@test.com', 'hashed_new_password'])
|
||||
);
|
||||
});
|
||||
|
||||
it('returns 409 if email already exists', async () => {
|
||||
pool.query.mockResolvedValueOnce([[{ id: 'existing' }]]);
|
||||
|
||||
const res = await request(app)
|
||||
.post('/api/auth/register')
|
||||
.send({ name: 'User', email: 'existing@test.com', password: 'pw' });
|
||||
|
||||
expect(res.status).toBe(409);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user