Skip to content

Commit 1a695fa

Browse files
authored
Merge pull request openjournals#88 from openjournals/validate-archive-doi
New responder to validate archive DOIs
2 parents 54987cd + ae6d2ee commit 1a695fa

File tree

7 files changed

+188
-4
lines changed

7 files changed

+188
-4
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
require_relative '../../lib/responder'
2+
require 'uri'
3+
require 'faraday'
4+
5+
6+
module Openjournals
7+
class SetArchiveResponder < Responder
8+
keyname :openjournals_set_archive
9+
10+
def define_listening
11+
@event_action = "issue_comment.created"
12+
@event_regex = /\A@#{bot_name} set (.*) as archive\.?\s*$/i
13+
end
14+
15+
def process_message(message)
16+
new_value = @match_data[1]
17+
new_value = new_value.gsub("https://doi.org/", "")
18+
19+
ok_reply = "Done! archive is now [#{new_value}](https://doi.org/#{new_value})"
20+
nok_reply = "Error: `archive` not found in the issue's body"
21+
22+
if valid_doi_value?(new_value)
23+
reply = update_value("archive", new_value) ? ok_reply : nok_reply
24+
else
25+
reply = "That doesn't look like a valid DOI value"
26+
end
27+
respond(reply)
28+
end
29+
30+
def valid_doi_value?(archive_value)
31+
escaped_archive_value = archive_value.gsub("<", "%3C").gsub(">", "%3E").gsub("[", "%5B").gsub("]", "%5D")
32+
doi_url = URI.join("https://doi.org", escaped_archive_value).to_s
33+
34+
status_code = Faraday.head(doi_url).status
35+
return [301, 302].include?(status_code)
36+
rescue
37+
return false
38+
end
39+
40+
def default_description
41+
"Set a value for the archive DOI"
42+
end
43+
44+
def default_example_invocation
45+
"@#{bot_name} set set 10.5281/zenodo.6861996 as archive"
46+
end
47+
end
48+
end

config/settings-production.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,6 @@ buffy:
6868
- version:
6969
only: editors
7070
sample_value: "v1.0.0"
71-
- archive:
72-
only: editors
73-
sample_value: "10.21105/zenodo.12345"
74-
template_file: set_archive.md
7571
- branch:
7672
sample_value: "joss-paper"
7773
- target-repository:
@@ -87,6 +83,8 @@ buffy:
8783
id: issue_id
8884
repository_url: new_value
8985
silent: true
86+
openjournals_set_archive:
87+
only: editors
9088
ping_track_eics:
9189
only: editors
9290
external_service:

docs/available_responders.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Buffy includes a list of Responders that can be used by configuring them in the
4747
:maxdepth: 1
4848

4949
responders/openjournals/ping_track_eics
50+
responders/openjournals/set_archive
5051
responders/openjournals/whedon
5152
responders/openjournals/reviewers_log_review_start
5253
responders/openjournals/reviewers_log_review_end
40.4 KB
Loading
39.3 KB
Loading
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
OpenJournals :: Set archive
2+
===========================
3+
4+
This responder can be used to set a valid DOI as the value of the archive field in the body of the issue.
5+
6+
## Listens to
7+
8+
9+
```
10+
@botname set <ARCHIVE-DOI> as archive
11+
```
12+
13+
where ARCHIVE-DOI is a valid DOI
14+
15+
## Requirements
16+
17+
The body of the issue should have the _archive_ field placeholder marked with HTML comments.
18+
19+
```html
20+
<!--archive--> <!--end-archive-->
21+
```
22+
23+
## Settings key
24+
25+
`openjournals_set_archive`
26+
27+
28+
## Examples
29+
30+
```yaml
31+
...
32+
33+
responders:
34+
openjournals_set_archive:
35+
only: editors
36+
...
37+
```
38+
39+
## In action
40+
41+
42+
![](../../images/responders/openjournals/set_archive_1.png "Set archive responder in action: valid DOI")
43+
44+
* **`DOIs are validated:`**
45+
46+
![](../../images/responders/openjournals/set_archive_2.png "Set archive responder in action: invalid value")
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
require_relative "../../spec_helper.rb"
2+
3+
describe Openjournals::SetArchiveResponder do
4+
5+
subject do
6+
described_class
7+
end
8+
9+
describe "listening" do
10+
before { @responder = subject.new({env: {bot_github_user: "botsci"}}, {}) }
11+
12+
it "should listen to new comments" do
13+
expect(@responder.event_action).to eq("issue_comment.created")
14+
end
15+
16+
it "should define regex" do
17+
expect(@responder.event_regex).to match("@botsci set 10.5281/zenodo.6861996 as archive")
18+
expect(@responder.event_regex).to match("@botsci set 10.5281/zenodo.6861996 as archive.")
19+
expect(@responder.event_regex).to match("@botsci set 10.5281/zenodo.6861996 as archive \r\n")
20+
expect(@responder.event_regex).to match("@botsci set 10.5281/zenodo.6861996 as archive \r\n more")
21+
expect(@responder.event_regex).to_not match("@botsci set 10.5281/zenodo.6861996 as editor")
22+
expect(@responder.event_regex).to_not match("@botsci set 10.5281/zenodo.6861996 as archive now")
23+
end
24+
end
25+
26+
describe "#process_message" do
27+
before do
28+
@responder = subject.new({env: {bot_github_user: "botsci"}}, {})
29+
disable_github_calls_for(@responder)
30+
31+
issue_body = "...Archive: <!--archive-->Pending<!--end-archive--> ..."
32+
allow(@responder).to receive(:issue_body).and_return(issue_body)
33+
end
34+
35+
describe "with a valid DOI" do
36+
before do
37+
@msg = "@botsci set 10.5281/zenodo.6861996 as archive"
38+
@responder.match_data = @responder.event_regex.match(@msg)
39+
expect(Faraday).to receive(:head).with("https://doi.org/10.5281/zenodo.6861996").and_return(double(status: 301))
40+
end
41+
42+
it "should update value in the body of the issue" do
43+
expected_new_body = "...Archive: <!--archive-->10.5281/zenodo.6861996<!--end-archive--> ..."
44+
expect(@responder).to receive(:update_issue).with({ body: expected_new_body })
45+
@responder.process_message(@msg)
46+
end
47+
48+
it "should respond to github" do
49+
expect(@responder).to receive(:respond).with("Done! archive is now [10.5281/zenodo.6861996](https://doi.org/10.5281/zenodo.6861996)")
50+
@responder.process_message(@msg)
51+
end
52+
end
53+
54+
describe "with invalid DOI values" do
55+
it "should clean doi.org URLs" do
56+
@msg = "@botsci set https://doi.org/10.5281/zenodo.6861996 as archive"
57+
@responder.match_data = @responder.event_regex.match(@msg)
58+
expect(Faraday).to receive(:head).with("https://doi.org/10.5281/zenodo.6861996").and_return(double(status: 301))
59+
60+
expected_new_body = "...Archive: <!--archive-->10.5281/zenodo.6861996<!--end-archive--> ..."
61+
expect(@responder).to receive(:update_issue).with({ body: expected_new_body })
62+
expect(@responder).to receive(:respond).with("Done! archive is now [10.5281/zenodo.6861996](https://doi.org/10.5281/zenodo.6861996)")
63+
64+
@responder.process_message(@msg)
65+
end
66+
67+
it "should reply error if DOI doesn't resolve" do
68+
@msg = "@botsci set https://zenodo.org/invalid.6573452618CX as archive"
69+
@responder.match_data = @responder.event_regex.match(@msg)
70+
71+
expect(Faraday).to receive(:head).with("https://zenodo.org/invalid.6573452618CX").and_return(double(status: 404))
72+
expect(@responder).to_not receive(:update_issue)
73+
expect(@responder).to receive(:respond).with("That doesn't look like a valid DOI value")
74+
75+
@responder.process_message(@msg)
76+
end
77+
78+
it "should reply error if malformed URI" do
79+
@msg = "@botsci set ' OR 1=1 as archive"
80+
@responder.match_data = @responder.event_regex.match(@msg)
81+
82+
expect(Faraday).to_not receive(:head)
83+
expect(@responder).to_not receive(:update_issue)
84+
expect(@responder).to receive(:respond).with("That doesn't look like a valid DOI value")
85+
86+
@responder.process_message(@msg)
87+
end
88+
end
89+
end
90+
91+
end

0 commit comments

Comments
 (0)