lita-github 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
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