caperoma 4.0.1 → 5.0.0

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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/Capefile +6 -6
  3. data/Capefile.template +4 -1
  4. data/Gemfile +1 -5
  5. data/Gemfile.lock +3 -45
  6. data/HELP +84 -13
  7. data/README.md +165 -29
  8. data/Rakefile +25 -22
  9. data/VERSION +1 -1
  10. data/bin/caperoma +6 -9
  11. data/caperoma.gemspec +15 -13
  12. data/config/crontab +0 -2
  13. data/config/schedule.rb +17 -19
  14. data/config/unschedule.rb +3 -0
  15. data/images/circle.png +0 -0
  16. data/images/report.png +0 -0
  17. data/lib/caperoma.rb +308 -98
  18. data/lib/caperoma/models/account.rb +1 -1
  19. data/lib/caperoma/models/project.rb +1 -2
  20. data/lib/caperoma/models/report.rb +15 -15
  21. data/lib/caperoma/models/task.rb +203 -46
  22. data/lib/caperoma/models/tasks/chore.rb +2 -0
  23. data/lib/caperoma/models/tasks/feature.rb +1 -0
  24. data/lib/caperoma/models/tasks/fix.rb +2 -0
  25. data/lib/caperoma/models/tasks/meeting.rb +2 -0
  26. data/lib/caperoma/models/tasks/modules/git.rb +94 -15
  27. data/lib/caperoma/models/tasks/task_with_commit.rb +8 -5
  28. data/lib/caperoma/models/tasks/task_with_separate_branch.rb +6 -4
  29. data/spec/caperoma_spec.rb +558 -2
  30. data/spec/factories/accounts.rb +1 -1
  31. data/spec/factories/projects.rb +1 -1
  32. data/spec/factories/report_recipients.rb +1 -1
  33. data/spec/factories/reports.rb +1 -1
  34. data/spec/factories/tasks.rb +1 -2
  35. data/spec/features/command_unknown_spec.rb +0 -1
  36. data/spec/features/feature_spec.rb +64 -44
  37. data/spec/features/init_spec.rb +20 -0
  38. data/spec/features/status_spec.rb +12 -11
  39. data/spec/models/project_spec.rb +0 -1
  40. data/spec/models/task_spec.rb +811 -27
  41. data/spec/models/task_with_commit_spec.rb +0 -4
  42. data/spec/models/task_with_separate_branch_spec.rb +4 -4
  43. data/spec/models/three_day_report_spec.rb +2 -3
  44. data/spec/spec_helper.rb +2 -0
  45. data/spec/support/capefile_generator.rb +35 -27
  46. data/spec/support/stubs.rb +7 -74
  47. metadata +47 -24
  48. data/lib/caperoma/models/branch.rb +0 -6
  49. data/lib/caperoma/services/airbrake_email_processor.rb +0 -47
  50. data/lib/caperoma/services/pivotal_fetcher.rb +0 -108
  51. data/spec/factories/branches.rb +0 -9
  52. data/spec/models/branch_spec.rb +0 -8
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Chore < Task
3
4
  before_create :inform_creation_started
4
5
  after_create :inform_creation_finished
5
6
 
6
7
  private
8
+
7
9
  def create_issue_on_pivotal_data
8
10
  Jbuilder.encode do |j|
9
11
  j.current_state 'unstarted'
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Feature < TaskWithSeparateBranch
3
4
  before_create :inform_creation_started
4
5
  after_create :inform_creation_finished
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Fix < TaskWithCommit
3
4
  before_create :update_parent_branch
4
5
  before_create :inform_creation_started
@@ -16,6 +17,7 @@ class Fix < TaskWithCommit
16
17
  end
17
18
 
18
19
  private
20
+
19
21
  def create_issue_on_pivotal_data
20
22
  Jbuilder.encode do |j|
21
23
  j.current_state 'unstarted'
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Meeting < Task
3
4
  before_create :inform_creation_started
4
5
  after_create :inform_creation_finished
5
6
 
6
7
  private
8
+
7
9
  def create_issue_on_pivotal_data
8
10
  Jbuilder.encode do |j|
9
11
  j.current_state 'unstarted'
@@ -1,32 +1,63 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Git
4
- def git_branch(name)
5
- `git -C "#{project.folder_path}" checkout -b #{name}` if ENV['CAPEROMA_INTEGRATION_TEST'].blank? && ENV['CAPEROMA_TEST'].blank?
4
+ def git_branch
5
+ `git -C "#{project.folder_path}" checkout -b #{branch}` if enable_git?
6
6
  end
