Skip to content

Commit 010337f

Browse files
committed
feat(application-feedback): update route name and add new schema chagnes
1 parent 0f75af9 commit 010337f

File tree

7 files changed

+134
-26
lines changed

7 files changed

+134
-26
lines changed

constants/application.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
const APPLICATION_STATUS_TYPES = ["accepted", "rejected", "pending"];
2+
const NEW_APPLICATION_STATUS_TYPES = ["not_submitted", "pending", "accepted", "rejected", "requested_changes"]
23

34
const API_RESPONSE_MESSAGES = {
45
APPLICATION_RETURN_SUCCESS: "Applications returned successfully",
56
};
67

7-
module.exports = { APPLICATION_STATUS_TYPES, API_RESPONSE_MESSAGES };
8+
module.exports = { APPLICATION_STATUS_TYPES, API_RESPONSE_MESSAGES, NEW_APPLICATION_STATUS_TYPES };

controllers/applications.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,21 +102,32 @@ const addApplication = async (req: CustomRequest, res: CustomResponse) => {
102102

103103
const updateApplication = async (req: CustomRequest, res: CustomResponse) => {
104104
try {
105+
const devFeatureFlag = req?.query?.dev === "true";
105106
const { applicationId } = req.params;
106107
const rawBody = req.body;
107108

109+
const updatePayload = devFeatureFlag
110+
? {
111+
status: rawBody.status,
112+
adminFeedback: admin.firestore.FieldValue.arrayUnion({
113+
status: rawBody.status,
114+
feedback: rawBody.feedback,
115+
createdAt: admin.firestore.Timestamp.now(),
116+
}),
117+
}
118+
: rawBody;
108119
const applicationLog = {
109120
type: logType.APPLICATION_UPDATED,
110121
meta: {
111122
applicationId,
112123
username: req.userData.username,
113124
userId: req.userData.id,
114125
},
115-
body: rawBody,
126+
body: updatePayload,
116127
};
117128

118129
const promises = [
119-
ApplicationModel.updateApplication(rawBody, applicationId),
130+
ApplicationModel.updateApplication(updatePayload, applicationId),
120131
addLog(applicationLog.type, applicationLog.meta, applicationLog.body),
121132
];
122133

middlewares/validators/application.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { NextFunction } from "express";
22
import { CustomRequest, CustomResponse } from "../../types/global";
33
import { customWordCountValidator } from "../../utils/customWordCountValidator";
44
const joi = require("joi");
5-
const { APPLICATION_STATUS_TYPES } = require("../../constants/application");
5+
const { APPLICATION_STATUS_TYPES, NEW_APPLICATION_STATUS_TYPES } = require("../../constants/application");
66
const logger = require("../../utils/logger");
77

88
const validateApplicationData = async (req: CustomRequest, res: CustomResponse, next: NextFunction) => {
@@ -46,6 +46,7 @@ const validateApplicationData = async (req: CustomRequest, res: CustomResponse,
4646
};
4747

4848
const validateApplicationUpdateData = async (req: CustomRequest, res: CustomResponse, next: NextFunction) => {
49+
const devFeatureFlag = req?.query?.dev === "true"
4950
const schema = joi
5051
.object()
5152
.strict()
@@ -55,7 +56,8 @@ const validateApplicationUpdateData = async (req: CustomRequest, res: CustomResp
5556
.min(1)
5657
.optional()
5758
.custom((value, helper) => {
58-
if (!APPLICATION_STATUS_TYPES.includes(value)) {
59+
const allowedStatus= devFeatureFlag? NEW_APPLICATION_STATUS_TYPES: APPLICATION_STATUS_TYPES
60+
if (!allowedStatus.includes(value)) {
5961
return helper.message("Status is not valid");
6062
}
6163
return value;

routes/applications.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ router.get(
1818
router.get("/:applicationId", authenticate, authorizeRoles([SUPERUSER]), applications.getApplicationById);
1919
router.post("/", authenticate, applicationValidator.validateApplicationData, applications.addApplication);
2020
router.patch(
21-
"/:applicationId",
21+
"/:applicationId/feedback",
2222
authenticate,
2323
authorizeRoles([SUPERUSER]),
2424
applicationValidator.validateApplicationUpdateData,

test/integration/application.test.ts

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ describe("Application", function () {
207207
});
208208
});
209209

210-
it("should return application with status accepted if status accepted is passed in query params", function (done) {
210+
it("should return application with status accepted if status accepted is passed in query params", function (done) {
211211
chai
212212
.request(app)
213213
.get("/applications?status=accepted")
@@ -247,7 +247,7 @@ describe("Application", function () {
247247
});
248248
});
249249

250-
250+
251251
it("should return application with status rejected and the total count of the rejected applications if dev = true ", function (done) {
252252
chai
253253
.request(app)
@@ -271,7 +271,7 @@ describe("Application", function () {
271271
});
272272
});
273273

274-
it("should return application with status accepted and the total count of the accepted applications if dev = true ", function (done) {
274+
it("should return application with status accepted and the total count of the accepted applications if dev = true ", function (done) {
275275
chai
276276
.request(app)
277277
.get("/applications?status=accepted&dev=true")
@@ -372,11 +372,11 @@ describe("Application", function () {
372372
});
373373
});
374374

375-
describe("PATCH /application/:applicationId", function () {
375+
describe("PATCH /application/:applicationId/feedback", function () {
376376
it("should return 200 if the user is super user and application is updated", function (done) {
377377
chai
378378
.request(app)
379-
.patch(`/applications/${applicationId1}`)
379+
.patch(`/applications/${applicationId1}/feedback`)
380380
.set("cookie", `${cookieName}=${superUserJwt}`)
381381
.send({
382382
status: "accepted",
@@ -395,7 +395,7 @@ describe("Application", function () {
395395
it("should return 401 if the user is not super user", function (done) {
396396
chai
397397
.request(app)
398-
.patch(`/applications/${applicationId1}`)
398+
.patch(`/applications/${applicationId1}/feedback`)
399399
.set("cookie", `${cookieName}=${jwt}`)
400400
.send({
401401
status: "accepted",
@@ -414,7 +414,7 @@ describe("Application", function () {
414414
it("should return 400 if anything other than status and feedback is passed in the body", function (done) {
415415
chai
416416
.request(app)
417-
.patch(`/applications/${applicationId1}`)
417+
.patch(`/applications/${applicationId1}/feedback`)
418418
.set("cookie", `${cookieName}=${superUserJwt}`)
419419
.send({
420420
status: "accepted",
@@ -432,10 +432,48 @@ describe("Application", function () {
432432
});
433433
});
434434

435-
it("should return 400 if any status other than accepted, reject or pending is passed", function (done) {
435+
it("should return 400 if any status other than accepted, reject or pending is passed when dev flag is not present", function (done) {
436+
chai
437+
.request(app)
438+
.patch(`/applications/${applicationId1}/feedback`)
439+
.set("cookie", `${cookieName}=${superUserJwt}`)
440+
.send({
441+
status: "something",
442+
})
443+
.end((err, res) => {
444+
if (err) {
445+
return done(err);
446+
}
447+
448+
expect(res).to.have.status(400);
449+
expect(res.body.error).to.be.equal("Bad Request");
450+
expect(res.body.message).to.be.equal("Status is not valid");
451+
return done();
452+
});
453+
});
454+
455+
it("should return 200 if status is from not_submitted, pending, accepted, rejected, requested_changes when dev flag is present", function (done) {
456+
chai
457+
.request(app)
458+
.patch(`/applications/${applicationId1}/feedback?dev=true`)
459+
.set("cookie", `${cookieName}=${superUserJwt}`)
460+
.send({
461+
status: "not_submitted",
462+
})
463+
.end((err, res) => {
464+
if (err) {
465+
return done(err);
466+
}
467+
468+
expect(res).to.have.status(200);
469+
expect(res.body.message).to.be.equal("Application updated successfully!");
470+
return done();
471+
});
472+
});
473+
it("should return 400 if any status other than not_submitted, pending, accepted, rejected, requested_changes is passed when dev flag is present", function (done) {
436474
chai
437475
.request(app)
438-
.patch(`/applications/${applicationId1}`)
476+
.patch(`/applications/${applicationId1}/feedback?dev=true`)
439477
.set("cookie", `${cookieName}=${superUserJwt}`)
440478
.send({
441479
status: "something",

test/unit/middlewares/application-validator.test.ts

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ describe("application validator test", function () {
88
describe("validateApplicationData", function () {
99
it("should call next function if everything is according to the validator", async function () {
1010
const rawData = {
11-
...applicationsData[6]
12-
}
11+
...applicationsData[6],
12+
};
1313

1414
const req = {
1515
body: rawData,
@@ -21,7 +21,7 @@ describe("application validator test", function () {
2121
});
2222

2323
it("should not call the next function if a required field is missed", async function () {
24-
const rawData = { ...applicationsData[6] }
24+
const rawData = { ...applicationsData[6] };
2525
delete rawData.numberOfHours;
2626

2727
const req = {
@@ -40,10 +40,10 @@ describe("application validator test", function () {
4040
});
4141

4242
it("should not call the next function if any of the values which have a wordCount restriction doesn't contain the expected number of words", async function () {
43-
const rawData = {
44-
...applicationsData[6],
45-
whyRds: 'jfaskdfjsd'
46-
};
43+
const rawData = {
44+
...applicationsData[6],
45+
whyRds: "jfaskdfjsd",
46+
};
4747

4848
const req = {
4949
body: rawData,
@@ -61,10 +61,10 @@ describe("application validator test", function () {
6161
});
6262

6363
it("should not call the next function if number of hours is not a number", async function () {
64-
const rawData = {
65-
...applicationsData[6],
66-
numberOfHours: '10'
67-
};
64+
const rawData = {
65+
...applicationsData[6],
66+
numberOfHours: "10",
67+
};
6868

6969
const req = {
7070
body: rawData,
@@ -133,6 +133,55 @@ describe("application validator test", function () {
133133
await applicationValidator.validateApplicationUpdateData(req, res, nextSpy);
134134
expect(nextSpy.callCount).to.equal(0);
135135
});
136+
137+
it("should call next function if only status and feedback is passed, and status has any of the allowed values and dev flag is true", async function () {
138+
const req = {
139+
query: { dev: "true" },
140+
body: {
141+
status: "accepted",
142+
feedback: "good job",
143+
},
144+
};
145+
const res = { boom: { badRequest: Sinon.spy() } };
146+
const nextSpy = Sinon.spy();
147+
148+
await applicationValidator.validateApplicationUpdateData(req, res, nextSpy);
149+
150+
expect(nextSpy.callCount).to.equal(1);
151+
expect(res.boom.badRequest.callCount).to.equal(0);
152+
});
153+
154+
it("should not call next function if any value which is not allowed is sent in status and dev flag is true", async function () {
155+
const req = {
156+
query: { dev: "true" },
157+
body: {
158+
status: "invalid-status",
159+
feedback: "good job",
160+
},
161+
};
162+
const res = { boom: { badRequest: Sinon.spy() } };
163+
const nextSpy = Sinon.spy();
164+
165+
await applicationValidator.validateApplicationUpdateData(req, res, nextSpy);
166+
expect(nextSpy.callCount).to.equal(0);
167+
});
168+
it("should not call next function if any value other than status and feedback is passed and dev flag is true", async function () {
169+
const req = {
170+
query: { dev: "true" },
171+
body: {
172+
batman: true,
173+
},
174+
};
175+
const res = {
176+
boom: {
177+
badRequest: () => {},
178+
},
179+
};
180+
181+
const nextSpy = Sinon.spy();
182+
await applicationValidator.validateApplicationUpdateData(req, res, nextSpy);
183+
expect(nextSpy.callCount).to.equal(0);
184+
});
136185
});
137186

138187
describe("validateApplicationQueryParam", function () {

types/application.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ export type application = {
2323
status?: string;
2424
createdAt?: string;
2525
foundFrom: string;
26+
adminFeedback?: AdminFeedbackItem[];
27+
};
28+
29+
export type AdminFeedbackItem = {
30+
status: string;
31+
feedback?: string | null;
32+
createdAt: string;
2633
};
2734

2835
export type applicationPayload = {

0 commit comments

Comments
 (0)