jiraby 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.
- data/.gitignore +9 -0
- data/.rspec +3 -0
- data/.travis.yml +4 -0
- data/.yardopts +8 -0
- data/Gemfile +7 -0
- data/README.md +132 -0
- data/Rakefile +5 -0
- data/docs/development.md +20 -0
- data/docs/history.md +5 -0
- data/docs/ideas.md +54 -0
- data/docs/index.md +11 -0
- data/docs/usage.md +64 -0
- data/jiraby.gemspec +31 -0
- data/lib/jiraby.rb +8 -0
- data/lib/jiraby/entity.rb +21 -0
- data/lib/jiraby/exceptions.rb +8 -0
- data/lib/jiraby/issue.rb +109 -0
- data/lib/jiraby/jira.rb +319 -0
- data/lib/jiraby/json_resource.rb +136 -0
- data/lib/jiraby/project.rb +19 -0
- data/spec/data/field.json +32 -0
- data/spec/data/issue_10002.json +187 -0
- data/spec/data/issue_createmeta.json +35 -0
- data/spec/data/jira_issues.rb +265 -0
- data/spec/data/jira_projects.rb +117 -0
- data/spec/data/project_TST.json +97 -0
- data/spec/data/search_results.json +26 -0
- data/spec/entity_spec.rb +20 -0
- data/spec/issue_spec.rb +289 -0
- data/spec/jira_spec.rb +314 -0
- data/spec/json_resource_spec.rb +222 -0
- data/spec/mockapp/config.ru +6 -0
- data/spec/mockapp/index.html +10 -0
- data/spec/mockapp/jira.rb +61 -0
- data/spec/mockapp/views/auth/login_failed.erb +1 -0
- data/spec/mockapp/views/auth/login_success.erb +7 -0
- data/spec/mockapp/views/error.erb +3 -0
- data/spec/mockapp/views/field.erb +32 -0
- data/spec/mockapp/views/issue/TST-1.erb +186 -0
- data/spec/mockapp/views/issue/createmeta.erb +35 -0
- data/spec/mockapp/views/issue/err_nonexistent.erb +1 -0
- data/spec/mockapp/views/project/TST.erb +97 -0
- data/spec/mockapp/views/project/err_nonexistent.erb +4 -0
- data/spec/mockapp/views/search.erb +26 -0
- data/spec/project_spec.rb +20 -0
- data/spec/spec_helper.rb +26 -0
- data/tasks/mockjira.rake +10 -0
- data/tasks/pry.rake +28 -0
- data/tasks/spec.rake +9 -0
- data/tasks/test.rake +8 -0
- metadata +288 -0
data/spec/jira_spec.rb
ADDED
@@ -0,0 +1,314 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require_relative 'data/jira_issues'
|
3
|
+
|
4
|
+
describe Jiraby::Jira do
|
5
|
+
before(:each) do
|
6
|
+
@jira = Jiraby::Jira.new('localhost:9292', 'username', 'password')
|
7
|
+
todo_stub = RuntimeError.new("RestClient call needs a stub")
|
8
|
+
RestClient.stub(:get).and_raise(todo_stub)
|
9
|
+
RestClient.stub(:post).and_raise(todo_stub)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#initialize' do
|
13
|
+
before(:each) do
|
14
|
+
end
|
15
|
+
|
16
|
+
it "raises an error for unknown API version" do
|
17
|
+
lambda do
|
18
|
+
Jiraby::Jira.new('jira.example.com', nil, nil, '1.0')
|
19
|
+
end.should raise_error
|
20
|
+
end
|
21
|
+
|
22
|
+
it "accepts valid API versions" do
|
23
|
+
jira = Jiraby::Jira.new('jira.example.com', nil, nil, '2')
|
24
|
+
jira.api_version.should == '2'
|
25
|
+
end
|
26
|
+
|
27
|
+
it "accepts URL beginning with http://" do
|
28
|
+
jira = Jiraby::Jira.new('http://jira.example.com', nil, nil)
|
29
|
+
jira.url.should == 'http://jira.example.com'
|
30
|
+
end
|
31
|
+
|
32
|
+
it "accepts URL beginning with https://" do
|
33
|
+
jira = Jiraby::Jira.new('https://jira.example.com', nil, nil)
|
34
|
+
jira.url.should == 'https://jira.example.com'
|
35
|
+
end
|
36
|
+
|
37
|
+
it "prepends http:// to the URL if needed" do
|
38
|
+
jira = Jiraby::Jira.new('jira.example.com', nil, nil)
|
39
|
+
jira.url.should == 'http://jira.example.com'
|
40
|
+
end
|
41
|
+
end #initialize
|
42
|
+
|
43
|
+
describe '#auth_url' do
|
44
|
+
it "returns the full REST authorization URL" do
|
45
|
+
jira = Jiraby::Jira.new('jira.example.com', nil, nil)
|
46
|
+
jira.auth_url.should == 'http://jira.example.com/rest/auth/1/session'
|
47
|
+
end
|
48
|
+
end #auth_url
|
49
|
+
|
50
|
+
describe '#not_implemented_in' do
|
51
|
+
it "raises an exception when API version is one of those listed" do
|
52
|
+
jira = Jiraby::Jira.new('jira.example.com', nil, nil, '2')
|
53
|
+
lambda do
|
54
|
+
jira.not_implemented_in('Issue creation', '2')
|
55
|
+
end.should raise_error
|
56
|
+
end
|
57
|
+
|
58
|
+
it "returns nil when API version is not one of those listed" do
|
59
|
+
jira = Jiraby::Jira.new('jira.example.com', nil, nil, '2')
|
60
|
+
jira.not_implemented_in('Issue creation', '2.0.alpha1').should be_nil
|
61
|
+
end
|
62
|
+
end #not_implemented_in
|
63
|
+
|
64
|
+
context "REST wrappers" do
|
65
|
+
before(:each) do
|
66
|
+
@path = 'fake/path'
|
67
|
+
@resource = Jiraby::JSONResource.new(@jira.base_url)
|
68
|
+
@jira.rest.stub(:[]).with(@path).and_return(@resource)
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#_path_with_query" do
|
72
|
+
it "returns path as-is if query is empty" do
|
73
|
+
@jira._path_with_query("user/search").should == "user/search"
|
74
|
+
end
|
75
|
+
|
76
|
+
it "returns path with query parameters appended" do
|
77
|
+
path = "user/search"
|
78
|
+
query = {:username => "someone", :startAt => 0, :maxResults => 10}
|
79
|
+
expect_path = "user/search?username=someone&startAt=0&maxResults=10"
|
80
|
+
@jira._path_with_query(path, query).should == expect_path
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "#get" do
|
85
|
+
it "sends a GET request" do
|
86
|
+
@resource.should_receive(:get)
|
87
|
+
@jira.get(@path)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "#put" do
|
92
|
+
it "sends a PUT request" do
|
93
|
+
@resource.should_receive(:put)
|
94
|
+
@jira.put(@path, {})
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "#post" do
|
99
|
+
it "sends a POST request" do
|
100
|
+
@resource.should_receive(:post)
|
101
|
+
@jira.post(@path, {})
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "#delete" do
|
106
|
+
it "sends a DELETE request" do
|
107
|
+
@resource.should_receive(:delete)
|
108
|
+
@jira.delete(@path)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end # REST wrappers
|
112
|
+
|
113
|
+
describe '#issue' do
|
114
|
+
it "returns an Issue for valid issue key" do
|
115
|
+
@jira.issue('TST-1').should be_a Jiraby::Issue
|
116
|
+
end
|
117
|
+
|
118
|
+
it "raises ArgumentError if key is nil" do
|
119
|
+
lambda do
|
120
|
+
@jira.issue(nil)
|
121
|
+
end.should raise_error(ArgumentError, /Issue key is required/)
|
122
|
+
end
|
123
|
+
|
124
|
+
it "raises ArgumentError if key is empty" do
|
125
|
+
lambda do
|
126
|
+
@jira.issue(' ')
|
127
|
+
end.should raise_error(ArgumentError, /Issue key is required/)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "raises IssueNotFound for invalid issue key" do
|
131
|
+
lambda do
|
132
|
+
@jira.issue('BOGUS-429')
|
133
|
+
end.should raise_error(Jiraby::IssueNotFound, /Issue 'BOGUS-429' not found/)
|
134
|
+
end
|
135
|
+
end #issue
|
136
|
+
|
137
|
+
describe '#create_issue' do
|
138
|
+
before(:each) do
|
139
|
+
@response = {
|
140
|
+
"id" => "10000",
|
141
|
+
"key" => "TST-24",
|
142
|
+
"self" => "http://www.example.com/jira/rest/api/2/issue/10000"
|
143
|
+
}
|
144
|
+
@response_json = Yajl::Encoder.encode(@response)
|
145
|
+
end
|
146
|
+
|
147
|
+
it "sends a POST request to the Jira API" do
|
148
|
+
#@jira.resource.should_receive(:post).and_return(@response_json)
|
149
|
+
@jira.create_issue('TST', 'Bug')
|
150
|
+
end
|
151
|
+
|
152
|
+
it "returns a Jiraby::Issue" do
|
153
|
+
RestClient.stub(:post => @response_json)
|
154
|
+
end
|
155
|
+
end #create_issue
|
156
|
+
|
157
|
+
describe "#enumerator" do
|
158
|
+
it "returns an Enumerator instance" do
|
159
|
+
enum = @jira.enumerator(:get, 'user/search')
|
160
|
+
enum.should be_an Enumerator
|
161
|
+
end
|
162
|
+
|
163
|
+
it "gets multiple pages by incrementing `startAt`" do
|
164
|
+
page1 = (1..50).map { |num| Jiraby::Entity.new(:key => "TST-#{num}") }
|
165
|
+
page2 = (51..100).map { |num| Jiraby::Entity.new(:key => "TST-#{num}") }
|
166
|
+
page3 = (101..129).map { |num| Jiraby::Entity.new(:key => "TST-#{num}") }
|
167
|
+
jql = 'project=TST'
|
168
|
+
params = {:jql => jql, :maxResults => 50}
|
169
|
+
@jira.should_receive(:post).
|
170
|
+
with('search', params.merge(:startAt => 0)).
|
171
|
+
once.and_return(page1)
|
172
|
+
@jira.should_receive(:post).
|
173
|
+
with('search', params.merge(:startAt => 50)).
|
174
|
+
once.and_return(page2)
|
175
|
+
@jira.should_receive(:post).
|
176
|
+
with('search', params.merge(:startAt => 100)).
|
177
|
+
once.and_return(page3)
|
178
|
+
|
179
|
+
items = @jira.enumerator(:post, 'search', {:jql => jql}).to_a
|
180
|
+
end
|
181
|
+
|
182
|
+
it "works when REST method returns an Entity" do
|
183
|
+
entity = Jiraby::Entity.new(
|
184
|
+
:issues => [
|
185
|
+
{:key => 'TST-1'},
|
186
|
+
{:key => 'TST-2'},
|
187
|
+
{:key => 'TST-3'},
|
188
|
+
]
|
189
|
+
)
|
190
|
+
@jira.stub(:post).and_return(entity)
|
191
|
+
|
192
|
+
enum = @jira.enumerator(:post, 'fake_search', {}, 'issues')
|
193
|
+
enum.count.should == 3
|
194
|
+
end
|
195
|
+
|
196
|
+
it "works when REST method returns an Array of Entity" do
|
197
|
+
issue_keys = ['TST-1', 'TST-2', 'TST-3']
|
198
|
+
entities = issue_keys.map {|key| Jiraby::Entity.new(:key => key)}
|
199
|
+
@jira.stub(:post).and_return(entities)
|
200
|
+
|
201
|
+
enum = @jira.enumerator(:post, 'fake_search')
|
202
|
+
enum.count.should == 3
|
203
|
+
enum.to_a.should == entities
|
204
|
+
end
|
205
|
+
|
206
|
+
it "supports the .next method" do
|
207
|
+
# FIXME: For some reason, .next works fine in this test, but when
|
208
|
+
# connected to an actual Jira instance, it blows up with
|
209
|
+
# SystemStackError: stack level too deep
|
210
|
+
issue_keys = ['TST-1', 'TST-2', 'TST-3']
|
211
|
+
entities = issue_keys.map {|key| Jiraby::Entity.new(:key => key)}
|
212
|
+
@jira.stub(:post).and_return(entities)
|
213
|
+
|
214
|
+
enum = @jira.enumerator(:post, 'fake_search')
|
215
|
+
enum.next.key.should == 'TST-1'
|
216
|
+
enum.next.key.should == 'TST-2'
|
217
|
+
enum.next.key.should == 'TST-3'
|
218
|
+
end
|
219
|
+
|
220
|
+
it "raises an exception if response is not Entity or Array" do
|
221
|
+
@jira.stub(:post).and_return('this string')
|
222
|
+
enum = @jira.enumerator(:post, 'fake_search')
|
223
|
+
lambda do
|
224
|
+
enum.first
|
225
|
+
end.should raise_error(RuntimeError, /Unexpected data: this string/)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
# TODO: Populate some more test issues in order to properly test this
|
230
|
+
describe '#search' do
|
231
|
+
before(:each) do
|
232
|
+
@jira.stub(:issue => Jiraby::Issue.new(@jira))
|
233
|
+
end
|
234
|
+
|
235
|
+
it "something or other" do
|
236
|
+
response = @jira.post(:search, {:jql => 'project=FOO'})
|
237
|
+
end
|
238
|
+
|
239
|
+
it "returns an Enumerator" do
|
240
|
+
require 'enumerator'
|
241
|
+
@jira.search('project=TST').should be_an Enumerator
|
242
|
+
end
|
243
|
+
|
244
|
+
it "yields one Issue instance for each issue key" do
|
245
|
+
@jira.search('project=TST').each do |issue|
|
246
|
+
issue.should be_a Jiraby::Issue
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end #search
|
250
|
+
|
251
|
+
# FIXME: Test this using the fake Jira instance
|
252
|
+
describe '#count' do
|
253
|
+
it "returns the number of issues matching a JQL query" do
|
254
|
+
search_results = Jiraby::Entity.new({'total' => 5})
|
255
|
+
@jira.should_receive(:post).
|
256
|
+
with('search', anything).
|
257
|
+
and_return(search_results)
|
258
|
+
@jira.count('key = TST-1').should == 5
|
259
|
+
end
|
260
|
+
|
261
|
+
it "returns a count of all issues when JQL is empty" do
|
262
|
+
search_results = Jiraby::Entity.new({'total' => 15})
|
263
|
+
@jira.stub(:post).and_return(search_results)
|
264
|
+
|
265
|
+
@jira.count('').should == 15
|
266
|
+
end
|
267
|
+
end #count
|
268
|
+
|
269
|
+
describe '#project' do
|
270
|
+
before(:each) do
|
271
|
+
#@jira.resource.stub(:get).and_return({})
|
272
|
+
#@jira.resource.stub(:get).with('project/TST').and_return(json_data('project_TST.json'))
|
273
|
+
end
|
274
|
+
|
275
|
+
it "returns project data" do
|
276
|
+
project = @jira.project('TST')
|
277
|
+
project.should be_a Jiraby::Project
|
278
|
+
# TODO: Verify attributes (requires fleshing out Project class)
|
279
|
+
end
|
280
|
+
|
281
|
+
it "raises ProjectNotFound if the project is not found" do
|
282
|
+
lambda do
|
283
|
+
@jira.project('BOGUS')
|
284
|
+
end.should raise_error(Jiraby::ProjectNotFound, /Project 'BOGUS' not found/)
|
285
|
+
end
|
286
|
+
end #project
|
287
|
+
|
288
|
+
describe '#project_meta' do
|
289
|
+
it "returns the project createmeta info if the project exists" do
|
290
|
+
meta = @jira.project_meta('TST')
|
291
|
+
expect_keys = ['name', 'self', 'issuetypes', 'id', 'avatarUrls', 'key']
|
292
|
+
meta.keys.sort.should == expect_keys.sort
|
293
|
+
end
|
294
|
+
|
295
|
+
it "raises ProjectNotFound if the project doesn't exist" do
|
296
|
+
RestClient.stub(:get).and_raise(RestClient::ResourceNotFound)
|
297
|
+
lambda do
|
298
|
+
@jira.project_meta('BOGUS')
|
299
|
+
end.should raise_error(Jiraby::ProjectNotFound, /Project 'BOGUS' not found/)
|
300
|
+
end
|
301
|
+
end #project_meta
|
302
|
+
|
303
|
+
describe '#field_mapping' do
|
304
|
+
it "returns a mapping of field IDs to names" do
|
305
|
+
@jira.field_mapping.should == {
|
306
|
+
'description' => "Description",
|
307
|
+
'summary' => "Summary",
|
308
|
+
'customfield_123' => "My Field",
|
309
|
+
}
|
310
|
+
end
|
311
|
+
end #field_mapping
|
312
|
+
|
313
|
+
end
|
314
|
+
|
@@ -0,0 +1,222 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require 'jiraby/jira'
|
3
|
+
require 'jiraby/json_resource'
|
4
|
+
|
5
|
+
describe Jiraby::JSONResource do
|
6
|
+
before(:each) do
|
7
|
+
@jr = Jiraby::JSONResource.new('http://example.com')
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#initialize" do
|
11
|
+
# Ensure that `options` contains appropriate JSON headers
|
12
|
+
def should_include_json_headers(options)
|
13
|
+
options.should include(:headers)
|
14
|
+
options[:headers].should include(:content_type)
|
15
|
+
options[:headers][:content_type].should == :json
|
16
|
+
options[:headers].should include(:accept)
|
17
|
+
options[:headers][:accept].should == :json
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns a JSONResource instance" do
|
21
|
+
jr = Jiraby::JSONResource.new('http://example.com')
|
22
|
+
jr.should be_a Jiraby::JSONResource
|
23
|
+
end
|
24
|
+
|
25
|
+
it "sets options[:headers] to send/receive JSON" do
|
26
|
+
jr = Jiraby::JSONResource.new('http://example.com')
|
27
|
+
should_include_json_headers(jr.options)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "merges additional options" do
|
31
|
+
options = {:headers => {:foo => 'bar'}, :other => 'x'}
|
32
|
+
jr = Jiraby::JSONResource.new('http://example.com', options)
|
33
|
+
should_include_json_headers(jr.options)
|
34
|
+
jr.options.should include(:other)
|
35
|
+
jr.options[:other].should == 'x'
|
36
|
+
jr.options[:headers].should include(:foo)
|
37
|
+
jr.options[:headers][:foo].should == 'bar'
|
38
|
+
end
|
39
|
+
end #initialize
|
40
|
+
|
41
|
+
describe "#[]" do
|
42
|
+
it "returns a JSONResource instance" do
|
43
|
+
@jr['subpath'].should be_a Jiraby::JSONResource
|
44
|
+
end
|
45
|
+
end #[]
|
46
|
+
|
47
|
+
describe "#get" do
|
48
|
+
it "invokes #wrap with :_head" do
|
49
|
+
@jr.should_receive(:wrap).with(:_get, {})
|
50
|
+
@jr.get({})
|
51
|
+
end
|
52
|
+
end #get
|
53
|
+
|
54
|
+
describe "#delete" do
|
55
|
+
it "invokes #wrap with :_delete" do
|
56
|
+
@jr.should_receive(:wrap).with(:_delete, {})
|
57
|
+
@jr.delete({})
|
58
|
+
end
|
59
|
+
end #delete
|
60
|
+
|
61
|
+
describe "#head" do
|
62
|
+
it "invokes #wrap with :_head" do
|
63
|
+
@jr.should_receive(:wrap).with(:_head, {})
|
64
|
+
@jr.head({})
|
65
|
+
end
|
66
|
+
end #head
|
67
|
+
|
68
|
+
describe "#post" do
|
69
|
+
it "invokes #wrap_with_payload with :_post" do
|
70
|
+
@jr.should_receive(:wrap_with_payload).with(:_post, {}, {})
|
71
|
+
@jr.post({}, {})
|
72
|
+
end
|
73
|
+
end #post
|
74
|
+
|
75
|
+
describe "#put" do
|
76
|
+
it "invokes #wrap_with_payload with :_put" do
|
77
|
+
@jr.should_receive(:wrap_with_payload).with(:_put, {}, {})
|
78
|
+
@jr.put({}, {})
|
79
|
+
end
|
80
|
+
end #put
|
81
|
+
|
82
|
+
describe "#patch" do
|
83
|
+
it "invokes #wrap_with_payload with :_patch" do
|
84
|
+
@jr.should_receive(:wrap_with_payload).with(:_patch, {}, {})
|
85
|
+
@jr.patch({}, {})
|
86
|
+
end
|
87
|
+
end #patch
|
88
|
+
|
89
|
+
describe "#wrap" do
|
90
|
+
before(:each) do
|
91
|
+
@headers = {}
|
92
|
+
end
|
93
|
+
|
94
|
+
it "invokes a REST method with additional headers and block" do
|
95
|
+
@jr.should_receive(:_get).with(@headers).and_return('{}')
|
96
|
+
@jr.wrap(:_get, @headers)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "returns the parsed JSON response as a hash" do
|
100
|
+
response_hash = {"status" => "ok"}
|
101
|
+
@jr.should_receive(:_get).
|
102
|
+
with(@headers).
|
103
|
+
and_return(response_hash.to_json)
|
104
|
+
result = @jr.wrap(:_get, @headers)
|
105
|
+
result.should == response_hash
|
106
|
+
end
|
107
|
+
|
108
|
+
it "when RestClient::Exception occurs, returns exception response as a hash" do
|
109
|
+
error_hash = {"error" => "Error message"}
|
110
|
+
exception = RestClient::Exception.new
|
111
|
+
exception.response = error_hash.to_json
|
112
|
+
got_response = @jr.wrap(:_get, {}) do
|
113
|
+
raise exception
|
114
|
+
end
|
115
|
+
got_response.should == error_hash
|
116
|
+
end
|
117
|
+
end #wrap
|
118
|
+
|
119
|
+
describe "#wrap_with_payload" do
|
120
|
+
before(:each) do
|
121
|
+
@payload = {"name" => "Foo"}
|
122
|
+
@headers = {}
|
123
|
+
end
|
124
|
+
|
125
|
+
it "when payload is a hash, it's encoded as JSON" do
|
126
|
+
@jr.should_receive(:_put).with(@payload.to_json, @headers).and_return('{}')
|
127
|
+
@jr.wrap_with_payload(:_put, @payload, @headers)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "when payload is already a JSON string, it's sent as-is" do
|
131
|
+
json_payload = @payload.to_json
|
132
|
+
@jr.should_receive(:_put).with(json_payload, @headers).and_return('{}')
|
133
|
+
@jr.wrap_with_payload(:_put, json_payload, @headers)
|
134
|
+
end
|
135
|
+
|
136
|
+
it "invokes a REST method with additional headers and block" do
|
137
|
+
@headers['extra'] = 'something'
|
138
|
+
@jr.should_receive(:_put).with(@payload.to_json, @headers).and_return('{}')
|
139
|
+
@jr.wrap_with_payload(:_put, @payload, @headers)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "returns the parsed JSON response as a hash" do
|
143
|
+
json_payload = @payload.to_json
|
144
|
+
response_hash = {"status" => "ok"}
|
145
|
+
@jr.should_receive(:_put).
|
146
|
+
with(json_payload, @headers).
|
147
|
+
and_return(response_hash.to_json)
|
148
|
+
result = @jr.wrap_with_payload(:_put, json_payload, @headers)
|
149
|
+
result.should == response_hash
|
150
|
+
end
|
151
|
+
|
152
|
+
it "when RestClient::Exception occurs, returns exception response as a hash" do
|
153
|
+
error_hash = {"error" => "Error message"}
|
154
|
+
exception = RestClient::Exception.new
|
155
|
+
exception.response = error_hash.to_json
|
156
|
+
got_response = @jr.wrap_with_payload(:_put, {}, {}) do
|
157
|
+
raise exception
|
158
|
+
end
|
159
|
+
got_response.should == error_hash
|
160
|
+
end
|
161
|
+
end #wrap_with_payload
|
162
|
+
|
163
|
+
describe "#parsed_response" do
|
164
|
+
it "returns a Hash if the response is a JSON object" do
|
165
|
+
hash = {
|
166
|
+
'foo' => 'bar',
|
167
|
+
'nested' => {
|
168
|
+
'a' => 'z',
|
169
|
+
'x' => 'y',
|
170
|
+
}
|
171
|
+
}
|
172
|
+
json = Yajl::Encoder.encode(hash)
|
173
|
+
@jr.parsed_response(json).should == hash
|
174
|
+
end
|
175
|
+
|
176
|
+
it "returns an Array of Hashes if the response is a JSON object array" do
|
177
|
+
hash_array = [{'foo' => 'bar'}, {'goo' => 'car'}]
|
178
|
+
json = Yajl::Encoder.encode(hash_array)
|
179
|
+
@jr.parsed_response(json).should == hash_array
|
180
|
+
end
|
181
|
+
|
182
|
+
it "returns nil if the response is an empty string" do
|
183
|
+
@jr.parsed_response("").should be_nil
|
184
|
+
end
|
185
|
+
|
186
|
+
it "raises JSONParseError when parsing fails" do
|
187
|
+
lambda do
|
188
|
+
@jr.parsed_response('bogus json')
|
189
|
+
end.should raise_error(Jiraby::JSONParseError)
|
190
|
+
end
|
191
|
+
end #parsed_response
|
192
|
+
|
193
|
+
describe "#maybe_error_response" do
|
194
|
+
it "yields the block return value if no exception occurs" do
|
195
|
+
expect_response = "The normalexpected response"
|
196
|
+
got_response = @jr.maybe_error_response do
|
197
|
+
expect_response
|
198
|
+
end
|
199
|
+
got_response.should == expect_response
|
200
|
+
end
|
201
|
+
|
202
|
+
it "re-raises RestClient::RequestTimeout" do
|
203
|
+
exception = RestClient::RequestTimeout.new
|
204
|
+
lambda do
|
205
|
+
@jr.maybe_error_response do
|
206
|
+
raise exception
|
207
|
+
end
|
208
|
+
end.should raise_error(exception)
|
209
|
+
end
|
210
|
+
|
211
|
+
it "yields the exception's response if a RestClient::Excception occurs" do
|
212
|
+
exception = RestClient::Exception.new
|
213
|
+
exception.response = "The exception response"
|
214
|
+
got_response = @jr.maybe_error_response do
|
215
|
+
raise exception
|
216
|
+
end
|
217
|
+
got_response.should == exception.response
|
218
|
+
end
|
219
|
+
end #maybe_error_response
|
220
|
+
|
221
|
+
end # describe Jiraby::JSONResource
|
222
|
+
|