diff --git a/test/integration/application.test.ts b/test/integration/application.test.ts index e38ae2a07..3d1212a3b 100644 --- a/test/integration/application.test.ts +++ b/test/integration/application.test.ts @@ -376,33 +376,34 @@ describe("Application", function () { }); }); - it("should return 401 if the user is not super user", function (done) { + it("should return 400 if anything other than status and feedback is passed in the body", function (done) { chai .request(app) .patch(`/applications/${applicationId1}/feedback`) - .set("cookie", `${cookieName}=${jwt}`) + .set("cookie", `${cookieName}=${superUserJwt}`) .send({ status: "accepted", + batman: true, }) .end((err, res) => { if (err) { return done(err); } - expect(res).to.have.status(401); - expect(res.body.message).to.be.equal("You are not authorized for this action."); + expect(res).to.have.status(400); + expect(res.body.error).to.be.equal("Bad Request"); + expect(res.body.message).to.be.equal('"batman" is not allowed'); return done(); }); }); - it("should return 400 if anything other than status and feedback is passed in the body", function (done) { + it("should return 400 if any status other than accepted, rejected or changes_requested is passed", function (done) { chai .request(app) .patch(`/applications/${applicationId1}/feedback`) .set("cookie", `${cookieName}=${superUserJwt}`) .send({ - status: "accepted", - batman: true, + status: "something", }) .end((err, res) => { if (err) { @@ -411,18 +412,57 @@ describe("Application", function () { expect(res).to.have.status(400); expect(res.body.error).to.be.equal("Bad Request"); - expect(res.body.message).to.be.equal('"batman" is not allowed'); + expect(res.body.message).to.be.equal("Status must be one of: accepted, rejected, or changes_requested"); return done(); }); }); - it("should return 400 if any status other than accepted, rejected or changes_requested is passed", function (done) { + it("should return 200 when submitting feedback with status rejected", function (done) { + chai + .request(app) + .patch(`/applications/${applicationId2}/feedback`) + .set("cookie", `${cookieName}=${superUserJwt}`) + .send({ + status: "rejected", + }) + .end((err, res) => { + if (err) { + return done(err); + } + + expect(res).to.have.status(200); + expect(res.body.message).to.be.equal("Application feedback submitted successfully"); + return done(); + }); + }); + + it("should return 200 when submitting feedback with status changes_requested and feedback text", function (done) { + chai + .request(app) + .patch(`/applications/${applicationId3}/feedback`) + .set("cookie", `${cookieName}=${superUserJwt}`) + .send({ + status: "changes_requested", + feedback: "Please update your skills section with more details", + }) + .end((err, res) => { + if (err) { + return done(err); + } + + expect(res).to.have.status(200); + expect(res.body.message).to.be.equal("Application feedback submitted successfully"); + return done(); + }); + }); + + it("should return 400 when status is changes_requested without feedback", function (done) { chai .request(app) .patch(`/applications/${applicationId1}/feedback`) .set("cookie", `${cookieName}=${superUserJwt}`) .send({ - status: "something", + status: "changes_requested", }) .end((err, res) => { if (err) { @@ -431,7 +471,126 @@ describe("Application", function () { expect(res).to.have.status(400); expect(res.body.error).to.be.equal("Bad Request"); - expect(res.body.message).to.be.equal("Status must be one of: accepted, rejected, or changes_requested"); + expect(res.body.message).to.include("Feedback is required when status is changes_requested"); + return done(); + }); + }); + + it("should return 200 when submitting feedback with status accepted and optional feedback text", function (done) { + chai + .request(app) + .patch(`/applications/${applicationId4}/feedback`) + .set("cookie", `${cookieName}=${superUserJwt}`) + .send({ + status: "accepted", + feedback: "Great application!", + }) + .end((err, res) => { + if (err) { + return done(err); + } + + expect(res).to.have.status(200); + expect(res.body.message).to.be.equal("Application feedback submitted successfully"); + return done(); + }); + }); + + it("should return 200 when submitting feedback with status rejected and optional feedback text", function (done) { + chai + .request(app) + .patch(`/applications/${applicationId5}/feedback`) + .set("cookie", `${cookieName}=${superUserJwt}`) + .send({ + status: "rejected", + feedback: "Not a good fit for this role", + }) + .end((err, res) => { + if (err) { + return done(err); + } + + expect(res).to.have.status(200); + expect(res.body.message).to.be.equal("Application feedback submitted successfully"); + return done(); + }); + }); + + it("should return 200 when submitting feedback with status accepted and empty feedback string", function (done) { + chai + .request(app) + .patch(`/applications/${applicationId2}/feedback`) + .set("cookie", `${cookieName}=${superUserJwt}`) + .send({ + status: "accepted", + feedback: "", + }) + .end((err, res) => { + if (err) { + return done(err); + } + + expect(res).to.have.status(200); + expect(res.body.message).to.be.equal("Application feedback submitted successfully"); + return done(); + }); + }); + + it("should return 404 when application does not exist", function (done) { + chai + .request(app) + .patch(`/applications/non-existent-application-id/feedback`) + .set("cookie", `${cookieName}=${superUserJwt}`) + .send({ + status: "accepted", + }) + .end((err, res) => { + if (err) { + return done(err); + } + + expect(res).to.have.status(404); + expect(res.body.error).to.be.equal("Not Found"); + expect(res.body.message).to.be.equal("Application not found"); + return done(); + }); + }); + + it("should return 401 when user is not authenticated", function (done) { + chai + .request(app) + .patch(`/applications/${applicationId1}/feedback`) + .send({ + status: "accepted", + }) + .end((err, res) => { + if (err) { + return done(err); + } + + expect(res).to.have.status(401); + expect(res.body.error).to.be.equal("Unauthorized"); + expect(res.body.message).to.be.equal("Unauthenticated User"); + return done(); + }); + }); + + it("should return 401 if user is not a super user", function (done) { + chai + .request(app) + .patch(`/applications/${applicationId1}/feedback`) + .set("cookie", `${cookieName}=${jwt}`) + .send({ + status: "accepted", + }) + .end((err, res) => { + if (err) { + return done(err); + } + + expect(res).to.have.status(401); + expect(res.body.error).to.be.equal("Unauthorized"); + expect(res.body.message).to.be.equal("You are not authorized for this action."); return done(); }); }); diff --git a/test/unit/controllers/applications.test.ts b/test/unit/controllers/applications.test.ts index 2e3036270..39aff8302 100644 --- a/test/unit/controllers/applications.test.ts +++ b/test/unit/controllers/applications.test.ts @@ -23,6 +23,7 @@ describe("nudgeApplication", () => { let boomBadRequest: sinon.SinonSpy; let boomTooManyRequests: sinon.SinonSpy; let boomBadImplementation: sinon.SinonSpy; + let nudgeApplicationStub: sinon.SinonStub; const mockApplicationId = "test-application-id-123"; const mockUserId = "test-user-id-456"; @@ -55,6 +56,8 @@ describe("nudgeApplication", () => { badImplementation: boomBadImplementation, }, }; + + nudgeApplicationStub = sinon.stub(ApplicationModel, "nudgeApplication"); }); afterEach(() => { @@ -69,7 +72,7 @@ describe("nudgeApplication", () => { lastNudgeAt: new Date().toISOString(), }; - const nudgeApplicationStub = sinon.stub(ApplicationModel, "nudgeApplication").resolves(mockResult); + nudgeApplicationStub.resolves(mockResult); await applicationsController.nudgeApplication(req as CustomRequest, res as CustomResponse); @@ -92,7 +95,7 @@ describe("nudgeApplication", () => { lastNudgeAt: new Date().toISOString(), }; - const nudgeApplicationStub = sinon.stub(ApplicationModel, "nudgeApplication").resolves(mockResult); + nudgeApplicationStub.resolves(mockResult); await applicationsController.nudgeApplication(req as CustomRequest, res as CustomResponse); @@ -115,7 +118,7 @@ describe("nudgeApplication", () => { lastNudgeAt: new Date().toISOString(), }; - sinon.stub(ApplicationModel, "nudgeApplication").resolves(mockResult); + nudgeApplicationStub.resolves(mockResult); await applicationsController.nudgeApplication(req as CustomRequest, res as CustomResponse); @@ -130,7 +133,7 @@ describe("nudgeApplication", () => { status: "notFound", }; - sinon.stub(ApplicationModel, "nudgeApplication").resolves(mockResult); + nudgeApplicationStub.resolves(mockResult); await applicationsController.nudgeApplication(req as CustomRequest, res as CustomResponse); @@ -144,7 +147,7 @@ describe("nudgeApplication", () => { status: "unauthorized", }; - sinon.stub(ApplicationModel, "nudgeApplication").resolves(mockResult); + nudgeApplicationStub.resolves(mockResult); await applicationsController.nudgeApplication(req as CustomRequest, res as CustomResponse); @@ -158,7 +161,7 @@ describe("nudgeApplication", () => { status: "tooSoon", }; - sinon.stub(ApplicationModel, "nudgeApplication").resolves(mockResult); + nudgeApplicationStub.resolves(mockResult); await applicationsController.nudgeApplication(req as CustomRequest, res as CustomResponse); @@ -172,7 +175,7 @@ describe("nudgeApplication", () => { status: "tooSoon", }; - sinon.stub(ApplicationModel, "nudgeApplication").resolves(mockResult); + nudgeApplicationStub.resolves(mockResult); await applicationsController.nudgeApplication(req as CustomRequest, res as CustomResponse); @@ -186,7 +189,7 @@ describe("nudgeApplication", () => { status: "notPending", }; - sinon.stub(ApplicationModel, "nudgeApplication").resolves(mockResult); + nudgeApplicationStub.resolves(mockResult); await applicationsController.nudgeApplication(req as CustomRequest, res as CustomResponse); @@ -196,3 +199,130 @@ describe("nudgeApplication", () => { }); }); }); + +describe("submitApplicationFeedback", () => { + let req: Partial; + let res: Partial & { + json: sinon.SinonSpy; + boom: { + notFound: sinon.SinonSpy; + badImplementation: sinon.SinonSpy; + }; + }; + let jsonSpy: sinon.SinonSpy; + let boomNotFound: sinon.SinonSpy; + let boomBadImplementation: sinon.SinonSpy; + let addApplicationFeedbackStub: sinon.SinonStub; + + const mockApplicationId = "test-application-id-123"; + const mockUsername = "superuser"; + const mockFeedback = "Great application!"; + const mockStatus = "accepted"; + + beforeEach(() => { + jsonSpy = sinon.spy(); + boomNotFound = sinon.spy(); + boomBadImplementation = sinon.spy(); + + req = { + params: { + applicationId: mockApplicationId, + }, + body: { + status: mockStatus, + feedback: mockFeedback, + }, + userData: { + id: "superuser-id", + username: mockUsername, + }, + }; + + res = { + json: jsonSpy, + boom: { + notFound: boomNotFound, + badImplementation: boomBadImplementation, + }, + }; + + addApplicationFeedbackStub = sinon.stub(ApplicationModel, "addApplicationFeedback"); + }); + + afterEach(() => { + sinon.restore(); + }); + + describe("Success cases", () => { + it("should successfully submit application feedback", async () => { + const mockResult = { + status: "success", + }; + + addApplicationFeedbackStub.resolves(mockResult); + + await applicationsController.submitApplicationFeedback(req as CustomRequest, res as CustomResponse); + + expect(addApplicationFeedbackStub.calledOnce).to.be.true; + expect(addApplicationFeedbackStub.firstCall.args[0]).to.deep.equal({ + applicationId: mockApplicationId, + status: mockStatus, + feedback: mockFeedback, + reviewerName: mockUsername, + }); + + expect(jsonSpy.calledOnce).to.be.true; + expect(jsonSpy.firstCall.args[0].message).to.equal(API_RESPONSE_MESSAGES.FEEDBACK_SUBMITTED_SUCCESS); + }); + + it("should successfully submit application feedback without optional feedback text", async () => { + req.body = { + status: mockStatus, + }; + + const mockResult = { + status: "success", + }; + + addApplicationFeedbackStub.resolves(mockResult); + + await applicationsController.submitApplicationFeedback(req as CustomRequest, res as CustomResponse); + + expect(addApplicationFeedbackStub.calledOnce).to.be.true; + expect(addApplicationFeedbackStub.firstCall.args[0]).to.deep.equal({ + applicationId: mockApplicationId, + status: mockStatus, + feedback: undefined, + reviewerName: mockUsername, + }); + + expect(jsonSpy.calledOnce).to.be.true; + expect(jsonSpy.firstCall.args[0].message).to.equal(API_RESPONSE_MESSAGES.FEEDBACK_SUBMITTED_SUCCESS); + }); + }); + + describe("Error cases", () => { + it("should return application not found error", async () => { + const mockResult = { + status: "notFound", + }; + + addApplicationFeedbackStub.resolves(mockResult); + + await applicationsController.submitApplicationFeedback(req as CustomRequest, res as CustomResponse); + + expect(boomNotFound.calledOnce).to.be.true; + expect(boomNotFound.firstCall.args[0]).to.equal("Application not found"); + expect(jsonSpy.notCalled).to.be.true; + }); + + it("should return internal server error when an unexpected error occurs", async () => { + addApplicationFeedbackStub.rejects(new Error("Database error")); + + await applicationsController.submitApplicationFeedback(req as CustomRequest, res as CustomResponse); + + expect(boomBadImplementation.calledOnce).to.be.true; + expect(jsonSpy.notCalled).to.be.true; + }); + }); +}); diff --git a/test/unit/middlewares/application-validator.test.ts b/test/unit/middlewares/application-validator.test.ts index fc08ad2c4..633d8231f 100644 --- a/test/unit/middlewares/application-validator.test.ts +++ b/test/unit/middlewares/application-validator.test.ts @@ -1,5 +1,6 @@ import chai from "chai"; -const Sinon = require("sinon"); +import sinon from "sinon"; +const Sinon = sinon; const { expect } = chai; const applicationValidator = require("../../../middlewares/validators/application"); const applicationsData = require("../../fixtures/applications/applications")(); @@ -89,91 +90,159 @@ describe("application validator test", function () { }); describe("validateApplicationUpdateData", function () { - it("should call next function if only status and feedback is passed, and status has any of the allowed values", async function () { - const req = { - body: { - status: "accepted", - feedback: "some feedback", - }, + let req: any; + let res: any; + let nextSpy: sinon.SinonSpy; + + beforeEach(function () { + req = { + body: {}, }; - const res = { + res = { boom: { badRequest: () => {}, }, }; - const nextSpy = Sinon.spy(); + nextSpy = Sinon.spy(); + }); + + it("should call next function if only status and feedback is passed, and status has any of the allowed values", async function () { + req.body = { + status: "accepted", + feedback: "some feedback", + }; await applicationValidator.validateApplicationUpdateData(req, res, nextSpy); expect(nextSpy.callCount).to.equal(1); }); it("should not call next function if any value other than status and feedback is passed", async function () { - const req = { - body: { - batman: true, - }, + req.body = { + batman: true, }; - const res = { - boom: { - badRequest: () => {}, - }, + await applicationValidator.validateApplicationUpdateData(req, res, nextSpy); + expect(nextSpy.callCount).to.equal(0); + }); + + it("should not call the next function if any value which is not allowed is sent in status", async function () { + req.body = { + status: "something", }; + await applicationValidator.validateApplicationUpdateData(req, res, nextSpy); + expect(nextSpy.callCount).to.equal(0); + }); - const nextSpy = Sinon.spy(); + it("should call next function when status is accepted with optional feedback", async function () { + req.body = { + status: "accepted", + feedback: "Great work!", + }; + await applicationValidator.validateApplicationUpdateData(req, res, nextSpy); + expect(nextSpy.callCount).to.equal(1); + }); + + it("should call next function when status is rejected with optional feedback", async function () { + req.body = { + status: "rejected", + feedback: "Not a good fit", + }; + await applicationValidator.validateApplicationUpdateData(req, res, nextSpy); + expect(nextSpy.callCount).to.equal(1); + }); + + it("should call next function when status is changes_requested with feedback", async function () { + req.body = { + status: "changes_requested", + feedback: "Please update your skills section", + }; + await applicationValidator.validateApplicationUpdateData(req, res, nextSpy); + expect(nextSpy.callCount).to.equal(1); + }); + + it("should not call next function when status is changes_requested without feedback", async function () { + req.body = { + status: "changes_requested", + }; await applicationValidator.validateApplicationUpdateData(req, res, nextSpy); expect(nextSpy.callCount).to.equal(0); }); - it("should not call the next function if any value which is not allowed is sent in status", async function () { - const req = { - body: { - status: "something", - }, + it("should not call next function when status is changes_requested with empty feedback string", async function () { + req.body = { + status: "changes_requested", + feedback: "", }; - const res = { - boom: { - badRequest: () => {}, - }, + await applicationValidator.validateApplicationUpdateData(req, res, nextSpy); + expect(nextSpy.callCount).to.equal(0); + }); + + it("should call next function when status is accepted with empty feedback string", async function () { + req.body = { + status: "accepted", + feedback: "", }; + await applicationValidator.validateApplicationUpdateData(req, res, nextSpy); + expect(nextSpy.callCount).to.equal(1); + }); - const nextSpy = Sinon.spy(); + it("should call next function when status is rejected with empty feedback string", async function () { + req.body = { + status: "rejected", + feedback: "", + }; + await applicationValidator.validateApplicationUpdateData(req, res, nextSpy); + expect(nextSpy.callCount).to.equal(1); + }); + + it("should not call next function when status is missing", async function () { + req.body = { + feedback: "Some feedback", + }; + await applicationValidator.validateApplicationUpdateData(req, res, nextSpy); + expect(nextSpy.callCount).to.equal(0); + }); + + it("should not call next function when status is null", async function () { + req.body = { + status: null, + }; await applicationValidator.validateApplicationUpdateData(req, res, nextSpy); expect(nextSpy.callCount).to.equal(0); }); }); describe("validateApplicationQueryParam", function () { - it("should call the next function if allowed query params are passed", async function () { - const req = { - query: { - userId: "kfjadskfj", - status: "accepted", - size: "4", - next: "kfsdfksdfjksd", - dev: "true", - }, + let req: any; + let res: any; + let nextSpy: sinon.SinonSpy; + + beforeEach(function () { + req = { + query: {}, }; - const res = { + res = { boom: { badRequest: () => {}, }, }; - const nextSpy = Sinon.spy(); + nextSpy = Sinon.spy(); + }); + + it("should call the next function if allowed query params are passed", async function () { + req.query = { + userId: "kfjadskfj", + status: "accepted", + size: "4", + next: "kfsdfksdfjksd", + dev: "true", + }; await applicationValidator.validateApplicationQueryParam(req, res, nextSpy); expect(nextSpy.callCount).to.equal(1); }); it("should not call next function if any value that is not allowed is passed in query params", async function () { - const req = { - query: { - hello: "true", - }, - }; - const res = { - boom: { - badRequest: () => {}, - }, + req.query = { + hello: "true", }; - const nextSpy = Sinon.spy(); await applicationValidator.validateApplicationQueryParam(req, res, nextSpy); expect(nextSpy.callCount).to.equal(0); }); diff --git a/test/unit/models/application.test.ts b/test/unit/models/application.test.ts index ea5f2d81d..07e1080aa 100644 --- a/test/unit/models/application.test.ts +++ b/test/unit/models/application.test.ts @@ -118,4 +118,192 @@ describe("applications", function () { expect(application.status).to.be.equal("accepted"); }); }); + + describe("addApplicationFeedback", function () { + let testApplicationId: string; + const reviewerName = "test-reviewer"; + + beforeEach(async function () { + const testApplication = { ...applicationsData[0], userId: "test-user-feedback" }; + testApplicationId = await ApplicationModel.addApplication(testApplication); + }); + + it("should successfully add feedback with status accepted", async function () { + const result = await ApplicationModel.addApplicationFeedback({ + applicationId: testApplicationId, + status: "accepted", + reviewerName, + }); + + expect(result.status).to.be.equal("success"); + + const application = await ApplicationModel.getApplicationById(testApplicationId); + expect(application.status).to.be.equal("accepted"); + expect(application.feedback).to.be.a("array"); + expect(application.feedback.length).to.be.equal(1); + expect(application.feedback[0].status).to.be.equal("accepted"); + expect(application.feedback[0].reviewerName).to.be.equal(reviewerName); + expect(application.feedback[0].createdAt).to.exist; + expect(application.feedback[0]).to.not.have.property("feedback"); + }); + + it("should successfully add feedback with status rejected", async function () { + const result = await ApplicationModel.addApplicationFeedback({ + applicationId: testApplicationId, + status: "rejected", + reviewerName, + }); + + expect(result.status).to.be.equal("success"); + + const application = await ApplicationModel.getApplicationById(testApplicationId); + expect(application.status).to.be.equal("rejected"); + expect(application.feedback.length).to.be.equal(1); + expect(application.feedback[0].status).to.be.equal("rejected"); + }); + + it("should successfully add feedback with status changes_requested", async function () { + const feedbackText = "Please update your skills section"; + const result = await ApplicationModel.addApplicationFeedback({ + applicationId: testApplicationId, + status: "changes_requested", + feedback: feedbackText, + reviewerName, + }); + + expect(result.status).to.be.equal("success"); + + const application = await ApplicationModel.getApplicationById(testApplicationId); + expect(application.status).to.be.equal("changes_requested"); + expect(application.feedback.length).to.be.equal(1); + expect(application.feedback[0].status).to.be.equal("changes_requested"); + expect(application.feedback[0].feedback).to.be.equal(feedbackText); + }); + + it("should successfully add feedback with feedback text for accepted status", async function () { + const feedbackText = "Great application!"; + const result = await ApplicationModel.addApplicationFeedback({ + applicationId: testApplicationId, + status: "accepted", + feedback: feedbackText, + reviewerName, + }); + + expect(result.status).to.be.equal("success"); + + const application = await ApplicationModel.getApplicationById(testApplicationId); + expect(application.feedback[0].feedback).to.be.equal(feedbackText); + }); + + it("should trim whitespace from feedback text", async function () { + const feedbackText = " Please update your skills "; + const result = await ApplicationModel.addApplicationFeedback({ + applicationId: testApplicationId, + status: "changes_requested", + feedback: feedbackText, + reviewerName, + }); + + expect(result.status).to.be.equal("success"); + + const application = await ApplicationModel.getApplicationById(testApplicationId); + expect(application.feedback[0].feedback).to.be.equal("Please update your skills"); + }); + + it("should append feedback to existing feedback array", async function () { + await ApplicationModel.addApplicationFeedback({ + applicationId: testApplicationId, + status: "changes_requested", + feedback: "First feedback", + reviewerName: "reviewer1", + }); + + const result = await ApplicationModel.addApplicationFeedback({ + applicationId: testApplicationId, + status: "accepted", + feedback: "Second feedback", + reviewerName: "reviewer2", + }); + + expect(result.status).to.be.equal("success"); + + const application = await ApplicationModel.getApplicationById(testApplicationId); + expect(application.feedback.length).to.be.equal(2); + expect(application.feedback[0].status).to.be.equal("changes_requested"); + expect(application.feedback[0].reviewerName).to.be.equal("reviewer1"); + expect(application.feedback[1].status).to.be.equal("accepted"); + expect(application.feedback[1].reviewerName).to.be.equal("reviewer2"); + expect(application.status).to.be.equal("accepted"); + }); + + it("should handle application with no existing feedback array", async function () { + const result = await ApplicationModel.addApplicationFeedback({ + applicationId: testApplicationId, + status: "accepted", + reviewerName, + }); + + expect(result.status).to.be.equal("success"); + + const application = await ApplicationModel.getApplicationById(testApplicationId); + expect(application.feedback).to.be.a("array"); + expect(application.feedback.length).to.be.equal(1); + }); + + it("should not include feedback field when feedback is empty string", async function () { + const result = await ApplicationModel.addApplicationFeedback({ + applicationId: testApplicationId, + status: "accepted", + feedback: "", + reviewerName, + }); + + expect(result.status).to.be.equal("success"); + + const application = await ApplicationModel.getApplicationById(testApplicationId); + expect(application.feedback[0]).to.not.have.property("feedback"); + }); + + it("should not include feedback field when feedback is only whitespace", async function () { + const result = await ApplicationModel.addApplicationFeedback({ + applicationId: testApplicationId, + status: "accepted", + feedback: " ", + reviewerName, + }); + + expect(result.status).to.be.equal("success"); + + const application = await ApplicationModel.getApplicationById(testApplicationId); + expect(application.feedback[0]).to.not.have.property("feedback"); + }); + + it("should return notFound status when application does not exist", async function () { + const result = await ApplicationModel.addApplicationFeedback({ + applicationId: "non-existent-id", + status: "accepted", + reviewerName, + }); + + expect(result.status).to.be.equal("notFound"); + }); + + it("should include createdAt timestamp in feedback item", async function () { + const beforeTime = new Date().toISOString(); + const result = await ApplicationModel.addApplicationFeedback({ + applicationId: testApplicationId, + status: "accepted", + reviewerName, + }); + const afterTime = new Date().toISOString(); + + expect(result.status).to.be.equal("success"); + + const application = await ApplicationModel.getApplicationById(testApplicationId); + expect(application.feedback[0].createdAt).to.exist; + expect(application.feedback[0].createdAt).to.be.a("string"); + expect(application.feedback[0].createdAt >= beforeTime).to.be.true; + expect(application.feedback[0].createdAt <= afterTime).to.be.true; + }); + }); });