Skip to content

Commit 629751d

Browse files
committed
tests work
1 parent d6ccb9e commit 629751d

File tree

3 files changed

+87
-54
lines changed

3 files changed

+87
-54
lines changed

api/main_endpoints/routes/LedSign.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,12 @@ router.post('/updateSignText', async (req, res) => {
4040
let decoded = await decodeToken(req, MEMBERSHIP_STATE.OFFICER);
4141
if (decoded.status === FORBIDDEN) {
4242
const memberDecoded = await decodeToken(req, MEMBERSHIP_STATE.MEMBER);
43+
if (memberDecoded.status !== OK) {
44+
// return whatever decoded status we originally had
45+
return res.sendStatus(decoded.status);
46+
}
4347

44-
if (memberDecoded.status === OK) {
48+
try {
4549
const hasPermission = await PermissionRequest.findOne({
4650
userId: memberDecoded.token._id,
4751
type: 'LED_SIGN',
@@ -53,11 +57,17 @@ router.post('/updateSignText', async (req, res) => {
5357
}
5458
// "elevate" the status to OK for the rest of the function
5559
decoded = memberDecoded;
60+
} catch(e) {
61+
logger.info('looking for a possible led sign permission didnt work', e);
5662
}
5763
} else if (decoded.status !== OK) {
5864
logger.warn('/updateSignText was requested with an invalid token');
5965
return res.sendStatus(decoded.status);
6066
}
67+
console.log({
68+
'!LED_SIGN.ENABLED,': !LED_SIGN.ENABLED,
69+
'!runningInTest': !runningInTest,
70+
})
6171
if (!LED_SIGN.ENABLED && !runningInTest) {
6272
logger.warn('led sign is disabled, returning 200 by default');
6373
return res.sendStatus(OK);

api/main_endpoints/routes/PermissionRequest.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,10 @@ router.post('/delete', async (req, res) => {
7171
const isOfficer = decoded.token.accessLevel >= membershipState.OFFICER;
7272

7373
try {
74-
const query = { _id };
74+
const query = {
75+
_id,
76+
deletedAt: null,
77+
};
7578

7679
if (!isOfficer) {
7780
query.userId = decoded.token._id;

test/api/PermissionRequest.js

Lines changed: 72 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -210,78 +210,98 @@ describe('PermissionRequest', () => {
210210

211211
describe('/POST delete', () => {
212212
it('Should return 401 when token is not sent or invalid', async () => {
213-
const res1 = await test.sendPostRequest('/api/PermissionRequest/delete', { type: PermissionRequestTypes.LED_SIGN });
214-
expect(res1).to.have.status(UNAUTHORIZED);
215-
const res2 = await test.sendPostRequestWithToken(token, '/api/PermissionRequest/delete', { type: PermissionRequestTypes.LED_SIGN });
216-
expect(res2).to.have.status(UNAUTHORIZED);
213+
const res = await test.sendPostRequest('/api/PermissionRequest/delete', { _id: new mongoose.Types.ObjectId() });
214+
expect(res).to.have.status(UNAUTHORIZED);
217215
});
218216

219-
it('Should return 400 when type is invalid or missing', async () => {
220-
const userId = createUserToken();
221-
const invalidRes = await test.sendPostRequestWithToken(token, '/api/PermissionRequest/delete', { type: 'INVALID' });
222-
expect(invalidRes).to.have.status(BAD_REQUEST);
223-
const missingRes = await test.sendPostRequestWithToken(token, '/api/PermissionRequest/delete', {});
224-
expect(missingRes).to.have.status(BAD_REQUEST);
225-
});
217+
it('Should allow a Member to cancel their own PENDING request', async () => {
218+
const userId = createUserToken(constants.MEMBERSHIP_STATE.MEMBER);
219+
const request = await new PermissionRequest({
220+
userId,
221+
type: PermissionRequestTypes.LED_SIGN,
222+
status: 'PENDING'
223+
}).save();
226224

227-
it('Should delete permission request successfully and set deletedAt', async () => {
228-
const userId = createUserToken();
229-
await PermissionRequest.deleteMany({ userId, type: PermissionRequestTypes.LED_SIGN });
230-
const request = await new PermissionRequest({ userId, type: PermissionRequestTypes.LED_SIGN }).save();
231-
const beforeDelete = new Date();
232-
// For non-officers, the API uses userId as _id in query, which won't match request._id
233-
// So we need to test with an officer who can provide the actual _id
234-
createUserToken(constants.MEMBERSHIP_STATE.OFFICER);
235225
const res = await test.sendPostRequestWithToken(token, '/api/PermissionRequest/delete', {
236-
type: PermissionRequestTypes.LED_SIGN, _id: request._id
226+
_id: request._id
237227
});
228+
238229
expect(res).to.have.status(OK);
239230
const deleted = await PermissionRequest.findById(request._id);
240231
expect(deleted.deletedAt).to.not.be.null;
241-
expect(new Date(deleted.deletedAt).getTime()).to.be.at.least(beforeDelete.getTime());
232+
// Status stays PENDING because the user canceled it themselves
233+
expect(deleted.status).to.equal('PENDING');
242234
});
243235

244-
it('Should return 404 when _id does not exist or request already deleted', async () => {
245-
const userId = createUserToken(constants.MEMBERSHIP_STATE.OFFICER);
246-
const nonExistentId = new mongoose.Types.ObjectId();
247-
const res1 = await test.sendPostRequestWithToken(token, '/api/PermissionRequest/delete', {
248-
type: PermissionRequestTypes.LED_SIGN, _id: nonExistentId
249-
});
250-
expect(res1).to.have.status(NOT_FOUND);
251-
const deletedRequest = await new PermissionRequest({ userId, type: PermissionRequestTypes.LED_SIGN, deletedAt: new Date() }).save();
252-
const res2 = await test.sendPostRequestWithToken(token, '/api/PermissionRequest/delete', {
253-
type: PermissionRequestTypes.LED_SIGN, _id: deletedRequest._id
236+
it('Should set status to DENIED when an Officer deletes a PENDING request', async () => {
237+
const memberId = new mongoose.Types.ObjectId();
238+
const request = await new PermissionRequest({
239+
userId: memberId,
240+
type: PermissionRequestTypes.LED_SIGN,
241+
status: 'PENDING'
242+
}).save();
243+
244+
// Switch to Officer
245+
createUserToken(constants.MEMBERSHIP_STATE.OFFICER);
246+
const res = await test.sendPostRequestWithToken(token, '/api/PermissionRequest/delete', {
247+
_id: request._id
254248
});
255-
expect(res2).to.have.status(NOT_FOUND);
249+
250+
expect(res).to.have.status(OK);
251+
const updated = await PermissionRequest.findById(request._id);
252+
expect(updated.status).to.equal('DENIED');
253+
expect(updated.deletedAt).to.not.be.null;
256254
});
257255

258-
it('Should enforce authorization: non-officer cannot delete others, officer can delete any', async () => {
259-
const userId1 = createUserToken(constants.MEMBERSHIP_STATE.MEMBER);
260-
const userId2 = new mongoose.Types.ObjectId();
261-
const request2 = await createRequest(userId2);
262-
// Non-officer cannot delete another user's request
263-
const memberRes = await test.sendPostRequestWithToken(token, '/api/PermissionRequest/delete', {
264-
type: PermissionRequestTypes.LED_SIGN, _id: request2._id
265-
});
266-
expect(memberRes).to.have.status(NOT_FOUND);
267-
expect((await PermissionRequest.findById(request2._id)).deletedAt).to.be.null;
268-
// Officer can delete any request
256+
it('Should set status to REVOKED when an Officer deletes an APPROVED request', async () => {
257+
const memberId = new mongoose.Types.ObjectId();
258+
const request = await new PermissionRequest({
259+
userId: memberId,
260+
type: PermissionRequestTypes.LED_SIGN,
261+
status: 'APPROVED'
262+
}).save();
263+
269264
createUserToken(constants.MEMBERSHIP_STATE.OFFICER);
270-
const officerRes = await test.sendPostRequestWithToken(token, '/api/PermissionRequest/delete', {
271-
type: PermissionRequestTypes.LED_SIGN, _id: request2._id
265+
const res = await test.sendPostRequestWithToken(token, '/api/PermissionRequest/delete', {
266+
_id: request._id
272267
});
273-
expect(officerRes).to.have.status(OK);
274-
expect((await PermissionRequest.findById(request2._id)).deletedAt).to.not.be.null;
268+
269+
expect(res).to.have.status(OK);
270+
const updated = await PermissionRequest.findById(request._id);
271+
expect(updated.status).to.equal('REVOKED');
272+
expect(updated.deletedAt).to.not.be.null;
275273
});
276274

277-
it('Should require _id parameter even for officers', async () => {
278-
const userId = createUserToken(constants.MEMBERSHIP_STATE.OFFICER);
279-
const request = await createRequest(userId);
275+
it('Should return 404 if a non-officer tries to delete their own APPROVED request', async () => {
276+
// According to your code: if (!isOfficer) { query.status = 'PENDING' }
277+
// This means a member cannot revoke their own approved permission via this endpoint.
278+
const userId = createUserToken(constants.MEMBERSHIP_STATE.MEMBER);
279+
const request = await new PermissionRequest({
280+
userId,
281+
type: PermissionRequestTypes.LED_SIGN,
282+
status: 'APPROVED'
283+
}).save();
284+
285+
const res = await test.sendPostRequestWithToken(token, '/api/PermissionRequest/delete', {
286+
_id: request._id
287+
});
288+
289+
expect(res).to.have.status(NOT_FOUND);
290+
});
291+
292+
it('Should return 404 when request is already deleted (deletedAt is not null)', async () => {
293+
createUserToken(constants.MEMBERSHIP_STATE.OFFICER);
294+
const deletedRequest = await new PermissionRequest({
295+
userId: new mongoose.Types.ObjectId(),
296+
type: PermissionRequestTypes.LED_SIGN,
297+
deletedAt: new Date(),
298+
status: 'PENDING'
299+
}).save();
300+
280301
const res = await test.sendPostRequestWithToken(token, '/api/PermissionRequest/delete', {
281-
type: PermissionRequestTypes.LED_SIGN
302+
_id: deletedRequest._id
282303
});
283304
expect(res).to.have.status(NOT_FOUND);
284-
expect((await PermissionRequest.findById(request._id)).deletedAt).to.be.null;
285305
});
286306
});
287307
});

0 commit comments

Comments
 (0)