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:
120
server/tests/tasks.test.js
Normal file
120
server/tests/tasks.test.js
Normal file
@@ -0,0 +1,120 @@
|
||||
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import { app } from '../index.js';
|
||||
import pool from '../db.js';
|
||||
|
||||
// Mock DB
|
||||
const mockQuery = vi.fn();
|
||||
const mockRelease = vi.fn();
|
||||
const mockCommit = vi.fn();
|
||||
const mockRollback = vi.fn();
|
||||
const mockBeginTransaction = vi.fn();
|
||||
|
||||
vi.mock('../db.js', () => ({
|
||||
default: {
|
||||
query: vi.fn(),
|
||||
getConnection: vi.fn()
|
||||
},
|
||||
initDB: vi.fn()
|
||||
}));
|
||||
|
||||
describe('Task Routes', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
mockQuery.mockReset(); // Important to clear implementations
|
||||
pool.query = mockQuery;
|
||||
pool.getConnection.mockResolvedValue({
|
||||
query: mockQuery,
|
||||
release: mockRelease,
|
||||
beginTransaction: mockBeginTransaction,
|
||||
commit: mockCommit,
|
||||
rollback: mockRollback
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /api/tasks', () => {
|
||||
it('returns list of tasks', async () => {
|
||||
// Mock fetching task IDs
|
||||
mockQuery.mockResolvedValueOnce([[{ id: 't1' }]]);
|
||||
|
||||
// Mock getFullTask queries for 't1'
|
||||
// 1. Task details
|
||||
mockQuery.mockResolvedValueOnce([[{ id: 't1', title: 'Task 1', status: 'todo' }]]); // Task
|
||||
// 2. Subtasks
|
||||
mockQuery.mockResolvedValueOnce([[]]); // Subtasks
|
||||
// 3. Comments
|
||||
mockQuery.mockResolvedValueOnce([[]]); // Comments
|
||||
// 4. Activities
|
||||
mockQuery.mockResolvedValueOnce([[]]); // Activities
|
||||
// 5. Tags
|
||||
mockQuery.mockResolvedValueOnce([[]]); // Tags
|
||||
// 6. Dependencies
|
||||
mockQuery.mockResolvedValueOnce([[]]); // Dependencies
|
||||
|
||||
const res = await request(app).get('/api/tasks');
|
||||
|
||||
expect(res.status).toBe(200);
|
||||
expect(res.body).toHaveLength(1);
|
||||
expect(res.body[0].title).toBe('Task 1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api/tasks', () => {
|
||||
it('creates a new task', async () => {
|
||||
// Mock INSERTs (1: Task, 2: Activities) -> Return {}
|
||||
mockQuery.mockResolvedValueOnce({}); // Insert task
|
||||
mockQuery.mockResolvedValueOnce({}); // Insert activity
|
||||
|
||||
// getFullTask queries (3-8)
|
||||
mockQuery.mockResolvedValueOnce([[{ id: 'new-id', title: 'New Task', status: 'todo' }]]); // Task
|
||||
mockQuery.mockResolvedValueOnce([[]]); // Subtasks
|
||||
mockQuery.mockResolvedValueOnce([[]]); // Comments
|
||||
mockQuery.mockResolvedValueOnce([[]]); // Activities
|
||||
mockQuery.mockResolvedValueOnce([[]]); // Tags
|
||||
mockQuery.mockResolvedValueOnce([[]]); // Deps
|
||||
|
||||
const newTask = {
|
||||
// For getFullTask called at end
|
||||
title: 'New Task',
|
||||
description: 'Desc',
|
||||
status: 'todo'
|
||||
};
|
||||
|
||||
const res = await request(app)
|
||||
.post('/api/tasks')
|
||||
.send(newTask);
|
||||
|
||||
expect(res.status).toBe(201);
|
||||
expect(mockBeginTransaction).toHaveBeenCalled();
|
||||
expect(mockCommit).toHaveBeenCalled();
|
||||
expect(mockRelease).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('rolls back on error', async () => {
|
||||
mockQuery.mockRejectedValue(new Error('DB Error'));
|
||||
|
||||
const res = await request(app)
|
||||
.post('/api/tasks')
|
||||
.send({ title: 'Task' });
|
||||
|
||||
expect(res.status).toBe(500);
|
||||
expect(mockRollback).toHaveBeenCalled();
|
||||
expect(mockRelease).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('DELETE /api/tasks/:id', () => {
|
||||
it('deletes a task', async () => {
|
||||
mockQuery.mockResolvedValue({});
|
||||
|
||||
const res = await request(app).delete('/api/tasks/t1');
|
||||
|
||||
expect(res.status).toBe(200);
|
||||
expect(mockQuery).toHaveBeenCalledWith(
|
||||
expect.stringContaining('DELETE FROM tasks'),
|
||||
['t1']
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user