Skip to content

Commit

Permalink
Merge pull request #408 from tcet-opensource/321-crud-endpoints-testc…
Browse files Browse the repository at this point in the history
…ases-apidoc-for-notification

[Mega-Feat]:- Added crud, endpoints, testcases and apidoc for notification model
  • Loading branch information
TejasNair9977 authored Oct 15, 2023
2 parents d8abd45 + bf84d17 commit 6242d5f
Show file tree
Hide file tree
Showing 7 changed files with 367 additions and 0 deletions.
69 changes: 69 additions & 0 deletions _apidoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -1567,6 +1567,75 @@
* @apiSuccess {ObjectId} student.coursesOpted by the student(ObjectId).
*/

// ------------------------------------------------------------------------------------------
// notification
// ------------------------------------------------------------------------------------------

/**
* @api {post} /notification/add Add Notification
* @apiName AddNotification
* @apiGroup Notification
* @apiDescription Adds a new notification to the system.
*
* @apiBody {String} data Notification data.
* @apiBody {String} title Notification title.
* @apiBody {String} from User ID of the sender (Faculty).
* @apiBody {String} type Notification type (Student/Faculty).
* @apiBody {String[]} filter Array of targeted User IDs.
*
* @apiSuccess {String} res Success message with the ID of the added notification.
*
* @apiError (Error 500) DatabaseError Error while inserting in the database.
*
*/

/**
* @api {get} /notification/list Get Notification List
* @apiName GetNotification
* @apiGroup Notification
*
* @apiQuery {String} [from] User ID of the sender (Faculty).
* @apiQuery {String} [type] Notification type (Student/Faculty).
* @apiQuery {String} [title] notification title.
* @apiQuery {String} [data] notification data.
* @apiQuery {String[]} [filter] array of targeted User IDs.
*
* @apiSuccess {Notification[]} res Array of filtered Notification documents.
* @apiSuccess {String} notification._id ID of the document given by the database.
* @apiSuccess {String} notification.data Notification data.
* @apiSuccess {String} notification.title Notification title.
* @apiSuccess {String} notification.from User ID of the sender (Faculty).
* @apiSuccess {String} notification.type Notification type (Student/Faculty).
* @apiSuccess {String[]} notification.filter Array of targeted User IDs.
*/

/**
* @api {delete} /notification/delete/:notificationId Delete Notification
* @apiName DeleteNotification
* @apiGroup Notification
*
* @apiParam {String} notificationId The ID of the notification document to delete.
*
* @apiSuccess {String} res Success message indicating the deletion.
*
* @apiError (Error 500) err Error message if there was an error during the deletion.
*/

