lita-github 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ece12c721d1b5311529352629acae15998e6d487
4
- data.tar.gz: 32877ccdac63d11a2ce09a1afe9368ad6a3000a4
3
+ metadata.gz: bb3cd200b9fc34080456111f08e27e79a3297311
4
+ data.tar.gz: eedcd297373ba3f19afe00e3ef460e8cf9248829
5
5
  SHA512:
6
- metadata.gz: d1baca6ba8a93e75740a0923e2e80947c01c175ca49acff466475247dae4d11357e4f2a21eab3cc24492b823ff394265a8de33e09aeaebe038c9d9de50ea2b4a
7
- data.tar.gz: 5c1a9c8fa5d8edfe12c17f082211e7de4db1a36705fad6a0247c3807d586aa549ab3eb027385ac15ebe6617a59643ac795a9194c4d512de0c6034f6c287a363b
6
+ metadata.gz: dfb028a7d353c084a53a9f9ed6c0811dc78850cad2eaf58f74cb00ab87be8d4f3cecb613a5369d3957ac237822c2207fd1d1af0dbce079c927018d11c1a949ef
7
+ data.tar.gz: 85f39a45bf8bc5e1b0a1b1308472e8dc5bf5a33c9033691b98ac30876813c36779246786a4cf5300766054db16d712981ace7bcd4143263ca6ced2d60b98c37c
@@ -12,3 +12,7 @@ Metrics/LineLength:
12
12
  Max: 120
13
13
  Metrics/MethodLength:
14
14
  Max: 30
15
+
16
+ # pending: https://github.com/bbatsov/rubocop/issues/1332
17
+ Style/GuardClause:
18
+ Enabled: false
data/README.md CHANGED
@@ -57,6 +57,12 @@ Here is the current functionality:
57
57
  * `!gh repo delete PagerDuty/lita-github`
58
58
  * Deletes the repo you specify, requires confirmation before doing so
59
59
  * **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
60
+ * `!gh repo teams PagerDuty/lita-github`
61
+ * list all of the teams currently attached to a repo
62
+ * `!gh repo team add <TEAM_ID|TEAM_SLUG> PagerDuty/lita-github`
63
+ * adds the team to the repo -- requires confirmation and enabling via config option (`repo_team_add_enabled = true`)
64
+ * `!gh repo team rm <TEAM_ID|TEAM_SLUG> PagerDuty/lita-github`
65
+ * removes the team to the repo -- requires confirmation and enabling via config option (`repo_team_rm_enabled = true`)
60
66
 
61
67
  ### Github PR Handler
62
68
  * `!gh pr info PagerDuty/lita-github #42`
@@ -66,3 +72,7 @@ Here is the current functionality:
66
72
  * This method can be disabled by setting `config.handlers.github.pr_merge_enabled = false` in your configuration file
67
73
  * `!gh pr list PagerDuty/lita-github`
68
74
  * list the open pull requests on a repo
75
+
76
+ ### Github Organization Handler
77
+ * `!gh org teams PagerDuty` & `!gh teams PagerDuty`
78
+ * list the teams for the GitHub repo
@@ -24,3 +24,4 @@ require 'lita-github/version'
24
24
  require 'lita/handlers/github'
25
25
  require 'lita/handlers/github_repo'
26
26
  require 'lita/handlers/github_pr'
27
+ require 'lita/handlers/github_org'
@@ -20,5 +20,9 @@ module LitaGithub
20
20
  def organization(name)
21
21
  name.nil? || name.empty? ? config.default_org : name
22
22
  end
23
+
24
+ def sort_by_name(teams)
25
+ teams.sort_by { |h| h[:name].downcase }
26
+ end
23
27
  end
24
28
  end
@@ -27,9 +27,13 @@ module LitaGithub
27
27
  octo.repository?(r)
28
28
  end
29
29
 
30
- def repo_match(response)
31
- md = response.match_data
30
+ def repo_match(md)
32
31
  [organization(md['org']), md['repo']]
33
32
  end
33
+
34
+ def repo_has_team?(full_name, team_id)
35
+ octo.repository_teams(full_name).each { |t| return true if t[:id] == team_id }
36
+ false
37
+ end
34
38
  end
35
39
  end
@@ -16,6 +16,6 @@
16
16
 
17
17
  # Administer your Hub of Gits with Lita!
18
18
  module LitaGithub
19
- VERSION = '0.0.8'
19
+ VERSION = '0.0.9'
20
20
  MAJ, MIN, REV = VERSION.split('.').map(&:to_i)
21
21
  end
@@ -70,8 +70,10 @@ module Lita
70
70
  config.totp_secret = nil
71
71
 
72
72
  # Lita::Handlers::GithubRepo
73
- config.repo_create_enabled = true
74
- config.repo_delete_enabled = false
73
+ config.repo_create_enabled = true
74
+ config.repo_delete_enabled = false
75
+ config.repo_team_add_enabled = false
76
+ config.repo_team_rm_enabled = false
75
77
 
76
78
  # Lita::Handlers::GithubPR
77
79
  config.pr_merge_enabled = true
