Skip to content

Commit a869288

Browse files
committed
added crud operation, all endpoints, testcases and apidoc for notification model
1 parent 208470e commit a869288

File tree

7 files changed

+372
-0
lines changed

7 files changed

+372
-0
lines changed

_apidoc.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,3 +1411,73 @@
14111411
* @apiSuccess {Number} student.roll no of the student.
14121412
* @apiSuccess {ObjectId} student.coursesOpted by the student(ObjectId).
14131413
*/
1414+
1415+
// ------------------------------------------------------------------------------------------
1416+
// notification
1417+
// ------------------------------------------------------------------------------------------
1418+
1419+
/**
1420+
* @api {post} /notification/add Add Notification
1421+
* @apiName AddNotification
1422+
* @apiGroup Notification
1423+
* @apiDescription Adds a new notification to the system.
1424+
*
1425+
* @apiBody {String} data Notification data.
1426+
* @apiBody {String} title Notification title.
1427+
* @apiBody {String} from User ID of the sender (Faculty).
1428+
* @apiBody {String} type Notification type (Student/Faculty).
1429+
* @apiBody {String[]} filter Array of targeted User IDs.
1430+
*
1431+
* @apiSuccess {String} res Success message with the ID of the added notification.
1432+
*
1433+
* @apiError (Error 500) DatabaseError Error while inserting in the database.
1434+
*
1435+
*/
1436+
1437+
/**
1438+
* @api {get} /notification/list Get Notification List
1439+
* @apiName GetNotification
1440+
* @apiGroup Notification
1441+
*
1442+
* @apiQuery {String} [from] User ID of the sender (Faculty).
1443+
* @apiQuery {String} [type] Notification type (Student/Faculty).
1444+
* @apiQuery {String} [title] notification title.
1445+
* @apiQuery {String} [data] notification data.
1446+
* @apiQuery {String[]} [filter] array of targeted User IDs.
1447+
*
1448+
* @apiSuccess {Notification[]} res Array of filtered Notification documents.
1449+
* @apiSuccess {String} notification._id ID of the document given by the database.
1450+
* @apiSuccess {String} notification.data Notification data.
1451+
* @apiSuccess {String} notification.title Notification title.
1452+
* @apiSuccess {String} notification.from User ID of the sender (Faculty).
1453+
* @apiSuccess {String} notification.type Notification type (Student/Faculty).
1454+
* @apiSuccess {String[]} notification.filter Array of targeted User IDs.
1455+
*/
1456+
1457+
/**
1458+
* @api {delete} /notification/delete/:notificationId Delete Notification
1459+
* @apiName DeleteNotification
1460+
* @apiGroup Notification
1461+
*
1462+
* @apiParam {String} notificationId The ID of the notification document to delete.
1463+
*
1464+
* @apiSuccess {String} res Success message indicating the deletion.
1465+
*
1466+
* @apiError (Error 500) err Error message if there was an error during the deletion.
1467+
*/
1468+
1469+
/**
1470+
* @api {post} /notification/update Update Notification Details
1471+
* @apiName UpdateNotification
1472+
* @apiGroup Notification
1473+
*
1474+
* @apiBody {String} id ID of the notification to be updated.
1475+
* @apiBody {String} [data] Updated notification data.
1476+
* @apiBody {String} [title] Updated notification title.
1477+
* @apiBody {String} [from] Updated User ID of the sender (Faculty).
1478+
* @apiBody {String} [type] Updated notification type (Student/Faculty).
1479+
* @apiBody {String[]} [filter] Updated array of targeted User IDs.
1480+
*
1481+
* @apiSuccess {String} res Notification updated.
1482+
* @apiError (Error 500) err Error in updating the database.
1483+
*/

app.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import departmentRouter from "#routes/department";
2626
import paperRouter from "#routes/paper";
2727
import groupRouter from "#routes/group";
2828
import performarouter from "#routes/performance";
29+
import notificationRouter from "#routes/notification";
2930

3031
const app = express();
3132
const currDirName = dirname(fileURLToPath(import.meta.url));
@@ -64,5 +65,6 @@ app.use("/group", groupRouter);
6465
app.use("/semester", semesterRouter);
6566
app.use("/faculty", facultyRouter);
6667
app.use("/performance", performarouter);
68+
app.use("/notification", notificationRouter);
6769

6870
export default app;

