Skip to content

Commit 466d8e3

Browse files
Merge rsvp into admission
1 parent 1f40a61 commit 466d8e3

File tree

5 files changed

+287
-316
lines changed

5 files changed

+287
-316
lines changed

src/app.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import eventRouter from "./services/event/event-router.js";
99
import profileRouter from "./services/profile/profile-router.js";
1010
import staffRouter from "./services/staff/staff-router.js";
1111
import newsletterRouter from "./services/newsletter/newsletter-router.js";
12-
import rsvpRouter from "./services/rsvp/rsvp-router.js";
1312
import versionRouter from "./services/version/version-router.js";
1413
import admissionRouter from "./services/admission/admission-router.js";
1514

@@ -37,7 +36,6 @@ app.use("/auth/", authRouter);
3736
app.use("/event/", eventRouter);
3837
app.use("/newsletter/", newsletterRouter);
3938
app.use("/profile/", profileRouter);
40-
app.use("/rsvp/", rsvpRouter);
4139
app.use("/staff/", staffRouter);
4240
app.use("/user/", userRouter);
4341
app.use("/admission/", admissionRouter);
Lines changed: 113 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
import { beforeEach, describe, expect, it } from "@jest/globals";
22
import Models from "../../database/models.js";
3-
import { DecisionStatus, DecisionResponse } from "../../database/admission-db.js";
4-
import { getAsStaff, getAsUser, putAsStaff, putAsUser, TESTER } from "../../testTools.js";
5-
import { AdmissionDecision } from "../../database/admission-db.js";
3+
import { DecisionStatus, DecisionResponse, AdmissionDecision } from "../../database/admission-db.js";
4+
import { getAsStaff, getAsUser, putAsStaff, putAsUser, getAsAttendee, putAsApplicant, TESTER } from "../../testTools.js";
65
import { StatusCode } from "status-code-enum";
76
import { ApplicantDecisionFormat } from "./admission-formats.js";
87