@@ -0,0 +1,70 @@
1
+ # -*- coding: UTF-8 -*-
2
+ #
3
+ # Copyright 2014 PagerDuty, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'lita-github/r'
18
+ require 'lita-github/config'
19
+ require 'lita-github/octo'
20
+ require 'lita-github/org'
21
+
22
+ module Lita
23
+ # Lita Handler
24
+ module Handlers
25
+ # GitHub Lita Handler
26
+ class GithubOrg < Handler
27
+ include LitaGithub::Config # Github handler Lita configuration methods
28
+ include LitaGithub::Octo # Github handler common-use Octokit methods
29
+ include LitaGithub::Org # Github handler common-use Organization methods
30
+
31
+ on :loaded, :setup_octo # from LitaGithub::Octo
32
+
33
+ # rubocop:disable Metrics/LineLength
34
+ route(
35
+ /#{LitaGithub::R::A_REG}(?:teams|org\s+?teams|org\s+?team\s+?list)(?<org>\s+[a-zA-Z0-9_\-]+)?/,
36
+ :org_teams_list,
37
+ command: true,
38
+ help: {
39
+ 'gh org teams [organization]' => 'show all teams of an organization',
40
+ 'gh teams [organization]' => 'an alias for gh org teams'
41
+ }
42
+ )
43
+ # rubocop:enable Metrics/LineLength
44
+
45
+ def org_teams_list(response)
46
+ md = response.match_data
47
+ org = md[:org].nil? ? config.default_org : organization(md[:org].strip)
48
+
49
+ begin
50
+ teams = octo.organization_teams(org)
51
+ rescue Octokit::NotFound
52
+ return response.reply(t('org_not_found', org: org))
53
+ end
54
+
55
+ tl = teams.length
56
+
57
+ o = teams.shift
58
+
59
+ reply = t('org_teams_list.header', org: org, num_teams: tl)
60
+ reply << t('org_teams_list.team', o.to_h)
61
+
62
+ sort_by_name(teams).each { |team| reply << t('org_teams_list.team', team.to_h) }
63
+
64
+ response.reply(reply)
65
+ end
66
+ end
67
+
68
+ Lita.register_handler(GithubOrg)
69
+ end
70
+ end
@@ -63,7 +63,7 @@ module Lita
63
63
  # rubocop:disable Metrics/CyclomaticComplexity
64
64
  # rubocop:disable Metrics/PerceivedComplexity
65
65
  def pr_info(response)
66
- org, repo, pr = pr_match(response)
66
+ org, repo, pr = pr_match(response.match_data)
67
67
  full_name = rpo(org, repo)
68
68
 
69
69
  pr_h = pull_request(full_name, pr)
@@ -82,7 +82,7 @@ module Lita
82
82
 
83
83
  def pr_merge(response)
84
84
  return response.reply(t('method_disabled')) if func_disabled?(__method__)
85
- org, repo, pr = pr_match(response)
85
+ org, repo, pr = pr_match(response.match_data)
86
86
  fullname = rpo(org, repo)
87
87
 
88
88
  pr_h = pull_request(fullname, pr)
@@ -107,7 +107,7 @@ module Lita
107
107
  # rubocop:enable Metrics/PerceivedComplexity
108
108
 
109
109
  def pr_list(response)
110
- org, repo = repo_match(response)
110
+ org, repo = repo_match(response.match_data)
111
111
  full_name = rpo(org, repo)
112
112
  reply = ''
113
113
 
@@ -132,8 +132,7 @@ module Lita
132
132
 
133
133
  private
134
134
 
135
- def pr_match(response)
136
- md = response.match_data
135
+ def pr_match(md)
137
136
  [organization(md['org']), md['repo'], md['pr']]
138
137
  end
139
138
 
@@ -63,10 +63,33 @@ module Lita
63
63
  }
64
64
  )
65
65
 
66
+ route(
67
+ /#{LitaGithub::R::A_REG}repo\s+?(teams|team\s+?list)\s+?#{LitaGithub::R::REPO_REGEX}/,
68
+ :repo_teams_list,
69
+ command: true,
70
+ help: {
71
+ 'gh repo teams PagerDuty/lita-github' => 'list the teams allowed to to access a repo',
72
+ 'gh repo team list PagerDuty/lita-github' => 'list the teams allowed to to access a repo'
73
+ }
74
+ )
75
+
76
+ # rubocop:disable Metrics/LineLength
77
+ route(
78
+ /#{LitaGithub::R::A_REG}repo\s+?team\s+?(?<action>add|rm)\s+?(?<team>[a-zA-Z0-9_\-]+?)(\s+?to)?\s+?#{LitaGithub::R::REPO_REGEX}/,
79
+ :repo_team_router, command: true, confirmation: true,
80
+ help: {
81
+ 'gh repo team add everyone PagerDuty/lita-test' => 'add a team using slug to your repo',
82
+ 'gh repo team add 42 PagerDuty/lita-test' => 'add a team using ID to your repo',
83
+ 'gh repo team rm everyone PagerDuty/lita-test' => 'remove a team using slug to your repo',
84
+ 'gh repo team rm 42 PagerDuty/lita-test' => 'remove a team using ID to your repo'
85
+ }
86
+ )
87
+ # rubocop:enable Metrics/LineLength
88
+
66
89
  def repo_create(response)
67
90
  return response.reply(t('method_disabled')) if func_disabled?(__method__)
68
91
 
69
- org, repo = repo_match(response)
92
+ org, repo = repo_match(response.match_data)
70
93
 
71
94
  if repo?(rpo(org, repo))
72
95
  return response.reply(t('repo_create.exists', org: org, repo: repo))
@@ -80,15 +103,15 @@ module Lita
80
103
  def repo_delete(response)
81
104
  return response.reply(t('method_disabled')) if func_disabled?(__method__)
82
105
 
