Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JOSE] Custom reviewer checklist responder #93

Merged
merged 1 commit into from
Aug 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions app/responders/openjournals/jose_reviewer_checklist_responder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
require_relative '../../lib/responder'

module Openjournals
class JoseReviewerChecklistResponder < Responder

keyname :jose_reviewer_checklist

def define_listening
@event_action = "issue_comment.created"
@event_regex = /\A@#{bot_name} #{command}\.?\s*$/i
end

def process_message(message)
if sender_in_reviewers_list?
checklist = render_external_template(checklist_template_file, template_locals)
update_comment(context.comment_id, checklist)
update_checklists_links
else
respond("@#{context.sender} I can't do that because you are not a reviewer")
end
end

def sender_in_reviewers_list?
reviewers.include?("@#{context.sender.downcase}")
end

def update_checklists_links
if issue_body_has?("checklist-comments")
mapping = checklists_mapping.merge({"#{context.sender}" => "📝 [Checklist for @#{context.sender}](#{comment_url})"})

checklists = mapping.keys.map do |k|
"<!--checklist-for-#{k}-->\n#{mapping[k]}\n<!--end-checklist-for-#{k}-->"
end

update_value("checklist-comments", "\n"+checklists.join("\n")+"\n")
end
end

def paper_kind
@paper_kind ||= read_value_from_body("paper-kind").strip
end

def checklist_template_file
if paper_kind.downcase == "learning module"
"reviewer_checklist_learning_module.md"
elsif paper_kind.downcase == "software"
"reviewer_checklist_software.md"
else
"reviewer_checklist_software.md"
end
end

def template_locals
locals.merge(get_data_from_issue(["target-repository", "author-handle"]))
end

def reviewers
@reviewers ||= read_value_from_body("reviewers-list").split(",").map(&:strip).map(&:downcase)
end

def checklists_mapping
mapping = {}
reviewers.each do |rev|
rev_login = rev.gsub("@", "")
checklink_link = read_value_from_body("checklist-for-#{rev_login}")
mapping[rev_login] = checklink_link unless checklink_link.empty?
end
mapping
end

def command
params[:command] || "generate my checklist"
end

def default_description
"Adds a checklist for the reviewer using this command"
end

def default_example_invocation
"@#{bot_name} #{command}"
end
end
end
6 changes: 1 addition & 5 deletions config/settings-production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,10 @@ buffy:
repo_checks:
description: "Perform checks on the repository"
example_invocation: "@editorialbot check repository"
reviewer_checklist_comment:
jose_reviewer_checklist:
if:
title: "^\\[REVIEW\\]:"
reject_msg: Checklists can only be created once the review has started in the review issue
template_file: reviewer_checklist.md
data_from_issue:
- target-repository
- author-handle
set_value:
- version:
only: editors
Expand Down
153 changes: 153 additions & 0 deletions spec/responders/openjournals/jose_reviewer_checklist_responder_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
require_relative "../../spec_helper.rb"

describe Openjournals::JoseReviewerChecklistResponder do

subject do
described_class
end

before do
@responder = subject.new({env: {bot_github_user: "botsci"}}, {})
end

describe "listening" do
it "should listen to new comments" do
expect(@responder.event_action).to eq("issue_comment.created")
end

it "should define regex" do
expect(@responder.event_regex).to match("@botsci generate my checklist")
expect(@responder.event_regex).to match("@botsci generate my checklist.")
expect(@responder.event_regex).to match("@botsci generate my checklist \r\n")
expect(@responder.event_regex).to match("@botsci generate my checklist \r\nmore")
expect(@responder.event_regex).to_not match("@botsci generate my checklist for @arfon.")
expect(@responder.event_regex).to_not match("@botsci generate my checkl")
end
end

describe "#process_message" do
before do
@responder.context = OpenStruct.new(sender: "reviewer1",
issue_id: 5,
issue_author: "opener",
repo: "openjournals/buffy",
comment_id: 111222,
issue_body: "Test Submission\n\n ... description ... \n\n" +
"<!--author-handle-->@submitter<!--end-author-handle-->\n" +
"<!--target-repository-->https://target.re.po/sitory<!--end-target-repository-->\n" +
"<!--reviewers-list-->@reviewer1, @reviewer2<!--end-reviewers-list-->")
@msg = "@botsci generate my checklist"
disable_github_calls_for(@responder)

@expected_locals = { issue_id: 5,
issue_author: "opener",
bot_name: "botsci",
repo: "openjournals/buffy",
sender: "reviewer1",
"author-handle" => "@submitter",
"target-repository" => "https://target.re.po/sitory"
}
end

