@@ -418,9 +418,50 @@ def test_reject_reviewer_assignment(self):
418418 r = self .client .get (req_url )
419419 self .assertEqual (r .status_code , 200 )
420420 self .assertContains (r , reject_url )
421+
422+ # anonymous user should not be able to reject
423+ self .client .logout ()
424+ r = self .client .post (reject_url , { "action" : "reject" , "message_to_secretary" : "Test message" })
425+ self .assertEqual (r .status_code , 302 ) # forwards to login page
426+ assignment = reload_db_objects (assignment )
427+ self .assertEqual (assignment .state_id , "accepted" )
428+
429+ # unrelated person should not be able to reject
430+ other_person = PersonFactory ()
431+ login_testing_unauthorized (self , other_person .user .username , reject_url )
432+ r = self .client .post (reject_url , { "action" : "reject" , "message_to_secretary" : "Test message" })
433+ self .assertEqual (r .status_code , 403 )
434+ assignment = reload_db_objects (assignment )
435+ self .assertEqual (assignment .state_id , "accepted" )
436+
437+ # Check that user can reject it
438+ login_testing_unauthorized (self , assignment .reviewer .person .user .username , reject_url )
439+ r = self .client .get (reject_url )
440+ self .assertEqual (r .status_code , 200 )
441+ self .assertContains (r , escape (assignment .reviewer .person .name ))
442+ self .assertNotContains (r , 'can not be rejected' )
443+ self .assertContains (r , '<button type="submit"' )
444+
445+ # reject
446+ empty_outbox ()
447+ r = self .client .post (reject_url , { "action" : "reject" , "message_to_secretary" : "Test message" })
448+ self .assertEqual (r .status_code , 302 )
449+
450+ assignment = reload_db_objects (assignment )
451+ self .assertEqual (assignment .state_id , "rejected" )
452+ self .assertNotEqual (assignment .completed_on ,None )
453+ e = doc .latest_event ()
454+ self .assertEqual (e .type , "closed_review_assignment" )
455+ self .assertTrue ("rejected" in e .desc )
456+ self .assertEqual (len (outbox ), 1 )
457+ self .assertNotIn (assignment .reviewer .address , outbox [0 ]["To" ])
458+ self .assertIn ("<reviewsecretary@example.com>" , outbox [0 ]["To" ])
459+ self .assertTrue ("Test message" in get_payload_text (outbox [0 ]))
421460 self .client .logout ()
422461
423- # get reject page
462+ # Secretary can also reject it
463+ assignment .state_id = 'assigned'
464+ assignment .save ()
424465 login_testing_unauthorized (self , "reviewsecretary" , reject_url )
425466 r = self .client .get (reject_url )
426467 self .assertEqual (r .status_code , 200 )
@@ -444,12 +485,17 @@ def test_reject_reviewer_assignment(self):
444485 self .assertNotIn ("<reviewsecretary@example.com>" , outbox [0 ]["To" ])
445486 self .assertTrue ("Test message" in get_payload_text (outbox [0 ]))
446487
447- # try again, but now with an expired review request, which should not be allowed (#2277)
488+ # try again, but now with an expired review request,
489+ # which should not be allowed (#2277)
448490 assignment .state_id = 'assigned'
449491 assignment .save ()
450492 review_req .deadline = datetime .date (2019 , 1 , 1 )
451493 review_req .save ()
494+ self .client .logout ()
452495
496+ # Login as reviewer to do this test, so it should fail, as the
497+ # request is past deadline
498+ login_testing_unauthorized (self , assignment .reviewer .person .user .username , reject_url )
453499 r = self .client .get (reject_url )
454500 self .assertEqual (r .status_code , 200 )
455501 self .assertContains (r , escape (assignment .reviewer .person .name ))
@@ -461,10 +507,67 @@ def test_reject_reviewer_assignment(self):
461507 r = self .client .post (reject_url , { "action" : "reject" , "message_to_secretary" : "Test message" })
462508 self .assertEqual (r .status_code , 200 )
463509 self .assertContains (r , 'can not be rejected' )
510+ self .client .logout ()
511+
512+ # Change settings so that even the reviewer should
513+ # be allowed to reject the request even after past deadline
514+ m = apps .get_model ('review' , 'ReviewTeamSettings' )
515+ for row in m .objects .all ():
516+ if row .group .upcase_acronym == review_team .upcase_acronym :
517+ row .allow_reviewer_to_reject_after_deadline = True
518+ row .save (update_fields = ['allow_reviewer_to_reject_after_deadline' ])
519+
520+ # Test again as user
521+ login_testing_unauthorized (self , assignment .reviewer .person .user .username , reject_url )
522+ r = self .client .get (reject_url )
523+ self .assertEqual (r .status_code , 200 )
524+ self .assertContains (r , escape (assignment .reviewer .person .name ))
525+ self .assertNotContains (r , 'can not be rejected' )
526+ self .assertContains (r , '<button type="submit"' )
527+
528+ # actually reject
529+ r = self .client .post (reject_url , { "action" : "reject" , "message_to_secretary" : "Test message" })
530+ self .assertEqual (r .status_code , 302 )
464531
465532 assignment = reload_db_objects (assignment )
466- self .assertEqual (assignment .state_id , "assigned" )
467- self .assertEqual (len (outbox ), 0 )
533+ self .assertEqual (assignment .state_id , "rejected" )
534+ self .assertNotEqual (len (outbox ), 0 )
535+ self .client .logout ()
536+
537+ # Log in as secretary and that should still allow rejecting the review
538+ assignment .state_id = 'assigned'
539+ assignment .save ()
540+ login_testing_unauthorized (self , "reviewsecretary" , reject_url )
541+ r = self .client .get (reject_url )
542+ self .assertEqual (r .status_code , 200 )
543+ self .assertContains (r , escape (assignment .reviewer .person .name ))
544+ self .assertNotContains (r , 'can not be rejected' )
545+ self .assertContains (r , '<button type="submit"' )
546+
547+ # actually reject
548+ empty_outbox ()
549+ r = self .client .post (reject_url , { "action" : "reject" , "message_to_secretary" : "Test message" })
550+ self .assertEqual (r .status_code , 302 )
551+
552+ assignment = reload_db_objects (assignment )
553+ self .assertEqual (assignment .state_id , "rejected" )
554+ self .assertNotEqual (len (outbox ), 0 )
555+
556+ # Revert the setting of allow_reviewer_to_reject_after_deadline
557+ # This should not affect the secretary's ability to reject.
558+ m = apps .get_model ('review' , 'ReviewTeamSettings' )
559+ for row in m .objects .all ():
560+ if row .group .upcase_acronym == review_team .upcase_acronym :
561+ row .allow_reviewer_to_reject_after_deadline = False
562+ row .save (update_fields = ['allow_reviewer_to_reject_after_deadline' ])
563+ assignment .state_id = 'assigned'
564+ assignment .save ()
565+ r = self .client .get (reject_url )
566+ self .assertEqual (r .status_code , 200 )
567+ self .assertContains (r , escape (assignment .reviewer .person .name ))
568+ self .assertNotContains (r , 'can not be rejected' )
569+ self .assertContains (r , '<button type="submit"' )
570+
468571
469572 def make_test_mbox_tarball (self , review_req ):
470573 mbox_path = os .path .join (self .review_dir , "testmbox.tar.gz" )
0 commit comments