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.
- checksums.yaml +4 -4
- data/Capefile +6 -6
- data/Capefile.template +4 -1
- data/Gemfile +1 -5
- data/Gemfile.lock +3 -45
- data/HELP +84 -13
- data/README.md +165 -29
- data/Rakefile +25 -22
- data/VERSION +1 -1
- data/bin/caperoma +6 -9
- data/caperoma.gemspec +15 -13
- data/config/crontab +0 -2
- data/config/schedule.rb +17 -19
- data/config/unschedule.rb +3 -0
- data/images/circle.png +0 -0
- data/images/report.png +0 -0
- data/lib/caperoma.rb +308 -98
- data/lib/caperoma/models/account.rb +1 -1
- data/lib/caperoma/models/project.rb +1 -2
- data/lib/caperoma/models/report.rb +15 -15
- data/lib/caperoma/models/task.rb +203 -46
- data/lib/caperoma/models/tasks/chore.rb +2 -0
- data/lib/caperoma/models/tasks/feature.rb +1 -0
- data/lib/caperoma/models/tasks/fix.rb +2 -0
- data/lib/caperoma/models/tasks/meeting.rb +2 -0
- data/lib/caperoma/models/tasks/modules/git.rb +94 -15
- data/lib/caperoma/models/tasks/task_with_commit.rb +8 -5
- data/lib/caperoma/models/tasks/task_with_separate_branch.rb +6 -4
- data/spec/caperoma_spec.rb +558 -2
- data/spec/factories/accounts.rb +1 -1
- data/spec/factories/projects.rb +1 -1
- data/spec/factories/report_recipients.rb +1 -1
- data/spec/factories/reports.rb +1 -1
- data/spec/factories/tasks.rb +1 -2
- data/spec/features/command_unknown_spec.rb +0 -1
- data/spec/features/feature_spec.rb +64 -44
- data/spec/features/init_spec.rb +20 -0
- data/spec/features/status_spec.rb +12 -11
- data/spec/models/project_spec.rb +0 -1
- data/spec/models/task_spec.rb +811 -27
- data/spec/models/task_with_commit_spec.rb +0 -4
- data/spec/models/task_with_separate_branch_spec.rb +4 -4
- data/spec/models/three_day_report_spec.rb +2 -3
- data/spec/spec_helper.rb +2 -0
- data/spec/support/capefile_generator.rb +35 -27
- data/spec/support/stubs.rb +7 -74
- metadata +47 -24
- data/lib/caperoma/models/branch.rb +0 -6
- data/lib/caperoma/services/airbrake_email_processor.rb +0 -47
- data/lib/caperoma/services/pivotal_fetcher.rb +0 -108
- data/spec/factories/branches.rb +0 -9
- data/spec/models/branch_spec.rb +0 -8
@@ -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,32 +1,63 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Git
|
4
|
-
def git_branch
|
5
|
-
`git -C "#{project.folder_path}" checkout -b #{
|
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
|
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
|
-
|
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
|
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
|
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
|
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
|
28
|
-
j.head
|
29
|
-
j.base
|
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
|
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
|
-
|
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
|
63
|
-
|
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
|
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
|
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 :
|
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
|
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
|
34
|
-
|
35
|
+
def set_branch
|
36
|
+
update_column :branch, branch_name
|
35
37
|
end
|
36
38
|
|
37
39
|
def branch_name
|
data/spec/caperoma_spec.rb
CHANGED
@@ -2,6 +2,562 @@
|
|
2
2
|
|
3
3
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
4
4
|
|
5
|
-
describe
|
6
|
-
|
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
|