83
- org, repo = repo_match(response)
106
+ org, repo = repo_match(response.match_data)
84
107
 
85
- return response.reply(t('repo_delete.not_found', org: org, repo: repo)) unless repo?(rpo(org, repo))
108
+ return response.reply(t('not_found', org: org, repo: repo)) unless repo?(rpo(org, repo))
86
109
 
87
110
  response.reply(delete_repo(org, repo))
88
111
  end
89
112
 
90
113
  def repo_info(response)
91
- org, repo = repo_match(response)
114
+ org, repo = repo_match(response.match_data)
92
115
  full_name = rpo(org, repo)
93
116
  opts = {}
94
117
  r_obj = octo.repository(full_name)
@@ -105,8 +128,68 @@ module Lita
105
128
  response.reply(t('repo_info.reply', opts))
106
129
  end
107
130
 
131
+ def repo_teams_list(response)
132
+ org, repo = repo_match(response.match_data)
133
+ full_name = rpo(org, repo)
134
+
135
+ begin
136
+ teams = octo.repository_teams(full_name)
137
+ rescue Octokit::NotFound
138
+ return response.reply(t('not_found', org: org, repo: repo))
139
+ end
140
+
141
+ if teams.length == 0
142
+ reply = t('repo_team_list.none', org: org, repo: full_name)
143
+ else
144
+ reply = t('repo_team_list.header', num_teams: teams.length, repo: full_name)
145
+ end
146
+
147
+ sort_by_name(teams).each { |team| reply << t('repo_team_list.team', team.to_h) }
148
+
149
+ response.reply(reply)
150
+ end
151
+
152
+ def repo_team_router(response)
153
+ action = response.match_data['action']
154
+ response.reply(send("repo_team_#{action}".to_sym, response))
155
+ end
156
+
108
157
  private
109
158
 
159
+ def repo_team_add(response)
160
+ return t('method_disabled') if func_disabled?(__method__)
161
+ md = response.match_data
162
+ org, repo = repo_match(md)
163
+ full_name = rpo(org, repo)
164
+ team = gh_team(org, md['team'])
165
+
166
+ return t('not_found', org: org, repo: repo) unless repo?(full_name)
167
+ return t('team_not_found', team: md['team']) if team.nil?
168
+
169
+ if repo_has_team?(full_name, team[:id])
170
+ return t('repo_team_add.exists', repo: full_name, team: team[:name])
171
+ end
172
+
173
+ add_team_to_repo(full_name, team)
174
+ end
175
+
176
+ def repo_team_rm(response)
177
+ return t('method_disabled') if func_disabled?(__method__)
178
+ md = response.match_data
179
+ org, repo = repo_match(md)
180
+ full_name = rpo(org, repo)
181
+ team = gh_team(org, md['team'])
182
+
183
+ return t('not_found', org: org, repo: repo) unless repo?(full_name)
184
+ return t('team_not_found', team: md['team']) if team.nil?
185
+
186
+ unless repo_has_team?(full_name, team[:id])
187
+ return t('repo_team_rm.exists', repo: full_name, team: team[:name])
188
+ end
189
+
190
+ remove_team_from_repo(full_name, team)
191
+ end
192
+
110
193
  def command_opts(cmd)
111
194
  o = {}
112
195
  cmd.scan(LitaGithub::R::OPT_REGEX).flatten.compact.each do |opt|
@@ -193,6 +276,34 @@ module Lita
193
276
  end
194
277
  reply
195
278
  end
279
+
280
+ def gh_team(org, team)
281
+ team_id = /^\d+$/.match(team.to_s) ? team : team_id_by_slug(team, org)
282
+
283
+ return nil if team_id.nil?
284
+
285
+ begin
286
+ octo.team(team_id)
287
+ rescue Octokit::NotFound
288
+ nil
289
+ end
290
+ end
291
+
292
+ def add_team_to_repo(full_name, team)
293
+ if octo.add_team_repository(team[:id], full_name)
294
+ return t('repo_team_add.pass', repo: full_name, team: team[:name])
295
+ else
296
+ return t('repo_team_add.fail', repo: full_name, team: team[:name])
297
+ end
298
+ end
299
+
300
+ def remove_team_from_repo(full_name, team)
301
+ if octo.remove_team_repository(team[:id], full_name)
302
+ return t('repo_team_rm.pass', repo: full_name, team: team[:name])
303
+ else
304
+ return t('repo_team_rm.fail', repo: full_name, team: team[:name])
305
+ end
306
+ end
196
307
  end
197
308
 
198
309
  Lita.register_handler(GithubRepo)
@@ -40,6 +40,7 @@ Gem::Specification.new do |s|
40
40
  s.add_development_dependency 'rubocop', '~> 0.26.0'
41
41
  s.add_development_dependency 'rspec', '~> 3.0'
42
42
  s.add_development_dependency 'fuubar', '~> 2.0'
43
+ s.add_development_dependency 'pry', '~> 0.10', '>= 0.10.1'
43
44
  s.add_development_dependency 'codeclimate-test-reporter', '~> 0.4', '>= 0.4.0'
44
45
 
45
46
  s.add_runtime_dependency 'lita', '~> 3.3'
@@ -11,6 +11,8 @@ en:
11
11
  totp: "%{token}"
12
12
  github_repo:
13
13
  method_disabled: "Sorry, this function has either been disabled or not enabled in the config"
14
+ not_found: "That repo (%{org}/%{repo}) does not exist"
15
+ team_not_found: "Unable to match any teams based on: %{team}"
14
16
  repo_create:
15
17
  pass: "Created %{org}/%{repo}: %{repo_url}"
16
18
  fail: "Unable to create %{org}/%{repo}"
@@ -18,9 +20,20 @@ en:
18
20
  repo_delete:
19
21
  pass: "Deleted %{org}/%{repo}"
20
22
  fail: "Unable to delete %{org}/%{repo}"
21
- not_found: "That repo (%{org}/%{repo}) does not exist"
22
23
  repo_info:
23
24
  reply: "%{repo} (private:%{private}) :: %{url}\nDesc: %{description}\nIssues: %{issues_count} PRs: %{pr_count}"
25
+ repo_team_list:
26
+ none: "Beyond the '%{org}' org owners, %{repo} has no teams"
27
+ header: "Showing %{num_teams} team(s) for %{repo}:\n"
28
+ team: "Name: %{name}, Slug: %{slug}, ID: %{id}, Perms: %{permission}\n"
29
+ repo_team_add:
30
+ pass: "Added the '%{team}' team to %{repo}"
31
+ fail: "Something went wrong trying to add the '%{team}' team to %{repo}. Is that team in your organization?"
32
+ exists: "The '%{team}' team is already a member of %{repo}"
33
+ repo_team_rm:
34
+ pass: "Removed the '%{team}' team from %{repo}"
35
+ fail: "Something went wrong trying to remove the '%{team}' team from %{repo}"
36
+ exists: "The '%{team}' team is not a member of %{repo}"
24
37
  github_pr:
25
38
  method_disabled: "Sorry, this function has either been disabled or not enabled in the config"
26
39
  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)"
@@ -38,3 +51,8 @@ en:
38
51
  pr_list:
39
52
  large_list: "You have more than %{max} open pull requests :(! Here are the ten newest oldest:\n"
40
53
  no_prs: "This repo has no open pull requests; good job!"
54
+ github_org:
55
+ org_not_found: "The organization '%{org}' was not found. Does my user have ownership permission?"
56
+ org_teams_list:
57
+ header: "Showing %{num_teams} team(s) for %{org}:\n"
58
+ team: "Name: %{name}, Slug: %{slug}, ID: %{id}, Perms: %{permission}\n"
@@ -34,10 +34,11 @@ describe LitaGithub::Octo do
34
34
  allow(Octokit::Client).to receive(:new).with(access_token: 'abc123').and_return(DoubleFixer)
35
35
  @conf_obj = double('Lita::Config', access_token: 'abc123')
36
36
  allow(self).to receive(:config).and_return(@conf_obj)
37
- allow_any_instance_of(DummyClass).to receive(:config).and_return(@conf_obj)
38
37
  @dummy = DummyClass.new
38
+ allow(@dummy).to receive(:config).and_return(@conf_obj)
39
39
  @dummy.setup_octo(nil)
40
40
  end
41
+ after { allow(Octokit::Client).to receive(:new).and_call_original }
41
42
 
42
43
  include LitaGithub::Octo
43
44
 
@@ -29,4 +29,21 @@ describe LitaGithub::Org do
29
29
  end
30
30
  end
31
31
  end
32
+
33
+ describe '.sort_by_name' do
34
+ let(:unsorted_list) do
35
+ [
36
+ { name: 'xy' }, { name: 'a' }, { name: 'Zx' }, { name: 'D' }, { name: 'z' }
37
+ ]
38
+ end
39
+ let(:sorted_list) do
40
+ [
41
+ { name: 'a' }, { name: 'D' }, { name: 'xy' }, { name: 'z' }, { name: 'Zx' }
42
+ ]
43
+ end
44
+
45
+ it 'should properly sort the list' do
46
+ expect(sort_by_name(unsorted_list)).to eql sorted_list
47
+ end
48
+ end
32
49
  end
@@ -45,13 +45,31 @@ describe LitaGithub::Repo do
45
45
  describe '.repo_match' do
46
46
  before { allow(self).to receive(:organization).and_return('GrapeDuty') }
47
47
 
48
- let(:resp_obj) do
49
- md_mock = { 'org' => 'GrapeDuty', 'repo' => 'lita-test' }
50
- double('Lita::Response', match_data: md_mock)
51
- end
48
+ let(:match_data) { { 'org' => 'GrapeDuty', 'repo' => 'lita-test' } }
52
49
 
53
50
  it 'should return the Org/Repo match' do
54
- expect(repo_match(resp_obj)).to eql ['GrapeDuty', 'lita-test']
51
+ expect(repo_match(match_data)).to eql ['GrapeDuty', 'lita-test']
52
+ end
53
+ end
54
+
55
+ describe '.repo_has_team?' do
56
+ before do
57
+ @teams = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }]
58
+ @octo_obj = double('Octokit::Client', repository_teams: @teams)
59
+ allow(self).to receive(:octo).and_return(@octo_obj)
60
+ end
61
+
62
+ context 'when repo has the team' do
63
+ it 'should return be truthy' do
64
+ expect(@octo_obj).to receive(:repository_teams).with('GrapeDuty/lita-test').and_return(@teams)
65
+ expect(repo_has_team?('GrapeDuty/lita-test', 4)).to be_truthy
66
+ end
67
+ end
68
+
69
+ context 'when the repo does not have the team' do
70
+ it 'should be falsey' do
71
+ expect(repo_has_team?('GrapeDuty/lita-test', 42)).to be_falsey
72
+ end
55
73
  end
56
74
  end
57
75
  end
