221 lines
7.1 KiB
JavaScript
221 lines
7.1 KiB
JavaScript
'use strict';
|
||
|
||
/**
|
||
* Integration tests – dlq controller (controllers/dlq.js)
|
||
*
|
||
* The dlq controller connects to RabbitMQ for most of its functionality.
|
||
* Tests here focus on pure input-validation paths that call next() with an
|
||
* error before any RabbitMQ or Management-API call is made, plus DB-backed
|
||
* partner paths (tracker stats, archive) that only require MongoDB.
|
||
*/
|
||
|
||
const { connectDB, disconnectDB } = require('./jest.setup');
|
||
const { mockReq, mockRes, newId } = require('./mock_data');
|
||
|
||
let PartnerLogTracker;
|
||
|
||
beforeAll(async () => {
|
||
await connectDB();
|
||
PartnerLogTracker = require('../../model/partner_log_tracker');
|
||
});
|
||
|
||
afterAll(async () => {
|
||
await disconnectDB();
|
||
});
|
||
|
||
const dlqCtl = require('../../controllers/dlq');
|
||
|
||
// Helper: build a req with params and/or body.
|
||
function makeReq({ params = {}, body = {}, query = {} } = {}) {
|
||
const req = mockReq({ body, query });
|
||
req.params = params;
|
||
return req;
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------
|
||
describe('dlq controller – getDLQStats_get', () => {
|
||
it('calls next() when queueName param is missing', async () => {
|
||
const req = makeReq({ params: {} });
|
||
const res = mockRes();
|
||
const next = jest.fn();
|
||
|
||
await dlqCtl.getDLQStats_get(req, res, next);
|
||
|
||
expect(next).toHaveBeenCalled();
|
||
expect(res.json).not.toHaveBeenCalled();
|
||
});
|
||
|
||
it('returns stats with a numeric messageCount for a non-partner queue', async () => {
|
||
const req = makeReq({ params: { queueName: 'dev_jobs' } });
|
||
const res = mockRes();
|
||
const next = jest.fn();
|
||
|
||
await dlqCtl.getDLQStats_get(req, res, next);
|
||
|
||
// Either RabbitMQ is reachable (messageCount >= 0) or not (-1); the
|
||
// response shape is always the same.
|
||
expect(res.json).toHaveBeenCalled();
|
||
expect(res._data).toHaveProperty('dlq');
|
||
expect(typeof res._data.dlq.messageCount).toBe('number');
|
||
expect(res._data.trackers).toBeUndefined();
|
||
});
|
||
|
||
it('returns stats with tracker data for a partner queue (DB is reachable)', async () => {
|
||
await PartnerLogTracker.deleteMany({});
|
||
const req = makeReq({ params: { queueName: 'partner_tasks' } });
|
||
const res = mockRes();
|
||
const next = jest.fn();
|
||
|
||
await dlqCtl.getDLQStats_get(req, res, next);
|
||
|
||
expect(res.json).toHaveBeenCalled();
|
||
expect(res._data).toHaveProperty('dlq');
|
||
// Partner queue: tracker stats and recent failures are always included.
|
||
expect(res._data.trackers).toBeDefined();
|
||
expect(res._data.recentFailures).toBeDefined();
|
||
expect(Array.isArray(res._data.recentFailures)).toBe(true);
|
||
});
|
||
});
|
||
|
||
// ---------------------------------------------------------------------------
|
||
describe('dlq controller – getDLQMessages_get', () => {
|
||
it('throws when queueName param is missing', async () => {
|
||
const req = makeReq({ params: {} });
|
||
const res = mockRes();
|
||
const next = jest.fn();
|
||
|
||
await expect(dlqCtl.getDLQMessages_get(req, res, next)).rejects.toThrow();
|
||
});
|
||
});
|
||
|
||
// ---------------------------------------------------------------------------
|
||
describe('dlq controller – processDLQ_post', () => {
|
||
it('calls next() when queueName param is missing', async () => {
|
||
const req = makeReq({ params: {}, body: {} });
|
||
const res = mockRes();
|
||
const next = jest.fn();
|
||
|
||
await dlqCtl.processDLQ_post(req, res, next);
|
||
|
||
expect(next).toHaveBeenCalled();
|
||
});
|
||
});
|
||
|
||
// ---------------------------------------------------------------------------
|
||
describe('dlq controller – retryFailedTask_post', () => {
|
||
it('calls next() when queueName is not a partner queue', async () => {
|
||
const req = makeReq({ params: { queueName: 'dev_jobs', id: newId().toString() } });
|
||
const res = mockRes();
|
||
const next = jest.fn();
|
||
|
||
await dlqCtl.retryFailedTask_post(req, res, next);
|
||
|
||
expect(next).toHaveBeenCalled();
|
||
});
|
||
|
||
it('calls next() when tracker id does not exist in the DB', async () => {
|
||
const req = makeReq({ params: { queueName: 'partner_tasks', id: newId().toString() } });
|
||
const res = mockRes();
|
||
const next = jest.fn();
|
||
|
||
await dlqCtl.retryFailedTask_post(req, res, next);
|
||
|
||
expect(next).toHaveBeenCalled();
|
||
});
|
||
});
|
||
|
||
// ---------------------------------------------------------------------------
|
||
describe('dlq controller – archiveFailedTask_post', () => {
|
||
it('calls next() when tracker id does not exist', async () => {
|
||
const req = makeReq({ params: { id: newId().toString() }, body: { reason: 'test' } });
|
||
const res = mockRes();
|
||
const next = jest.fn();
|
||
|
||
await dlqCtl.archiveFailedTask_post(req, res, next);
|
||
|
||
expect(next).toHaveBeenCalled();
|
||
});
|
||
});
|
||
|
||
// ---------------------------------------------------------------------------
|
||
describe('dlq controller – purgeDLQ_delete', () => {
|
||
it('calls next() when confirm is not true', async () => {
|
||
const req = makeReq({ params: { queueName: 'dev_jobs' }, body: { confirm: false } });
|
||
const res = mockRes();
|
||
const next = jest.fn();
|
||
|
||
await dlqCtl.purgeDLQ_delete(req, res, next);
|
||
|
||
expect(next).toHaveBeenCalled();
|
||
});
|
||
|
||
it('calls next() when queueName param is missing', async () => {
|
||
const req = makeReq({ params: {}, body: { confirm: true } });
|
||
const res = mockRes();
|
||
const next = jest.fn();
|
||
|
||
await dlqCtl.purgeDLQ_delete(req, res, next);
|
||
|
||
expect(next).toHaveBeenCalled();
|
||
});
|
||
});
|
||
|
||
// ---------------------------------------------------------------------------
|
||
describe('dlq controller – retryAllDLQ_post', () => {
|
||
it('calls next() when queueName param is missing', async () => {
|
||
const req = makeReq({ params: {}, body: {} });
|
||
const res = mockRes();
|
||
const next = jest.fn();
|
||
|
||
await dlqCtl.retryAllDLQ_post(req, res, next);
|
||
|
||
expect(next).toHaveBeenCalled();
|
||
});
|
||
});
|
||
|
||
// ---------------------------------------------------------------------------
|
||
describe('dlq controller – retryDLQByPosition_post', () => {
|
||
it('calls next() when position is missing from body', async () => {
|
||
const req = makeReq({ params: { queueName: 'dev_jobs' }, body: {} });
|
||
const res = mockRes();
|
||
const next = jest.fn();
|
||
|
||
await dlqCtl.retryDLQByPosition_post(req, res, next);
|
||
|
||
expect(next).toHaveBeenCalled();
|
||
});
|
||
|
||
it('calls next() when position is negative', async () => {
|
||
const req = makeReq({ params: { queueName: 'dev_jobs' }, body: { position: -1 } });
|
||
const res = mockRes();
|
||
const next = jest.fn();
|
||
|
||
await dlqCtl.retryDLQByPosition_post(req, res, next);
|
||
|
||
expect(next).toHaveBeenCalled();
|
||
});
|
||
});
|
||
|
||
// ---------------------------------------------------------------------------
|
||
describe('dlq controller – retryDLQByHeader_post', () => {
|
||
it('calls next() when headerName is missing', async () => {
|
||
const req = makeReq({ params: { queueName: 'dev_jobs' }, body: { headerValue: 'val' } });
|
||
const res = mockRes();
|
||
const next = jest.fn();
|
||
|
||
await dlqCtl.retryDLQByHeader_post(req, res, next);
|
||
|
||
expect(next).toHaveBeenCalled();
|
||
});
|
||
|
||
it('calls next() when headerValue is missing', async () => {
|
||
const req = makeReq({ params: { queueName: 'dev_jobs' }, body: { headerName: 'x-id' } });
|
||
const res = mockRes();
|
||
const next = jest.fn();
|
||
|
||
await dlqCtl.retryDLQByHeader_post(req, res, next);
|
||
|
||
expect(next).toHaveBeenCalled();
|
||
});
|
||
});
|