Spaces:
Running
Running
| // 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)); | |
| } | |
| }); | |