From 465e22ef4dcb7c33e2d17ecfd90e3aaafdf92934 Mon Sep 17 00:00:00 2001 From: hasiburratul Date: Wed, 29 Nov 2023 10:16:26 -0500 Subject: [PATCH 1/5] allowing empty array --- back-end/src/controllers/createIssueHandler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back-end/src/controllers/createIssueHandler.js b/back-end/src/controllers/createIssueHandler.js index 5472799..4842607 100644 --- a/back-end/src/controllers/createIssueHandler.js +++ b/back-end/src/controllers/createIssueHandler.js @@ -28,7 +28,7 @@ export async function createIssueHandler(req, res) { description: req.body.issueDesc, attachments: attachments, departments: req.body.deptTagged.includes(',') ? req.body.deptTagged.split(',') : [req.body.deptTagged], - comments: [null], + comments: [], dateCreated: issueDateCreated, timeCreated: issueTimeCreated, currentStatus:'Open', From b99645db9eef7d423203c1399617f933820deb47 Mon Sep 17 00:00:00 2001 From: hasiburratul Date: Wed, 29 Nov 2023 13:13:34 -0500 Subject: [PATCH 2/5] updated login.test.js --- back-end/src/controllers/loginHandler.js | 23 ------- back-end/test/login.test.js | 86 ++++++------------------ 2 files changed, 19 insertions(+), 90 deletions(-) diff --git a/back-end/src/controllers/loginHandler.js b/back-end/src/controllers/loginHandler.js index efa3ef3..df2296e 100644 --- a/back-end/src/controllers/loginHandler.js +++ b/back-end/src/controllers/loginHandler.js @@ -2,21 +2,7 @@ import bcrypt from "bcryptjs"; import User from "../../models/UserModel.js"; import jwt from "jsonwebtoken"; -// Previous Hardcoded values -// const student = { username: "s", password: "1" }; -// const admin = { username: "a", password: "1" }; - export async function loginStudentHandler(req, res) { - // previous implementation - // if ( - // req.body.username === student.username && - // req.body.password === student.password - // ) { - // res.status(200).json({ authenticated: true }); - // } else { - // res.status(200).json({ authenticated: false }); - // } - try { const { username, password } = req.body; // for case insensitive search @@ -54,15 +40,6 @@ export async function loginStudentHandler(req, res) { } export async function loginAdminHandler(req, res) { - // if ( - // req.body.username === admin.username && - // req.body.password === admin.password - // ) { - // res.json({ authenticated: true }); - // } else { - // res.json({ authenticated: false }); - // } - try { const { username, password } = req.body; // for case insensitive search diff --git a/back-end/test/login.test.js b/back-end/test/login.test.js index 138258b..32d14fe 100644 --- a/back-end/test/login.test.js +++ b/back-end/test/login.test.js @@ -1,67 +1,5 @@ /* eslint-disable */ - import chai, { assert } from "chai"; -import sinon from "sinon"; -import { - loginStudentHandler, - loginAdminHandler -} from "../src/controllers/loginHandler.js"; - -// Unit Testing -describe("Unit Tests for Login Handlers", () => { - let req, res, statusSpy, jsonSpy; - - beforeEach(() => { - req = { body: {} }; - res = { - json: () => {}, - status: function (s) { - this.statusCode = s; - return this; - } - }; - statusSpy = sinon.spy(res, "status"); - jsonSpy = sinon.spy(res, "json"); - }); - - afterEach(() => { - statusSpy.restore(); - jsonSpy.restore(); - }); - - describe("loginStudentHandler", () => { - it("should authenticate valid student credentials", () => { - req.body = { username: "s", password: "1" }; - loginStudentHandler(req, res); - assert(statusSpy.calledWith(200)); - assert(jsonSpy.calledWith({ authenticated: true })); - }); - - it("should not authenticate invalid student credentials", () => { - req.body = { username: "wrong", password: "user" }; - loginStudentHandler(req, res); - assert(statusSpy.calledWith(200)); - assert(jsonSpy.calledWith({ authenticated: false })); - }); - }); - - describe("loginAdminHandler", () => { - it("should authenticate valid admin credentials", () => { - req.body = { username: "a", password: "1" }; - loginAdminHandler(req, res); - assert(jsonSpy.calledWith({ authenticated: true })); - }); - - it("should not authenticate invalid admin credentials", () => { - req.body = { username: "wrong", password: "user" }; - loginAdminHandler(req, res); - assert(jsonSpy.calledWith({ authenticated: false })); - }); - }); -}); - -//Integration Testing - import chaiHttp from "chai-http"; import server from "../app.js"; @@ -73,9 +11,16 @@ describe("Integration Tests for Login Endpoints", () => { const res = await chai .request(server) .post("/api/login/student") - .send({ username: "s", password: "1" }); + .send({ username: "student", password: "student" }); assert.equal(res.status, 200); - assert.deepEqual(res.body, { authenticated: true }); + assert.deepEqual(res.body, { + "__v": 0, + authenticated: true, + name: "student", + netId: "student", + userDept: "student", + userType: "student", + }); }); it("should not authenticate student with incorrect credentials", async () => { @@ -84,7 +29,7 @@ describe("Integration Tests for Login Endpoints", () => { .post("/api/login/student") .send({ username: "wrong", password: "user" }); assert.equal(res.status, 200); - assert.deepEqual(res.body, { authenticated: false }); + assert.deepEqual(res.body, { authenticated: false}); }); }); @@ -93,9 +38,16 @@ describe("Integration Tests for Login Endpoints", () => { const res = await chai .request(server) .post("/api/login/admin") - .send({ username: "a", password: "1" }); + .send({ username: "admin", password: "admin" }); assert.equal(res.status, 200); - assert.deepEqual(res.body, { authenticated: true }); + assert.deepEqual(res.body, { + "__v": 0, + authenticated: true, + name: "admin", + netId: "admin", + userDept: "admin", + userType: "admin", + }); }); it("should not authenticate admin with incorrect credentials", async () => { From 7038b9cad68b5d42f23d25aed76522814390bc0f Mon Sep 17 00:00:00 2001 From: hasiburratul Date: Wed, 29 Nov 2023 14:15:35 -0500 Subject: [PATCH 3/5] added student dashboard test file --- .../src/controllers/studentIssuesHandler.js | 10 ++ back-end/test/login.test.js | 8 +- back-end/test/studentIssueRetrieval.test.js | 106 ------------------ back-end/test/studentIssuesHandler.test.js | 37 ++++++ 4 files changed, 54 insertions(+), 107 deletions(-) delete mode 100644 back-end/test/studentIssueRetrieval.test.js create mode 100644 back-end/test/studentIssuesHandler.test.js diff --git a/back-end/src/controllers/studentIssuesHandler.js b/back-end/src/controllers/studentIssuesHandler.js index 0c61836..a5bf16e 100644 --- a/back-end/src/controllers/studentIssuesHandler.js +++ b/back-end/src/controllers/studentIssuesHandler.js @@ -1,11 +1,21 @@ import IssueModel from '../../models/issueModel.js'; +import User from "../../models/UserModel.js"; export async function issueRetrievalHandler(req, res) { const { paramName } = req.params; try { + // Check if user exists + const user = await User.findOne({ + netId: paramName + }); + // If user does not exist, return error + if (!user) { res.status(500).send("User does not exist.");} + // If user exists, return all issues for that user + else { const issues = await IssueModel.find({ "studentNetID": paramName }); res.json(issues); + } } catch (error) { console.error("Error retrieving data:", error.message); res.status(500).send("An error occurred while retrieving the data."); diff --git a/back-end/test/login.test.js b/back-end/test/login.test.js index 32d14fe..e4c4f8b 100644 --- a/back-end/test/login.test.js +++ b/back-end/test/login.test.js @@ -4,15 +4,18 @@ import chaiHttp from "chai-http"; import server from "../app.js"; chai.use(chaiHttp); - +// Integration tests for the login.js file describe("Integration Tests for Login Endpoints", () => { + // Check student login describe("POST /api/login/student", () => { it("should authenticate student with correct credentials", async () => { const res = await chai .request(server) .post("/api/login/student") .send({ username: "student", password: "student" }); + // Check that the response is correct assert.equal(res.status, 200); + // Check if response matches expected response assert.deepEqual(res.body, { "__v": 0, authenticated: true, @@ -34,12 +37,15 @@ describe("Integration Tests for Login Endpoints", () => { }); describe("POST /api/login/admin", () => { + // Check admin login it("should authenticate admin with correct credentials", async () => { const res = await chai .request(server) .post("/api/login/admin") .send({ username: "admin", password: "admin" }); + // Check that the response is correct assert.equal(res.status, 200); + // Check if response matches expected response assert.deepEqual(res.body, { "__v": 0, authenticated: true, diff --git a/back-end/test/studentIssueRetrieval.test.js b/back-end/test/studentIssueRetrieval.test.js deleted file mode 100644 index 2df7d3b..0000000 --- a/back-end/test/studentIssueRetrieval.test.js +++ /dev/null @@ -1,106 +0,0 @@ -/* eslint-disable */ - -// Unit Testing -import chai, { assert } from "chai"; -import sinon from "sinon"; -import axios from "axios"; -import fs from "fs/promises"; -import { issueRetrievalHandler } from "../src/controllers/studentIssuesHandler.js"; - -const data = await fs.readFile("./public/json/mockapi.json", "utf8"); -const mockData = JSON.parse(data); -// Filter the mock data to match the handler's expected behavior -const filteredData = mockData.filter( - (item) => item.studentNetID[0] === "tm2005" -); - -describe("Unit Tests for Student Dashboard", () => { - let req, res, axiosGetStub; - let sendSpy, jsonSpy; - - beforeEach(() => { - req = { params: { paramName: "tm2005" } }; - res = { - json: sinon.spy(), - status: sinon.stub().returns({ send: sinon.spy() }) // Stubbed here - }; - sendSpy = res.status().send; // Save a reference to the send spy created above - jsonSpy = res.json; // Save a reference to the json spy - axiosGetStub = sinon.stub(axios, "get"); - }); - - afterEach(() => { - sinon.restore(); // Restores all stubs and spies created through sinon - }); - - it('should filter and return the correct number of data records for studentNetID "tm2005"', async () => { - // Stub the axios call to resolve with the entire mock data - axiosGetStub.resolves({ data: mockData }); - - // Execute the handler - await issueRetrievalHandler(req, res); - - // Assert the axios call was made once - assert(axiosGetStub.calledOnce); - // Assert the correct amount of data is returned - assert.equal( - res.json.firstCall.args[0].length, - filteredData.length, - "Number of records should match the filtered data length" - ); - // Assert the returned data matches the filtered data - assert.deepEqual( - res.json.firstCall.args[0], - filteredData, - "Returned data should match the filtered data" - ); - }); -}); - -// Integration Testing - -import chaiHttp from "chai-http"; - -chai.use(chaiHttp); - -describe("Integration Tests for Issue Retrieval Endpoints", () => { - describe("GET /api/issues/student/:paramName", () => { - it("should retrieve issues for a given student and match all records", async () => { - const studentNetID = "tm2005"; - const res = await chai - .request("http://localhost:5000") - .get(`/api/issues/student/${studentNetID}`); - - assert.equal(res.status, 200, "Response status should be 200"); - assert.isArray(res.body, "Response body should be an array"); - assert.lengthOf( - res.body, - filteredData.length, - `Response body should have ${filteredData.length} records` - ); - - // Check if each record in the response matches the corresponding record in filteredData - res.body.forEach((record, index) => { - assert.deepEqual( - record, - filteredData[index], - `Record at index ${index} should match the expected data` - ); - }); - }); - - // it("should handle requests for a non-existent student gracefully", async () => { - // const nonExistentStudentNetID = "nonexistent"; - // const res = await chai - // .request(server) - // .get(`/api/issues/student/${nonExistentStudentNetID}`); - - // assert.equal( - // res.status, - // 500, - // "Response status should be 500 for a non-existent student" - // ); - // }); - }); -}); -/* eslint-enable */ diff --git a/back-end/test/studentIssuesHandler.test.js b/back-end/test/studentIssuesHandler.test.js new file mode 100644 index 0000000..610124a --- /dev/null +++ b/back-end/test/studentIssuesHandler.test.js @@ -0,0 +1,37 @@ +/* eslint-disable */ +import chai, { assert } from "chai"; +import IssueModel from "../models/issueModel.js"; +import chaiHttp from "chai-http"; +import server from "../app.js"; +chai.use(chaiHttp); + +// Integration tests for the studentIssuesHandler.js file +describe("Integration Tests for Issue Retrieval Endpoint", () => { + describe("GET /api/issues/student/:paramName", () => { + it("should retrieve all issues for a valid student NetID", async () => { + const paramName = "student"; + const res = await chai + .request(server) + .get(`/api/issues/student/${paramName}`); + // Check that the response is correct + assert.equal(res.status, 200); + // Check that the response is an array + assert.isArray(res.body); + // Check that the response is the same length as the number of issues + const userIssues = await IssueModel.find({ "studentNetID": paramName }); + // Check that the response is the same length as the number of issues of that user + assert.equal(res.body.length, userIssues.length); + }); + + it("should handle errors gracefully for an invalid student NetID", async () => { + const paramName = "invalidStudentNetID"; + const res = await chai + .request(server) + .get(`/api/issues/student/${paramName}`); + assert.equal(res.status, 500); + assert.equal(res.text, "User does not exist."); + }); + }); +}); + +/* eslint-enable */ From 8142744d221ca272c6168a241a0bc94596ccae9c Mon Sep 17 00:00:00 2001 From: hasiburratul Date: Wed, 29 Nov 2023 14:18:38 -0500 Subject: [PATCH 4/5] updated student dashboard test file --- back-end/test/studentIssuesHandler.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back-end/test/studentIssuesHandler.test.js b/back-end/test/studentIssuesHandler.test.js index 610124a..4a0e61a 100644 --- a/back-end/test/studentIssuesHandler.test.js +++ b/back-end/test/studentIssuesHandler.test.js @@ -6,7 +6,7 @@ import server from "../app.js"; chai.use(chaiHttp); // Integration tests for the studentIssuesHandler.js file -describe("Integration Tests for Issue Retrieval Endpoint", () => { +describe("Integration Tests for Student Issue Handler Endpoint", () => { describe("GET /api/issues/student/:paramName", () => { it("should retrieve all issues for a valid student NetID", async () => { const paramName = "student"; From 35ee9f37c7442de59d4a2e2f6aa67b69f471f2b8 Mon Sep 17 00:00:00 2001 From: hasiburratul Date: Wed, 29 Nov 2023 18:29:28 -0500 Subject: [PATCH 5/5] added srpint 4 details --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 19a60b8..bd7bc51 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,10 @@ We decided to rotate the assignment of the following roles for each sprint. * **Product Owner:** Basil Ahmed * **Scrum Master:** Nada Elsharkawy +### Sprint 4 +* **Product Owner:** Avinash Gyawali +* **Scrum Master:** Swostik Pati + ## About ### Product Vision Statement The NYUAD Issue Resolution Platform is envisioned as a transformative solution that streamlines and revolutionizes the way NYU Abu Dhabi students and administrative departments interact and resolve issues. Our vision is to create a transparent, efficient, and user-friendly web application that serves as a central hub for issue tracking and resolution. The platform will bridge the communication gap between students and departments, offering real-time insights, accountability, and enhanced collaboration.