lita-github 0.0.3 → 0.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 96790f8b19467db1f1534304ce67a2129c90e9e8
4
- data.tar.gz: 3b99912b047f352b94457b769967458f7e9b5cd2
3
+ metadata.gz: 0cc46959df4d539d8ae57127dc70528eb0f8c693
4
+ data.tar.gz: d1a064ef57e8a8dd86e72cb4336b93f221ced29a
5
5
  SHA512:
6
- metadata.gz: 1f2e72eb7d50a462147e7266ba607727af6442a8c2aec2b6cdd10fa4b944acd942a33d895a9e8b53694a742eac2dad1f7cc9a3246242458bdea497577a67af15
7
- data.tar.gz: b75bc26eeea1a9863fdda9102f5be53a7b2d719c5f2dc5fc117b66fb4f44cb86bbd3c0eff8fedf3186f8ebe79a37ce48eb11124635ec42fea34ca0f5b55ea4f5
6
+ metadata.gz: 3e9d24e71ecc36a25262e459c924c60ed4f0c2667a0008a6122fe2fbde1ea23628c91620280677f28dadc2b48685ff43365ac247774b7d06a627dad867d10300
7
+ data.tar.gz: 0368bb271581c4aa7939a423c1cd16e62d6ec795d2f1df84701aed8bc7bc5c6e33bde356bb74f3d9d13e7e2f491fffd1b05f04d9b0ed2c23e864fac456919289
data/README.md CHANGED
@@ -3,7 +3,6 @@ lita-github
3
3
  [![Build Status](https://img.shields.io/travis/PagerDuty/lita-github/master.svg)](https://travis-ci.org/PagerDuty/lita-github)
4
4
  [![MIT License](https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg)](https://tldrlegal.com/license/apache-license-2.0-(apache-2.0))
5
5
  [![RubyGems :: lita-github Gem Version](http://img.shields.io/gem/v/lita-github.svg)](https://rubygems.org/gems/lita-github)
6
- [![Code Climate Quality](https://img.shields.io/codeclimate/github/PagerDuty/lita-github.svg)](https://codeclimate.com/github/PagerDuty/lita-github)
7
6
  [![Code Climate Coverage](http://img.shields.io/codeclimate/coverage/github/PagerDuty/lita-github.svg)](https://codeclimate.com/github/PagerDuty/lita-github)
8
7
 
9
8
  Copyright 2014 PagerDuty, Inc.
@@ -57,6 +56,8 @@ Here is the current functionality:
57
56
  * **Note:** This method is disabled by default, you need to enable it by setting `config.handlers.github.repo_delete_enabled = true` in your configuration file
58
57
 
59
58
  ### Github PR Handler
59
+ * `!gh pr info #42 PagerDuty/lita-github`
60
+ * output some information about the PR. Such as: state (open|closed|merged), build status, user who opened, user who merged, amongst others...
60
61
  * `!gh pr merge #42 PagerDuty/lita-github` or `!shipit #42 PagerDuty/lita-github`
61
62
  * This merges the specified pull request
62
63
  * This method can be disabled by setting `config.handlers.github.pr_merge_enabled = false` in your configuration file
@@ -16,6 +16,6 @@
16
16
 
17
17
  # Administer your Hub of Gits with Lita!
18
18
  module LitaGithub
19
- VERSION = '0.0.3'
19
+ VERSION = '0.0.4'
20
20
  MAJ, MIN, REV = VERSION.split('.').map(&:to_i)
21
21
  end
@@ -35,6 +35,13 @@ module Lita
35
35
 
36
36
  on :loaded, :setup_octo # from LitaGithub::Octo
37
37
 
38
+ route(
39
+ /#{LitaGithub::R::A_REG}pr\s+?info\s+?#(?<pr>\d+?)\s+?#{LitaGithub::R::REPO_REGEX}/,
40
+ :pr_info,
41
+ command: true,
42
+ help: { 'gh pr info #42 PagerDuty/lita-github' => 'show some information about the pull request' }
43
+ )
44
+
38
45
  route(
39
46
  /(?:#{LitaGithub::R::A_REG}(?:pr merge|shipit)|shipit)\s+?#(?<pr>\d+?)\s+?#{LitaGithub::R::REPO_REGEX}/,
40
47
  :pr_merge, command: true, confirmation: true,
@@ -45,18 +52,36 @@ module Lita
45
52
  }
46
53
  )
47
54
 
55
+ # rubocop:disable Metrics/CyclomaticComplexity
56
+ # rubocop:disable Metrics/PerceivedComplexity
57
+ def pr_info(response)
58
+ org, repo, pr = pr_match(response)
59
+ full_name = rpo(org, repo)
60
+
61
+ pr_h = pull_request(full_name, pr)
62
+ return response.reply(t('not_found', pr: pr, org: org, repo: repo)) if pr_h[:fail] && pr_h[:not_found]
63
+
64
+ info = build_pr_info(pr_h[:pr], full_name)
65
+ comparison_url = "https://github.com/#{full_name}/compare/#{info[:base_sha]}...#{info[:pr_sha]}"
66
+ info.merge!(repo: full_name, compare: comparison_url)
67
+
68
+ reply = t('pr_info.header', info) << t('pr_info.status', info)
69
+ reply << (info[:state] == :merged ? t('pr_info.merged', info) : t('pr_info.mergeable', info))
70
+ reply << t('pr_info.commit_info', info) << t('pr_info.comments', info)
71
+
72
+ response.reply(reply)
73
+ end
74
+
48
75
  def pr_merge(response)
49
76
  return response.reply(t('method_disabled')) if func_disabled?(__method__)
50
77
  org, repo, pr = pr_match(response)
78
+ fullname = rpo(org, repo)
51
79
 
52
- begin
53
- pr_obj = octo.pull_request(rpo(org, repo), pr)
54
- rescue Octokit::NotFound
55
- return response.reply(t('not_found', pr: pr, org: org, repo: repo))
56
- end
80
+ pr_h = pull_request(fullname, pr)
81
+ return response.reply(t('not_found', pr: pr, org: org, repo: repo)) if pr_h[:fail] && pr_h[:not_found]
57
82
 
58
- branch = pr_obj[:head][:ref]
59
- title = pr_obj[:title]
83
+ branch = pr_h[:pr][:head][:ref]
84
+ title = pr_h[:pr][:title]
60
85
  commit = "Merge pull request ##{pr} from #{org}/#{branch}\n\n#{title}"
61
86
 
62
87
  status = merge_pr(org, repo, pr, commit)
@@ -70,6 +95,8 @@ module Lita
70
95
  response.reply(t('pr_merge.fail', pr: pr, title: title, url: url, msg: status[:message]))
71
96
  end
72
97
  end
98
+ # rubocop:enable Metrics/CyclomaticComplexity
99
+ # rubocop:enable Metrics/PerceivedComplexity
73
100
 
74
101
  private
75
102
 
@@ -78,6 +105,29 @@ module Lita
78
105
  [organization(md['org']), md['repo'], md['pr']]
79
106
  end
80
107
 
108
+ def pull_request(full_name, pr_num)
109
+ ret = { fail: false, not_found: false }
110
+ begin
111
+ ret[:pr] = octo.pull_request(full_name, pr_num)
112
+ rescue Octokit::NotFound
113
+ ret[:fail] = true
114
+ ret[:not_found] = true
115
+ end
116
+ ret
117
+ end
118
+
119
+ def build_pr_info(pr_obj, full_name)
120
+ info = {}
121
+
122
+ build_pr_header!(info, pr_obj)
123
+ build_pr_commitinfo!(info, pr_obj)
124
+ build_pr_status!(info, pr_obj, full_name)
125
+ build_pr_merge!(info, pr_obj)
126
+ build_pr_comments!(info, pr_obj)
127
+
128
+ info
129
+ end
130
+
81
131
  def merge_pr(org, repo, pr, commit)
82
132
  status = nil
83
133
  # rubocop:disable Lint/HandleExceptions
@@ -89,6 +139,50 @@ module Lita
89
139
  # rubocop:enable Lint/HandleExceptions
90
140
  status
91
141
  end
142
+
143
+ def build_pr_header!(info, pr_obj)
144
+ info[:title] = pr_obj[:title]
145
+ info[:number] = pr_obj[:number]
146
+ info[:url] = pr_obj[:html_url]
147
+ info
148
+ end
149
+
150
+ def build_pr_commitinfo!(info, pr_obj)
151
+ info[:commits] = pr_obj[:commits]
152
+ info[:plus] = pr_obj[:additions]
153
+ info[:minus] = pr_obj[:deletions]
154
+ info[:changed_files] = pr_obj[:changed_files]
155
+ info[:pr_sha] = pr_obj[:head][:sha]
156
+ info[:base_sha] = pr_obj[:base][:sha]
157
+ info[:pr_sha_short] = info[:pr_sha].slice(0, 7)
158
+ info
159
+ end
160
+
161
+ def build_pr_status!(info, pr_obj, full_name)
162
+ user = octo.user(pr_obj[:user][:login])
163
+ info[:user] = pr_obj[:user][:login]
164
+ info[:user] << " (#{user[:name]})" if user.key?(:name)
165
+ info[:state] = pr_obj[:merged] ? :merged : pr_obj[:state].to_sym
166
+ info[:state_str] = pr_obj[:merged] ? 'Merged' : pr_obj[:state].capitalize
167
+ info[:build_status] = octo.combined_status(full_name, info[:pr_sha])[:state]
168
+ info
169
+ end
170
+
171
+ def build_pr_merge!(info, pr_obj)
172
+ info[:mergeable] = pr_obj[:mergeable]
173
+ if info[:state] == :merged
174
+ merger = octo.user(pr_obj[:merged_by][:login])
175
+ info[:merged_by] = pr_obj[:merged_by][:login]
176
+ info[:merged_by] << " (#{merger[:name]})" if merger.key?(:name)
177
+ end
178
+ info
179
+ end
180
+
181
+ def build_pr_comments!(info, pr_obj)
182
+ info[:review_comments] = pr_obj[:review_comments]
183
+ info[:comments] = pr_obj[:comments]
184
+ info
185
+ end
92
186
  end
93
187
 
94
188
  Lita.register_handler(GithubPR)
@@ -89,9 +89,10 @@ module Lita
89
89
 
90
90
  def repo_info(response)
91
91
  org, repo = repo_match(response)
92
+ full_name = rpo(org, repo)
92
93
  opts = {}
93
- r_obj = octo.repository(rpo(org, repo))
94
- p_obj = octo.pull_requests(rpo(org, repo))
94
+ r_obj = octo.repository(full_name)
95
+ p_obj = octo.pull_requests(full_name)
95
96
 
96
97
  opts[:repo] = r_obj[:full_name]
97
98
  opts[:description] = r_obj[:description]
@@ -116,6 +117,7 @@ module Lita
116
117
  o
117
118
  end
118
119
 
120
+ # TODO: convert this to a mixin method for reuse
119
121
  def repo_match(response)
120
122
  md = response.match_data
121
123
  [organization(md['org']), md['repo']]
@@ -159,12 +161,13 @@ module Lita
159
161
  end
160
162
 
161
163
  def create_repo(org, repo, opts)
164
+ full_name = rpo(org, repo)
162
165
  reply = nil
163
166
  begin
164
167
  octo.create_repository(repo, opts)
165
168
  ensure
166
- if repo?(rpo(org, repo))
167
- repo_url = "https://github.com/#{rpo(org, repo)}"
169
+ if repo?(full_name)
170
+ repo_url = "https://github.com/#{full_name}"
168
171
  reply = t('repo_create.pass', org: org, repo: repo, repo_url: repo_url)
169
172
  else
170
173
  reply = t('repo_create.fail', org: org, repo: repo)
@@ -174,11 +177,12 @@ module Lita
174
177
  end
175
178
 
176
179
  def delete_repo(org, repo)
180
+ full_name = rpo(org, repo)
177
181
  reply = nil
178
182
  begin
179
- octo.delete_repository(rpo(org, repo))
183
+ octo.delete_repository(full_name)
180
184
  ensure
181
- if repo?(rpo(org, repo))
185
+ if repo?(full_name)
182
186
  reply = t('repo_delete.fail', org: org, repo: repo)
183
187
  else
184
188
  reply = t('repo_delete.pass', org: org, repo: repo)
@@ -22,6 +22,13 @@ en:
22
22
  method_disabled: "Sorry, this function has either been disabled or not enabled in the config"
23
23
  exception: "An unexpected exception was hit during the GitHub API operation. Please make sure all arguments are proper and try again, or try checking the GitHub status (gh status)"
24
24
  not_found: "Pull request #%{pr} on %{org}/%{repo} not found"
25
+ pr_info:
26
+ header: "%{repo} #%{number}: %{title} :: %{url}\n"
27
+ status: "Opened By: %{user} | State: %{state_str} | Build: %{build_status}"
28
+ merged: " | Merged By: %{merged_by}\n"
29
+ mergeable: " | Mergeable: %{mergeable}\n"
30
+ commit_info: "Head: %{pr_sha_short} | Commits: %{commits} (+%{plus}/-%{minus}) :: %{compare}\n"
31
+ comments: "PR Comments: %{comments} | Code Comments: %{review_comments}\n"
25
32
  pr_merge:
26
33
  pass: "Merged pull request #%{pr} from %{org}/%{branch}\n%{title}"
27
34
  fail: "Failed trying to merge PR #%{pr} (%{title}) :: %{url}\nMessage: %{msg}"
@@ -10,8 +10,12 @@ describe Lita::Handlers::GithubPR, lita_handler: true do
10
10
  let(:github_pr) { Lita::Handlers::GithubPR.new('robot') }
11
11
  let(:github_org) { 'GrapeDuty' }
12
12
  let(:github_repo) { 'lita-test' }
13
+ let(:full_name) { "#{github_org}/#{github_repo}" }
13
14
  let(:disabled_reply) { 'Sorry, this function has either been disabled or not enabled in the config' }
14
15
 
16
+ ####
17
+ # Helper Methods
18
+ ####
15
19
  describe '.pr_match' do
16
20
  it 'should return the content of the match data' do
17
21
  mock_md = { 'org' => github_org, 'repo' => github_repo, 'pr' => 42 }
@@ -20,6 +24,351 @@ describe Lita::Handlers::GithubPR, lita_handler: true do
20
24
  end
21
25
  end
22
26
 
27
+ describe '.merge_pr' do
28
+ before do
29
+ @octo_obj = double('Octokit::Client', merge_pull_request: :ohai)
30
+ allow(github_pr).to receive(:octo).and_return(@octo_obj)
31
+ end
32
+
33
+ let(:pr_num) { 42 }
34
+ let(:ref) { '1234567890' }
35
+
36
+ context 'when all goes to plan' do
37
+ it 'should call octo.merge_pull_request with the proper args' do
38
+ expect(@octo_obj).to receive(:merge_pull_request).with(full_name, pr_num, ref)
39
+ .and_return(:ohai)
40
+ github_pr.send(:merge_pr, github_org, github_repo, pr_num, ref)
41
+ end
42
+
43
+ it 'should return the return of octo.merge_pull_request' do
44
+ x = github_pr.send(:merge_pr, github_org, github_repo, 42, '1234567890')
45
+ expect(x).to eql :ohai
46
+ end
47
+ end
48
+
49
+ context 'when the merging throws an exception' do
50
+ before do
51
+ allow(@octo_obj).to receive(:merge_pull_request).with(full_name, pr_num, ref)
52
+ .and_raise(StandardError.new)
53
+ end
54
+
55
+ it 'should return nil' do
56
+ expect(github_pr.send(:merge_pr, github_org, github_repo, pr_num, ref)).to be_nil
57
+ end
58
+ end
59
+ end
60
+
61
+ describe '.build_pr_header!' do
62
+ let(:pr_obj) do
63
+ { title: 'abc123', number: 42, html_url: 'https://github.com/' }
64
+ end
65
+
66
+ it 'should return a Hash' do
67
+ info = {}
68
+ x = github_pr.send(:build_pr_header!, info, pr_obj)
69
+ expect(x).to be_an_instance_of Hash
70
+ end
71
+
72
+ it 'should set the :title key' do
73
+ info = {}
74
+ github_pr.send(:build_pr_header!, info, pr_obj)
75
+ expect(info[:title]).to eql pr_obj[:title]
76
+ end
77
+
78
+ it 'should set the :number key' do
79
+ info = {}
80
+ github_pr.send(:build_pr_header!, info, pr_obj)
81
+ expect(info[:number]).to eql pr_obj[:number]
82
+ end
83
+
84
+ it 'should set the :url key' do
85
+ info = {}
86
+ github_pr.send(:build_pr_header!, info, pr_obj)
87
+ expect(info[:url]).to eql pr_obj[:html_url]
88
+ end
89
+ end
90
+
91
+ describe '.build_pr_commitinfo!' do
92
+ let(:pr_obj) do
93
+ {
94
+ commits: 1, additions: 4, deletions: 2, changed_files: 1,
95
+ head: { sha: '1234567890' }, base: { sha: '0987654321' }
96
+ }
97
+ end
98
+ let(:info) { {} }
99
+
100
+ it 'should return a Hash' do
101
+ expect(github_pr.send(:build_pr_commitinfo!, info, pr_obj)).to be_an_instance_of Hash
102
+ end
103
+
104
+ it 'should set the :commits key' do
105
+ github_pr.send(:build_pr_commitinfo!, info, pr_obj)
106
+ expect(info[:commits]).to eql pr_obj[:commits]
107
+ end
108
+
109
+ it 'should set the :plus key' do
110
+ github_pr.send(:build_pr_commitinfo!, info, pr_obj)
111
+ expect(info[:plus]).to eql pr_obj[:additions]
112
+ end
113
+
114
+ it 'should set the :minus key' do
115
+ github_pr.send(:build_pr_commitinfo!, info, pr_obj)
116
+ expect(info[:minus]).to eql pr_obj[:deletions]
117
+ end
118
+
119
+ it 'should set the :changed_files key' do
120
+ github_pr.send(:build_pr_commitinfo!, info, pr_obj)
121
+ expect(info[:changed_files]).to eql pr_obj[:changed_files]
122
+ end
123
+
124
+ it 'should set the :pr_sha key' do
125
+ github_pr.send(:build_pr_commitinfo!, info, pr_obj)
126
+ expect(info[:pr_sha]).to eql pr_obj[:head][:sha]
127
+ end
128
+
129
+ it 'should be set the :base_sha key' do
130
+ github_pr.send(:build_pr_commitinfo!, info, pr_obj)
131
+ expect(info[:base_sha]).to eql pr_obj[:base][:sha]
132
+ end
133
+
134
+ it 'should set the :pr_sha_short key' do
135
+ github_pr.send(:build_pr_commitinfo!, info, pr_obj)
136
+ expect(info[:pr_sha_short]).to eql info[:pr_sha].slice(0, 7)
137
+ end
138
+ end
139
+
140
+ describe '.build_pr_status!' do
141
+ before do
142
+ @user_obj = { name: 'Tim Heckman' }
143
+ @cs_obj = { state: 'success' }
144
+ @octo_obj = double('Octokit::Client', user: @user_obj, combined_status: @cs_obj)
145
+ allow(github_pr).to receive(:octo).and_return(@octo_obj)
146
+ end
147
+
148
+ let(:pr_obj) do
149
+ {
150
+ user: { login: 'theckman' }, state: 'closed', merged: true, pr_sha: '1234567890'
151
+ }
152
+ end
153
+ let(:info) { { pr_sha: '1234567890' } }
154
+
155
+ it 'should return an instance of Hash' do
156
+ expect(github_pr.send(:build_pr_status!, info, pr_obj, full_name))
157
+ .to be_an_instance_of Hash
158
+ end
159
+
160
+ it 'should call octo.user' do
161
+ expect(@octo_obj).to receive(:user).with('theckman')
162
+ github_pr.send(:build_pr_status!, info, pr_obj, full_name)
163
+ end
164
+
165
+ it 'should call octo.combined_status and set it to :build_status' do
166
+ expect(@octo_obj).to receive(:combined_status)
167
+ .with(full_name, '1234567890')
168
+ .and_return(@cs_obj)
169
+ github_pr.send(:build_pr_status!, info, pr_obj, full_name)
170
+ expect(info[:build_status]).to eql 'success'
171
+ end
172
+
173
+ context 'when user has a name set' do
174
+ it 'should include the name' do
175
+ github_pr.send(:build_pr_status!, info, pr_obj, full_name)
176
+ expect(info[:user]).to eql 'theckman (Tim Heckman)'
177
+ end
178
+ end
179
+
180
+ context 'when the PR has been merged' do
181
+ it 'should set the :state key to :merged' do
182
+ github_pr.send(:build_pr_status!, info, pr_obj, full_name)
183
+ expect(info[:state]).to eql :merged
184
+ end
185
+
186
+ it 'should set the :state_str to "Merged"' do
187
+ github_pr.send(:build_pr_status!, info, pr_obj, full_name)
188
+ expect(info[:state_str]).to eql 'Merged'
189
+ end
190
+ end
191
+
192
+ context 'when user has no name set' do
193
+ before do
194
+ @octo_obj = double('Octokit::Client', user: {}, combined_status: @cs_obj)
195
+ allow(github_pr).to receive(:octo).and_return(@octo_obj)
196
+ end
197
+
198
+ it 'should not include the real name parenthesis' do
199
+ github_pr.send(:build_pr_status!, info, pr_obj, full_name)
200
+ expect(info[:user]).to eql 'theckman'
201
+ end
202
+ end
203
+
204
+ context 'when PR not merged' do
205
+ context 'when status is open' do
206
+ let(:pr_obj) do
207
+ {
208
+ user: { login: 'theckman' }, state: 'open', merged: false
209
+ }
210
+ end
211
+
212
+ it 'should set the :state key to :open' do
213
+ github_pr.send(:build_pr_status!, info, pr_obj, full_name)
214
+ expect(info[:state]).to eql :open
215
+ end
216
+
217
+ it 'should set the :state_str to "Open"' do
218
+ github_pr.send(:build_pr_status!, info, pr_obj, full_name)
219
+ expect(info[:state_str]).to eql 'Open'
220
+ end
221
+ end
222
+
223
+ context 'when status is closed' do
224
+ let(:pr_obj) do
225
+ {
226
+ user: { login: 'theckman' }, state: 'closed', merged: false
227
+ }
228
+ end
229
+
230
+ it 'should set the :state key to :closed' do
231
+ github_pr.send(:build_pr_status!, info, pr_obj, full_name)
232
+ expect(info[:state]).to eql :closed
233
+ end
234
+
235
+ it 'should set the :state_str to "Closed"' do
236
+ github_pr.send(:build_pr_status!, info, pr_obj, full_name)
237
+ expect(info[:state_str]).to eql 'Closed'
238
+ end
239
+ end
240
+ end
241
+ end
242
+
243
+ describe '.build_pr_merge!' do
244
+ before do
245
+ @user_obj = { name: 'Tim Heckman' }
246
+ @octo_obj = double('Octokit::Client', user: @user_obj)
247
+ allow(github_pr).to receive(:octo).and_return(@octo_obj)
248
+ end
249
+
250
+ let(:pr_obj) do
251
+ {
252
+ state: :open, mergeable: true
253
+ }
254
+ end
255
+ let(:info) { { state: :open } }
256
+
257
+ it 'should return an instance of Hash' do
258
+ expect(github_pr.send(:build_pr_merge!, info, pr_obj))
259
+ .to be_an_instance_of Hash
260
+ end
261
+
262
+ it 'should set the :mergable key' do
263
+ github_pr.send(:build_pr_merge!, info, pr_obj)
264
+ expect(info[:mergeable]).to eql true
265
+ end
266
+
267
+ context 'when not merged' do
268
+ it 'should not set the :merged_by key' do
269
+ github_pr.send(:build_pr_merge!, info, pr_obj)
270
+ expect(info.key?(:merged_by)).to be_falsey
271
+ end
272
+ end
273
+
274
+ context 'when merged' do
275
+ let(:pr_obj) do
276
+ {
277
+ state: :merged, mergeable: nil, merged_by: { login: 'theckman' }
278
+ }
279
+ end
280
+ let(:info) { { state: :merged } }
281
+
282
+ it 'should grab some user info about who merged' do
283
+ expect(@octo_obj).to receive(:user).with('theckman').and_return(@user_obj)
284
+ github_pr.send(:build_pr_merge!, info, pr_obj)
285
+ end
286
+
287
+ context 'when user has a name field' do
288
+ it 'should set the :merged_by key' do
289
+ github_pr.send(:build_pr_merge!, info, pr_obj)
290
+ expect(info[:merged_by]).to eql 'theckman (Tim Heckman)'
291
+ end
292
+ end
293
+
294
+ context 'when the user has no name field' do
295
+ before do
296
+ @user_obj = {}
297
+ @octo_obj = double('Octokit::Client', user: @user_obj)
298
+ allow(github_pr).to receive(:octo).and_return(@octo_obj)
299
+ end
300
+
301
+ it 'should set the :merged_by key without parenthesis' do
302
+ github_pr.send(:build_pr_merge!, info, pr_obj)
303
+ expect(info[:merged_by]).to eql 'theckman'
304
+ end
305
+ end
306
+ end
307
+ end
308
+
309
+ describe '.build_pr_comments!' do
310
+ let(:pr_obj) { { comments: 1, review_comments: 3 } }
311
+ let(:info) { {} }
312
+
313
+ it 'should return a Hash' do
314
+ expect(github_pr.send(:build_pr_comments!, info, pr_obj)).to be_an_instance_of Hash
315
+ end
316
+
317
+ it 'should set the :comments key' do
318
+ github_pr.send(:build_pr_comments!, info, pr_obj)
319
+ expect(info[:comments]).to eql 1
320
+ end
321
+
322
+ it 'should set the :review_comments key' do
323
+ github_pr.send(:build_pr_comments!, info, pr_obj)
324
+ expect(info[:review_comments]).to eql 3
325
+ end
326
+ end
327
+
328
+ describe '.build_pr_info' do
329
+ before do
330
+ allow(github_pr).to receive(:build_pr_header!).and_return(nil)
331
+ allow(github_pr).to receive(:build_pr_commitinfo!).and_return(nil)
332
+ allow(github_pr).to receive(:build_pr_status!).and_return(nil)
333
+ allow(github_pr).to receive(:build_pr_merge!).and_return(nil)
334
+ allow(github_pr).to receive(:build_pr_comments!).and_return(nil)
335
+ end
336
+
337
+ let(:pr_obj) { :ohai }
338
+
339
+ it 'should return an instance of Hash' do
340
+ expect(github_pr.send(:build_pr_info, pr_obj, full_name)).to be_an_instance_of Hash
341
+ end
342
+
343
+ it 'should call .build_pr_header!' do
344
+ expect(github_pr).to receive(:build_pr_header!).with({}, pr_obj).and_return(nil)
345
+ github_pr.send(:build_pr_info, pr_obj, full_name)
346
+ end
347
+
348
+ it 'should call .build_pr_commitinfo!' do
349
+ expect(github_pr).to receive(:build_pr_commitinfo!).with({}, pr_obj).and_return(nil)
350
+ github_pr.send(:build_pr_info, pr_obj, full_name)
351
+ end
352
+
353
+ it 'should call .build_pr_status!' do
354
+ expect(github_pr).to receive(:build_pr_status!).with({}, pr_obj, full_name).and_return(nil)
355
+ github_pr.send(:build_pr_info, pr_obj, full_name)
356
+ end
357
+
358
+ it 'should call .build_pr_merge!' do
359
+ expect(github_pr).to receive(:build_pr_merge!).with({}, pr_obj).and_return(nil)
360
+ github_pr.send(:build_pr_info, pr_obj, full_name)
361
+ end
362
+
363
+ it 'should call .build_pr_comments!' do
364
+ expect(github_pr).to receive(:build_pr_comments!).with({}, pr_obj).and_return(nil)
365
+ github_pr.send(:build_pr_info, pr_obj, full_name)
366
+ end
367
+ end
368
+
369
+ ####
370
+ # Handlers
371
+ ####
23
372
  describe '.merge_pr' do
24
373
  before do
25
374
  @merge_status = { sha: 'abc456', merged: true, message: 'Pull Request successfully merged' }
@@ -49,6 +398,75 @@ describe Lita::Handlers::GithubPR, lita_handler: true do
49
398
  end
50
399
  end
51
400
 
401
+ describe '.pr_info' do
402
+ context 'when PR is not merged' do
403
+ before do
404
+ @pr_info = {
405
+ title: 'Test Pull Request (Not Real)', number: 42,
406
+ url: "https://github.com/#{github_org}/#{github_repo}/pulls/42",
407
+ commits: 1, plus: 42, minus: 0, changed_files: 1, pr_sha: '1234567890',
408
+ base_sha: '0987654321', pr_sha_short: '1234567', user: 'theckman (Tim Heckman)',
409
+ state: :open, state_str: 'Open', build_status: 'success', mergeable: true,
410
+ review_comments: 2, comments: 1
411
+ }
412
+ @pr_resp = { fail: false, not_found: false, pr: @pr_info }
413
+ allow(github_pr).to receive(:pull_request).and_return(@pr_resp)
414
+ allow(github_pr).to receive(:build_pr_info).and_return(@pr_info)
415
+ end
416
+
417
+ it 'should reply with the expeced output' do
418
+ r = 'GrapeDuty/lita-test #42: Test Pull Request (Not Real) :: ' \
419
+ "https://github.com/GrapeDuty/lita-test/pulls/42\n" \
420
+ "Opened By: theckman (Tim Heckman) | State: Open | Build: success | Mergeable: true\n" \
421
+ 'Head: 1234567 | Commits: 1 (+42/-0) :: ' \
422
+ "https://github.com/GrapeDuty/lita-test/compare/0987654321...1234567890\n" \
423
+ "PR Comments: 1 | Code Comments: 2\n"
424
+ send_command("gh pr info #42 #{github_org}/#{github_repo}")
425
+ expect(replies.last).to eql r
426
+ end
427
+ end
428
+
429
+ context 'when the PR has been merged' do
430
+ before do
431
+ @pr_info = {
432
+ title: 'Test Pull Request (Not Real)', number: 42,
433
+ url: "https://github.com/#{github_org}/#{github_repo}/pulls/42",
434
+ commits: 1, plus: 42, minus: 0, changed_files: 1, pr_sha: '1234567890',
435
+ base_sha: '0987654321', pr_sha_short: '1234567', user: 'theckman (Tim Heckman)',
436
+ state: :merged, state_str: 'Merged', build_status: 'success', mergeable: true,
437
+ merged_by: 'theckman (Tim Heckman)', review_comments: 2, comments: 1
438
+ }
439
+ @pr_resp = { fail: false, not_found: false, pr: @pr_info }
440
+ allow(github_pr).to receive(:pull_request).and_return(@pr_resp)
441
+ allow(github_pr).to receive(:build_pr_info).and_return(@pr_info)
442
+ end
443
+
444
+ it 'should reply with the expeced output' do
445
+ r = 'GrapeDuty/lita-test #42: Test Pull Request (Not Real) :: ' \
446
+ "https://github.com/GrapeDuty/lita-test/pulls/42\n" \
447
+ 'Opened By: theckman (Tim Heckman) | State: Merged | Build: success | ' \
448
+ "Merged By: theckman (Tim Heckman)\n" \
449
+ 'Head: 1234567 | Commits: 1 (+42/-0) :: ' \
450
+ "https://github.com/GrapeDuty/lita-test/compare/0987654321...1234567890\n" \
451
+ "PR Comments: 1 | Code Comments: 2\n"
452
+ send_command("gh pr info #42 #{github_org}/#{github_repo}")
453
+ expect(replies.last).to eql r
454
+ end
455
+ end
456
+
457
+ context 'when the PR was not found' do
458
+ before do
459
+ @pr_resp = { fail: true, not_found: true, pr: @pr_info }
460
+ allow(github_pr).to receive(:pull_request).and_return(@pr_resp)
461
+ end
462
+
463
+ it 'should reply with the not found error' do
464
+ send_command("gh pr info #42 #{github_org}/#{github_repo}")
465
+ expect(replies.last).to eql 'Pull request #42 on GrapeDuty/lita-test not found'
466
+ end
467
+ end
468
+ end
469
+
52
470
  describe '.pr_merge' do
53
471
  before do
54
472
  @cfg_obj = double('Lita::Configuration', pr_merge_enabled: true)
@@ -66,7 +484,7 @@ describe Lita::Handlers::GithubPR, lita_handler: true do
66
484
  allow(github_pr).to receive(:func_disabled?).and_return(true)
67
485
  end
68
486
 
69
- it 'should no-op and say such if the command is disabled' do
487
+ it 'should no-op and say such' do
70
488
  send_command("shipit #42 #{github_org}/#{github_repo}")
71
489
  expect(replies.last).to eql disabled_reply
72
490
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lita-github
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Heckman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-29 00:00:00.000000000 Z
11
+ date: 2014-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -218,3 +218,4 @@ test_files:
218
218
  - spec/unit/lita/handlers/github_pr_spec.rb
219
219
  - spec/unit/lita/handlers/github_repo_spec.rb
220
220
  - spec/unit/lita/handlers/github_spec.rb
221
+ has_rdoc: