From b2e13b5c4a1e9cbf0864a4fcfa08319c234cc8e0 Mon Sep 17 00:00:00 2001
From: basil-ahmed <bq2024@nyu.edu>
Date: Mon, 13 Nov 2023 22:27:53 -0500
Subject: [PATCH 1/2] Unit Testing for Student Issue Details Improved Error
 Handling

---
 .../studentIssueViewDetailsHandler.js         |  38 +++---
 back-end/test/studentIssueDetails.test.js     | 115 ++++++++++++++++++
 .../DesktopIssueDetails.js                    |   3 +-
 3 files changed, 136 insertions(+), 20 deletions(-)
 create mode 100644 back-end/test/studentIssueDetails.test.js

diff --git a/back-end/src/controllers/studentIssueViewDetailsHandler.js b/back-end/src/controllers/studentIssueViewDetailsHandler.js
index 8bd4c5e..2b94f4d 100644
--- a/back-end/src/controllers/studentIssueViewDetailsHandler.js
+++ b/back-end/src/controllers/studentIssueViewDetailsHandler.js
@@ -1,39 +1,39 @@
-
-// const StudentIssue = require('../models/studentIssue');
-
-// async function getStudentIssueDetails(req, res) {
-//   try {
-//     const { id } = req.params;
-//     const studentIssue = await StudentIssue.findById(id);
-//     if (!studentIssue) {
-//       return res.status(404).json({ message: 'Student issue not found' });
-//     }
-//     return res.status(200).json(studentIssue);
-//   } catch (error) {
-//     console.error(error);
-//     return res.status(500).json({ message: 'Server error' });
-//   }
-// }
-
-// module.exports = { getStudentIssueDetails };
-
 import axios from "axios";
 
 // The function retrieves all the issues related to this student
 export async function studentIssueViewDetailsHandler(req, res) {
   const { paramName } = req.params;
   const { studentNetID } = req.params;
+
+  if (!studentNetID) {
+    return res.status(400).send("Missing or invalid studentNetID.");
+  }
+
+  if (!paramName) {
+    return res.status(400).send("Missing or invalid issue index.");
+  }
+
   try {
     // Assuming the data you want is at the response.data property
     const response = await axios.get(
       `${process.env.BACKEND_URL}/api/issues/student/${studentNetID}`
     );
 
+    // Check if any data is returned for the student
+    if (!response.data || response.data.length === 0) {
+      return res.status(500).send("No issues found for the given studentNetID.");
+    }
+
     // Assuming response.data is an array of items and each item has a index
     const filteredData = response.data.filter(
       (item) => String(item.index) === String(paramName)
     );
 
+    // Check if the specific issue index exists
+    if (filteredData.length === 0) {
+      return res.status(500).send("Issue with the given index not found.");
+    }
+
     res.json(filteredData); // Send only the data that matches the specific issue index
   } catch (error) {
     // Log the error and send an appropriate response
diff --git a/back-end/test/studentIssueDetails.test.js b/back-end/test/studentIssueDetails.test.js
new file mode 100644
index 0000000..f516896
--- /dev/null
+++ b/back-end/test/studentIssueDetails.test.js
@@ -0,0 +1,115 @@
+import chai, { assert } from "chai";
+import chaiHttp from "chai-http";
+import sinon from "sinon";
+import axios from "axios";
+import fs from "fs/promises";
+import {studentIssueViewDetailsHandler} from "../src/controllers/studentIssueViewDetailsHandler.js";
+
+let server = "http://localhost:5000";
+
+const data = await fs.readFile("./public/json/mockapi.json", "utf8");
+const mockResponse = JSON.parse(data);
+
+chai.use(chaiHttp);
+
+describe("StudentIssueViewDetailsHandler Test Suite", () => {
+  // Stub for axios
+  let req, res, axiosStub;
+
+  before(() => {
+    req = { params: { paramName: "tm2005" } };
+    res = {
+      json: sinon.spy(),
+      status: sinon.stub().returns({ send: sinon.spy() }) // Stubbed here
+    };
+    axiosStub = sinon.stub(axios, 'get');
+  });
+
+  after(() => {
+    axiosStub.restore();
+  });
+
+  it("should retrieve and filter specific student issue correctly", async () => {
+    // const mockResponse = {
+    //   data: [
+    //     {
+    //         "index": 6,
+    //         "studentNetID": ["tm2005"],
+    //         "studentName": ["Ted Mosby"],
+    //         "title": "Global Programs Information Session",
+    //         "description": "When is the next information session for global education programs?",
+    //         "attachments": [null],
+    //         "departments": ["GlobalEd"],
+    //         "comments": [
+    //           "Our international student office can assist you with the visa process."
+    //         ],
+    //         "dateCreated": "05/01/2023",
+    //         "timeCreated": "21:51",
+    //         "currentStatus": "Action Required",
+    //         "currentPriority": "High Priority"
+    //       },
+    //       {
+    //         "index": 7,
+    //         "studentNetID": ["tm2005"],
+    //         "studentName": ["Ted Mosby"],
+    //         "title": "Career Fair Event Details",
+    //         "description": "Could you provide the details for the upcoming career fair event?",
+    //         "attachments": [null],
+    //         "departments": ["CDC", "Facilities"],
+    //         "comments": ["Details for the career fair have been sent to your email."],
+    //         "dateCreated": "11/09/2023",
+    //         "timeCreated": "16:20",
+    //         "currentStatus": "Action Required",
+    //         "currentPriority": "High Priority"
+    //       }
+    //   ]
+    // };
+
+    // Execute the handler
+    await studentIssueViewDetailsHandler(req, res);
+
+    axiosStub.resolves(mockResponse);
+
+    const studentNetID = "tm2005";
+    const paramName = "6";
+    const response = await chai.request(server)
+      .get(`/api/issues/student/${studentNetID}/${paramName}`); // Update this with the correct route
+
+    //   response= response.filter(
+    //     (item) => String(item.index) === String(paramName)
+    //   )
+
+    // assert(axiosStub.called);
+    assert.equal(response.status, 200);
+    assert.deepEqual(response.body, [{
+        "index": 6,
+        "studentNetID": ["tm2005"],
+        "studentName": ["Ted Mosby"],
+        "title": "Global Programs Information Session",
+        "description": "When is the next information session for global education programs?",
+        "attachments": [null],
+        "departments": ["GlobalEd"],
+        "comments": [
+          "Our international student office can assist you with the visa process."
+        ],
+        "dateCreated": "05/01/2023",
+        "timeCreated": "21:51",
+        "currentStatus": "Action Required",
+        "currentPriority": "High Priority"
+      }]);
+  });
+
+  it("should handle errors gracefully", async () => {
+    // axiosStub.rejects(new Error("Network error"));
+
+    const studentNetID = "tm2005";
+    const paramName = "9999";
+    const response = await chai.request(server)
+      .get(`/api/issues/student/${studentNetID}/${paramName}`) // Update this with the correct route
+    //   .query({ studentNetID: 'tm2005', paramName: '6' });
+
+    // assert(axiosStub.called);
+    assert.equal(response.status, 500);
+    assert.equal(response.text, "Issue with the given index not found.");
+  });
+});
diff --git a/front-end/src/components/student/StudentIssueOverlay/DesktopIssueDetails.js b/front-end/src/components/student/StudentIssueOverlay/DesktopIssueDetails.js
index 6cfbb3a..2538366 100644
--- a/front-end/src/components/student/StudentIssueOverlay/DesktopIssueDetails.js
+++ b/front-end/src/components/student/StudentIssueOverlay/DesktopIssueDetails.js
@@ -21,7 +21,8 @@ const DesktopIssueDetails = ({ index }) => {
         e.preventDefault(); // Prevent the default form submit action
         if (comment.trim()) {
             try {
-                const response = await axios.post(
+                const response = await axios
+                .post(
                     `${BACKEND_BASE_URL}/api/actions/student/${mockStudent.netid}/${index}`,
                     {
                         issueindex: index,

From a3aee779e3ed9c71c2c43a7b933de23113fc40ee Mon Sep 17 00:00:00 2001
From: basil-ahmed <bq2024@nyu.edu>
Date: Mon, 13 Nov 2023 23:01:36 -0500
Subject: [PATCH 2/2] Completed Testing

---
 back-end/test/studentIssueDetails.test.js | 69 ++++++++++++++++++++++-
 1 file changed, 68 insertions(+), 1 deletion(-)

diff --git a/back-end/test/studentIssueDetails.test.js b/back-end/test/studentIssueDetails.test.js
index f516896..5372561 100644
--- a/back-end/test/studentIssueDetails.test.js
+++ b/back-end/test/studentIssueDetails.test.js
@@ -10,9 +10,76 @@ let server = "http://localhost:5000";
 const data = await fs.readFile("./public/json/mockapi.json", "utf8");
 const mockResponse = JSON.parse(data);
 
+// Unit Testing
+
+describe("Unit Tests for studentIssueViewDetailsHandler", () => {
+    let req, res, axiosGetStub, sendSpy, jsonSpy, statusSpy;
+
+    beforeEach(() => {
+        req = { params: { paramName: "123", studentNetID: "s123456" } };
+        res = {
+            json: sinon.spy(),
+            status: sinon.stub().returns({ send: sinon.spy() })
+        };
+        sendSpy = res.status().send;
+        jsonSpy = res.json;
+        statusSpy = res.status;
+        axiosGetStub = sinon.stub(axios, "get");
+    });
+
+    afterEach(() => {
+        sinon.restore();
+    });
+
+    it("should return 400 error if studentNetID is missing", async () => {
+        delete req.params.studentNetID;
+        await studentIssueViewDetailsHandler(req, res);
+        assert.isTrue(statusSpy.calledWith(400));
+        assert.isTrue(sendSpy.calledWith("Missing or invalid studentNetID."));
+    });
+
+    it("should return 400 error if paramName is missing", async () => {
+        delete req.params.paramName;
+        await studentIssueViewDetailsHandler(req, res);
+        assert.isTrue(statusSpy.calledWith(400));
+        assert.isTrue(sendSpy.calledWith("Missing or invalid issue index."));
+    });
+
+    it("should return filtered data for a valid request", async () => {
+        const mockData = [{ index: "123", detail: "Issue details" }];
+        axiosGetStub.resolves({ data: mockData });
+        await studentIssueViewDetailsHandler(req, res);
+        assert.isTrue(jsonSpy.calledWith([mockData[0]]));
+    });
+
+    it("should return 500 error if no data found for student", async () => {
+        axiosGetStub.resolves({ data: [] });
+        await studentIssueViewDetailsHandler(req, res);
+        assert.isTrue(statusSpy.calledWith(500));
+        assert.isTrue(sendSpy.calledWith("No issues found for the given studentNetID."));
+    });
+
+    it("should return 500 error if issue index not found", async () => {
+        const mockData = [{ index: "124", detail: "Issue details" }];
+        axiosGetStub.resolves({ data: mockData });
+        await studentIssueViewDetailsHandler(req, res);
+        assert.isTrue(statusSpy.calledWith(500));
+        assert.isTrue(sendSpy.calledWith("Issue with the given index not found."));
+    });
+
+    it("should handle axios errors", async () => {
+        axiosGetStub.rejects(new Error("Axios error"));
+        await studentIssueViewDetailsHandler(req, res);
+        assert.isTrue(statusSpy.calledWith(500));
+        assert.isTrue(sendSpy.calledWith("An error occurred while retrieving the data."));
+    });
+});
+
+// Integration Testing
+
 chai.use(chaiHttp);
 
-describe("StudentIssueViewDetailsHandler Test Suite", () => {
+describe("Integration Tests for Student Issue Details", () => {
   // Stub for axios
   let req, res, axiosStub;