backlog_api 0.0.1

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.
@@ -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
+