backlog_api 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.coveralls.yml +1 -0
- data/.gitignore +20 -0
- data/.travis.yml +7 -0
- data/Gemfile +10 -0
- data/Guardfile +33 -0
- data/LICENSE.txt +22 -0
- data/README.md +39 -0
- data/Rakefile +1 -0
- data/backlog_api.gemspec +52 -0
- data/bin/backlog +4 -0
- data/config.ru +8 -0
- data/lib/application.rb +124 -0
- data/lib/backlog_api/client.rb +69 -0
- data/lib/backlog_api/command.rb +120 -0
- data/lib/backlog_api/const.rb +5 -0
- data/lib/backlog_api/version.rb +3 -0
- data/lib/backlog_api.rb +23 -0
- data/lib/data/api_methods.yml +148 -0
- data/lib/views/index.erb +1 -0
- data/spec/lib/application_spec.rb +41 -0
- data/spec/lib/backlog_api/client_spec.rb +392 -0
- data/spec/lib/backlog_api/comand_spec.rb +7 -0
- data/spec/lib/backlog_api/command_spec.rb +106 -0
- data/spec/lib/backlog_api/const_spec.rb +9 -0
- data/spec/lib/backlog_api_spec.rb +5 -0
- data/spec/spec_helper.rb +61 -0
- metadata +513 -0
@@ -0,0 +1,148 @@
|
|
1
|
+
getProjects:
|
2
|
+
type: null
|
3
|
+
required: []
|
4
|
+
not_required: []
|
5
|
+
return_type: Array
|
6
|
+
desc: '参加プロジェクトを配列で返します。指定できるパラメータはありません。'
|
7
|
+
getProject:
|
8
|
+
type: scalar
|
9
|
+
required: [projectKey]
|
10
|
+
desc: 'プロジェクトキーを指定して、プロジェクトを取得します。'
|
11
|
+
# getProject:
|
12
|
+
# type: scalar
|
13
|
+
# required: [projectId]
|
14
|
+
# desc: 'プロジェクトIDを指定して、プロジェクトを取得します。'
|
15
|
+
getComponents:
|
16
|
+
type: scalar
|
17
|
+
required: [projectId]
|
18
|
+
desc: 'プロジェクトのカテゴリを返します。'
|
19
|
+
getVersions:
|
20
|
+
type: scalar
|
21
|
+
required: [projectId]
|
22
|
+
desc: 'プロジェクトの発生バージョン/マイルストーンを返します。'
|
23
|
+
getUsers:
|
24
|
+
type: scalar
|
25
|
+
required: [projectId]
|
26
|
+
desc: 'プロジェクトの参加メンバーを返します。'
|
27
|
+
getIssueTypes:
|
28
|
+
type: scalar
|
29
|
+
required: [projectId]
|
30
|
+
desc: 'プロジェクトの種別を返します。'
|
31
|
+
# getIssue:
|
32
|
+
# type: scalar
|
33
|
+
# required: [issueKey]
|
34
|
+
# desc: '課題キーを指定して、課題を取得します。'
|
35
|
+
getIssue:
|
36
|
+
type: scalar
|
37
|
+
required: [issueId]
|
38
|
+
desc: '課題IDを指定して、課題を取得します。'
|
39
|
+
getComments:
|
40
|
+
type: scalar
|
41
|
+
required: [issueId]
|
42
|
+
desc: '課題のコメントを返します。'
|
43
|
+
countIssue:
|
44
|
+
type: struct
|
45
|
+
required: [projectId]
|
46
|
+
desc: '指定した条件に該当する課題件数を返します。'
|
47
|
+
findIssue:
|
48
|
+
type: struct
|
49
|
+
required: [projectId]
|
50
|
+
desc: '指定した条件に該当する課題を返します。'
|
51
|
+
createIssue:
|
52
|
+
type: struct
|
53
|
+
required: [projectId, summary]
|
54
|
+
desc: '課題を追加します。'
|
55
|
+
updateIssue:
|
56
|
+
type: struct
|
57
|
+
required: [key]
|
58
|
+
desc: '課題を更新します。'
|
59
|
+
switchStatus:
|
60
|
+
type: struct
|
61
|
+
required: [key, statusId]
|
62
|
+
desc: '課題の状態を変更します。'
|
63
|
+
addComment:
|
64
|
+
type: struct
|
65
|
+
required: [key, content]
|
66
|
+
desc: '課題にコメントを追加します。'
|
67
|
+
addIssueType:
|
68
|
+
type: struct
|
69
|
+
required: [project_id, name, color]
|
70
|
+
desc: 'プロジェクトの課題種別を追加します。'
|
71
|
+
updateIssueType:
|
72
|
+
type: struct
|
73
|
+
required: [id, name, color]
|
74
|
+
desc: 'プロジェクトの課題種別を更新します。'
|
75
|
+
deleteIssueType:
|
76
|
+
type: struct
|
77
|
+
# required: [id, substitute_id]
|
78
|
+
required: [id]
|
79
|
+
desc: 'プロジェクトの課題種別を削除します。'
|
80
|
+
addVersion:
|
81
|
+
type: struct
|
82
|
+
required: [project_id, name]
|
83
|
+
desc: 'プロジェクトの発生バージョン/マイルストーンを追加します。'
|
84
|
+
updateVersion:
|
85
|
+
type: struct
|
86
|
+
required: [id, name]
|
87
|
+
desc: 'プロジェクトの発生バージョン/マイルストーンを更新します。'
|
88
|
+
# deleteVersion:
|
89
|
+
# type: scalor
|
90
|
+
# required: [id]
|
91
|
+
# desc: 'プロジェクトの発生バージョン/マイルストーンを削除します。'
|
92
|
+
# addComponent:
|
93
|
+
# type: struct
|
94
|
+
# required: [project_id, name]
|
95
|
+
# desc: 'プロジェクトのカテゴリを追加します。'
|
96
|
+
# updateComponent:
|
97
|
+
# type: struct
|
98
|
+
# required: [id, name]
|
99
|
+
# desc: 'プロジェクトのカテゴリを更新します。'
|
100
|
+
# deleteComponent:
|
101
|
+
# type: struct
|
102
|
+
# required: [id]
|
103
|
+
# desc: 'プロジェクトのカテゴリを削除します。'
|
104
|
+
getTimeline:
|
105
|
+
type: struct
|
106
|
+
required: []
|
107
|
+
desc: '参加プロジェクトすべての課題の更新情報を配列で返します(最大50件)。'
|
108
|
+
getProjectSummary:
|
109
|
+
type: scalar
|
110
|
+
required: [projectId]
|
111
|
+
desc: 'プロジェクト状況を取得します。'
|
112
|
+
getProjectSummaries:
|
113
|
+
type: null
|
114
|
+
required: []
|
115
|
+
desc: '全ての参加プロジェクト状況を取得します。'
|
116
|
+
# getUser:
|
117
|
+
# type: scalar
|
118
|
+
# required: [id]
|
119
|
+
# desc: 'ユーザID(数値またはログインID)を指定して、ユーザを取得します。'
|
120
|
+
# getUserIcon:
|
121
|
+
# type: scalar
|
122
|
+
# required: [id]
|
123
|
+
# desc: 'ユーザID(数値またはログインID)を指定して、ユーザのアイコン画像を取得します。'
|
124
|
+
getActivityTypes:
|
125
|
+
type: null
|
126
|
+
required: []
|
127
|
+
desc: '課題の更新情報の種別一覧を取得します。'
|
128
|
+
getStatuses:
|
129
|
+
type: null
|
130
|
+
required: []
|
131
|
+
desc: '課題の状態一覧を取得します。'
|
132
|
+
getResolutions:
|
133
|
+
type: null
|
134
|
+
required: []
|
135
|
+
desc: '課題の完了理由一覧を取得します。'
|
136
|
+
getPriorities:
|
137
|
+
type: null
|
138
|
+
required: []
|
139
|
+
desc: '課題の優先度一覧を取得します。'
|
140
|
+
# getCustomFields:
|
141
|
+
# type: struct
|
142
|
+
# required: [projectId]
|
143
|
+
# desc: 'プロジェクトに登録してあるカスタム属性の情報を取得します。'
|
144
|
+
# getChildIssues:
|
145
|
+
# type: struct
|
146
|
+
# required: [parent_issue_id]
|
147
|
+
# desc: '指定した親課題のIDの子課題を返します。'
|
148
|
+
|
data/lib/views/index.erb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
インラインテンプレートを使用してね
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
#ENV['RACK_ENV'] = 'test'
|
5
|
+
|
6
|
+
# ドライバ
|
7
|
+
# Capybara.register_driver :my_selenium do |app|
|
8
|
+
# Capybara::Selenium::Driver.new(app, :browser => :firefox)
|
9
|
+
# end
|
10
|
+
# Capybara.default_driver = :my_selenium
|
11
|
+
# Capybara.javascript_driver = :my_selenium
|
12
|
+
Capybara.default_driver = :webkit
|
13
|
+
Capybara.javascript_driver = :webkit
|
14
|
+
|
15
|
+
include Capybara::DSL
|
16
|
+
|
17
|
+
# Sinatraアプリ起動
|
18
|
+
def setup
|
19
|
+
# classicスタイルの場合、Sinatra::Application.newがアプリインスタンスになる
|
20
|
+
Capybara.app = Sinatra::Application.new
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '/test' do
|
24
|
+
before { setup }
|
25
|
+
|
26
|
+
it do
|
27
|
+
visit '/test'
|
28
|
+
expect(page).to have_content('test')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
describe '/' do
|
34
|
+
before { setup }
|
35
|
+
|
36
|
+
it do
|
37
|
+
pending
|
38
|
+
visit '/'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -0,0 +1,392 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require_relative '../../spec_helper' # このファイルからの相対パス
|
3
|
+
|
4
|
+
module BacklogApi
|
5
|
+
|
6
|
+
WebMock.allow_net_connect! # 指定URL以外のアクセスはok by webmock
|
7
|
+
HOST = '%s.backlog.jp'
|
8
|
+
|
9
|
+
describe Client do
|
10
|
+
|
11
|
+
subject { Client.new }
|
12
|
+
|
13
|
+
# letはitの度に生成されるよ。letは遅延評価でlet!は即評価だよ
|
14
|
+
let(:url) { 'https://%s%s' % [subject.host, Client::PATH]}
|
15
|
+
|
16
|
+
# for vcr
|
17
|
+
let(:opt) { {record: :new_episodes} }
|
18
|
+
let(:path) {example.metadata[:full_description].split(/\s+/, 2).join("/").underscore.gsub(/[^\w\/]+/, "_")}
|
19
|
+
|
20
|
+
# for backlog_api's key
|
21
|
+
let(:project_key) {ENV['BACKLOG_PROJECTKEY'] }
|
22
|
+
let(:project_id) {ENV['BACKLOG_PROJECTID'].to_i}
|
23
|
+
let(:issue_key) {ENV['BACKLOG_ISSUEKEY']}
|
24
|
+
let(:issue_id) {ENV['BACKLOG_ISSUEID'].to_i}
|
25
|
+
let(:summary) {ENV['BACKLOG_SUMMARY']}
|
26
|
+
let(:key) {ENV['BACKLOG_KEY']}
|
27
|
+
let(:status_id) {ENV['BACKLOG_STATUSID'].to_i}
|
28
|
+
let(:name) {ENV['BACKLOG_NAME']}
|
29
|
+
let(:color) {ENV['BACKLOG_COLOR']}
|
30
|
+
let(:substitute_id) {ENV['BACKLOG_SUBSTITUTE_ID'].to_i}
|
31
|
+
let(:id) {ENV['BACKLOG_ID'].to_i}
|
32
|
+
let(:parent_issue_id) {ENV['BACKLOG_PARENTISSUEID'].to_i}
|
33
|
+
let(:project_name) {ENV['BACKLOG_PROJECTNAME']}
|
34
|
+
let(:category_name) {ENV['BACKLOG_CATEGORYNAME']}
|
35
|
+
let(:project_id2) {ENV['BACKLOG_PROJECTID2'].to_i}
|
36
|
+
let(:user_id) {ENV['BACKLOG_USERID'].to_i}
|
37
|
+
|
38
|
+
METHOD = 'backlog.%s'
|
39
|
+
|
40
|
+
describe '#get_projects' do
|
41
|
+
it do
|
42
|
+
VCR.use_cassette(path, opt) do # vcrのキャッシュ
|
43
|
+
expect(subject.get_projects).to be_a(Array)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#get_project' do
|
49
|
+
it do
|
50
|
+
VCR.use_cassette(path, opt) do # vcrのキャッシュ
|
51
|
+
expect(subject.get_project(project_key)).to be_a(Hash)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#get_components' do
|
57
|
+
it do
|
58
|
+
VCR.use_cassette(path, opt) do
|
59
|
+
expect(subject.get_components(project_id)).to be_a(Array)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#get_versions' do
|
65
|
+
it do
|
66
|
+
VCR.use_cassette(path, opt) do
|
67
|
+
expect(subject.get_versions(project_id)).to be_a(Array)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#get_users' do
|
73
|
+
it do
|
74
|
+
VCR.use_cassette(path, opt) do
|
75
|
+
expect(subject.get_users(project_id)).to be_a(Array)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '#get_issue_types' do
|
81
|
+
it do
|
82
|
+
VCR.use_cassette(path, opt) do
|
83
|
+
expect(subject.get_issue_types(project_id)).to be_a(Array)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#get_issue' do
|
89
|
+
it do
|
90
|
+
VCR.use_cassette(path, opt) do
|
91
|
+
expect(subject.get_issue(project_id)).to be_a(Hash)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#get_users' do
|
97
|
+
it do
|
98
|
+
VCR.use_cassette(path, opt) do
|
99
|
+
expect(subject.get_users(project_id)).to be_a(Array)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe '#get_issue' do
|
105
|
+
it do
|
106
|
+
VCR.use_cassette(path, opt) do
|
107
|
+
expect(subject.get_issue(issue_id)).to be_a(Hash)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe '#get_comments' do
|
113
|
+
it do
|
114
|
+
VCR.use_cassette(path, opt) do
|
115
|
+
expect(subject.get_comments(issue_id)).to be_a(Array)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe '#count_issue' do
|
121
|
+
it do
|
122
|
+
VCR.use_cassette(path, opt) do
|
123
|
+
expect(subject.count_issue(projectId: project_id)).to be_a(Integer)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe '#find_issue' do
|
129
|
+
it do
|
130
|
+
VCR.use_cassette(path, opt) do
|
131
|
+
expect(subject.find_issue(projectId: project_id)).to be_a(Array)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe '#create_issue' do
|
137
|
+
it do
|
138
|
+
VCR.use_cassette(path, opt) do
|
139
|
+
expect(
|
140
|
+
subject.create_issue(
|
141
|
+
projectId: project_id,
|
142
|
+
summary: summary,
|
143
|
+
)
|
144
|
+
).to be_a(Hash)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe '#update_issue' do
|
150
|
+
it do
|
151
|
+
VCR.use_cassette(path, opt) do
|
152
|
+
expect(subject.update_issue(key: key)).to be_a(Hash)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe '#switch_status' do
|
158
|
+
it do
|
159
|
+
VCR.use_cassette(path, opt) do
|
160
|
+
expect(subject.switch_status(key: key, statusId: status_id)).to be_a(Hash)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
describe '#add_issue_type' do
|
166
|
+
it do
|
167
|
+
VCR.use_cassette(path, opt) do
|
168
|
+
expect(
|
169
|
+
subject.add_issue_type(
|
170
|
+
project_id: project_id,
|
171
|
+
name: name,
|
172
|
+
color: color,
|
173
|
+
)
|
174
|
+
).to be_a(Hash)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
describe '#update_issue_type' do
|
180
|
+
it do
|
181
|
+
VCR.use_cassette(path, opt) do
|
182
|
+
expect(
|
183
|
+
subject.update_issue_type(
|
184
|
+
id: id,
|
185
|
+
name: name,
|
186
|
+
color: color,
|
187
|
+
)
|
188
|
+
).to be_a(Hash)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
|
194
|
+
describe '#delete_issue_type' do
|
195
|
+
it do
|
196
|
+
VCR.use_cassette(path, opt) do
|
197
|
+
expect(
|
198
|
+
subject.delete_issue_type(
|
199
|
+
id: id,
|
200
|
+
)
|
201
|
+
).to be_a(Hash)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
|
207
|
+
describe '#add_version' do
|
208
|
+
it do
|
209
|
+
VCR.use_cassette(path, opt) do
|
210
|
+
expect(
|
211
|
+
subject.add_version(
|
212
|
+
project_id: project_id,
|
213
|
+
name: project_name
|
214
|
+
)
|
215
|
+
).to be_a(Hash)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
|
221
|
+
describe '#update_version' do
|
222
|
+
it do
|
223
|
+
VCR.use_cassette(path, opt) do
|
224
|
+
expect(subject.update_version(id: project_id, name: project_name)).to be_a(Hash)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
describe '#get_timeline' do
|
230
|
+
it do
|
231
|
+
VCR.use_cassette(path, opt) do
|
232
|
+
expect(subject.get_timeline).to be_a(Array)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
|
238
|
+
describe '#get_project_summary' do
|
239
|
+
it do
|
240
|
+
VCR.use_cassette(path, opt) do
|
241
|
+
expect(subject.get_project_summary(project_id)).to be_a(Hash)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
describe '#get_statuses' do
|
247
|
+
it do
|
248
|
+
VCR.use_cassette(path, opt) do
|
249
|
+
expect(subject.get_statuses).to be_a(Array)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
describe '#get_resolutions' do
|
255
|
+
it do
|
256
|
+
VCR.use_cassette(path, opt) do
|
257
|
+
expect(subject.get_resolutions).to be_a(Array)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
describe '#get_priorities' do
|
263
|
+
it do
|
264
|
+
VCR.use_cassette(path, opt) do
|
265
|
+
expect(subject.get_priorities).to be_a(Array)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
|
271
|
+
|
272
|
+
|
273
|
+
# describe "#get_project" do
|
274
|
+
# it do
|
275
|
+
# request_body = '<data projectId="projectId" />'
|
276
|
+
# response_body = {
|
277
|
+
# "use_parent_child_issue" => true,
|
278
|
+
# "id" => 1,
|
279
|
+
# "text_formatting_rule" => "backlog",
|
280
|
+
# "archived" => false,
|
281
|
+
# "name" => "name",
|
282
|
+
# "url" => "url",
|
283
|
+
# "key" => "key"}
|
284
|
+
# WebMock
|
285
|
+
# .stub_request(:post, url) # url
|
286
|
+
# .with(body: request_body, content_type: 'application/xml') # request
|
287
|
+
# .to_return(status: 200, body: response_body, headers: {}) # response
|
288
|
+
# expect(subject.get_project("projectId" => "projectID")).to be_a(Hash) # webmock
|
289
|
+
|
290
|
+
# expect(subject.get_project("2014YC")).to be_a(Hash) # webmock
|
291
|
+
# end
|
292
|
+
# end
|
293
|
+
|
294
|
+
# describe "#get_components" do
|
295
|
+
# it do
|
296
|
+
# pending
|
297
|
+
# request_body = 1
|
298
|
+
# response_body = [
|
299
|
+
# {"id"=>2, "name"=>"name1"},
|
300
|
+
# {"id"=>3, "name"=>"name2"}
|
301
|
+
# ]
|
302
|
+
# WebMock
|
303
|
+
# .stub_request(:post, url) # url
|
304
|
+
# .with(body: request_body, headers: {}) # request
|
305
|
+
# .to_return(status: 200, body: response_body, headers: {}) # response
|
306
|
+
# expect(subject.get_components(1)).to be_a(Array) # webmock
|
307
|
+
# end
|
308
|
+
# end
|
309
|
+
|
310
|
+
|
311
|
+
describe '#new' do
|
312
|
+
it do
|
313
|
+
expect(subject).to be_an_instance_of Client # instance_of(直接のインスタンス)
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
|
318
|
+
# ====================================================
|
319
|
+
# private
|
320
|
+
# ====================================================
|
321
|
+
describe '#call' do
|
322
|
+
it do
|
323
|
+
VCR.use_cassette(path, opt) do
|
324
|
+
response = subject.send :call, METHOD % "getProjects"
|
325
|
+
expect(response).to be_a Array
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
describe '#login_from_args' do
|
331
|
+
subject { Client.allocate }
|
332
|
+
context '成功時' do
|
333
|
+
it do
|
334
|
+
subject.send :login_from_args, "a", "b", "c"
|
335
|
+
expect(subject.user).to eq "a"
|
336
|
+
expect(subject.password).to eq "b"
|
337
|
+
expect(subject.space).to eq "c"
|
338
|
+
expect(subject.host).to eq(HOST % "c")
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
context '失敗時' do
|
343
|
+
it do
|
344
|
+
subject.send :login_from_args, "a", "b"
|
345
|
+
expect(subject.user).to be_nil
|
346
|
+
expect(subject.password).to be_nil
|
347
|
+
expect(subject.space).to be_nil
|
348
|
+
expect(subject.host).to be_nil
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
# # :TODO だめだー修正だー
|
354
|
+
# describe '#login_from_netrc' do
|
355
|
+
# it do
|
356
|
+
# subject.send :login_from_netrc
|
357
|
+
# expect(subject.user).not_to be_nil # nil?
|
358
|
+
# end
|
359
|
+
# end
|
360
|
+
|
361
|
+
# # :TODO これもだめ。めちゃくちゃ
|
362
|
+
# describe '#login_from_environment_variables' do
|
363
|
+
# context '環境変数がセットされている場合は' do
|
364
|
+
# it do
|
365
|
+
# ENV["BACKLOG_USER"], ENV["BACKLOG_PASSWORD"],ENV["BACKLOG_SPACE"] = "a", "b", "c"
|
366
|
+
# subject = Client.new
|
367
|
+
# subject.send :login_from_environment_variables
|
368
|
+
# expect(subject.user).not_to be_nil
|
369
|
+
# end
|
370
|
+
# end
|
371
|
+
# context '環境変数がセットされていない場合は' do
|
372
|
+
# it do
|
373
|
+
# ENV["BACKLOG_USER"], ENV["BACKLOG_PASSWORD"],ENV["BACKLOG_SPACE"] = nil, nil, nil
|
374
|
+
# subject = Client.new
|
375
|
+
# subject.send :login_from_environment_variables
|
376
|
+
# expect(subject.user).to be_nil
|
377
|
+
# end
|
378
|
+
# end
|
379
|
+
# end
|
380
|
+
|
381
|
+
|
382
|
+
|
383
|
+
|
384
|
+
|
385
|
+
|
386
|
+
|
387
|
+
|
388
|
+
|
389
|
+
|
390
|
+
|
391
|
+
end # describe
|
392
|
+
end # module
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require_relative '../../spec_helper'
|
3
|
+
|
4
|
+
PROJECT_ID = ENV['BACKLOG_PROJECTID2'].to_i
|
5
|
+
|
6
|
+
module BacklogApi
|
7
|
+
describe Command do
|
8
|
+
subject { Command.new }
|
9
|
+
|
10
|
+
# =============================
|
11
|
+
# private
|
12
|
+
# =============================
|
13
|
+
describe '#group_issues_by_assigner' do
|
14
|
+
|
15
|
+
|
16
|
+
let(:issues) do
|
17
|
+
# :TODO mock使うように修正
|
18
|
+
[
|
19
|
+
{
|
20
|
+
"status"=>{"id"=>4, "name"=>"完了"},
|
21
|
+
"assigner"=>{"id"=>100000000, "name"=>"山田 太郎"},
|
22
|
+
},
|
23
|
+
{
|
24
|
+
"status"=>{"id"=>4, "name"=>"完了"},
|
25
|
+
"assigner"=>{"id"=>100000001, "name"=>"山田 花子"},
|
26
|
+
},
|
27
|
+
]
|
28
|
+
end
|
29
|
+
|
30
|
+
it do
|
31
|
+
grouped_issues = subject.send :group_issues_by_assigner, issues
|
32
|
+
expect(grouped_issues.tapp).to have(2).members
|
33
|
+
expect(grouped_issues.keys).to eq ["山田 太郎", "山田 花子"]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
describe '#progress_rate' do
|
39
|
+
context '全て完了している時' do
|
40
|
+
it do
|
41
|
+
issues =
|
42
|
+
[{"status"=>{"id"=>4, "name"=>"完了"},
|
43
|
+
"assigner"=>{"id"=>100000000, "name"=>"山田 太郎"}}]
|
44
|
+
|
45
|
+
progress_rate = subject.send :progress_rate, issues
|
46
|
+
expect(progress_rate).to eq "100%"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
context '1/2完了している時' do
|
50
|
+
it do
|
51
|
+
issues =
|
52
|
+
[{"status"=>{"id"=>4, "name"=>"完了"},
|
53
|
+
"assigner"=>{"id"=>100000000, "name"=>"山田 太郎"}},
|
54
|
+
{"status"=>{"id"=>1, "name"=>"作業中"},
|
55
|
+
"assigner"=>{"id"=>100000000, "name"=>"山田 太郎"}}]
|
56
|
+
|
57
|
+
progress_rate = subject.send :progress_rate, issues
|
58
|
+
expect(progress_rate).to eq "50%"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#completed_count_per_total_count' do
|
64
|
+
context '全て完了している時' do
|
65
|
+
it do
|
66
|
+
issues =
|
67
|
+
[{"status"=>{"id"=>4, "name"=>"完了"},
|
68
|
+
"assigner"=>{"id"=>100000000, "name"=>"山田 太郎"}}]
|
69
|
+
|
70
|
+
progress_rate = subject.send :completed_count_per_total_count, issues
|
71
|
+
expect(progress_rate).to eq "1/1"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
context '1/2完了している時' do
|
75
|
+
it do
|
76
|
+
issues =
|
77
|
+
[{"status"=>{"id"=>4, "name"=>"完了"},
|
78
|
+
"assigner"=>{"id"=>100000000, "name"=>"山田 太郎"}},
|
79
|
+
{"status"=>{"id"=>1, "name"=>"作業中"},
|
80
|
+
"assigner"=>{"id"=>100000000, "name"=>"山田 太郎"}}]
|
81
|
+
|
82
|
+
progress_rate = subject.send :completed_count_per_total_count, issues
|
83
|
+
expect(progress_rate).to eq "1/2"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#progress_bar' do
|
89
|
+
it do
|
90
|
+
issues =
|
91
|
+
[{"status"=>{"id"=>4, "name"=>"完了"},
|
92
|
+
"assigner"=>{"id"=>100000000, "name"=>"山田 太郎"}},
|
93
|
+
{"status"=>{"id"=>3, "name"=>"処理済み"},
|
94
|
+
"assigner"=>{"id"=>100000000, "name"=>"山田 太郎"}},
|
95
|
+
{"status"=>{"id"=>2, "name"=>"処理中"},
|
96
|
+
"assigner"=>{"id"=>100000000, "name"=>"山田 太郎"}},
|
97
|
+
{"status"=>{"id"=>1, "name"=>"未対応"},
|
98
|
+
"assigner"=>{"id"=>100000000, "name"=>"山田 太郎"}}
|
99
|
+
]
|
100
|
+
progress_bar = subject.send :progress_bar, issues
|
101
|
+
expect(progress_bar).to eq("|".blue + "|".green + "|".yellow + "|".red )
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|