controller/notification.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import {
2+
createNotification,
3+
deleteNotificationById,
4+
listNotifications,
5+
updateNotificationById,
6+
} from "#services/notification";
7+
import { logger } from "#util";
8+
9+
async function addNotification(req, res) {
10+
const {
11+
data, title, type, from, filter,
12+
} = req.body;
13+
try {
14+
const newNotification = await createNotification({
15+
data, title, type, from, filter,
16+
});
17+
res.json({ res: `Added notification with ID: ${newNotification.id}`, id: newNotification.id });
18+
} catch (error) {
19+
logger.error("Error while inserting", error);
20+
res.status(500);
21+
res.json({ error: "Error while inserting in DB" });
22+
}
23+
}
24+
25+
async function updateNotification(req, res) {
26+
const { id } = req.params;
27+
const{
28+
...data
29+
} = req.body;
30+
try {
31+
await updateNotificationById(id, data);
32+
res.json({ res: `Updated notification with ID: ${id}` });
33+
} catch (error) {
34+
logger.error("Error while updating", error);
35+
res.status(500)
36+
res.json({ error: "Error while updating in DB" });
37+
}
38+
}
39+
40+
async function getNotifications(req, res) {
41+
const filter = req.query;
42+
const notificationList = await listNotifications(filter);
43+
res.json({ res: notificationList });
44+
}
45+
46+
async function deleteNotification(req, res) {
47+
const { id } = req.params;
48+
try {
49+
await deleteNotificationById(id);
50+
res.json({ res: `Deleted notification with ID: ${id}` });
51+
} catch (error) {
52+
logger.error("Error while deleting", error);
53+
res.status(500).json({ error: "Error while deleting from DB" });
54+
}
55+
}
56+
57+
export default {
58+
addNotification,
59+
deleteNotification,
60+
getNotifications,
61+
updateNotification,
62+
};
63+

models/notification.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import connector from "#models/databaseUtil";
2+
3+
const notificationSchema = {
4+
data: {
5+
type: String,
6+
required: true,
7+
},
8+
title: {
9+
type: String,
10+
required: true,
11+
},
12+
from: {
13+
type: connector.Schema.Types.ObjectId,
14+
ref: "Faculty", // Reference to the Faculty model
15+
required: true,
16+
},
17+
type: {
18+
type: String,
19+
enum: ["Student", "Faculty"],
20+
required: true,
21+
},
22+
filter: [
23+
{
24+
type: connector.Schema.Types.ObjectId,
25+
ref: "User", // You might have a User model for storing IDs
26+
},
27+
],
28+
};
29+
30+
const Notification = connector.model("Notification", notificationSchema);
31+
32+
// CRUD Operations
33+
34+
async function create(notificationData) {
35+
const{
36+
data,title,from,type,filter,
37+
} =notificationData;
38+
const notification=new Notification({
39+
data,title,from,type,filter,
40+
});
41+
const notificationDOC=await notification.save();
42+
return notificationDOC;
43+
}
44+
45+
async function read(filter, limit = 1) {
46+
const notificationDoc = await Notification.find(filter).limit(limit);
47+
return notificationDoc;
48+
}
49+
50+
async function update(filter, updateObject, options = { multi: true }) {
51+
const updateResult = await Notification.updateMany(filter, { $set: updateObject }, options);
52+
return updateResult.acknowledged;
53+
}
54+
55+
async function remove(filter) {
56+
const deleteResult = await Notification.deleteMany(filter);
57+
return deleteResult.acknowledged;
58+
}
59+
60+
export default {
61+
create,
62+
read,
63+
update,
64+
remove,
65+
};

routes/notification.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import express from "express";
2+
import notificationController from "#controller/notification";
3+
4+
const router = express.Router();
5+
6+
// Create a new Notification
7+
router.post("/add", notificationController.addNotification);
8+
9+
// List Notification entities with optional filters
10+
router.get("/list", notificationController.getNotifications);
11+
12+
// Update Notification entities based on filters and update data
13+
router.post("/update/:id", notificationController.updateNotification);
14+
15+
// Delete Notification entities based on ID
16+
router.delete("/delete/:id", notificationController.deleteNotification);
17+
18+
export default router;

