Skip to content

Commit 6242d5f

Browse files
Merge pull request #408 from tcet-opensource/321-crud-endpoints-testcases-apidoc-for-notification
[Mega-Feat]:- Added crud, endpoints, testcases and apidoc for notification model
2 parents d8abd45 + bf84d17 commit 6242d5f

File tree

7 files changed

+367
-0
lines changed

7 files changed

+367
-0
lines changed

_apidoc.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,6 +1567,75 @@
15671567
* @apiSuccess {ObjectId} student.coursesOpted by the student(ObjectId).
15681568
*/
15691569

1570+
// ------------------------------------------------------------------------------------------
1571+
// notification
1572+
// ------------------------------------------------------------------------------------------
1573+
1574+
/**
1575+
* @api {post} /notification/add Add Notification
1576+
* @apiName AddNotification
1577+
* @apiGroup Notification
1578+
* @apiDescription Adds a new notification to the system.
1579+
*
1580+
* @apiBody {String} data Notification data.
1581+
* @apiBody {String} title Notification title.
1582+
* @apiBody {String} from User ID of the sender (Faculty).
1583+
* @apiBody {String} type Notification type (Student/Faculty).
1584+
* @apiBody {String[]} filter Array of targeted User IDs.
1585+
*
1586+
* @apiSuccess {String} res Success message with the ID of the added notification.
1587+
*
1588+
* @apiError (Error 500) DatabaseError Error while inserting in the database.
1589+
*
1590+
*/
1591+
1592+
/**
1593+
* @api {get} /notification/list Get Notification List
1594+
* @apiName GetNotification
1595+
* @apiGroup Notification
1596+
*
1597+
* @apiQuery {String} [from] User ID of the sender (Faculty).
1598+
* @apiQuery {String} [type] Notification type (Student/Faculty).
1599+
* @apiQuery {String} [title] notification title.
1600+
* @apiQuery {String} [data] notification data.
1601+
* @apiQuery {String[]} [filter] array of targeted User IDs.
1602+
*
1603+
* @apiSuccess {Notification[]} res Array of filtered Notification documents.
1604+
* @apiSuccess {String} notification._id ID of the document given by the database.
1605+
* @apiSuccess {String} notification.data Notification data.
1606+
* @apiSuccess {String} notification.title Notification title.
1607+
* @apiSuccess {String} notification.from User ID of the sender (Faculty).
1608+
* @apiSuccess {String} notification.type Notification type (Student/Faculty).
1609+
* @apiSuccess {String[]} notification.filter Array of targeted User IDs.
1610+
*/
1611+
1612+
/**
1613+
* @api {delete} /notification/delete/:notificationId Delete Notification
1614+
* @apiName DeleteNotification
1615+
* @apiGroup Notification
1616+
*
1617+
* @apiParam {String} notificationId The ID of the notification document to delete.
1618+
*
1619+
* @apiSuccess {String} res Success message indicating the deletion.
1620+
*
1621+
* @apiError (Error 500) err Error message if there was an error during the deletion.
1622+
*/
1623+
1624+
/**
1625+
* @api {post} /notification/update Update Notification Details
1626+
* @apiName UpdateNotification
1627+
* @apiGroup Notification
1628+
*
1629+
* @apiBody {String} id ID of the notification to be updated.
1630+
* @apiBody {String} [data] Updated notification data.
1631+
* @apiBody {String} [title] Updated notification title.
1632+
* @apiBody {String} [from] Updated User ID of the sender (Faculty).
1633+
* @apiBody {String} [type] Updated notification type (Student/Faculty).
1634+
* @apiBody {String[]} [filter] Updated array of targeted User IDs.
1635+
*
1636+
* @apiSuccess {String} res Notification updated.
1637+
* @apiError (Error 500) err Error in updating the database.
1638+
15701639
// ------------------------------------------------------------------------------------------
15711640
// Topic.
15721641
// ------------------------------------------------------------------------------------------

app.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import examRouter from "#routes/exam";
2828
import paperRouter from "#routes/paper";
2929
import groupRouter from "#routes/group";
3030
import performarouter from "#routes/performance";
31+
import notificationRouter from "#routes/notification";
3132
import topicRouter from "#routes/topic";
3233

3334
const app = express();
@@ -69,6 +70,7 @@ app.use("/group", groupRouter);
6970
app.use("/semester", semesterRouter);
7071
app.use("/faculty", facultyRouter);
7172
app.use("/performance", performarouter);
73+
app.use("/notification", notificationRouter);
7274
app.use("/topic",topicRouter);
7375

7476
export default app;

controller/notification.js

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

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

test/routes/notification.test.js

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

0 commit comments

Comments
 (0)