diff --git a/openreview/arr/arr.py b/openreview/arr/arr.py index a0a091647..86a7e81a9 100644 --- a/openreview/arr/arr.py +++ b/openreview/arr/arr.py @@ -163,6 +163,9 @@ def get_id(self): def get_short_name(self): return self.venue.get_short_name() + def get_message_sender(self): + return self.venue.get_message_sender() + def get_edges_archive_date(self): return self.venue.get_edges_archive_date() @@ -214,6 +217,9 @@ def get_custom_user_demands_id(self, committee_id): def get_constraint_label_id(self, committee_id): return self.venue.get_constraint_label_id(committee_id) + def get_message_id(self, committee_id=None, number=None): + return self.venue.get_message_id(committee_id=committee_id, number=number) + def get_recommendation_id(self, committee_id=None): return self.venue.get_recommendation_id(committee_id) @@ -307,6 +313,9 @@ def get_desk_rejection_id(self, number = None): def get_desk_rejected_id(self): return self.venue.get_desk_rejected_id() + def get_group_recruitment_id(self, committee_name): + return self.venue.get_group_recruitment_id(committee_name) + def get_participants(self, number=None, with_program_chairs=False, with_authors=False): return self.venue.get_participants(number, with_program_chairs, with_authors) @@ -381,6 +390,37 @@ def setup(self, program_chair_ids=[], publication_chairs_ids=[]): def set_impersonators(self, impersonators): return self.venue.set_impersonators(impersonators) + def recruit_reviewers(self, + title, + message, + invitees = [], + reviewers_name = 'Reviewers', + remind = False, + invitee_names = [], + retry_declined = False, + contact_info = '', + reduced_load_on_decline = None, + allow_accept_with_reduced_load = False, + default_load= 0, + allow_overlap_official_committee = False, + accept_recruitment_template=None + ): + return self.venue.recruit_reviewers( + title, + message, + invitees = invitees, + reviewers_name = reviewers_name, + remind = remind, + invitee_names = invitee_names, + retry_declined = retry_declined, + contact_info = contact_info, + reduced_load_on_decline = reduced_load_on_decline, + allow_accept_with_reduced_load = allow_accept_with_reduced_load, + default_load= default_load, + allow_overlap_official_committee = allow_overlap_official_committee, + accept_recruitment_template=accept_recruitment_template + ) + # For stage invitations, pass value to inner venue objects def create_submission_stage(self): self.venue.submission_stage = self.submission_stage @@ -492,6 +532,9 @@ def setup_committee_matching(self, committee_id=None, compute_affinity_scores=Fa def set_assignments(self, assignment_title, committee_id, enable_reviewer_reassignment=False, overwrite=False): return self.venue.set_assignments(assignment_title, committee_id, enable_reviewer_reassignment, overwrite) + def unset_assignments(self, assignment_title, committee_id): + return self.venue.unset_assignments(assignment_title, committee_id) + def setup_assignment_recruitment(self, committee_id, hash_seed, due_date, assignment_title=None, invitation_labels={}, email_template=None): return self.venue.setup_assignment_recruitment(committee_id, hash_seed, due_date, assignment_title, invitation_labels, email_template) diff --git a/tests/test_arr_venue_v2.py b/tests/test_arr_venue_v2.py index 0b1bcd6c4..edc848445 100644 --- a/tests/test_arr_venue_v2.py +++ b/tests/test_arr_venue_v2.py @@ -966,6 +966,116 @@ def test_june_cycle(self, client, openreview_client, helpers, test_client, profi assert reviewer_five_client.get_note(license_edit['note']['id']) + def test_ac_recruitment(self, client, openreview_client, helpers, request_page, selenium): + + pc_client = openreview.Client(username='pc@aclrollingreview.org', password=helpers.strong_password) + request_form=pc_client.get_notes(invitation='openreview.net/Support/-/Request_Form')[1] + + reviewer_details = '''acextra1@aclrollingreview.com, AC ARRExtraOne\nacextra2@aclrollingreview.com, AC ARRExtraOne''' + pc_client.post_note(openreview.Note( + content={ + 'title': 'Recruitment', + 'invitee_role': 'Area_Chairs', + 'invitee_details': reviewer_details, + 'invitation_email_subject': '[ARR August 2023] Invitation to serve as {{invitee_role}}', + 'invitation_email_content': 'Dear {{fullname}},\n\nYou have been nominated by the program chair committee of ACL ARR 2023 August to serve as {{invitee_role}}.\n\n{{invitation_url}}\n\nCheers!\n\nProgram Chairs' + }, + forum=request_form.forum, + replyto=request_form.forum, + invitation='openreview.net/Support/-/Request{}/Recruitment'.format(request_form.number), + readers=['aclweb.org/ACL/ARR/2023/August/Program_Chairs', 'openreview.net/Support'], + signatures=['~Program_ARRChair1'], + writers=[] + )) + + helpers.await_queue() + + assert len(openreview_client.get_group('aclweb.org/ACL/ARR/2023/August/Area_Chairs').members) == 0 + assert len(openreview_client.get_group('aclweb.org/ACL/ARR/2023/August/Area_Chairs/Invited').members) == 2 + + messages = openreview_client.get_messages(subject = '[ARR August 2023] Invitation to serve as Area Chair') + assert len(messages) == 2 + + for message in messages: + text = message['content']['text'] + + invitation_url = re.search('https://.*\n', text).group(0).replace('https://openreview.net', 'http://localhost:3030').replace('&', '&')[:-1] + helpers.respond_invitation(selenium, request_page, invitation_url, accept=True) + + helpers.await_queue_edit(openreview_client, invitation='aclweb.org/ACL/ARR/2023/August/Area_Chairs/-/Recruitment', count=2) + + messages = openreview_client.get_messages(subject='[ARR - August 2023] Area Chair Invitation accepted') + assert len(messages) == 2 + + assert 'acextra1@aclrollingreview.com' in openreview_client.get_group('aclweb.org/ACL/ARR/2023/August/Area_Chairs').members + assert 'acextra2@aclrollingreview.com' in openreview_client.get_group('aclweb.org/ACL/ARR/2023/August/Area_Chairs').members + + openreview_client.remove_members_from_group( + 'aclweb.org/ACL/ARR/2023/August/Area_Chairs', + [ + 'acextra1@aclrollingreview.com', + 'acextra2@aclrollingreview.com' + ] + ) + + def test_reviewer_recruitment(self, client, openreview_client, helpers, request_page, selenium): + + pc_client = openreview.Client(username='pc@aclrollingreview.org', password=helpers.strong_password) + request_form=pc_client.get_notes(invitation='openreview.net/Support/-/Request_Form')[1] + + reviewer_details = '''reviewerextra1@aclrollingreview.com, Reviewer ARRExtraOne +reviewerextra2@aclrollingreview.com, Reviewer ARRExtraTwo +''' + pc_client.post_note(openreview.Note( + content={ + 'title': 'Recruitment', + 'invitee_role': 'Reviewers', + 'invitee_details': reviewer_details, + 'invitation_email_subject': '[ARR August 2023] Invitation to serve as {{invitee_role}}', + 'invitation_email_content': 'Dear {{fullname}},\n\nYou have been nominated by the program chair committee of ACL ARR 2023 August to serve as {{invitee_role}}.\n\n{{invitation_url}}\n\nCheers!\n\nProgram Chairs' + }, + forum=request_form.forum, + replyto=request_form.forum, + invitation='openreview.net/Support/-/Request{}/Recruitment'.format(request_form.number), + readers=['aclweb.org/ACL/ARR/2023/August/Program_Chairs', 'openreview.net/Support'], + signatures=['~Program_ARRChair1'], + writers=[] + )) + + helpers.await_queue() + + assert len(openreview_client.get_group('aclweb.org/ACL/ARR/2023/August/Reviewers/Invited').members) == 2 + assert len(openreview_client.get_group('aclweb.org/ACL/ARR/2023/August/Reviewers/Declined').members) == 0 + + messages = openreview_client.get_messages(subject = '[ARR August 2023] Invitation to serve as Reviewer') + assert len(messages) == 2 + + for idx, message in enumerate(messages): + text = message['content']['text'] + + invitation_url = re.search('https://.*\n', text).group(0).replace('https://openreview.net', 'http://localhost:3030').replace('&', '&')[:-1] + if idx == 0: + helpers.respond_invitation(selenium, request_page, invitation_url, accept=True) + else: + helpers.respond_invitation(selenium, request_page, invitation_url, accept=False) + + helpers.await_queue_edit(openreview_client, invitation='aclweb.org/ACL/ARR/2023/August/Reviewers/-/Recruitment', count=2) + + messages = openreview_client.get_messages(subject='[ARR - August 2023] Reviewer Invitation accepted') + assert len(messages) == 1 + messages = openreview_client.get_messages(subject='[ARR - August 2023] Reviewer Invitation declined') + assert len(messages) == 1 + + assert len(openreview_client.get_group('aclweb.org/ACL/ARR/2023/August/Reviewers/Invited').members) == 2 + assert len(openreview_client.get_group('aclweb.org/ACL/ARR/2023/August/Reviewers/Declined').members) == 1 + + assert 'reviewerextra1@aclrollingreview.com' in openreview_client.get_group('aclweb.org/ACL/ARR/2023/August/Reviewers').members + + openreview_client.remove_members_from_group( + 'aclweb.org/ACL/ARR/2023/August/Reviewers', + ['reviewerextra1@aclrollingreview.com'] + ) + def test_submission_preprocess(self, client, openreview_client, test_client, helpers): # Update the submission preprocess function and test validation for combinations