7
7
 
8
8
  def git_commit(msg)
9
- `git -C "#{project.folder_path}" add -A && git -C "#{project.folder_path}" commit --allow-empty -m "#{msg}"` if ENV['CAPEROMA_INTEGRATION_TEST'].blank? && ENV['CAPEROMA_TEST'].blank?
9
+ `git -C "#{project.folder_path}" add -A && git -C "#{project.folder_path}" commit --allow-empty -m "#{msg}"` if enable_git?
10
10
  end
11
11
 
12
12
  def git_push
13
- `git -C "#{project.folder_path}" push --set-upstream origin #{git_current_branch}` if ENV['CAPEROMA_INTEGRATION_TEST'].blank? && ENV['CAPEROMA_TEST'].blank?
13
+ if enable_git?
14
+ puts 'Pushing the code to Github'
15
+
16
+ conn = Faraday.new(url: 'https://api.github.com') do |c|
17
+ c.basic_auth(Account.git.email, Account.git.password)
18
+ c.adapter Faraday.default_adapter
19
+ end
20
+
21
+ response = conn.get do |request|
22
+ request.url "/repos/#{project.github_repo}/pulls"
23
+ request.headers['User-Agent'] = 'Caperoma'
24
+ request.headers['Accept'] = 'application/vnd.github.v3+json'
25
+ request.headers['Content-Type'] = 'application/json'
26
+ end
27
+
28
+ case response.status
29
+ when 200, 201, 202, 204, 301, 302, 303, 304, 307
30
+ `git -C "#{project.folder_path}" push --set-upstream origin #{git_current_branch}`
31
+ when 401, 403
32
+ puts 'No access to Git. Maybe login or password are incorrect.'
33
+ when 404
34
+ puts "A resource on Git was not found. Maybe the repository name #{project.github_repo} is incorrect."
35
+ else
36
+ puts 'Could not push to Git.'
37
+ puts "Error status: #{response.status}"
38
+ puts "Message from server: #{response.reason_phrase}"
39
+ end
40
+ end
41
+ rescue Faraday::ConnectionFailed
42
+ puts 'Connection failed. Performing the task without pushing to Git.'
14
43
  end
15
44
 
16
45
  def git_last_commit_name
17
- `git -C "#{project.folder_path}" log --pretty=format:'%s' -1` if ENV['CAPEROMA_INTEGRATION_TEST'].blank? && ENV['CAPEROMA_TEST'].blank?
46
+ `git -C "#{project.folder_path}" log #{parent_branch}..#{branch} --oneline --pretty=format:'%s' --skip=1 -1` if enable_git?
18
47
  end
19
48
 
20
49
  def git_current_branch
21
- `git -C "#{project.folder_path}" rev-parse --abbrev-ref HEAD`.gsub("\n", '') if ENV['CAPEROMA_INTEGRATION_TEST'].blank? && ENV['CAPEROMA_TEST'].blank?
50
+ `git -C "#{project.folder_path}" rev-parse --abbrev-ref HEAD`.gsub("\n", '') if enable_git?
22
51
  end
23
52
 
24
- def git_pull_request(into, title, description = '')
53
+ def git_pull_request
54
+ puts 'Making a pull request'
55
+
25
56
  pull_request_data = Jbuilder.encode do |j|
26
57
  j.title title
27
- j.body description
28
- j.head git_current_branch
29
- j.base into
58
+ j.body description_for_pull_request
59
+ j.head branch
60
+ j.base parent_branch
30
61
  end
31
62
 
32
63
  conn = Faraday.new(url: 'https://api.github.com') do |c|
@@ -34,17 +65,32 @@ module Git
34
65
  c.adapter Faraday.default_adapter
35
66
  end
36
67
 
37
- conn.post do |request|
68
+ response = conn.post do |request|
38
69
  request.url "/repos/#{project.github_repo}/pulls"
39
70
  request.body = pull_request_data
40
71
  request.headers['User-Agent'] = 'Caperoma'
41
72
  request.headers['Accept'] = 'application/vnd.github.v3+json'
42
73
  request.headers['Content-Type'] = 'application/json'
43
74
  end
75
+
76
+ case response.status
77
+ when 200, 201, 202, 204, 301, 302, 303, 304, 307
78
+ puts 'The pull request was sent.'
79
+ when 401, 403
80
+ puts 'No access to Git. Maybe login or password are incorrect.'
81
+ when 404
82
+ puts "A resource on Git not found. Maybe the repository name #{project.github_repo} is incorrect."
83
+ else
84
+ puts 'Could not make a pull request.'
85
+ puts "Error status: #{response.status}"
86
+ puts "Message from server: #{response.reason_phrase}"
87
+ end
88
+ rescue Faraday::ConnectionFailed
89
+ puts 'Connection failed. Performing the task without requests to Git.'
44
90
  end
45
91
 
46
92
  def git_rebase_to_upstream
47
- if ENV['CAPEROMA_INTEGRATION_TEST'].blank? && ENV['CAPEROMA_TEST'].blank?
93
+ if enable_git?
48
94
  has_untracked_files = !`git -C "#{project.folder_path}" ls-files --others --exclude-standard`.empty?
49
95
  has_changes = !`git -C "#{project.folder_path}" diff`.empty?
50
96
  has_staged_changes = !`git -C "#{project.folder_path}" diff HEAD`.empty?
@@ -53,13 +99,46 @@ module Git
53
99
 
54
100
  `git -C "#{project.folder_path}" add -A && git -C "#{project.folder_path}" stash` if changes_were_made
55
101
 
56
- `git -C "#{project.folder_path}" fetch && git -C "#{project.folder_path}" rebase $(git -C "#{project.folder_path}" rev-parse --abbrev-ref --symbolic-full-name @{u})`
102
+ git_actual_rebase
57
103
 
58
104
  `git -C "#{project.folder_path}" stash apply` if changes_were_made
59
105
  end
60
106
  end
61
107
 
62
- def git_checkout(branch)
63
- `git -C "#{project.folder_path}" checkout #{branch}` if ENV['CAPEROMA_INTEGRATION_TEST'].blank? && ENV['CAPEROMA_TEST'].blank?
108
+ def git_actual_rebase
109
+ if enable_git?
110
+ pp 'Getting the latest code from Github'
111
+
112
+ conn = Faraday.new(url: 'https://api.github.com') do |c|
113
+ c.basic_auth(Account.git.email, Account.git.password)
114
+ c.adapter Faraday.default_adapter
115
+ end
116
+
117
+ response = conn.get do |request|
118
+ request.url "/repos/#{project.github_repo}/pulls"
119
+ request.headers['User-Agent'] = 'Caperoma'
120
+ request.headers['Accept'] = 'application/vnd.github.v3+json'
121
+ request.headers['Content-Type'] = 'application/json'
122
+ end
123
+
124
+ case response.status
125
+ when 200, 201, 202, 204, 301, 302, 303, 304, 307
126
+ `git -C "#{project.folder_path}" fetch && git -C "#{project.folder_path}" rebase $(git -C "#{project.folder_path}" rev-parse --abbrev-ref --symbolic-full-name @{u})`
127
+ when 401, 403
128
+ puts 'No access to Git. Maybe login or password are incorrect.'
129
+ when 404
130
+ puts "A resource on Git not found. Maybe the repository name #{project.github_repo} is incorrect."
131
+ else
132
+ puts 'Could not get the latest changes from Github.'
133
+ puts "Error status: #{response.status}"
134
+ puts "Message from server: #{response.reason_phrase}"
135
+ end
136
+ end
137
+ rescue Faraday::ConnectionFailed
138
+ puts 'Connection failed. Performing the task without pulling the latest code from Git.'
139
+ end
140
+
141
+ def git_checkout(_branch)
142
+ `git -C "#{project.folder_path}" checkout #{_branch}` if enable_git?
64
143
  end
65
144
  end
@@ -1,20 +1,19 @@
1
1
  # frozen_string_literal: true
2
- class TaskWithCommit < Task
3
- belongs_to :branch
4
2
 
3
+ class TaskWithCommit < Task
5
4
  def finish(comment)
6
5
  super
7
6
  git_commit(commit_message)
8
7
  # here I should pass the path
9
- `rubocop -a "#{project.folder_path}"` if ENV['CAPEROMA_INTEGRATION_TEST'].blank? && ENV['CAPEROMA_TEST'].blank?
8
+ `rubocop -a "#{project.folder_path}"` if enable_rubocop?
10
9
  git_commit(commit_rubocop_message)
11
- git_push
10
+ git_push
12
11
  end
13
12
 
14
13
  def pause(comment)
15
14
  super
16
15
  git_commit(commit_message)
17
- `rubocop -a "#{project.folder_path}"` if ENV['CAPEROMA_INTEGRATION_TEST'].blank? && ENV['CAPEROMA_TEST'].blank?
16
+ `rubocop -a "#{project.folder_path}"` if enable_rubocop?
18
17
  git_commit(commit_rubocop_message)