@@ -0,0 +1,65 @@
1
+ # -*- coding: UTF-8 -*-
2
+ #
3
+ # Copyright 2014 PagerDuty, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'spec_helper'
18
+
19
+ describe Lita::Handlers::GithubOrg, lita_handler: true do
20
+ it { routes_command('gh teams PagerDuty').to(:org_teams_list) }
21
+ it { routes_command('gh org teams GrapeDuty').to(:org_teams_list) }
22
+ it { routes_command('gh org team list PagerDuty').to(:org_teams_list) }
23
+ it { routes_command('gh teams').to(:org_teams_list) }
24
+ it { routes_command('gh org teams').to(:org_teams_list) }
25
+ it { routes_command('gh org team list').to(:org_teams_list) }
26
+
27
+ let(:github_org) { Lita::Handlers::GithubOrg.new('robot') }
28
+
29
+ describe '.org_teams_list' do
30
+ before do
31
+ @teams = [
32
+ { name: 'Owners', id: 1, slug: 'owners', permission: 'admin' },
33
+ { name: 'HeckmanTest', slug: 'heckmantest', id: 42, permission: 'push' },
34
+ { name: 'A Team', slug: 'a-team', id: 84, permission: 'pull' }
35
+ ]
36
+ conf_obj = double('Lita::Configuration', default_org: 'GrapeDuty')
37
+ @octo_obj = double('Octokit::Client', organization_teams: @teams)
38
+ allow(github_org).to receive(:config).and_return(conf_obj)
39
+ allow(github_org).to receive(:octo).and_return(@octo_obj)
40
+ end
41
+
42
+ context 'when provided a valid org' do
43
+ it 'should return a list of the team sorted, with Owners at the top' do
44
+ expect(@octo_obj).to receive(:organization_teams).with('GrapeDuty').and_return(@teams)
45
+ send_command('gh teams GrapeDuty')
46
+ expect(replies.last).to eql 'Showing 3 team(s) for GrapeDuty:
47
+ Name: Owners, Slug: owners, ID: 1, Perms: admin
48
+ Name: A Team, Slug: a-team, ID: 84, Perms: pull
49
+ Name: HeckmanTest, Slug: heckmantest, ID: 42, Perms: push
50
+ '
51
+ end
52
+ end
53
+
54
+ context 'when provided an invalid org' do
55
+ before { allow(@octo_obj).to receive(:organization_teams).and_raise(Octokit::NotFound.new) }
56
+
57
+ it 'should return a message indicating it could not find the organization' do
58
+ send_command('gh teams GrapeDuty')
59
+ expect(replies.last).to eql(
60
+ "The organization 'GrapeDuty' was not found. Does my user have ownership permission?"
61
+ )
62
+ end
63
+ end
64
+ end
65
+ end
@@ -31,8 +31,7 @@ describe Lita::Handlers::GithubPR, lita_handler: true do
31
31
  describe '.pr_match' do
32
32
  it 'should return the content of the match data' do
33
33
  mock_md = { 'org' => github_org, 'repo' => github_repo, 'pr' => 42 }
34
- mock_resp = double('Lita::Response', match_data: mock_md)
35
- expect(github_pr.send(:pr_match, mock_resp)).to eql [github_org, github_repo, 42]
34
+ expect(github_pr.send(:pr_match, mock_md)).to eql [github_org, github_repo, 42]
36
35
  end
37
36
  end
38
37
 
@@ -32,6 +32,30 @@ describe Lita::Handlers::GithubRepo, lita_handler: true do
32
32
  it { routes_command('gh repo info GrapeDuty/lita-test').to(:repo_info) }
33
33
  it { routes_command('gh repo info lita-test').to(:repo_info) }
34
34
 
35
+ # repo_teams_list routing
36
+ it { routes_command('gh repo teams GrapeDuty/lita-test').to(:repo_teams_list) }
37
+ it { routes_command('gh repo team list GrapeDuty/lita-test').to(:repo_teams_list) }
38
+ it { routes_command('gh repo teams lita-test').to(:repo_teams_list) }
39
+ it { routes_command('gh repo team list lita-test').to(:repo_teams_list) }
40
+
41
+ # repo_team_router routing
42
+ it { routes_command('gh repo team add everyone GrapeDuty/lita-test').to(:repo_team_router) }
43
+ it { routes_command('gh repo team add everyone to GrapeDuty/lita-test').to(:repo_team_router) }
44
+ it { routes_command('gh repo team add everyone lita-test').to(:repo_team_router) }
45
+ it { routes_command('gh repo team add everyone to lita-test').to(:repo_team_router) }
46
+ it { routes_command('gh repo team add 42 GrapeDuty/lita-test').to(:repo_team_router) }
47
+ it { routes_command('gh repo team add 42 to GrapeDuty/lita-test').to(:repo_team_router) }
48
+ it { routes_command('gh repo team add 42 lita-test').to(:repo_team_router) }
49
+ it { routes_command('gh repo team add 42 to lita-test').to(:repo_team_router) }
50
+ it { routes_command('gh repo team rm everyone GrapeDuty/lita-test').to(:repo_team_router) }
51
+ it { routes_command('gh repo team rm everyone to GrapeDuty/lita-test').to(:repo_team_router) }
52
+ it { routes_command('gh repo team rm everyone lita-test').to(:repo_team_router) }
53
+ it { routes_command('gh repo team rm everyone to lita-test').to(:repo_team_router) }
54
+ it { routes_command('gh repo team rm 42 GrapeDuty/lita-test').to(:repo_team_router) }
55
+ it { routes_command('gh repo team rm 42 to GrapeDuty/lita-test').to(:repo_team_router) }
56
+ it { routes_command('gh repo team rm 42 lita-test').to(:repo_team_router) }
57
+ it { routes_command('gh repo team rm 42 to lita-test').to(:repo_team_router) }
58
+
35
59
  let(:github_repo) { Lita::Handlers::GithubRepo.new('robot') }
