@@ -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