19
18
  git_push
20
19
  end
@@ -37,4 +36,8 @@ class TaskWithCommit < Task
37
36
  string += ' Applying good practices'
38
37
  string.strip
39
38
  end
39
+
40
+ def enable_rubocop?
41
+ ENV['CAPEROMA_TEST'].blank? && ENV['CAPEROMA_INTEGRATION_TEST'].blank?
42
+ end
40
43
  end
@@ -1,13 +1,15 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class TaskWithSeparateBranch < TaskWithCommit
3
4
  before_create :update_parent_branch
4
5
  before_create :remember_parent_branch
5
- after_create :new_git_branch
6
+ after_create :set_branch
7
+ after_create :git_branch
6
8
 
7
9
  def finish(comment)
8
10
  puts comment
9
11
  super
10
- puts git_pull_request(parent_branch, title, description_for_pull_request)
12
+ puts git_pull_request
11
13
  puts git_checkout(parent_branch)
12
14
  end
13
15
 
@@ -30,8 +32,8 @@ class TaskWithSeparateBranch < TaskWithCommit
30
32
  self.parent_branch = git_current_branch
31
33
  end
32
34
 
33
- def new_git_branch
34
- git_branch(branch_name)
35
+ def set_branch
36
+ update_column :branch, branch_name
35
37
  end
36
38
 
37
39
  def branch_name
@@ -2,6 +2,562 @@
2
2
 
3
3
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
4
4
 
