tinfo-web-server / test /errorLogRoutes.test.js
Faridaqurr
initial backend
e8c33fa
Raw
History Blame Contribute Delete
6.59 kB
// server/test/errorLogRoutes.test.js
const test = require('node:test');
const assert = require('node:assert/strict');
const http = require('node:http');
require('dotenv').config();
// ─── Helpers ────────────────────────────────────────────────────────────────
function httpRequest(server, options, body) {
return new Promise((resolve, reject) => {
const addr = server.address();
const req = http.request(
{ host: '127.0.0.1', port: addr.port, ...options },
(res) => {
let data = '';
res.on('data', (chunk) => { data += chunk; });
res.on('end', () => {
try {
resolve({ status: res.statusCode, body: JSON.parse(data) });
} catch {
resolve({ status: res.statusCode, body: data });
}
});
}
);
req.on('error', reject);
if (body) {
req.setHeader('Content-Type', 'application/json');
req.write(JSON.stringify(body));
}
req.end();
});
}
function startTestServer() {
// Fresh copies each run so module-level state is clean
delete require.cache[require.resolve('../utils/errorLogger')];
delete require.cache[require.resolve('../controllers/errorLogController')];
delete require.cache[require.resolve('../routes/errorLogRoutes')];
const express = require('express');
const cookieParser = require('cookie-parser');
const { protect, adminOnly } = require('../middleware/authMiddleware');
const { getErrorLogs, clearErrorLogs } = require('../controllers/errorLogController');
const app = express();
app.use(express.json());
app.use(cookieParser());
app.get('/api/admin/errors', protect, adminOnly, getErrorLogs);
app.delete('/api/admin/errors', protect, adminOnly, clearErrorLogs);
const server = http.createServer(app);
return new Promise((resolve) => server.listen(0, '127.0.0.1', () => resolve(server)));
}
function makeAdminToken() {
const jwt = require('jsonwebtoken');
const { env } = require('../configs/env');
return jwt.sign(
{ id: '507f1f77bcf86cd799439011' },
env.jwtSecret || 'test-secret-32-characters-minimum!!',
{ expiresIn: '1h' }
);
}
function mockAdminUser(role = 'admin') {
const AdminUser = require('../models/AdminUser');
const original = AdminUser.findById.bind(AdminUser);
AdminUser.findById = () => ({
select: () => ({
lean: async () => ({
_id: '507f1f77bcf86cd799439011',
username: 'testadmin',
role,
isActive: true,
}),
}),
});
return () => { AdminUser.findById = original; };
}
// ─── Tests ───────────────────────────────────────────────────────────────────
test('GET /api/admin/errors returns paginated error log shape', async () => {
const server = await startTestServer();
const restore = mockAdminUser('admin');
const token = makeAdminToken();
try {
const { logError } = require('../utils/errorLogger');
logError(new Error('test error for GET'));
const result = await httpRequest(server, {
path: '/api/admin/errors?page=1&pageSize=10',
method: 'GET',
headers: { Cookie: `token=${token}` },
});
assert.equal(result.status, 200);
assert.equal(result.body.success, true);
assert.ok(Array.isArray(result.body.items), 'items must be an array');
assert.ok(typeof result.body.total === 'number', 'total must be a number');
assert.ok(typeof result.body.page === 'number', 'page must be a number');
assert.ok(typeof result.body.pageSize === 'number', 'pageSize must be a number');
assert.ok(typeof result.body.totalPages === 'number', 'totalPages must be a number');
} finally {
restore();
await new Promise((r) => server.close(r));
}
});
test('GET /api/admin/errors returns 401 with no token', async () => {
const server = await startTestServer();
try {
const result = await httpRequest(server, {
path: '/api/admin/errors',
method: 'GET',
});
assert.equal(result.status, 401);
} finally {
await new Promise((r) => server.close(r));
}
});
test('GET /api/admin/errors returns 403 for non-admin role', async () => {
const server = await startTestServer();
const restore = mockAdminUser('viewer');
const token = makeAdminToken();
try {
const result = await httpRequest(server, {
path: '/api/admin/errors',
method: 'GET',
headers: { Cookie: `token=${token}` },
});
assert.equal(result.status, 403);
} finally {
restore();
await new Promise((r) => server.close(r));
}
});
test('DELETE /api/admin/errors clears the memory buffer', async () => {
const server = await startTestServer();
const restore = mockAdminUser('admin');
const token = makeAdminToken();
try {
const { logError } = require('../utils/errorLogger');
logError(new Error('error before clear'));
const deleteResult = await httpRequest(server, {
path: '/api/admin/errors',
method: 'DELETE',
headers: { Cookie: `token=${token}` },
});
assert.equal(deleteResult.status, 200);
assert.equal(deleteResult.body.success, true);
assert.equal(deleteResult.body.cleared, true);
const getResult = await httpRequest(server, {
path: '/api/admin/errors?page=1&pageSize=10',
method: 'GET',
headers: { Cookie: `token=${token}` },
});
assert.equal(getResult.body.total, 0);
assert.deepEqual(getResult.body.items, []);
} finally {
restore();
await new Promise((r) => server.close(r));
}
});
test('DELETE /api/admin/errors returns 401 with no token', async () => {
const server = await startTestServer();
try {
const result = await httpRequest(server, {
path: '/api/admin/errors',
method: 'DELETE',
});
assert.equal(result.status, 401);
} finally {
await new Promise((r) => server.close(r));
}
});
test('DELETE /api/admin/errors returns 403 for non-admin role', async () => {
const server = await startTestServer();
const restore = mockAdminUser('viewer');
const token = makeAdminToken();
try {
const result = await httpRequest(server, {
path: '/api/admin/errors',
method: 'DELETE',
headers: { Cookie: `token=${token}` },
});
assert.equal(result.status, 403);
} finally {
restore();
await new Promise((r) => server.close(r));
}
});