services/notification.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Import the Notification model
2+
import Notification from "#models/notification";
3+
import databaseError from "#error/database";
4+
5+
// Service function to create a new Notification entity
6+
export async function createNotification({
7+
data, title, type, from, filter,
8+
}) {
9+
try {
10+
const newNotification = await Notification.create({
11+
data, title, type, from, filter,
12+
});
13+
return newNotification;
14+
} catch (error) {
15+
throw new databaseError.DataEntryError("notification");
16+
}
17+
}
18+
19+
// Service function to update a Notification entity by ID
20+
export async function updateNotificationById(id, data) {
21+
try {
22+
const updated = await Notification.findByIdAndUpdate({_id : id} , data);
23+
if (updated) {
24+
return updated;
25+
}
26+
throw new databaseError.DataEntryError("notification");
27+
} catch (error) {
28+
throw new databaseError.DataEntryError("notification");
29+
}
30+
}
31+
32+
// Service function to retrieve a list of Notification entities based on filters
33+
export async function listNotifications(filter) {
34+
try {
35+
const notificationList = await Notification.read(filter);
36+
return notificationList;
37+
} catch (error) {
38+
throw new databaseError.DataEntryError("notification");
39+
}
40+
}
41+
42+
// Service function to delete a Notification entity by ID
43+
export async function deleteNotificationById(notificationId) {
44+
try {
45+
const deleted = await Notification.deleteOne({ _id: notificationId });
46+
if (deleted.deletedCount > 0) {
47+
return deleted;
48+
}
49+
throw new databaseError.DataDeleteError("notification");
50+
} catch (error) {
51+
throw new databaseError.DataDeleteError("notification");
52+
}
53+
}

test/routes/notification.test.js

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { jest } from "@jest/globals";
2+
import notificationModel from "#models/notification";
3+
import connector from "#models/databaseUtil"; // Import your Express app instance
4+
5+
jest.mock("#util");
6+
const {agent}= global;
7+
8+
9+
function cleanUp(callback) {
10+
notificationModel.remove({
11+
data: "Sample Notification",
12+
title: "Test Title",
13+
from: "YOUR_FACULTY_ID",
14+
type: "Student",
15+
filter: ["TARGETED_USER_ID"],
16+
})
17+
.then(() => {
18+
connector.disconnect((DBerr) => {
19+
if (DBerr) console.log("database disconnect error: ", DBerr);
20+
callback();
21+
});
22+
})
23+
24+
}
25+
26+
afterAll((done) => {
27+
cleanUp(done);
28+
});
29+
30+
describe("Notification API", () => {
31+
let notificationId;
32+
33+
it("should create a new notification", async () => {
34+
const response = await agent.post("/notification/add").send({
35+
data: "Sample Notification",
36+
title: "Test Title",
37+
from: "YOUR_FACULTY_ID", // Use a valid Faculty ID
38+
type: "Student",
39+
filter: ["TARGETED_USER_ID"], // Use a valid User ID
40+
});
41+
42+
expect(response.status).toBe(200);
43+
expect(response.body.res).toMatch(/added notification/);
44+
45+
46+
});
47+
48+
describe("after adding notification", () => {
49+
let notificationId;
50+
beforeEach(async () => {
51+
notificationId=await agent.post("notification/add").send({
52+
data: "Sample Notification",
53+
title: "Test Title",
54+
from: "YOUR_FACULTY_ID",
55+
type: "Student",
56+
filter: ["TARGETED_USER_ID"],
57+
});
58+
notificationId=JSON.parse(id.res.text).id;
59+
});
60+
afterEach(async () => {
61+
await notificationModel.remove({
62+
data: "Sample Notification",
63+
title: "Test Title",
64+
from: "YOUR_FACULTY_ID",
65+
type: "Student",
66+
filter: ["TARGETED_USER_ID"],
67+
68+
});
69+
});
70+
71+
it("should update a notification entity", async () => {
72+
const response = await agent.post(`/notification/update/${notificationId}`).send({
73+
data: "Updated Notification Data",
74+
title: "Updated Title",
75+
from: "YOUR_FACULTY_ID",
76+
type: "Faculty",
77+
filter: ["TARGETED_USER_ID"],
78+
});
79+
80+
expect(response.status).toBe(200);
81+
expect(response.body.res).toMatch(/updated notification/);
82+
});
83+
84+
it("should list notification entities", async () => {
85+
const response = await agent.get("/notification/list").send({
86+
data: "Sample Notification",
87+
title: "Test Title",
88+
from: "YOUR_FACULTY_ID",
89+
type: "Student",
90+
filter: ["TARGETED_USER_ID"],
91+
92+
});
93+
expect(response.status).toBe(200);
94+
expect(response.body.res).toBeDefined();
95+
});
96+
97+
98+
})
99+
100+
101+
});

0 commit comments

Comments
 (0)