9-
const TESTER_USER = {
8+
const TESTER_DECISION = {
109
userId: TESTER.id,
1110
status: DecisionStatus.ACCEPTED,
1211
response: DecisionResponse.PENDING,
1312
emailSent: false,
1413
reviewer: "tester-reviewer",
1514
} satisfies AdmissionDecision;
1615

17-
const OTHER_USER = {
16+
const OTHER_DECISION = {
1817
userId: "other-user",
1918
status: DecisionStatus.REJECTED,
2019
response: DecisionResponse.DECLINED,
2120
emailSent: true,
2221
reviewer: "other-reviewer",
2322
} satisfies AdmissionDecision;
2423

25-
const updateData = [
24+
const updateRequest = [
2625
{
2726
userId: TESTER.id,
2827
status: DecisionStatus.WAITLISTED,
@@ -35,39 +34,136 @@ const updateData = [
3534

3635
beforeEach(async () => {
3736
Models.initialize();
38-
await Models.AdmissionDecision.create(TESTER_USER);
39-
await Models.AdmissionDecision.create(OTHER_USER);
37+
await Models.AdmissionDecision.create(TESTER_DECISION);
38+
await Models.AdmissionDecision.create(OTHER_DECISION);
4039
});
4140

42-
describe("GET /admission", () => {
41+
describe("GET /admission/not-sent/", () => {
4342
it("gives forbidden error for user without elevated perms", async () => {
44-
const responseUser = await getAsUser("/admission/").expect(StatusCode.ClientErrorForbidden);
43+
const responseUser = await getAsUser("/admission/not-sent/").expect(StatusCode.ClientErrorForbidden);
4544
expect(JSON.parse(responseUser.text)).toHaveProperty("error", "Forbidden");
4645
});
4746
it("should return a list of applicants without email sent", async () => {
48-
const response = await getAsStaff("/admission/").expect(StatusCode.SuccessOK);
49-
expect(JSON.parse(response.text)).toMatchObject(expect.arrayContaining([expect.objectContaining(TESTER_USER)]));
47+
const response = await getAsStaff("/admission/not-sent/").expect(StatusCode.SuccessOK);
48+
expect(JSON.parse(response.text)).toMatchObject(expect.arrayContaining([expect.objectContaining(TESTER_DECISION)]));
5049
});
5150
});
5251

53-
describe("PUT /admission", () => {
52+
describe("PUT /admission/", () => {
5453
it("gives forbidden error for user without elevated perms", async () => {
55-
const responseUser = await putAsUser("/admission/").send(updateData).expect(StatusCode.ClientErrorForbidden);
54+
const responseUser = await putAsUser("/admission/").send(updateRequest).expect(StatusCode.ClientErrorForbidden);
5655
expect(JSON.parse(responseUser.text)).toHaveProperty("error", "Forbidden");
5756
});
5857
it("should update application status of applicants", async () => {
59-
const response = await putAsStaff("/admission/").send(updateData).expect(StatusCode.SuccessOK);
58+
const response = await putAsStaff("/admission/").send(updateRequest).expect(StatusCode.SuccessOK);
6059
expect(JSON.parse(response.text)).toHaveProperty("message", "StatusSuccess");
61-
const ops = updateData.map((entry) => {
60+
const ops = updateRequest.map((entry) => {
6261
return Models.AdmissionDecision.findOne({ userId: entry.userId });
6362
});
6463
const retrievedEntries = await Promise.all(ops);
6564
expect(retrievedEntries).toMatchObject(
6665
expect.arrayContaining(
67-
updateData.map((item) => {
66+
updateRequest.map((item) => {
6867
return expect.objectContaining({ status: item.status, userId: item.userId });
6968
}),
7069
),
7170
);
7271
});
7372
});
73+
74+
describe("GET /admission/rsvp/", () => {
75+
it("gives a UserNotFound error for an non-existent user", async () => {
76+
await Models.AdmissionDecision.deleteOne({
77+
userId: TESTER.id,
78+
});
79+
80+
const response = await getAsAttendee("/admission/rsvp/").expect(StatusCode.ClientErrorBadRequest);
81+
82+
expect(JSON.parse(response.text)).toHaveProperty("error", "UserNotFound");
83+
});
84+
85+
it("works for an attendee user and returns filtered data", async () => {
86+
const response = await getAsAttendee("/admission/rsvp/").expect(StatusCode.SuccessOK);
87+
88+
expect(JSON.parse(response.text)).toMatchObject({
89+
userId: TESTER_DECISION.userId,
90+
status: TESTER_DECISION.status,
91+
response: TESTER_DECISION.response,
92+
});
93+
});
94+
95+
it("works for a staff user and returns unfiltered data", async () => {
96+
const response = await getAsStaff("/admission/rsvp/").expect(StatusCode.SuccessOK);
97+
98+
expect(JSON.parse(response.text)).toMatchObject(TESTER_DECISION);
99+
});
100+
});
101+
102+
describe("GET /admission/rsvp/:USERID", () => {
103+
it("returns forbidden error if caller doesn't have elevated perms", async () => {
104+
const response = await getAsAttendee(`/admission/rsvp/${TESTER.id}`).expect(StatusCode.ClientErrorForbidden);
105+
106+
expect(JSON.parse(response.text)).toHaveProperty("error", "Forbidden");
107+
});
108+
109+
it("gets if caller has elevated perms", async () => {
110+
const response = await getAsStaff(`/admission/rsvp/${TESTER.id}`).expect(StatusCode.SuccessOK);
111+
112+
expect(JSON.parse(response.text)).toMatchObject(TESTER_DECISION);
113+
});
114+
115+
it("returns UserNotFound error if user doesn't exist", async () => {
116+
const response = await getAsStaff("/admission/rsvp/idontexist").expect(StatusCode.ClientErrorBadRequest);
117+
118+
expect(JSON.parse(response.text)).toHaveProperty("error", "UserNotFound");
119+
});
120+
});
121+
122+
describe("PUT /admission/rsvp", () => {
123+
it("error checking for empty query works", async () => {
124+
const response = await putAsApplicant("/admission/rsvp/").send({}).expect(StatusCode.ClientErrorBadRequest);
125+
126+
expect(JSON.parse(response.text)).toHaveProperty("error", "InvalidParams");
127+
});
128+
129+
it("returns UserNotFound for nonexistent user", async () => {
130+
await Models.AdmissionDecision.deleteOne({
131+
userId: TESTER.id,
132+
});
133+
const response = await putAsApplicant("/admission/rsvp/")
134+
.send({ isAttending: true })
135+
.expect(StatusCode.ClientErrorBadRequest);
136+
137+
expect(JSON.parse(response.text)).toHaveProperty("error", "UserNotFound");
138+
});
139+
140+
it("lets applicant accept accepted decision", async () => {
141+
await putAsApplicant("/admission/rsvp/").send({ isAttending: true }).expect(StatusCode.SuccessOK);
142+
const stored = await Models.AdmissionDecision.findOne({ userId: TESTER.id });
143+
144+
expect(stored).toMatchObject({
145+
...TESTER_DECISION,
146+
response: DecisionResponse.ACCEPTED,
147+
} satisfies AdmissionDecision);
148+
});
149+
150+
it("lets applicant reject accepted decision", async () => {
151+
await putAsApplicant("/admission/rsvp/").send({ isAttending: false }).expect(StatusCode.SuccessOK);
152+
const stored = await Models.AdmissionDecision.findOne({ userId: TESTER.id });
153+
154+
expect(stored).toMatchObject({
155+
...TESTER_DECISION,
156+
response: DecisionResponse.DECLINED,
157+
} satisfies AdmissionDecision);
158+
});
159+
160+
it("doesn't let applicant accept rejected decision", async () => {
161+
await Models.AdmissionDecision.findOneAndUpdate({ userId: TESTER.id }, { status: DecisionStatus.REJECTED });
162+
163+
const response = await putAsApplicant("/admission/rsvp/")
164+
.send({ isAttending: false })
165+
.expect(StatusCode.ClientErrorForbidden);
166+
167+
expect(JSON.parse(response.text)).toHaveProperty("error", "NotAccepted");
168+
});
169+
});

0 commit comments

Comments
 (0)