backlog_api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+
@@ -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,7 @@
1
+ # -*- coding: utf-8 -*-
2
+ require_relative '../../spec_helper'
3
+ # とっぷもじゅーる
4
+ module BacklogApi
5
+ describe Command do
6
+ end
7
+ end
@@ -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
@@ -0,0 +1,9 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ module BacklogApi
4
+ # describe API_METHODS do
5
+ # end
6
+ end
7
+
8
+
9
+