Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
247 changes: 247 additions & 0 deletions backend/routers/events.router.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
const express = require('express');

const supertest = require('supertest');
// Mock the Mongoose Event model
jest.mock('../models/event.model', () => ({
Event: {
find: jest.fn(),
},
}));

const { Event } = require('../models/event.model');
//Mock the EventController to isolate router tests router tests fro controller logic
jest.mock('../controllers', () => ({
EventController: {
event_list: jest.fn(),

create: jest.fn(),

event_by_id: jest.fn(),

destroy: jest.fn(),

update: jest.fn(),
},
}));

const { EventController } = require('../controllers');

const eventsRouter = require('./events.router');
//Setup a test application
const testapp = express();

testapp.use(express.json());

testapp.use(express.urlencoded({ extended: false }));

testapp.use('/api/events', eventsRouter);

const request = supertest(testapp);

describe('Unit Tests for events.router.js', () => {
//Mock data
const mockEvent = {
_id: 'event123',

name: 'Test Event',

project: 'projectABC',

date: '2025-01-01T10:00:00Z',
};

const mockEventId = 'event123';

const mockProjectId = 'projectABC';

const mockUpdatedEventData = {
name: 'Updated Test Event Name',
};

afterEach(() => {
jest.clearAllMocks();
});
// Test suite for GET /api/events (event_list)

describe('GET /api/events (event_list)', () => {
it('should call EventController.event_list and return a list of events', async (done) => {
EventController.event_list.mockImplementationOnce((req, res) =>
res.status(200).send([mockEvent]),
);

const response = await request.get('/api/events');

expect(EventController.event_list).toHaveBeenCalledWith(
expect.anything(),

expect.anything(),

expect.anything(),
);

expect(response.status).toBe(200);

expect(response.body).toEqual([mockEvent]);

done();
});
});
// Test suite for POST /api/events (create)
describe('POST /api/events (create)', () => {
it('should call EventController.create and return the created event', async (done) => {
EventController.create.mockImplementationOnce((req, res) => res.status(201).send(mockEvent));

const newEventData = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't really need this object. We could just reuse. mockEvent

name: mockEvent.name,

project: mockEvent.project,

date: mockEvent.date,
};

const response = await request.post('/api/events/').send(newEventData);

expect(EventController.create).toHaveBeenCalledWith(
expect.objectContaining({ body: newEventData }),

expect.anything(),

expect.anything(),
);

expect(response.status).toBe(201);

expect(response.body).toEqual(mockEvent);

done();
});
});
// Test suite for GET /api/events/:EventId (event_by_id)
describe('GET /api/events/:EventId (event_by_id)', () => {
it('should call EventController.event_by_id and return a specific event', async (done) => {
EventController.event_by_id.mockImplementationOnce((req, res) =>
res.status(200).send(mockEvent),
);

const response = await request.get(`/api/events/${mockEventId}`);

expect(EventController.event_by_id).toHaveBeenCalledWith(
expect.objectContaining({ params: { EventId: mockEventId } }),

expect.anything(),

expect.anything(),
);

expect(response.status).toBe(200);

expect(response.body).toEqual(mockEvent);

done();
});
});
// Test suite for DELETE /api/events/:EventId (destroy)
describe('DELETE /api/events/:EventId (destroy)', () => {
it('should call EventController.destroy and return 204 No Content', async (done) => {
EventController.destroy.mockImplementationOnce((req, res) => res.status(204).send());

const response = await request.delete(`/api/events/${mockEventId}`);

expect(EventController.destroy).toHaveBeenCalledWith(
expect.objectContaining({ params: { EventId: mockEventId } }),

expect.anything(),

expect.anything(),
);

expect(response.status).toBe(204);

expect(response.body).toEqual({});

done();
});
});
// Test suite for PATCH /api/events/:EventId (update)
describe('PATCH /api/events/:EventId (update)', () => {
it('should call EventController.update and return the updated event', async (done) => {
EventController.update.mockImplementationOnce((req, res) =>
res.status(200).send({ ...mockEvent, ...mockUpdatedEventData }),
);

const response = await request.patch(`/api/events/${mockEventId}`).send(mockUpdatedEventData);

expect(EventController.update).toHaveBeenCalledWith(
expect.objectContaining({
params: { EventId: mockEventId },

body: mockUpdatedEventData,
}),

expect.anything(),

expect.anything(),
);

expect(response.status).toBe(200);

expect(response.body).toEqual({ ...mockEvent, ...mockUpdatedEventData });

done();
});
});
// Test suite for GET /api/events/nexteventbyproject/:id
describe('GET /api/events/nexteventbyproject/:id', () => {
it('should return the last event for a given project ID directly from the router', async (done) => {
const mockEventsForProject = [
{ _id: 'eventA', project: mockProjectId, name: 'Event A' },

{ _id: 'eventB', project: mockProjectId, name: 'Event B' },

{ _id: 'eventC', project: mockProjectId, name: 'Event C' },
];

Event.find.mockImplementationOnce(() => ({
populate: jest.fn().mockReturnThis(),

then: jest.fn(function (callback) {
return Promise.resolve(callback(mockEventsForProject));
}),

catch: jest.fn(),
}));

const response = await request.get(`/api/events/nexteventbyproject/${mockProjectId}`);

expect(Event.find).toHaveBeenCalledWith({ project: mockProjectId });

expect(Event.find.mock.results[0].value.populate).toHaveBeenCalledWith('project');

expect(response.status).toBe(200);

expect(response.body).toEqual(mockEventsForProject[mockEventsForProject.length - 1]);

done();
});
// Test case for error handling when fetching next event by project
it('should return 500 if an error occurs when fetching next event by project', async (done) => {
const mockError = new Error('Simulated database error for next event by project');

Event.find.mockImplementationOnce(() => ({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please write some comments for this and other sections

populate: jest.fn().mockReturnThis(),

then: jest.fn(() => Promise.reject(mockError)),

catch: jest.fn(function (callback) {
return Promise.resolve(callback(mockError));
}),
}));

const response = await request.get(`/api/events/nexteventbyproject/${mockProjectId}`);

expect(response.status).toBe(500);

done();
});
});
});
Loading