36
60
  let(:github_org) { 'GrapeDuty' }
37
61
  let(:disabled_reply) { 'Sorry, this function has either been disabled or not enabled in the config' }
@@ -299,6 +323,229 @@ describe Lita::Handlers::GithubRepo, lita_handler: true do
299
323
  end
300
324
  end
301
325
 
326
+ describe '.remove_team_from_repo' do
327
+ before do
328
+ @octo_obj = double('Octokit::Client', remove_team_repository: true)
329
+ allow(github_repo).to receive(:octo).and_return(@octo_obj)
330
+ end
331
+
332
+ context 'when it succeeds' do
333
+ it 'should reply with the success message' do
334
+ expect(@octo_obj).to receive(:remove_team_repository).with(42, 'GrapeDuty/lita-test')
335
+ .and_return(true)
336
+ r = github_repo.send(:remove_team_from_repo, 'GrapeDuty/lita-test', id: 42, name: 'HeckmanTest')
337
+ expect(r).to eql "Removed the 'HeckmanTest' team from GrapeDuty/lita-test"
338
+ end
339
+ end
340
+
341
+ context 'when it fails' do
342
+ before { allow(@octo_obj).to receive(:remove_team_repository).and_return(false) }
343
+
344
+ it 'should reply with the failure message' do
345
+ r = github_repo.send(:remove_team_from_repo, 'GrapeDuty/lita-test', id: 42, name: 'HeckTest')
346
+ expect(r).to eql "Something went wrong trying to remove the 'HeckTest' team from GrapeDuty/lita-test"
347
+ end
348
+ end
349
+ end
350
+
351
+ describe '.add_team_to_repo' do
352
+ before do
353
+ @octo_obj = double('Octokit::Client', add_team_repository: true)
354
+ allow(github_repo).to receive(:octo).and_return(@octo_obj)
355
+ end
356
+
357
+ context 'when it succeeds' do
358
+ it 'should reply with the success message' do
359
+ expect(@octo_obj).to receive(:add_team_repository).with(42, 'GrapeDuty/lita-test')
360
+ .and_return(true)
361
+ r = github_repo.send(:add_team_to_repo, 'GrapeDuty/lita-test', id: 42, name: 'HeckmanTest')
362
+ expect(r).to eql "Added the 'HeckmanTest' team to GrapeDuty/lita-test"
363
+ end
364
+ end
365
+
366
+ context 'when it fails' do
367
+ before { allow(@octo_obj).to receive(:add_team_repository).and_return(false) }
368
+
369
+ it 'should reply with the failure message' do
370
+ r = github_repo.send(:add_team_to_repo, 'GrapeDuty/lita-test', id: 42, name: 'HeckTest')
371
+ expect(r).to eql(
372
+ "Something went wrong trying to add the 'HeckTest' team to GrapeDuty/lita-test. " \
373
+ 'Is that team in your organization?'
374
+ )
375
+ end
376
+ end
377
+ end
378
+
379
+ describe '.gh_team' do
380
+ before do
381
+ @team1 = { name: 'HeckTest', id: 42 }
382
+ @team2 = { name: 'Heckman', id: 84 }
383
+ @octo_obj = double('Octokit::Client', team: {})
384
+ allow(github_repo).to receive(:octo).and_return(@octo_obj)
385
+ allow(github_repo).to receive(:team_id_by_slug).with('Heckman', 'GrapeDuty').and_return(@team2[:id])
386
+ end
387
+
388
+ context 'when the team provided is the team id' do
389
+ before { allow(@octo_obj).to receive(:team).with(42).and_return(@team1) }
390
+
391
+ it 'should return the specific team' do
392
+ expect(github_repo.send(:gh_team, 'GrapeDuty', 42)).to eql @team1
393
+ end
394
+ end
395
+
396
+ context 'when the team provided is the team' do
397
+ before { allow(@octo_obj).to receive(:team).with(84).and_return(@team2) }
398
+
399
+ it 'should return the specific team' do
400
+ expect(github_repo.send(:gh_team, 'GrapeDuty', 'Heckman')).to eql @team2
401
+ end
402
+ end
403
+
404
+ context 'when the team was not found' do
405
+ context 'but it found the id by the slug' do
406
+ before do
407
+ allow(github_repo).to receive(:team_id_by_slug).with('Wtf', 'GrapeDuty').and_return(88)
408
+ allow(@octo_obj).to receive(:team).and_raise(Octokit::NotFound.new)
409
+ end
410
+
411
+ it 'should return nil' do
412
+ expect(github_repo.send(:gh_team, 'GrapeDuty', 'Wtf')).to eql nil
413
+ end
414
+ end
415
+
416
+ context 'not even by the slug' do
417
+ before do
418
+ allow(github_repo).to receive(:team_id_by_slug).with('Wtf', 'GrapeDuty').and_return(nil)
419
+ allow(@octo_obj).to receive(:team).and_raise(Octokit::NotFound.new)
420
+ end
421
+
422
+ it 'should return nil' do
423
+ expect(github_repo.send(:gh_team, 'GrapeDuty', 'Wtf')).to eql nil
424
+ end
425
+ end
426
+ end
427
+ end
428
+
429
+ describe '.repo_team_add' do
430
+ before do
431
+ match_data = { 'org' => github_org, 'repo' => 'lita-test', 'team' => 'HeckmanTest' }
432
+ conf_obj = double('Lita::Configuration', default_org: 'GrapeDuty', repo_team_add_enabled: true)
433
+ @response = double('Lita::Response', match_data: match_data)
434
+ team = { id: 42, name: 'HeckmanTest' }
435
+ allow(github_repo).to receive(:config).and_return(conf_obj)
436
+ allow(github_repo).to receive(:gh_team).with('GrapeDuty', 'HeckmanTest').and_return(team)
437
+ allow(github_repo).to receive(:repo?).and_return(true)
438
+ allow(github_repo).to receive(:repo_has_team?).and_return(false)
439
+ allow(github_repo).to receive(:add_team_to_repo).and_return('attr')
440
+ end
441
+
442
+ context 'when function is disabled' do
443
+ before do
444
+ conf_obj = double('Lita::Configuration', default_org: 'GrapeDuty', repo_team_add_enabled: false)
445
+ allow(github_repo).to receive(:config).and_return(conf_obj)
446
+ end
447
+
448
+ it 'should return the method disabled error' do
449
+ r = github_repo.send(:repo_team_add, @response)
450
+ expect(r).to eql 'Sorry, this function has either been disabled or not enabled in the config'
451
+ end
452
+ end
453
+
454
+ context 'when valid inputs provided, and all things work out' do
455
+ it 'should return the text from add_team_to_repo' do
456
+ r = github_repo.send(:repo_team_add, @response)
457
+ expect(r).to eql 'attr'
458
+ end
459
+ end
460
+
461
+ context 'when repo not found' do
462
+ before { allow(github_repo).to receive(:repo?).and_return(false) }
463
+
464
+ it 'should return the repo not found error' do
465
+ r = github_repo.send(:repo_team_add, @response)
466
+ expect(r).to eql 'That repo (GrapeDuty/lita-test) does not exist'
467
+ end
468
+ end
469
+
470
+ context 'when team not found' do
471
+ before { allow(github_repo).to receive(:gh_team).and_return(nil) }
472
+
473
+ it 'should return the team not found error' do
474
+ r = github_repo.send(:repo_team_add, @response)
475
+ expect(r).to eql 'Unable to match any teams based on: HeckmanTest'
476
+ end
477
+ end
478
+
479
+ context 'when the team is already part of the repo' do
480
+ before { allow(github_repo).to receive(:repo_has_team?).and_return(true) }
481
+
482
+ it 'should mention that the team already exists on the repo' do
483
+ r = github_repo.send(:repo_team_add, @response)
484
+ expect(r).to eql "The 'HeckmanTest' team is already a member of GrapeDuty/lita-test"
485
+ end
486
+ end
487
+ end
488
+
489
+ describe '.repo_team_rm' do
490
+ before do
491
+ match_data = { 'org' => github_org, 'repo' => 'lita-test', 'team' => 'HeckmanTest' }
492
+ conf_obj = double('Lita::Configuration', default_org: 'GrapeDuty', repo_team_rm_enabled: true)
493
+ @response = double('Lita::Response', match_data: match_data)
494
+ team = { id: 42, name: 'HeckmanTest' }
495
+ allow(github_repo).to receive(:config).and_return(conf_obj)
496
+ allow(github_repo).to receive(:gh_team).with('GrapeDuty', 'HeckmanTest').and_return(team)
497
+ allow(github_repo).to receive(:repo?).and_return(true)
498
+ allow(github_repo).to receive(:repo_has_team?).and_return(true)
499
+ allow(github_repo).to receive(:remove_team_from_repo).and_return('rtfr')
500
+ end
501
+
502
+ context 'when function is disabled' do
503
+ before do
504
+ conf_obj = double('Lita::Configuration', default_org: 'GrapeDuty', repo_team_rm_enabled: false)
505
+ allow(github_repo).to receive(:config).and_return(conf_obj)
506
+ end
507
+
508
+ it 'should return the method disabled error' do
509
+ r = github_repo.send(:repo_team_rm, @response)
510
+ expect(r).to eql 'Sorry, this function has either been disabled or not enabled in the config'
511
+ end
512
+ end
513
+
514
+ context 'when valid inputs provided, and all things work out' do
515
+ it 'should return the text from remove_team_to_repo' do
516
+ r = github_repo.send(:repo_team_rm, @response)
517
+ expect(r).to eql 'rtfr'
518
+ end
519
+ end
520
+
521
+ context 'when repo not found' do
522
+ before { allow(github_repo).to receive(:repo?).and_return(false) }
523
+
524
+ it 'should return the repo not found error' do
525
+ r = github_repo.send(:repo_team_rm, @response)
526
+ expect(r).to eql 'That repo (GrapeDuty/lita-test) does not exist'
527
+ end
528
+ end
529
+
530
+ context 'when team not found' do
531
+ before { allow(github_repo).to receive(:gh_team).and_return(nil) }
532
+
533
+ it 'should return the team not found error' do
534
+ r = github_repo.send(:repo_team_rm, @response)
535
+ expect(r).to eql 'Unable to match any teams based on: HeckmanTest'
536
+ end
537
+ end
538
+
539
+ context 'when the team is not part of the repo' do
540
+ before { allow(github_repo).to receive(:repo_has_team?).and_return(false) }
541
+
542
+ it 'should mention that the team already exists on the repo' do
543
+ r = github_repo.send(:repo_team_rm, @response)
544
+ expect(r).to eql "The 'HeckmanTest' team is not a member of GrapeDuty/lita-test"
545
+ end
546
+ end
547
+ end
548
+
302
549
  ####