5
- describe 'Caperoma' do
6
- pending 'all this is tested using feature tests for now'
5
+ describe Caperoma do
6
+ let!(:project) { create :project, jira_project_id: '123' }
7
+
8
+ before { create_capefile('123') }
9
+
10
+ describe 'create tasks' do
11
+ context 'title present' do
12
+ let!(:args) { ['bug', '-t', 'awesome bug', '-d', 'some description'] }
13
+
14
+ it 'should create' do
15
+ expect do
16
+ Caperoma.create_task(args)
17
+ end.to change {
18
+ Bug.where(
19
+ title: 'awesome bug',
20
+ description: 'some description',
21
+ project_id: project.id
22
+ ).count
23
+ }.by(1)
24
+ end
25
+ end
26
+
27
+ context 'title present and additional time present' do
28
+ let!(:args) { ['bug', '-t', 'awesome bug', '-a', '5'] }
29
+
30
+ it 'should create' do
31
+ expect do
32
+ Caperoma.create_task(args)
33
+ end.to change {
34
+ Bug.where(
35
+ title: 'awesome bug',
36
+ project_id: project.id,
37
+ additional_time: 5
38
+ ).count
39
+ }.by(1)
40
+ end
41
+ end
42
+
43
+ context 'title present but additional time is invalid' do
44
+ let!(:args) { ['bug', '-t', 'awesome bug', '-a', 'gsov'] }
45
+
46
+ subject { Caperoma.create_task(args) }
47
+
48
+ it 'should not create' do
49
+ expect do
50
+ subject
51
+ end.to change {
52
+ Bug.where(
53
+ title: 'awesome bug',
54
+ project_id: project.id
55
+ ).count
56
+ }.by(0)
57
+ end
58
+
59
+ it 'should say why it is not starting' do
60
+ expect { subject }.to output(/not_a_number/).to_stdout
61
+ end
62
+ end
63
+
64
+ context 'title and pivotal id present but pivotal id is invalid' do
65
+ let!(:args) { ['bug', '-t', 'awesome bug', '-p', 'sdklfvnslfkvs'] }
66
+ let!(:account) { create :account, type: '--pivotal' }
67
+
68
+ subject { Caperoma.create_task(args) }
69
+
70
+ it 'should create but skip pivotal id' do
71
+ expect do
72
+ subject
73
+ end.to change {
74
+ Bug.where(
75
+ title: 'awesome bug',
76
+ pivotal_id: nil,
77
+ project_id: project.id
78
+ ).count
79
+ }.by(1)
80
+ end
81
+
82
+ it 'should say why it is skipping' do
83
+ expect { subject }.to output(/Pivotal ID needs to be copied from the task in Pivotal/).to_stdout
84
+ end
85
+ end
86
+
87
+ context 'title not present but -p can access pivotal', :unstab_api_calls do
88
+ let!(:args) { ['bug', '-p', '1234567'] }
89
+
90
+ let(:response_body) { { 'name' => 'awesome bug', 'description' => 'some description', 'estimate' => estimate }.to_json }
91
+ let(:response) { double('Faraday', body: response_body, status: 200) }
92
+ let(:faraday) { double('Faraday', post: response) }
93
+
94
+ let!(:account) { create :account, type: '--pivotal' }
95
+
96
+ before do
97
+ allow(Faraday).to receive(:new).and_return faraday
98
+ allow(Faraday).to receive(:default_adapter)
99
+
100
+ allow(faraday).to receive(:post).and_return response
101
+ allow(faraday).to receive(:get).and_return response
102
+ allow(faraday).to receive(:put).and_return response
103
+ end
104
+
105
+ context 'estimate is present' do
106
+ let(:estimate) { 1 }
107
+
108
+ it 'should create getting values from pivotal' do
109
+ expect do
110
+ Caperoma.create_task(args)
111
+ end.to change {
112
+ Bug.where(
113
+ title: 'awesome bug',
114
+ description: 'some description',
115
+ pivotal_estimate: 1,
116
+ project_id: project.id
117
+ ).count
118
+ }.by(1)
119
+ end
120
+ end
121
+
122
+ context 'estimate is not present' do
123
+ let(:estimate) { nil }
124
+
125
+ it 'should set zero to estimate' do
126
+ expect do
127
+ Caperoma.create_task(args)
128
+ end.to change {
129
+ Bug.where(
130
+ title: 'awesome bug',
131
+ description: 'some description',
132
+ pivotal_estimate: 0,
133
+ project_id: project.id
134
+ ).count
135
+ }.by(1)
136
+ end
137
+ end
138
+ end
139
+
140
+ context 'title not present, -p present, but pivotal Account is not set up' do
141
+ let!(:args) { ['bug', '-p', '1234567'] }
142
+
143
+ let(:response_body) { { 'name' => 'awesome bug', 'description' => 'some description' }.to_json }
144
+ let(:response) { double('Faraday', body: response_body, status: 200) }
145
+ let(:faraday) { double('Faraday', post: response) }
146
+
147
+ before do
148
+ allow(Faraday).to receive(:new).and_return faraday
149
+ allow(Faraday).to receive(:default_adapter)
150
+
151
+ allow(faraday).to receive(:post).and_return response
152
+ allow(faraday).to receive(:get).and_return response
153
+ allow(faraday).to receive(:put).and_return response
154
+ end
155
+
156
+ subject { Caperoma.create_task(args) }
157
+
158
+ it 'should not create' do
159
+ expect do
160
+ subject
161
+ end.to change {
162
+ Bug.where(
163
+ title: 'awesome bug',
164
+ description: 'some description',
165
+ project_id: project.id
166
+ ).count
167
+ }.by(0)
168
+ end
169
+
170
+ it 'should say it could not get access' do
171
+ expect { subject }.to output(/Please set up Pivotal account/).to_stdout
172
+ end
173
+ end
174
+
175
+ context 'title not present, -p present, but pivotal gave an error', :unstab_api_calls do
176
+ let!(:args) { ['bug', '-p', '1234567'] }
177
+
178
+ let(:response_body) { { 'name' => 'awesome bug', 'description' => 'some description' }.to_json }
179
+ let(:response) { double('Faraday', body: response_body, status: 401) }
180
+ let(:faraday) { double('Faraday', post: response) }
181
+
182
+ let!(:account) { create :account, type: '--pivotal' }
183
+
184
+ before do
185
+ allow(Faraday).to receive(:new).and_return faraday
186
+ allow(Faraday).to receive(:default_adapter)
187
+
188
+ allow(faraday).to receive(:post).and_return response
189
+ allow(faraday).to receive(:get).and_return response
190
+ allow(faraday).to receive(:put).and_return response
191
+ end
192
+
193
+ subject { Caperoma.create_task(args) }
194
+
195
+ it 'should not create' do
196
+ expect do
197
+ end.to change {
198
+ Bug.where(
199
+ title: 'awesome bug',
200
+ description: 'some description',
201
+ project_id: project.id
202
+ ).count
203
+ }.by(0)
204
+ end
205
+
206
+ it 'should say it could not get access' do
207
+ expect { subject }.to output(/No access/).to_stdout
208
+ end
209
+ end
210
+
211
+ context 'title not present but -p can get the title from pivotal, but pivotal_id is set in #1234567 format (not just numbers)', :unstab_api_calls do
212
+ let!(:args) { ['bug', '-p', '#1234567'] }
213
+
214
+ let(:response_body) { { 'name' => 'awesome bug', 'description' => 'some description' }.to_json }
215
+
216
+ let(:response) { double('Faraday', body: response_body, status: 200) }
217
+ let(:faraday) { double('Faraday', post: response) }
218
+
219
+ let!(:account) { create :account, type: '--pivotal' }
220
+
221
+ before do
222
+ allow(Faraday).to receive(:new).and_return faraday
223
+ allow(Faraday).to receive(:default_adapter)
224
+
225
+ allow(faraday).to receive(:post).and_return response
226
+ allow(faraday).to receive(:get).and_return response
227
+ allow(faraday).to receive(:put).and_return response
228
+ end
229
+
230
+ it 'should create the same way as it does without #' do
231
+ expect do
232
+ Caperoma.create_task(args)
233
+ end.to change {
234
+ Bug.where(
235
+ title: 'awesome bug',
236
+ description: 'some description',
237
+ project_id: project.id
238
+ ).count
239
+ }.by(1)
240
+ end
241
+ end
242
+ end
243
+
244
+ describe 'get_jira_project_ids' do
245
+ subject { Caperoma.get_jira_project_ids }
246
+
247
+ context 'Account does not exist' do
248
+ it { expect { subject }.to output(/set up Jira/).to_stdout }
249
+ end
250
+
251
+ context 'Account exists' do
252
+ let!(:account) { create :account, type: '--jira' }
253
+
254
+ before { remove_capefile }
255
+
256
+ context 'capefile does not exist' do
257
+ it { expect { subject }.to output(/Capefile not found/).to_stdout }
258
+ end
259
+
260
+ context 'capefile without jira_url' do
261
+ before { File.write 'Capefile.test', 'pivotal_id: 12345' }
262
+
263
+ it { expect { subject }.to output(/Please put at least jira url into your Capefile/).to_stdout }
264
+ end
265
+
266
+ context 'invalid capefile' do
267
+ before { File.write 'Capefile.test', '#(*$#>#)@*@' }
268
+
269
+ it { expect { subject }.to output(/Can not parse/).to_stdout }
270
+ end
271
+
272
+ context 'capefile exists' do
273
+ let(:response_body) { [{ 'name' => 'Project 1', 'id' => '34' }, { 'name' => 'Project 2', 'id' => '55' }].to_json }
274
+ let(:response) { double('Faraday', body: response_body, status: status, reason_phrase: reason_phrase) }
275
+ let(:faraday) { double('Faraday', post: response) }
276
+
277
+ let(:status) { 200 }
278
+ let(:reason_phrase) { 'OK' }
279
+
280
+ before do
281
+ create_capefile # move out
282
+ allow(Faraday).to receive(:new).and_return faraday
283
+ allow(Faraday).to receive(:default_adapter)
284
+ end
285
+
286
+ context 'no connection' do
287
+ before do
288
+ allow(faraday).to receive(:post).and_raise Faraday::ConnectionFailed, [404]
289
+ allow(faraday).to receive(:get).and_raise Faraday::ConnectionFailed, [404]
290
+ allow(faraday).to receive(:put).and_raise Faraday::ConnectionFailed, [404]
291
+ end
292
+
293
+ it { expect { subject }.to output(/Connection failed/).to_stdout }
294
+ end
295
+
296
+ describe 'statuses' do
297
+ before do
298
+ allow(faraday).to receive(:post).and_return response
299
+ allow(faraday).to receive(:get).and_return response
300
+ allow(faraday).to receive(:put).and_return response
301
+ end
302
+
303
+ context 'everything is ok' do
304
+ let(:status) { 200 }
305
+ let(:reason_phrase) { 'OK' }
306
+
307
+ it { expect { subject }.to output(/Name: Project 1, jira_project_id: 34/).to_stdout }
308
+ it { expect { subject }.to output(/Name: Project 2, jira_project_id: 55/).to_stdout }
309
+ end
310
+
311
+ context 'unauthorized 401' do
312
+ let(:status) { 401 }
313
+ let(:reason_phrase) { 'not authorized' }
314
+
315
+ it { expect { subject }.to output(/No access to Jira/).to_stdout }
316
+ end
317
+
318
+ context 'unauthorized 403' do
319
+ let(:status) { 403 }
320
+ let(:reason_phrase) { 'not authorized' }
321
+
322
+ it { expect { subject }.to output(/No access to Jira/).to_stdout }
323
+ end
324
+
325
+ context 'not found 404' do
326
+ let(:status) { 404 }
327
+ let(:reason_phrase) { 'not found' }
328
+
329
+ it { expect { subject }.to output(/not found/).to_stdout }
330
+ end
331
+
332
+ context 'other error' do
333
+ let(:status) { 500 }
334
+ let(:reason_phrase) { 'server error' }
335
+
336
+ it { expect { subject }.to output(/Could not/).to_stdout }
337
+ it { expect { subject }.to output(/500/).to_stdout }
338
+ it { expect { subject }.to output(/server error/).to_stdout }
339
+ end
340
+ end
341
+ end
342
+ end
343
+ end
344
+
345
+ describe 'get_jira_issue_type_ids' do
346
+ subject { Caperoma.get_jira_issue_type_ids }
347
+
348
+ context 'Account does not exist' do
349
+ it { expect { subject }.to output(/set up Jira/).to_stdout }
350
+ end
351
+
352
+ context 'Account exists' do
353
+ let!(:account) { create :account, type: '--jira' }
354
+
355
+ before { remove_capefile }
356
+
357
+ context 'capefile does not exist' do
358
+ it { expect { subject }.to output(/Capefile not found/).to_stdout }
359
+ end
360
+
361
+ context 'capefile without jira_url' do
362
+ before { File.write 'Capefile.test', 'pivotal_id: 12345' }
363
+
364
+ it { expect { subject }.to output(/Please put at least jira url into your Capefile/).to_stdout }
365
+ end
366
+
367
+ context 'invalid capefile' do
368
+ before { File.write 'Capefile.test', '#(*$#>#)@*@' }
369
+
370
+ it { expect { subject }.to output(/Can not parse/).to_stdout }
371
+ end
372
+
373
+ context 'capefile exists' do
374
+ let(:response_body) { [{ 'name' => 'Type 1', 'id' => '34' }, { 'name' => 'Type 2', 'id' => '55' }].to_json }
375
+ let(:response) { double('Faraday', body: response_body, status: status, reason_phrase: reason_phrase) }
376
+ let(:faraday) { double('Faraday', post: response) }
377
+
378
+ let(:status) { 200 }
379
+ let(:reason_phrase) { 'OK' }
380
+
381
+ before do
382
+ create_capefile # move out
383
+ allow(Faraday).to receive(:new).and_return faraday
384
+ allow(Faraday).to receive(:default_adapter)
385
+ end
386
+
387
+ context 'no connection' do
388
+ before do
389
+ allow(faraday).to receive(:post).and_raise Faraday::ConnectionFailed, [404]
390
+ allow(faraday).to receive(:get).and_raise Faraday::ConnectionFailed, [404]
391
+ allow(faraday).to receive(:put).and_raise Faraday::ConnectionFailed, [404]
392
+ end
393
+
394
+ it { expect { subject }.to output(/Connection failed/).to_stdout }
395
+ end
396
+
397
+ describe 'statuses' do
398
+ before do
399
+ allow(faraday).to receive(:post).and_return response
400
+ allow(faraday).to receive(:get).and_return response
401
+ allow(faraday).to receive(:put).and_return response
402
+ end
403
+
404
+ context 'everything is ok' do
405
+ let(:status) { 200 }
406
+ let(:reason_phrase) { 'OK' }
407
+
408
+ it { expect { subject }.to output(/Name: Type 1, ID: 34/).to_stdout }
409
+ it { expect { subject }.to output(/Name: Type 2, ID: 55/).to_stdout }
410
+ end
411
+
412
+ context 'unauthorized 401' do
413
+ let(:status) { 401 }
414
+ let(:reason_phrase) { 'not authorized' }
415
+
416
+ it { expect { subject }.to output(/No access to Jira/).to_stdout }
417
+ end
418
+
419
+ context 'unauthorized 403' do
420
+ let(:status) { 403 }
421
+ let(:reason_phrase) { 'not authorized' }
422
+
423
+ it { expect { subject }.to output(/No access to Jira/).to_stdout }
424
+ end
425
+
426
+ context 'not found 404' do
427
+ let(:status) { 404 }
428
+ let(:reason_phrase) { 'not found' }
429
+
430
+ it { expect { subject }.to output(/not found/).to_stdout }
431
+ end
432
+
433
+ context 'other error' do
434
+ let(:status) { 500 }
435
+ let(:reason_phrase) { 'server error' }
436
+
437
+ it { expect { subject }.to output(/Could not/).to_stdout }
438
+ it { expect { subject }.to output(/500/).to_stdout }
439
+ it { expect { subject }.to output(/server error/).to_stdout }
440
+ end
441
+ end
442
+ end
443
+ end
444
+ end
445
+
446
+ describe 'get_jira_transition_ids' do
447
+ subject { Caperoma.get_jira_transition_ids }
448
+
449
+ context 'Account does not exist' do
450
+ it { expect { subject }.to output(/set up Jira/).to_stdout }
451
+ end
452
+
453
+ context 'Account exists' do
454
+ let!(:account) { create :account, type: '--jira' }
455
+
456
+ before { remove_capefile }
457
+
458
+ context 'capefile does not exist' do
459
+ it { expect { subject }.to output(/Capefile not found/).to_stdout }
460
+ end
461
+
462
+ context 'capefile without jira_url' do
463
+ before { File.write 'Capefile.test', 'pivotal_id: 12345' }
464
+
465
+ it { expect { subject }.to output(/Please put jira_url into your Capefile/).to_stdout }
466
+ end
467
+
468
+ context 'invalid capefile' do
469
+ before { File.write 'Capefile.test', '#(*$#>#)@*@' }
470
+
471
+ it { expect { subject }.to output(/Can not parse/).to_stdout }
472
+ end
473
+
474
+ context 'capefile exists' do
475
+ let(:response_body) { { 'issues' => issues, 'transitions' => [{ 'name' => 'Transition 1', 'id' => '34' }, { 'name' => 'Transition 2', 'id' => '55' }] }.to_json }
476
+ let(:response) { double('Faraday', body: response_body, status: status, reason_phrase: reason_phrase) }
477
+ let(:faraday) { double('Faraday', post: response) }
478
+
479
+ let(:status) { 200 }
480
+ let(:reason_phrase) { 'OK' }
481
+
482
+ before do
483
+ allow(Faraday).to receive(:new).and_return faraday
484
+ allow(Faraday).to receive(:default_adapter)
485
+ end
486
+
487
+ before { create_capefile }
488
+
489
+ before do
490
+ allow(faraday).to receive(:post).and_return response
491
+ allow(faraday).to receive(:get).and_return response
492
+ allow(faraday).to receive(:put).and_return response
493
+ end
494
+
495
+ context 'issues do not exist' do
496
+ let(:issues) { [] }
497
+
498
+ it { expect { subject }.to output(/Please create at least one issue in this project manually in the browser/).to_stdout }
499
+ end
500
+
501
+ context 'issues exist' do
502
+ let(:issues) { [{ 'key' => 'RUC-123' }] }
503
+
504
+ context 'no connection' do
505
+ before do
506
+ allow(faraday).to receive(:post).and_raise Faraday::ConnectionFailed, [404]
507
+ allow(faraday).to receive(:get).and_raise Faraday::ConnectionFailed, [404]
508
+ allow(faraday).to receive(:put).and_raise Faraday::ConnectionFailed, [404]
509
+ end
510
+
511
+ it { expect { subject }.to output(/Connection failed/).to_stdout }
512
+ end
513
+
514
+ describe 'statuses' do
515
+ before do
516
+ allow(faraday).to receive(:post).and_return response
517
+ allow(faraday).to receive(:get).and_return response
518
+ allow(faraday).to receive(:put).and_return response
519
+ end
520
+
521
+ context 'everything is ok' do
522
+ let(:status) { 200 }
523
+ let(:reason_phrase) { 'OK' }
524
+
525
+ it { expect { subject }.to output(/Name: Transition 1, ID: 34/).to_stdout }
526
+ it { expect { subject }.to output(/Name: Transition 2, ID: 55/).to_stdout }
527
+ end
528
+
529
+ context 'unauthorized 401' do
530
+ let(:status) { 401 }
531
+ let(:reason_phrase) { 'not authorized' }
532
+
533
+ it { expect { subject }.to output(/No access to Jira/).to_stdout }
534
+ end
535
+
536
+ context 'unauthorized 403' do
537
+ let(:status) { 403 }
538
+ let(:reason_phrase) { 'not authorized' }
539
+
540
+ it { expect { subject }.to output(/No access to Jira/).to_stdout }
541
+ end
542
+
543
+ context 'not found 404' do
544
+ let(:status) { 404 }
545
+ let(:reason_phrase) { 'not found' }
546
+
547
+ it { expect { subject }.to output(/not found/).to_stdout }
548
+ end
549
+
550
+ context 'other error' do
551
+ let(:status) { 500 }
552
+ let(:reason_phrase) { 'server error' }
553
+
554
+ it { expect { subject }.to output(/Could not/).to_stdout }
555
+ it { expect { subject }.to output(/500/).to_stdout }
556
+ it { expect { subject }.to output(/server error/).to_stdout }
557
+ end
558
+ end
559
+ end
560
+ end
561
+ end
562
+ end
7
563
  end