reviewlette 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +7 -0
- data/Gemfile.lock +49 -0
- data/Guardfile +70 -0
- data/config/github_example.yml +3 -1
- data/lib/reviewlette/github_connection.rb +7 -5
- data/lib/reviewlette/trello_connection.rb +4 -4
- data/lib/reviewlette/vacations.rb +2 -2
- data/lib/reviewlette.rb +48 -26
- data/spec/github_connection_spec.rb +15 -9
- data/spec/reviewlette_spec.rb +38 -24
- data/spec/trello_connection_spec.rb +17 -14
- data/spec/vacation_spec.rb +13 -11
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 163d81e853831b82b114bf4705a4b89621e308dc
|
4
|
+
data.tar.gz: 75186e2b3813ee25c38b8ebdf60df1c9a5205171
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4daa9c0f5d7e62f4dc08604b66a6b8888b3ae5d6ca4486ac29d67cff05bec0ea9d5e7659e682b3107562e7021ac665e0d25e4955d067d4729e64c3d8a1d572ed
|
7
|
+
data.tar.gz: 56f797d47df14a587b4b3bbfe99ad5290e345565c47548adb33f5d11641cc6fefdcd62f413798ad974d07bea0a3340f44a293a5684e44cea224b8c5d21e5e7f4
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -16,6 +16,9 @@ GEM
|
|
16
16
|
builder (3.2.2)
|
17
17
|
byebug (3.1.2)
|
18
18
|
columnize (~> 0.8)
|
19
|
+
celluloid (0.16.0)
|
20
|
+
timers (~> 4.0.0)
|
21
|
+
coderay (1.1.0)
|
19
22
|
columnize (0.8.9)
|
20
23
|
coveralls (0.7.0)
|
21
24
|
multi_json (~> 1.3)
|
@@ -29,25 +32,61 @@ GEM
|
|
29
32
|
docile (1.1.3)
|
30
33
|
faraday (0.9.1)
|
31
34
|
multipart-post (>= 1.2, < 3)
|
35
|
+
ffi (1.9.8)
|
36
|
+
formatador (0.2.5)
|
37
|
+
guard (2.12.6)
|
38
|
+
formatador (>= 0.2.4)
|
39
|
+
listen (~> 2.7)
|
40
|
+
lumberjack (~> 1.0)
|
41
|
+
nenv (~> 0.1)
|
42
|
+
notiffany (~> 0.0)
|
43
|
+
pry (>= 0.9.12)
|
44
|
+
shellany (~> 0.0)
|
45
|
+
thor (>= 0.18.1)
|
46
|
+
guard-compat (1.2.1)
|
47
|
+
guard-rspec (4.5.2)
|
48
|
+
guard (~> 2.1)
|
49
|
+
guard-compat (~> 1.1)
|
50
|
+
rspec (>= 2.99.0, < 4.0)
|
32
51
|
haml (4.0.5)
|
33
52
|
tilt
|
53
|
+
hitimes (1.2.2)
|
34
54
|
httparty (0.13.1)
|
35
55
|
json (~> 1.8)
|
36
56
|
multi_xml (>= 0.5.2)
|
37
57
|
i18n (0.6.9)
|
38
58
|
json (1.8.1)
|
59
|
+
libnotify (0.9.1)
|
60
|
+
ffi (>= 1.0.11)
|
61
|
+
listen (2.10.1)
|
62
|
+
celluloid (~> 0.16.0)
|
63
|
+
rb-fsevent (>= 0.9.3)
|
64
|
+
rb-inotify (>= 0.9)
|
65
|
+
lumberjack (1.0.9)
|
66
|
+
method_source (0.8.2)
|
39
67
|
mime-types (2.3)
|
40
68
|
minitest (5.3.4)
|
41
69
|
multi_json (1.10.0)
|
42
70
|
multi_xml (0.5.5)
|
43
71
|
multipart-post (2.0.0)
|
72
|
+
nenv (0.2.0)
|
73
|
+
notiffany (0.0.6)
|
74
|
+
nenv (~> 0.1)
|
75
|
+
shellany (~> 0.0)
|
44
76
|
oauth (0.4.7)
|
45
77
|
octokit (3.8.0)
|
46
78
|
sawyer (~> 0.6.0, >= 0.5.3)
|
47
79
|
prophet (1.5.5)
|
48
80
|
octokit
|
49
81
|
rspec
|
82
|
+
pry (0.10.1)
|
83
|
+
coderay (~> 1.1.0)
|
84
|
+
method_source (~> 0.8.1)
|
85
|
+
slop (~> 3.4)
|
50
86
|
rake (10.3.2)
|
87
|
+
rb-fsevent (0.9.5)
|
88
|
+
rb-inotify (0.9.5)
|
89
|
+
ffi (>= 0.5.0)
|
51
90
|
rdoc (4.1.1)
|
52
91
|
json (~> 1.4)
|
53
92
|
rest-client (1.6.7)
|
@@ -75,17 +114,21 @@ GEM
|
|
75
114
|
addressable (~> 2.3.5)
|
76
115
|
faraday (~> 0.8, < 0.10)
|
77
116
|
sequel (4.13.0)
|
117
|
+
shellany (0.0.1)
|
78
118
|
simplecov (0.8.2)
|
79
119
|
docile (~> 1.1.0)
|
80
120
|
multi_json
|
81
121
|
simplecov-html (~> 0.8.0)
|
82
122
|
simplecov-html (0.8.0)
|
123
|
+
slop (3.6.0)
|
83
124
|
sqlite3 (1.3.9)
|
84
125
|
term-ansicolor (1.3.0)
|
85
126
|
tins (~> 1.0)
|
86
127
|
thor (0.19.1)
|
87
128
|
thread_safe (0.3.4)
|
88
129
|
tilt (2.0.1)
|
130
|
+
timers (4.0.1)
|
131
|
+
hitimes
|
89
132
|
tins (1.1.0)
|
90
133
|
tzinfo (1.2.1)
|
91
134
|
thread_safe (~> 0.1)
|
@@ -100,8 +143,11 @@ DEPENDENCIES
|
|
100
143
|
ap
|
101
144
|
byebug
|
102
145
|
coveralls
|
146
|
+
guard
|
147
|
+
guard-rspec
|
103
148
|
haml
|
104
149
|
json
|
150
|
+
libnotify
|
105
151
|
octokit (~> 3.8.0)
|
106
152
|
prophet
|
107
153
|
rake
|
@@ -112,3 +158,6 @@ DEPENDENCIES
|
|
112
158
|
simplecov
|
113
159
|
sqlite3
|
114
160
|
webmock
|
161
|
+
|
162
|
+
BUNDLED WITH
|
163
|
+
1.10.6
|
data/Guardfile
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
## Uncomment and set this to only include directories you want to watch
|
5
|
+
# directories %w(app lib config test spec features) \
|
6
|
+
# .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
|
7
|
+
|
8
|
+
## Note: if you are using the `directories` clause above and you are not
|
9
|
+
## watching the project directory ('.'), then you will want to move
|
10
|
+
## the Guardfile to a watched dir and symlink it back, e.g.
|
11
|
+
#
|
12
|
+
# $ mkdir config
|
13
|
+
# $ mv Guardfile config/
|
14
|
+
# $ ln -s config/Guardfile .
|
15
|
+
#
|
16
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
17
|
+
|
18
|
+
# Note: The cmd option is now required due to the increasing number of ways
|
19
|
+
# rspec may be run, below are examples of the most common uses.
|
20
|
+
# * bundler: 'bundle exec rspec'
|
21
|
+
# * bundler binstubs: 'bin/rspec'
|
22
|
+
# * spring: 'bin/rspec' (This will use spring if running and you have
|
23
|
+
# installed the spring binstubs per the docs)
|
24
|
+
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
25
|
+
# * 'just' rspec: 'rspec'
|
26
|
+
|
27
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
28
|
+
require "guard/rspec/dsl"
|
29
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
30
|
+
|
31
|
+
# Feel free to open issues for suggestions and improvements
|
32
|
+
|
33
|
+
# RSpec files
|
34
|
+
rspec = dsl.rspec
|
35
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
36
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
37
|
+
watch(rspec.spec_files)
|
38
|
+
|
39
|
+
# Ruby files
|
40
|
+
ruby = dsl.ruby
|
41
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
42
|
+
|
43
|
+
# Rails files
|
44
|
+
rails = dsl.rails(view_extensions: %w(erb haml slim))
|
45
|
+
dsl.watch_spec_files_for(rails.app_files)
|
46
|
+
dsl.watch_spec_files_for(rails.views)
|
47
|
+
|
48
|
+
watch(rails.controllers) do |m|
|
49
|
+
[
|
50
|
+
rspec.spec.("routing/#{m[1]}_routing"),
|
51
|
+
rspec.spec.("controllers/#{m[1]}_controller"),
|
52
|
+
rspec.spec.("acceptance/#{m[1]}")
|
53
|
+
]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Rails config changes
|
57
|
+
watch(rails.spec_helper) { rspec.spec_dir }
|
58
|
+
watch(rails.routes) { "#{rspec.spec_dir}/routing" }
|
59
|
+
watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
|
60
|
+
|
61
|
+
# Capybara features specs
|
62
|
+
watch(rails.view_dirs) { |m| rspec.spec.("features/#{m[1]}") }
|
63
|
+
watch(rails.layouts) { |m| rspec.spec.("features/#{m[1]}") }
|
64
|
+
|
65
|
+
# Turnip features and steps
|
66
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
67
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
|
68
|
+
Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
|
69
|
+
end
|
70
|
+
end
|
data/config/github_example.yml
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
require 'octokit'
|
3
3
|
|
4
|
-
GITHUB_CONFIG = YAML.load_file("#{File.dirname(__FILE__)}/../../config/github.yml")
|
5
|
-
|
6
4
|
class GithubConnection
|
7
5
|
|
8
6
|
attr_accessor :client, :repo
|
9
7
|
|
10
|
-
def initialize
|
11
|
-
@client
|
12
|
-
@repo
|
8
|
+
def initialize(repo, token)
|
9
|
+
@client = Octokit::Client.new(access_token: token)
|
10
|
+
@repo = repo
|
13
11
|
end
|
14
12
|
|
15
13
|
def list_pulls
|
@@ -37,4 +35,8 @@ class GithubConnection
|
|
37
35
|
list_pulls.select { |issue| !issue[:assignee] }
|
38
36
|
end
|
39
37
|
|
38
|
+
def repo_exists?
|
39
|
+
@client.repository?(@repo)
|
40
|
+
end
|
41
|
+
|
40
42
|
end
|
@@ -1,18 +1,18 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
require 'trello'
|
3
3
|
|
4
|
-
TRELLO_CONFIG = YAML.load_file("#{File.dirname(__FILE__)}/../../config/trello.yml")
|
5
4
|
|
6
5
|
class TrelloConnection
|
7
6
|
|
8
7
|
attr_accessor :board
|
9
8
|
|
10
9
|
def initialize
|
10
|
+
@trello = YAML.load_file("#{File.dirname(__FILE__)}/../../config/trello.yml")
|
11
11
|
Trello.configure do |config|
|
12
|
-
config.developer_public_key =
|
13
|
-
config.member_token =
|
12
|
+
config.developer_public_key = @trello['consumerkey']
|
13
|
+
config.member_token = @trello['oauthtoken']
|
14
14
|
end
|
15
|
-
@board = Trello::Board.find(
|
15
|
+
@board = Trello::Board.find(@trello['board_id'])
|
16
16
|
end
|
17
17
|
|
18
18
|
def add_reviewer_to_card(reviewer, card)
|
@@ -19,8 +19,8 @@ class Vacations
|
|
19
19
|
vacations
|
20
20
|
end
|
21
21
|
|
22
|
-
def self.members_on_vacation
|
23
|
-
members_on_vacation =
|
22
|
+
def self.members_on_vacation(members)
|
23
|
+
members_on_vacation = members.collect do |member|
|
24
24
|
username = member['suse_username']
|
25
25
|
username if (username && Vacations.find_vacations(username).any? { |v| v === Date.today })
|
26
26
|
end
|
data/lib/reviewlette.rb
CHANGED
@@ -3,50 +3,72 @@ require 'reviewlette/github_connection'
|
|
3
3
|
require 'reviewlette/vacations'
|
4
4
|
require 'yaml'
|
5
5
|
|
6
|
-
VERSION = '0.0.
|
7
|
-
MEMBERS_CONFIG = YAML.load_file("#{File.dirname(__FILE__)}/../config/members.yml")
|
6
|
+
VERSION = '0.0.9'
|
8
7
|
|
9
8
|
class Reviewlette
|
10
|
-
|
11
9
|
def initialize
|
12
|
-
@
|
13
|
-
@
|
10
|
+
@trello = TrelloConnection.new
|
11
|
+
@members = YAML.load_file("#{File.dirname(__FILE__)}/../config/members.yml")
|
12
|
+
@github = YAML.load_file("#{File.dirname(__FILE__)}/../config/github.yml")
|
14
13
|
end
|
15
14
|
|
16
15
|
def run
|
17
|
-
@github.
|
18
|
-
|
16
|
+
@github['repos'].each do |repo|
|
17
|
+
puts "Checking repository #{repo}..."
|
18
|
+
check_repo(repo, @github['token'])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def check_repo(repo_name, token)
|
23
|
+
repo = GithubConnection.new(repo_name, token)
|
24
|
+
|
25
|
+
unless repo.repo_exists?
|
26
|
+
puts "Repository #{repo_name} does not exist. Check your configuration"
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
repo.unassigned_pull_requests.each do |issue|
|
31
|
+
issue_id = issue[:number]
|
19
32
|
issue_title = issue[:title]
|
33
|
+
|
20
34
|
puts "*** Checking unassigned github pull request: #{issue_title}"
|
21
35
|
card_id = issue_title.split(/[_ -#\.]/).last.to_i
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
if reviewer
|
26
|
-
@github.add_assignee(issue_id, reviewer['github_username'])
|
27
|
-
@github.reviewer_comment(issue_id, reviewer['github_username'], card)
|
28
|
-
comment = "@#{reviewer['trello_username']} will review https://github.com/#{@github.repo}/issues/#{issue_id}"
|
29
|
-
@trello.comment_on_card(comment, card)
|
30
|
-
@trello.move_card_to_list(card, 'In review')
|
31
|
-
else
|
32
|
-
puts "Could not find a reviewer for card: #{card.name}"
|
33
|
-
end
|
34
|
-
else
|
36
|
+
card = @trello.find_card_by_id(card_id)
|
37
|
+
|
38
|
+
unless card
|
35
39
|
puts "No matching card found (id #{card_id})"
|
40
|
+
next
|
36
41
|
end
|
37
|
-
end
|
38
42
|
|
43
|
+
puts "Found matching trello card: #{card.name}"
|
44
|
+
reviewer = select_reviewer(issue, card)
|
45
|
+
|
46
|
+
unless reviewer
|
47
|
+
puts "Could not find a reviewer for card: #{card.name}"
|
48
|
+
next
|
49
|
+
end
|
50
|
+
|
51
|
+
repo.add_assignee(issue_id, reviewer['github_username'])
|
52
|
+
repo.reviewer_comment(issue_id, reviewer['github_username'], card)
|
53
|
+
comment = "@#{reviewer['trello_username']} will review https://github.com/#{repo_name}/issues/#{issue_id}"
|
54
|
+
|
55
|
+
@trello.comment_on_card(comment, card)
|
56
|
+
@trello.move_card_to_list(card, 'In review')
|
57
|
+
end
|
39
58
|
end
|
40
59
|
|
41
60
|
def select_reviewer(issue, card)
|
42
|
-
reviewers =
|
61
|
+
reviewers = @members['members']
|
62
|
+
|
43
63
|
# remove people on vacation
|
44
|
-
members_on_vacation = Vacations.members_on_vacation
|
45
|
-
|
64
|
+
members_on_vacation = Vacations.members_on_vacation(reviewers)
|
65
|
+
|
66
|
+
reviewers = reviewers.reject {|r| members_on_vacation.include? r['suse_username'] }
|
67
|
+
|
46
68
|
# remove trello card owner
|
47
|
-
reviewers = reviewers.reject{|r| card.members.map(&:username).include? r['trello_username'] }
|
69
|
+
reviewers = reviewers.reject {|r| card.members.map(&:username).include? r['trello_username'] }
|
48
70
|
reviewer = reviewers.sample
|
49
|
-
puts "Selected reviewer: #{reviewer['name']} from pool #{reviewers.map{|r| r['name']}}" if reviewer
|
71
|
+
puts "Selected reviewer: #{reviewer['name']} from pool #{reviewers.map {|r| r['name'] }}" if reviewer
|
50
72
|
reviewer
|
51
73
|
end
|
52
74
|
|
@@ -2,22 +2,21 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe GithubConnection do
|
4
4
|
|
5
|
-
GITHUB_CONFIG = { token: '661', repo: 'SUSE/reviewlette' }
|
6
5
|
subject { GithubConnection }
|
7
|
-
let( :connection ) { subject.new }
|
6
|
+
let( :connection ) { subject.new(repo, token) }
|
7
|
+
let( :repo ) { "test" }
|
8
|
+
let( :token ) { "foo" }
|
8
9
|
|
9
10
|
describe '.new' do
|
10
|
-
|
11
11
|
it 'initializes octokit client and repo' do
|
12
|
-
expect(Octokit::Client).to receive(:new).with(:access_token =>
|
13
|
-
connection
|
14
|
-
expect(connection.repo).to eq(GITHUB_CONFIG['repo'])
|
12
|
+
expect(Octokit::Client).to receive(:new).with(:access_token => token)
|
13
|
+
expect(connection.repo).to eq(repo)
|
15
14
|
end
|
16
15
|
end
|
17
16
|
|
18
17
|
describe '#add_assignee' do
|
19
18
|
it 'adds an assignee to the gh issue' do
|
20
|
-
expect(connection.client).to receive(:update_issue).with(
|
19
|
+
expect(connection.client).to receive(:update_issue).with(repo, 11, :assignee => 'test')
|
21
20
|
connection.add_assignee(11, 'test')
|
22
21
|
end
|
23
22
|
end
|
@@ -26,16 +25,23 @@ describe GithubConnection do
|
|
26
25
|
it 'comments on a given issue' do
|
27
26
|
card = Trello::Card.new
|
28
27
|
allow(card).to receive(:url).and_return('url')
|
29
|
-
expect(connection.client).to receive(:add_comment).with(
|
28
|
+
expect(connection.client).to receive(:add_comment).with(repo, 11, anything)
|
30
29
|
connection.reviewer_comment(11, 'test', card)
|
31
30
|
end
|
32
31
|
end
|
33
32
|
|
34
33
|
describe '#list_pulls' do
|
35
34
|
it 'lists all pullrequests for a given repository' do
|
36
|
-
expect(connection.client).to receive(:pull_requests).with(
|
35
|
+
expect(connection.client).to receive(:pull_requests).with(repo)
|
37
36
|
connection.list_pulls
|
38
37
|
end
|
39
38
|
end
|
40
39
|
|
40
|
+
describe '#repo_exists?' do
|
41
|
+
it 'checks if a certain repository exists' do
|
42
|
+
expect(connection.client).to receive(:repository?).with(repo)
|
43
|
+
connection.repo_exists?
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
41
47
|
end
|
data/spec/reviewlette_spec.rb
CHANGED
@@ -1,71 +1,85 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Reviewlette do
|
4
|
-
|
5
4
|
subject { Reviewlette }
|
6
|
-
let( :reviewlette ) { subject.new }
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
}
|
6
|
+
let(:reviewlette) { subject.new }
|
7
|
+
|
8
|
+
let(:members_config) { { 'members' => [member1, member2] } }
|
9
|
+
let(:member1) { { 'name' => 'test1', 'suse_username' => 'test1', 'trello_username' => 'trellotest1' } }
|
10
|
+
let(:member2) { { 'name' => 'test2', 'suse_username' => 'test2', 'trello_username' => 'trellotest2' } }
|
12
11
|
|
12
|
+
let(:github_config) { { token: token, repos: [repo, repo2] } }
|
13
|
+
let(:token) { '1234' }
|
14
|
+
let(:repo) { 'SUSE/test' }
|
15
|
+
let(:repo2) { 'SUSE/foo' }
|
16
|
+
|
17
|
+
before do
|
18
|
+
allow(TrelloConnection).to receive(:new).and_return TrelloConnection
|
19
|
+
allow(GithubConnection).to receive(:new).with(repo, token).and_return GithubConnection
|
20
|
+
allow(YAML).to receive(:load_file).with(/github\.yml/).and_return github_config
|
21
|
+
allow(YAML).to receive(:load_file).with(/members\.yml/).and_return members_config
|
22
|
+
end
|
13
23
|
|
14
24
|
describe '.new' do
|
15
|
-
it 'sets
|
16
|
-
|
17
|
-
|
18
|
-
subject.new
|
25
|
+
it 'sets trello connections' do
|
26
|
+
expect(TrelloConnection).to receive(:new)
|
27
|
+
subject.new
|
19
28
|
end
|
20
29
|
end
|
21
30
|
|
22
31
|
describe '.run' do
|
32
|
+
it 'iterates over all open repositories and looks for unassigned pull requests' do
|
33
|
+
github_config[:repos].each do |r|
|
34
|
+
expect(reviewlette).to receive(:check_repo).with(r, token)
|
35
|
+
reviewlette.check_repo(r, token)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
23
39
|
|
40
|
+
describe '.check_repo' do
|
24
41
|
it 'iterates over all open pull requests and extracts trello ids from name' do
|
42
|
+
expect(GithubConnection).to receive(:repo_exists?).and_return true
|
25
43
|
expect(GithubConnection).to receive(:unassigned_pull_requests).and_return([{number: 11, title: 'test_issue_12'}])
|
26
44
|
expect(TrelloConnection).to receive(:find_card_by_id).with(12)
|
27
45
|
|
28
|
-
reviewlette.
|
46
|
+
reviewlette.check_repo(repo, token)
|
29
47
|
end
|
30
48
|
|
31
49
|
it 'adds assignee and reviewer comment on github, adds comment on trello and moves card' do
|
32
50
|
card = Trello::Card.new
|
51
|
+
|
52
|
+
expect(GithubConnection).to receive(:repo_exists?).and_return true
|
33
53
|
expect(GithubConnection).to receive(:unassigned_pull_requests).and_return([{number: 11, title: 'test_issue_12'}])
|
34
54
|
expect(TrelloConnection).to receive(:find_card_by_id).with(12).and_return(card)
|
35
55
|
expect(reviewlette).to receive(:select_reviewer).and_return({'suse_username' => 'test', 'github_username' => 'testgit'})
|
36
56
|
|
37
57
|
expect(GithubConnection).to receive(:add_assignee).with(11, 'testgit')
|
38
58
|
expect(GithubConnection).to receive(:reviewer_comment).with(11, 'testgit', card)
|
39
|
-
expect(GithubConnection).to receive(:repo).and_return('SUSE/test')
|
40
59
|
|
41
60
|
expect(TrelloConnection).to receive(:comment_on_card).with("@ will review https://github.com/SUSE/test/issues/11", card)
|
42
61
|
expect(TrelloConnection).to receive(:move_card_to_list).with(card, 'In review')
|
43
62
|
|
44
|
-
reviewlette.
|
63
|
+
reviewlette.check_repo(repo, token)
|
45
64
|
end
|
46
65
|
|
47
66
|
end
|
48
67
|
|
49
68
|
describe '.select_reviewer' do
|
50
|
-
|
51
|
-
MEMBERS_CONFIG['members'] = [{'suse_username' => 'test1', 'trello_username' => 'trellotest1'},
|
52
|
-
{'suse_username' => 'test2', 'trello_username' => 'trellotest2'}]
|
53
|
-
|
54
69
|
it 'excludes members on vacation' do
|
55
|
-
card
|
70
|
+
card = Trello::Card.new
|
71
|
+
|
56
72
|
allow(card).to receive(:members).and_return([])
|
57
|
-
expect(Vacations).to receive(:members_on_vacation).and_return(
|
58
|
-
expect(reviewlette.select_reviewer(nil, card)).to eq(
|
73
|
+
expect(Vacations).to receive(:members_on_vacation).and_return([member1['suse_username']])
|
74
|
+
expect(reviewlette.select_reviewer(nil, card)).to eq(member2)
|
59
75
|
end
|
60
76
|
|
61
77
|
it 'excludes the owner of the trello card' do
|
62
78
|
card = Trello::Card.new
|
79
|
+
|
63
80
|
allow(card).to receive_message_chain(:members, :map).and_return(['trellotest1'])
|
64
81
|
expect(Vacations).to receive(:members_on_vacation).and_return([])
|
65
|
-
expect(reviewlette.select_reviewer(nil, card)).to eq(
|
82
|
+
expect(reviewlette.select_reviewer(nil, card)).to eq(members_config['members'].last)
|
66
83
|
end
|
67
|
-
|
68
84
|
end
|
69
|
-
|
70
|
-
|
71
85
|
end
|
@@ -1,26 +1,31 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe TrelloConnection do
|
4
|
-
|
5
|
-
TRELLO_CONFIG = { :consumerkey => '4a6', :consumersecret => '899', :oauthtoken => 'a8e', :board_id => 'T5S' }
|
6
4
|
subject { TrelloConnection }
|
7
|
-
let (:trello) { subject.new }
|
8
|
-
let (:card) { Trello::Card.new }
|
9
5
|
|
10
|
-
|
6
|
+
let(:trello) { subject.new }
|
7
|
+
let(:card) { Trello::Card.new }
|
8
|
+
let(:trello_config) { { 'consumerkey' => consumerkey, 'oauthtoken' => oauthtoken } }
|
9
|
+
let(:consumerkey) { '4a6' }
|
10
|
+
let(:oauthtoken) { 'a8e' }
|
11
|
+
|
12
|
+
|
13
|
+
before do
|
11
14
|
allow(Trello::Board).to receive(:find).and_return(Trello::Board.new)
|
12
|
-
|
15
|
+
allow(YAML).to receive(:load_file).and_return(trello_config)
|
16
|
+
end
|
17
|
+
|
13
18
|
|
14
19
|
describe '.new' do
|
15
20
|
it 'sets up trello' do
|
16
|
-
expect_any_instance_of(Trello::Configuration).to receive(:developer_public_key=).with(
|
17
|
-
expect_any_instance_of(Trello::Configuration).to receive(:member_token=).with(
|
21
|
+
expect_any_instance_of(Trello::Configuration).to receive(:developer_public_key=).with(consumerkey)
|
22
|
+
expect_any_instance_of(Trello::Configuration).to receive(:member_token=).with(oauthtoken)
|
18
23
|
subject.new
|
19
24
|
end
|
20
25
|
end
|
21
26
|
|
22
27
|
describe '#add_reviewer_to_card' do
|
23
|
-
it
|
28
|
+
it 'adds the valid member to the trello card and comments it' do
|
24
29
|
expect(trello).to receive(:find_member_by_username).with('testuser1').and_return 'testuser1'
|
25
30
|
expect_any_instance_of(Trello::Card).to receive(:add_member).with('testuser1')
|
26
31
|
trello.add_reviewer_to_card('testuser1', card)
|
@@ -28,7 +33,7 @@ describe TrelloConnection do
|
|
28
33
|
end
|
29
34
|
|
30
35
|
describe '#comment_on_card' do
|
31
|
-
it
|
36
|
+
it 'comments on the assigned trello card ' do
|
32
37
|
allow(card).to receive(:add_comment).with('comment').and_return true
|
33
38
|
expect(trello.comment_on_card('comment', card)).to eq true
|
34
39
|
end
|
@@ -50,18 +55,16 @@ describe TrelloConnection do
|
|
50
55
|
end
|
51
56
|
|
52
57
|
describe '#find_member_by_username' do
|
53
|
-
it
|
58
|
+
it 'finds a member based on a username and returns a trello member object' do
|
54
59
|
expect_any_instance_of(Trello::Board).to receive_message_chain(:members, :find)
|
55
60
|
trello.find_member_by_username('testuser')
|
56
61
|
end
|
57
62
|
end
|
58
63
|
|
59
64
|
describe '#find_card_by_id(id)' do
|
60
|
-
it
|
65
|
+
it 'finds the right card based on the trello id' do
|
61
66
|
expect_any_instance_of(Trello::Board).to receive_message_chain(:cards, :find)
|
62
67
|
trello.find_card_by_id(123)
|
63
68
|
end
|
64
69
|
end
|
65
|
-
|
66
|
-
|
67
70
|
end
|
data/spec/vacation_spec.rb
CHANGED
@@ -1,34 +1,36 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Vacations do
|
4
|
-
|
5
4
|
subject { Vacations }
|
6
5
|
|
7
|
-
|
6
|
+
let(:members_config) { { members: [member1, member2, member3] } }
|
7
|
+
let(:member1) { { 'suse_username' => 'testuser1' } }
|
8
|
+
let(:member2) { { 'suse_username' => 'testuser2' } }
|
9
|
+
let(:member3) { { 'suse_username' => 'testuser3' } }
|
10
|
+
let(:timestamp) { 'Absence : Thu 2015-04-02 - Tue 2015-04-07' }
|
8
11
|
|
12
|
+
describe '.find_vacations' do
|
9
13
|
it 'parses the vacations dates out of tel' do
|
10
|
-
|
14
|
+
stub_telnet = double
|
15
|
+
expect(stub_telnet).to receive(:cmd).with('testuser1').and_return(timestamp)
|
16
|
+
expect(stub_telnet).to receive(:close).and_return(true)
|
11
17
|
|
18
|
+
expect(Net::Telnet).to receive(:new).and_return(stub_telnet)
|
12
19
|
vacations = subject.find_vacations('testuser1')
|
20
|
+
|
13
21
|
expect(vacations).to be_kind_of(Array)
|
14
22
|
expect(vacations).to eq([Date.parse('2015-04-02')..Date.parse('2015-04-07')])
|
15
23
|
end
|
16
|
-
|
17
24
|
end
|
18
25
|
|
19
|
-
|
20
26
|
describe '.members_on_vacation' do
|
21
|
-
|
22
27
|
it 'finds members on vacation' do
|
23
|
-
MEMBERS_CONFIG['members'] = [{'suse_username' => 'testuser1'}, {'suse_username' =>'testuser2'}, {'suse_username' =>'testuser3'}]
|
24
28
|
allow(subject).to receive(:find_vacations).with('testuser1').and_return [(Date.today - 1)..(Date.today + 2)]
|
25
29
|
allow(subject).to receive(:find_vacations).with('testuser2').and_return [(Date.today - 1)..(Date.today - 1)]
|
26
30
|
allow(subject).to receive(:find_vacations).with('testuser3').and_return []
|
27
31
|
|
28
|
-
expect(subject.members_on_vacation).to be_kind_of(Array)
|
29
|
-
expect(subject.members_on_vacation).to eq(['testuser1'])
|
32
|
+
expect(subject.members_on_vacation(members_config[:members])).to be_kind_of(Array)
|
33
|
+
expect(subject.members_on_vacation(members_config[:members])).to eq(['testuser1'])
|
30
34
|
end
|
31
|
-
|
32
35
|
end
|
33
|
-
|
34
36
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reviewlette
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jschmid1
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-trello
|
@@ -79,6 +79,7 @@ files:
|
|
79
79
|
- ".travis.yml"
|
80
80
|
- Gemfile
|
81
81
|
- Gemfile.lock
|
82
|
+
- Guardfile
|
82
83
|
- LICENSE
|
83
84
|
- README.md
|
84
85
|
- Rakefile
|