303
550
  # Handlers
304
551
  ####
@@ -403,4 +650,49 @@ describe Lita::Handlers::GithubRepo, lita_handler: true do
403
650
  end
404
651
  end
405
652
  end
653
+
654
+ describe '.repo_teams_list' do
655
+ before do
656
+ @teams = [
657
+ { name: 'Interns', slug: 'interns', id: 84, permission: 'pull' },
658
+ { name: 'Everyone', slug: 'everyone', id: 42, permission: 'push' }
659
+ ]
660
+ @octo_obj = double('Octokit::Client', repository_teams: @teams)
661
+ allow(github_repo).to receive(:octo).and_return(@octo_obj)
662
+ end
663
+
664
+ context 'when it finds a repo' do
665
+ it 'should return the list of teams' do
666
+ expect(@octo_obj).to receive(:repository_teams).with('GrapeDuty/lita-test').and_return(@teams)
667
+ send_command("gh repo teams #{github_org}/lita-test")
668
+ expect(replies.last).to eql 'Showing 2 team(s) for GrapeDuty/lita-test:
669
+ Name: Everyone, Slug: everyone, ID: 42, Perms: push
670
+ Name: Interns, Slug: interns, ID: 84, Perms: pull
671
+ '
672
+ end
673
+ end
674
+
675
+ context 'when the repo is not valid' do
676
+ before { allow(@octo_obj).to receive(:repository_teams).and_raise(Octokit::NotFound.new) }
677
+
678
+ it 'should say the repo was not found' do
679
+ send_command("gh repo teams #{github_org}/lita-test")
680
+ expect(replies.last).to eql 'That repo (GrapeDuty/lita-test) does not exist'
681
+ end
682
+ end
683
+ end
684
+
685
+ describe '.repo_team_router' do
686
+ before do
687
+ allow(github_repo).to receive(:repo_team_something)
688
+ .with(an_instance_of(Lita::Response)).and_return('ohai')
689
+ end
690
+
691
+ it 'should call the method based on action and respond with its return' do
692
+ expect(github_repo).to receive(:repo_team_add)
693
+ .with(an_instance_of(Lita::Response)).and_return('ohai')
694
+ send_command("gh repo team add 42 #{github_org}/lita-test")
695
+ expect(replies.last).to eql 'ohai'
696
+ end
697
+ end
406
698
  end