context "generate checklist command" do
it "should add default checklist for reviewer" do
expected_checklist = "Checklist for @reviewer1 \n[] A"

expect(@responder).to receive(:render_external_template).with("reviewer_checklist_software.md", @expected_locals).and_return(expected_checklist)
expect(@responder).to receive(:update_comment).with(111222, expected_checklist)
expect(@responder).to_not receive(:respond)
@responder.process_message(@msg)
end

it "should add software checklist for reviewer" do
@responder.context[:issue_body] += "\n<!--paper-kind-->software<!--end-paper-kind-->"

expected_checklist = "Checklist for @reviewer1 \n[] A"

expect(@responder).to receive(:render_external_template).with("reviewer_checklist_software.md", @expected_locals).and_return(expected_checklist)
expect(@responder).to receive(:update_comment).with(111222, expected_checklist)
expect(@responder).to_not receive(:respond)
@responder.process_message(@msg)
end

it "should add learning module checklist for reviewer" do
@responder.context[:issue_body] += "\n<!--paper-kind-->learning module<!--end-paper-kind-->"

expected_checklist = "Checklist for @reviewer1 \n[] A"

expect(@responder).to receive(:render_external_template).with("reviewer_checklist_learning_module.md", @expected_locals).and_return(expected_checklist)
expect(@responder).to receive(:update_comment).with(111222, expected_checklist)
expect(@responder).to_not receive(:respond)
@responder.process_message(@msg)
end

it "should be case insensitive for the reviewer's username" do
@responder.context[:sender] = "ReVIEwer1"

expected_locals = @expected_locals.dup
expected_locals[:sender] = "ReVIEwer1"

expected_checklist = "Checklist for @ReVIEwer1 \n[] A"

expect(@responder).to receive(:render_external_template).with("reviewer_checklist_software.md", expected_locals).and_return(expected_checklist)
expect(@responder).to receive(:update_comment).with(111222, expected_checklist)
expect(@responder).to_not receive(:respond)
@responder.process_message(@msg)
end

it "should not add user checklist if sender is not a reviewer" do
@responder.context[:sender] = "nonreviewer"

expect(@responder).to receive(:respond).with("@nonreviewer I can't do that because you are not a reviewer")
@responder.process_message(@msg)
end
end

context "checklist links" do
before do
expected_checklist = "Checklist for @reviewer1 \n[] A"

expect(@responder).to receive(:render_external_template).with("reviewer_checklist_software.md", @expected_locals).and_return(expected_checklist)
expect(@responder).to receive(:update_comment).with(111222, expected_checklist)


@link1 = "<!--checklist-for-reviewer1-->\n📝 [Checklist for @reviewer1](https://github.com/openjournals/buffy/issues/5#issuecomment-111222)\n<!--end-checklist-for-reviewer1-->"
@link2 = "<!--checklist-for-reviewer2-->\n📝 [Checklist for @reviewer2](https://github.com/openjournals/buffy/issues/5#issuecomment-222222)\n<!--end-checklist-for-reviewer2-->"
end

it "should not add link to checklist if no checklist-comments mark" do
expect(@responder).to_not receive(:update_value)
@responder.process_message(@msg)
end

it "should add link to the issue's text" do
@responder.context[:issue_body] += "<!--checklist-comments--><!--end-checklist-comments-->"

expect(@responder).to receive(:update_value).with("checklist-comments", "\n#{@link1}\n")
@responder.process_message(@msg)
end

it "should add link to existing checklist" do
@responder.context[:issue_body] += "<!--checklist-comments-->#{@link2}<!--end-checklist-comments-->"

expect(@responder).to receive(:update_value).with("checklist-comments", "\n#{@link2}\n#{@link1}\n")
@responder.process_message(@msg)
end

it "should update links to checklist in the issue's text" do
previous_link = "<!--checklist-for-reviewer1-->Whatever<!--end-checklist-for-reviewer1-->"
@responder.context[:issue_body] += "<!--checklist-comments--><!--end-checklist-comments-->"

expect(@responder).to receive(:update_value).with("checklist-comments", "\n#{@link1}\n")
@responder.process_message(@msg)
end
end
end

it "command is customizable" do
responder = subject.new({env: {bot_github_user: "botsci"}}, {command: "create check-list"})

expect(responder.event_regex).to match("@botsci create check-list")
expect(responder.event_regex).to_not match("@botsci generate my checklist")
end
end