/**
* @api {post} /notification/update Update Notification Details
* @apiName UpdateNotification
* @apiGroup Notification
*
* @apiBody {String} id ID of the notification to be updated.
* @apiBody {String} [data] Updated notification data.
* @apiBody {String} [title] Updated notification title.
* @apiBody {String} [from] Updated User ID of the sender (Faculty).
* @apiBody {String} [type] Updated notification type (Student/Faculty).
* @apiBody {String[]} [filter] Updated array of targeted User IDs.
*
* @apiSuccess {String} res Notification updated.
* @apiError (Error 500) err Error in updating the database.
// ------------------------------------------------------------------------------------------
// Topic.
// ------------------------------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import examRouter from "#routes/exam";
import paperRouter from "#routes/paper";
import groupRouter from "#routes/group";
import performarouter from "#routes/performance";
import notificationRouter from "#routes/notification";
import topicRouter from "#routes/topic";

const app = express();
Expand Down Expand Up @@ -69,6 +70,7 @@ app.use("/group", groupRouter);
app.use("/semester", semesterRouter);
app.use("/faculty", facultyRouter);
app.use("/performance", performarouter);
app.use("/notification", notificationRouter);
app.use("/topic",topicRouter);

export default app;
65 changes: 65 additions & 0 deletions controller/notification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import {
createNotification,
deleteNotificationById,
listNotifications,
updateNotificationById,
} from "#services/notification";
import { logger } from "#util";

async function addNotification(req, res) {
const { data, title, type, from, filter } = req.body;
try {
const newNotification = await createNotification({
data,
title,
type,
from,
filter,
});
res.json({
res: `Added notification with ID: ${newNotification.id}`,
id: newNotification.id,
});
} catch (error) {
logger.error("Error while inserting", error);
res.status(500);
res.json({ error: "Error while inserting in DB" });
}
}

async function updateNotification(req, res) {
const { id } = req.params;
const { ...data } = req.body;
try {
await updateNotificationById(id, data);
res.json({ res: `Updated notification with ID: ${id}` });
} catch (error) {
logger.error("Error while updating", error);
res.status(500);
res.json({ error: "Error while updating in DB" });
}
}

async function getNotifications(req, res) {
const filter = req.query;
const notificationList = await listNotifications(filter);
res.json({ res: notificationList });
}

async function deleteNotification(req, res) {
const { id } = req.params;
try {
await deleteNotificationById(id);
res.json({ res: `Deleted notification with ID: ${id}` });
} catch (error) {
logger.error("Error while deleting", error);
res.status(500).json({ error: "Error while deleting from DB" });
}
}

export default {
addNotification,
deleteNotification,
getNotifications,
updateNotification,
};
65 changes: 65 additions & 0 deletions models/notification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import connector from "#models/databaseUtil";

const notificationSchema = {
data: {
type: String,
required: true,
},
title: {
type: String,
required: true,
},
from: {
type: connector.Schema.Types.ObjectId,
ref: "Faculty", // Reference to the Faculty model
required: true,
},
type: {
type: String,
enum: ["Student", "Faculty"],
required: true,
},
filter: [
{
type: connector.Schema.Types.ObjectId,
ref: "User", // You might have a User model for storing IDs
},
],
};

const Notification = connector.model("Notification", notificationSchema);

// CRUD Operations

async function create(notificationData) {
const{
data,title,from,type,filter,
} =notificationData;
const notification=new Notification({
data,title,from,type,filter,
});
const notificationDOC=await notification.save();
return notificationDOC;
}

async function read(filter, limit = 1) {
const notificationDoc = await Notification.find(filter).limit(limit);
return notificationDoc;
}

async function update(filter, updateObject, options = { multi: true }) {
const updateResult = await Notification.updateMany(filter, { $set: updateObject }, options);
return updateResult.acknowledged;
}

async function remove(filter) {
const deleteResult = await Notification.deleteMany(filter);
return deleteResult.acknowledged;
}

export default {
create,
read,
update,
remove,
};
18 changes: 18 additions & 0 deletions routes/notification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import express from "express";
import notificationController from "#controller/notification";

const router = express.Router();

// Create a new Notification
router.post("/add", notificationController.addNotification);

// List Notification entities with optional filters
router.get("/list", notificationController.getNotifications);

// Update Notification entities based on filters and update data
router.post("/update/:id", notificationController.updateNotification);

// Delete Notification entities based on ID
router.delete("/delete/:id", notificationController.deleteNotification);

export default router;
55 changes: 55 additions & 0 deletions services/notification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Import the Notification model
import Notification from "#models/notification";
import databaseError from "#error/database";

// Service function to create a new Notification entity
export async function createNotification({ data, title, type, from, filter }) {
try {
const newNotification = await Notification.create({
data,
title,
type,
from,
filter,
});
return newNotification;
} catch (error) {
throw new databaseError.DataEntryError("notification");
}
}

// Service function to update a Notification entity by ID
export async function updateNotificationById(id, data) {
try {
const updated = await Notification.update({ _id: id }, data);
if (updated) {
return updated;
}
throw new databaseError.DataEntryError("notification");
} catch (error) {
throw new databaseError.DataEntryError("notification");
}
}

// Service function to retrieve a list of Notification entities based on filters
export async function listNotifications(filter) {
try {
const notificationList = await Notification.read(filter);
return notificationList;
} catch (error) {
throw new databaseError.DataEntryError("notification");
}
}

// Service function to delete a Notification entity by ID
export async function deleteNotificationById(notificationId) {
try {
const deleted = await Notification.deleteOne({ _id: notificationId });
if (deleted.deletedCount > 0) {
return deleted;
}
throw new databaseError.DataDeleteError("notification");
} catch (error) {
throw new databaseError.DataDeleteError("notification");
}
}
93 changes: 93 additions & 0 deletions test/routes/notification.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies
import notificationModel from "#models/notification";
import connector from "#models/databaseUtil"; // Import your Express app instance

jest.mock("#util");
const { agent } = global;

function cleanUp(callback) {
notificationModel
.remove({
data: "Sample Notification",
title: "Test Title",
from: "64fc3c8bde9fa947ea1f412f",
type: "Student",
filter: ["64fc3c8bde9fa947ea1f412f"],
})
.then(() => {
connector.disconnect((DBerr) => {
if (DBerr) console.log("database disconnect error: ", DBerr);
callback();
});
});
}

afterAll((done) => {
cleanUp(done);
});

describe("Notification API", () => {
it("should create a new notification", async () => {
const response = await agent.post("/notification/add").send({
data: "Sample Notification",
title: "Test Title",
from: "64fc3c8bde9fa947ea1f412f", // Use a valid Faculty ID
type: "Student",
filter: ["64fc3c8bde9fa947ea1f412f"], // Use a valid User ID
});
expect(response.status).toBe(200);
expect(response.body.res).toMatch(/Added notification/);
const notificationId = JSON.parse(response.res.text).id;
await notificationModel.remove({ _id: notificationId });
});

describe("after adding notification", () => {
let notificationId;
beforeEach(async () => {
const id = await agent.post("/notification/add").send({
data: "Sample Notification",
title: "Test Title",
from: "64fc3c8bde9fa947ea1f412f",
type: "Student",
filter: ["64fc3c8bde9fa947ea1f412f"],
});
notificationId = JSON.parse(id.res.text).id;
});
afterEach(async () => {
await notificationModel.remove({
data: "Sample Notification",
title: "Test Title",
from: "64fc3c8bde9fa947ea1f412f",
type: "Student",
filter: ["64fc3c8bde9fa947ea1f412f"],
});
});

it("should update a notification entity", async () => {
const response = await agent
.post(`/notification/update/${notificationId}`)
.send({
data: "Updated Notification Data",
title: "Updated Title",
from: "64fc3c8bde9fa947ea1f412f",
type: "Faculty",
filter: ["64fc3c8bde9fa947ea1f412f"],
});

expect(response.status).toBe(200);
expect(response.body.res).toMatch(/Updated notification/);
});

it("should list notification entities", async () => {
const response = await agent.get("/notification/list").send({
data: "Sample Notification",
title: "Test Title",
from: "64fc3c8bde9fa947ea1f412f",
type: "Student",
filter: ["64fc3c8bde9fa947ea1f412f"],
});
expect(response.status).toBe(200);
expect(response.body.res).toBeDefined();
});
});
});

0 comments on commit 6242d5f

Please sign in to comment.