@@ -41,6 +41,14 @@ describe Lita::Handlers::Github, lita_handler: true do
41
41
  expect(Lita.config.handlers.github.repo_delete_enabled).to be_falsey
42
42
  end
43
43
 
44
+ it 'should disable Lita::Handlers::GithubRepo.repo_team_add by default' do
45
+ expect(Lita.config.handlers.github.repo_team_add_enabled).to be_falsey
46
+ end
47
+
48
+ it 'should disable Lita::Handlers::GithubRepo.repo_team_rm by default' do
49
+ expect(Lita.config.handlers.github.repo_team_rm_enabled).to be_falsey
50
+ end
51
+
44
52
  it 'should enable Lita::Handlers::GithubPR.pr_merge by default' do
45
53
  expect(Lita.config.handlers.github.pr_merge_enabled).to be_truthy
46
54
  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.8
4
+ version: 0.0.9
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-09-09 00:00:00.000000000 Z
11
+ date: 2014-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,6 +80,26 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '2.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.10'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 0.10.1
93
+ type: :development
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '0.10'
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 0.10.1
83
103
  - !ruby/object:Gem::Dependency
84
104
  name: codeclimate-test-reporter
85
105
  requirement: !ruby/object:Gem::Requirement
@@ -180,6 +200,7 @@ files:
180
200
  - lib/lita-github/repo.rb
181
201
  - lib/lita-github/version.rb
182
202
  - lib/lita/handlers/github.rb
203
+ - lib/lita/handlers/github_org.rb
183
204
  - lib/lita/handlers/github_pr.rb
184
205
  - lib/lita/handlers/github_repo.rb
185
206
  - lita-github.gemspec
@@ -192,6 +213,7 @@ files:
192
213
  - spec/unit/lita-github/r_spec.rb
193
214
  - spec/unit/lita-github/repo_spec.rb
194
215
  - spec/unit/lita-github/version_spec.rb
216
+ - spec/unit/lita/handlers/github_org_spec.rb
195
217
  - spec/unit/lita/handlers/github_pr_spec.rb
196
218
  - spec/unit/lita/handlers/github_repo_spec.rb
197
219
  - spec/unit/lita/handlers/github_spec.rb
@@ -230,6 +252,7 @@ test_files:
230
252
  - spec/unit/lita-github/r_spec.rb
231
253
  - spec/unit/lita-github/repo_spec.rb
232
254
  - spec/unit/lita-github/version_spec.rb
255
+ - spec/unit/lita/handlers/github_org_spec.rb
233
256
  - spec/unit/lita/handlers/github_pr_spec.rb
234
257
  - spec/unit/lita/handlers/github_repo_spec.rb
235
258
  - spec/unit/lita/handlers/github_spec.rb