fix: update tests to pass JWT token for authenticated routes

This commit is contained in:
ikechukwu Elizabeth
2026-05-30 07:55:39 +01:00
parent 88b57420d4
commit 8b2db39f8d
+32 -21
View File
@@ -1,27 +1,32 @@
const request = require('supertest'); const request = require('supertest');
const jwt = require('jsonwebtoken');
// Mock the pg Pool before importing app so no real // Mock pg Pool before importing app so no real
// database connection is attempted during tests // database connection is attempted during tests
jest.mock('pg', () => { jest.mock('pg', () => {
const mPool = { const mPool = { query: jest.fn() };
query: jest.fn(),
};
return { Pool: jest.fn(() => mPool) }; return { Pool: jest.fn(() => mPool) };
}); });
// Mock initDb so the server does not try to create // Mock initDb so the server does not try to create
// the tasks table on startup during tests // tables on startup during tests
jest.mock('./db', () => ({ jest.mock('./db', () => ({
pool: { pool: { query: jest.fn() },
query: jest.fn(),
},
initDb: jest.fn().mockResolvedValue(), initDb: jest.fn().mockResolvedValue(),
})); }));
const { pool } = require('./db'); const { pool } = require('./db');
const app = require('./server'); const app = require('./server');
// Reset all mocks between tests so they don't bleed into each other // Generate a valid test token so authenticated routes pass
const TEST_USER = { id: 1, email: 'test@example.com', name: 'Test User' };
const TEST_TOKEN = jwt.sign(
TEST_USER,
process.env.JWT_SECRET || 'changeme-use-a-real-secret-in-production',
{ expiresIn: '1h' }
);
// Reset all mocks between tests so they do not bleed into each other
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks(); jest.clearAllMocks();
}); });
@@ -37,8 +42,9 @@ describe('Health Check', () => {
describe('Tasks API', () => { describe('Tasks API', () => {
it('GET /api/tasks returns empty array initially', async () => { it('GET /api/tasks returns empty array initially', async () => {
pool.query.mockResolvedValueOnce({ rows: [] }); pool.query.mockResolvedValueOnce({ rows: [] });
const res = await request(app)
const res = await request(app).get('/api/tasks'); .get('/api/tasks')
.set('Authorization', `Bearer ${TEST_TOKEN}`);
expect(res.statusCode).toBe(200); expect(res.statusCode).toBe(200);
expect(Array.isArray(res.body)).toBe(true); expect(Array.isArray(res.body)).toBe(true);
expect(res.body).toHaveLength(0); expect(res.body).toHaveLength(0);
@@ -48,9 +54,9 @@ describe('Tasks API', () => {
pool.query.mockResolvedValueOnce({ pool.query.mockResolvedValueOnce({
rows: [{ id: 1, title: 'Test task', completed: false, created_at: new Date() }], rows: [{ id: 1, title: 'Test task', completed: false, created_at: new Date() }],
}); });
const res = await request(app) const res = await request(app)
.post('/api/tasks') .post('/api/tasks')
.set('Authorization', `Bearer ${TEST_TOKEN}`)
.send({ title: 'Test task' }); .send({ title: 'Test task' });
expect(res.statusCode).toBe(201); expect(res.statusCode).toBe(201);
expect(res.body.title).toBe('Test task'); expect(res.body.title).toBe('Test task');
@@ -60,6 +66,7 @@ describe('Tasks API', () => {
it('POST /api/tasks returns 400 when title is missing', async () => { it('POST /api/tasks returns 400 when title is missing', async () => {
const res = await request(app) const res = await request(app)
.post('/api/tasks') .post('/api/tasks')
.set('Authorization', `Bearer ${TEST_TOKEN}`)
.send({}); .send({});
expect(res.statusCode).toBe(400); expect(res.statusCode).toBe(400);
}); });
@@ -69,30 +76,34 @@ describe('Tasks API', () => {
rowCount: 1, rowCount: 1,
rows: [{ id: 1, title: 'Test task', completed: true, created_at: new Date() }], rows: [{ id: 1, title: 'Test task', completed: true, created_at: new Date() }],
}); });
const res = await request(app)
const res = await request(app).patch('/api/tasks/1'); .patch('/api/tasks/1')
.set('Authorization', `Bearer ${TEST_TOKEN}`);
expect(res.statusCode).toBe(200); expect(res.statusCode).toBe(200);
expect(res.body.completed).toBe(true); expect(res.body.completed).toBe(true);
}); });
it('PATCH /api/tasks/:id returns 404 when task not found', async () => { it('PATCH /api/tasks/:id returns 404 when task not found', async () => {
pool.query.mockResolvedValueOnce({ rowCount: 0, rows: [] }); pool.query.mockResolvedValueOnce({ rowCount: 0, rows: [] });
const res = await request(app)
const res = await request(app).patch('/api/tasks/999'); .patch('/api/tasks/999')
.set('Authorization', `Bearer ${TEST_TOKEN}`);
expect(res.statusCode).toBe(404); expect(res.statusCode).toBe(404);
}); });
it('DELETE /api/tasks/:id deletes a task', async () => { it('DELETE /api/tasks/:id deletes a task', async () => {
pool.query.mockResolvedValueOnce({ rowCount: 1 }); pool.query.mockResolvedValueOnce({ rowCount: 1 });
const res = await request(app)
const res = await request(app).delete('/api/tasks/1'); .delete('/api/tasks/1')
.set('Authorization', `Bearer ${TEST_TOKEN}`);
expect(res.statusCode).toBe(204); expect(res.statusCode).toBe(204);
}); });
it('DELETE /api/tasks/:id returns 404 when task not found', async () => { it('DELETE /api/tasks/:id returns 404 when task not found', async () => {
pool.query.mockResolvedValueOnce({ rowCount: 0 }); pool.query.mockResolvedValueOnce({ rowCount: 0 });
const res = await request(app)
const res = await request(app).delete('/api/tasks/999'); .delete('/api/tasks/999')
.set('Authorization', `Bearer ${TEST_TOKEN}`);
expect(res.statusCode).toBe(404); expect(res.statusCode).toBe(404);
}); });
}); });