jira-ruby 0.0.2
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/Gemfile +5 -0
- data/README.markdown +81 -0
- data/Rakefile +9 -0
- data/example.rb +66 -0
- data/jira-ruby.gemspec +28 -0
- data/lib/jira.rb +12 -0
- data/lib/jira/client.rb +105 -0
- data/lib/jira/resource/base.rb +148 -0
- data/lib/jira/resource/base_factory.rb +44 -0
- data/lib/jira/resource/component.rb +15 -0
- data/lib/jira/resource/http_error.rb +17 -0
- data/lib/jira/resource/issue.rb +15 -0
- data/lib/jira/resource/project.rb +9 -0
- data/lib/jira/tasks.rb +0 -0
- data/lib/jira/version.rb +3 -0
- data/lib/tasks/generate.rake +16 -0
- data/spec/integration/component_spec.rb +70 -0
- data/spec/integration/issue_spec.rb +72 -0
- data/spec/integration/project_spec.rb +48 -0
- data/spec/jira/client_spec.rb +157 -0
- data/spec/jira/resource/base_factory_spec.rb +36 -0
- data/spec/jira/resource/base_spec.rb +292 -0
- data/spec/jira/resource/http_error_spec.rb +25 -0
- data/spec/jira/resource/project_factory_spec.rb +13 -0
- data/spec/mock_responses/component.post.json +28 -0
- data/spec/mock_responses/component/10000.json +39 -0
- data/spec/mock_responses/component/10000.put.json +39 -0
- data/spec/mock_responses/issue.post.json +5 -0
- data/spec/mock_responses/issue/10002.json +114 -0
- data/spec/mock_responses/project.json +12 -0
- data/spec/mock_responses/project/SAMPLEPROJECT.json +70 -0
- data/spec/spec_helper.rb +26 -0
- metadata +148 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Jira::Resource::BaseFactory do
|
4
|
+
|
5
|
+
class Jira::Resource::FooFactory < Jira::Resource::BaseFactory ; end
|
6
|
+
class Jira::Resource::Foo ; end
|
7
|
+
|
8
|
+
let(:client) { mock() }
|
9
|
+
subject { Jira::Resource::FooFactory.new(client) }
|
10
|
+
|
11
|
+
it "initializes correctly" do
|
12
|
+
subject.class.should == Jira::Resource::FooFactory
|
13
|
+
subject.client.should == client
|
14
|
+
subject.target_class.should == Jira::Resource::Foo
|
15
|
+
end
|
16
|
+
|
17
|
+
it "proxies all to the target class" do
|
18
|
+
Jira::Resource::Foo.should_receive(:all).with(client)
|
19
|
+
subject.all
|
20
|
+
end
|
21
|
+
|
22
|
+
it "proxies find to the target class" do
|
23
|
+
Jira::Resource::Foo.should_receive(:find).with(client, 'FOO')
|
24
|
+
subject.find('FOO')
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns the target class" do
|
28
|
+
subject.target_class.should == Jira::Resource::Foo
|
29
|
+
end
|
30
|
+
|
31
|
+
it "proxies build to the target class" do
|
32
|
+
attrs = mock()
|
33
|
+
Jira::Resource::Foo.should_receive(:build).with(client, attrs)
|
34
|
+
subject.build(attrs)
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,292 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Jira::Resource::Base do
|
4
|
+
|
5
|
+
class Jira::Resource::Deadbeef < Jira::Resource::Base ; end
|
6
|
+
|
7
|
+
let(:client) { mock() }
|
8
|
+
let(:attrs) { mock() }
|
9
|
+
|
10
|
+
subject { Jira::Resource::Deadbeef.new(client, :attrs => attrs) }
|
11
|
+
|
12
|
+
it "assigns the client and attrs" do
|
13
|
+
subject.client.should == client
|
14
|
+
subject.attrs.should == attrs
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns all the deadbeefs" do
|
18
|
+
response = mock()
|
19
|
+
response.should_receive(:body).and_return('[{"self":"http://deadbeef/","key":"FOO"}]')
|
20
|
+
client.should_receive(:get).with('/jira/rest/api/2/deadbeef').and_return(response)
|
21
|
+
Jira::Resource::Deadbeef.should_receive(:rest_base_path).and_return('/jira/rest/api/2/deadbeef')
|
22
|
+
deadbeefs = Jira::Resource::Deadbeef.all(client)
|
23
|
+
deadbeefs.length.should == 1
|
24
|
+
first = deadbeefs.first
|
25
|
+
first.class.should == Jira::Resource::Deadbeef
|
26
|
+
first.attrs['self'].should == 'http://deadbeef/'
|
27
|
+
first.attrs['key'].should == 'FOO'
|
28
|
+
first.expanded?.should be_false
|
29
|
+
end
|
30
|
+
|
31
|
+
it "finds a deadbeef by key" do
|
32
|
+
response = mock()
|
33
|
+
response.stub(:body).and_return('{"self":"http://deadbeef/","key":"FOO"}')
|
34
|
+
client.should_receive(:get).with('/jira/rest/api/2/deadbeef/FOO').and_return(response)
|
35
|
+
Jira::Resource::Deadbeef.should_receive(:rest_base_path).and_return('/jira/rest/api/2/deadbeef')
|
36
|
+
deadbeef = Jira::Resource::Deadbeef.find(client, 'FOO')
|
37
|
+
deadbeef.client.should == client
|
38
|
+
deadbeef.attrs['self'].should == 'http://deadbeef/'
|
39
|
+
deadbeef.attrs['key'].should == 'FOO'
|
40
|
+
deadbeef.expanded?.should be_true
|
41
|
+
end
|
42
|
+
|
43
|
+
it "builds a deadbeef" do
|
44
|
+
deadbeef = Jira::Resource::Deadbeef.build(client, 'key' => "FOO" )
|
45
|
+
deadbeef.expanded?.should be_false
|
46
|
+
|
47
|
+
deadbeef.client.should == client
|
48
|
+
deadbeef.attrs['key'].should == 'FOO'
|
49
|
+
end
|
50
|
+
|
51
|
+
it "returns the endpoint name" do
|
52
|
+
subject.class.endpoint_name.should == 'deadbeef'
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
describe "rest_base_path" do
|
57
|
+
|
58
|
+
before(:each) do
|
59
|
+
client.should_receive(:options).and_return(:rest_base_path => '/deadbeef/bar')
|
60
|
+
end
|
61
|
+
|
62
|
+
it "returns the rest_base_path" do
|
63
|
+
subject.rest_base_path.should == '/deadbeef/bar/deadbeef'
|
64
|
+
end
|
65
|
+
|
66
|
+
it "has a class method that returns the rest_base_path" do
|
67
|
+
subject.class.rest_base_path(client).should == '/deadbeef/bar/deadbeef'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it "parses json" do
|
72
|
+
described_class.parse_json('{"foo":"bar"}').should == {"foo" => "bar"}
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "dynamic instance methods" do
|
76
|
+
|
77
|
+
let(:attrs) { {'foo' => 'bar', 'flum' => 'goo', 'object_id' => 'dummy'} }
|
78
|
+
subject { Jira::Resource::Deadbeef.new(client, :attrs => attrs) }
|
79
|
+
|
80
|
+
it "responds to each of the top level attribute names" do
|
81
|
+
subject.should respond_to(:foo)
|
82
|
+
subject.should respond_to('flum')
|
83
|
+
subject.should respond_to(:object_id)
|
84
|
+
|
85
|
+
subject.foo.should == 'bar'
|
86
|
+
subject.flum.should == 'goo'
|
87
|
+
|
88
|
+
# Should not override existing method names, but should still allow
|
89
|
+
# access to their values via the attrs[] hash
|
90
|
+
subject.object_id.should_not == 'dummy'
|
91
|
+
subject.attrs['object_id'].should == 'dummy'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "fetch" do
|
96
|
+
|
97
|
+
subject { Jira::Resource::Deadbeef.new(client, :attrs => {'key' => 'FOO'}) }
|
98
|
+
|
99
|
+
describe "not cached" do
|
100
|
+
|
101
|
+
before(:each) do
|
102
|
+
response = mock()
|
103
|
+
response.stub(:body).and_return('{"self":"http://deadbeef/","key":"FOO"}')
|
104
|
+
client.should_receive(:get).with('/jira/rest/api/2/deadbeef/FOO').and_return(response)
|
105
|
+
Jira::Resource::Deadbeef.should_receive(:rest_base_path).and_return('/jira/rest/api/2/deadbeef')
|
106
|
+
end
|
107
|
+
|
108
|
+
it "sets expanded to true after fetch" do
|
109
|
+
subject.expanded?.should be_false
|
110
|
+
subject.fetch
|
111
|
+
subject.expanded?.should be_true
|
112
|
+
end
|
113
|
+
|
114
|
+
it "performs a fetch" do
|
115
|
+
subject.expanded?.should be_false
|
116
|
+
subject.fetch
|
117
|
+
subject.self.should == "http://deadbeef/"
|
118
|
+
subject.key.should == "FOO"
|
119
|
+
end
|
120
|
+
|
121
|
+
it "performs a fetch if already fetched and force flag is true" do
|
122
|
+
subject.expanded = true
|
123
|
+
subject.fetch(true)
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "cached" do
|
129
|
+
it "doesn't perform a fetch if already fetched" do
|
130
|
+
subject.expanded = true
|
131
|
+
client.should_not_receive(:get)
|
132
|
+
subject.fetch
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "save" do
|
139
|
+
|
140
|
+
let(:response) { mock() }
|
141
|
+
|
142
|
+
subject { Jira::Resource::Deadbeef.new(client) }
|
143
|
+
|
144
|
+
before(:each) do
|
145
|
+
subject.should_receive(:url).and_return('/foo/bar')
|
146
|
+
end
|
147
|
+
|
148
|
+
it "POSTs a new record" do
|
149
|
+
response.stub(:body => '{"id":"123"}')
|
150
|
+
subject.stub(:new_record? => true)
|
151
|
+
client.should_receive(:post).with('/foo/bar','{"foo":"bar"}').and_return(response)
|
152
|
+
subject.save("foo" => "bar").should be_true
|
153
|
+
subject.id.should == "123"
|
154
|
+
subject.expanded.should be_false
|
155
|
+
end
|
156
|
+
|
157
|
+
it "PUTs an existing record" do
|
158
|
+
response.stub(:body => nil)
|
159
|
+
subject.stub(:new_record? => false)
|
160
|
+
client.should_receive(:put).with('/foo/bar','{"foo":"bar"}').and_return(response)
|
161
|
+
subject.save("foo" => "bar").should be_true
|
162
|
+
subject.expanded.should be_false
|
163
|
+
end
|
164
|
+
|
165
|
+
it "merges attrs on save" do
|
166
|
+
response.stub(:body => nil)
|
167
|
+
client.should_receive(:post).with('/foo/bar','{"foo":{"fum":"dum"}}').and_return(response)
|
168
|
+
subject.attrs = {"foo" => {"bar" => "baz"}}
|
169
|
+
subject.save({"foo" => {"fum" => "dum"}})
|
170
|
+
subject.foo.should == {"bar" => "baz", "fum" => "dum"}
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
describe "set_attrs" do
|
176
|
+
it "merges hashes correctly when clobber is true (default)" do
|
177
|
+
subject.attrs = {"foo" => {"bar" => "baz"}}
|
178
|
+
subject.set_attrs({"foo" => {"fum" => "dum"}})
|
179
|
+
subject.foo.should == {"fum" => "dum"}
|
180
|
+
end
|
181
|
+
|
182
|
+
it "merges hashes correctly when clobber is false" do
|
183
|
+
subject.attrs = {"foo" => {"bar" => "baz"}}
|
184
|
+
subject.set_attrs({"foo" => {"fum" => "dum"}}, false)
|
185
|
+
subject.foo.should == {"bar" => "baz", "fum" => "dum"}
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
describe "delete" do
|
190
|
+
|
191
|
+
before(:each) do
|
192
|
+
client.should_receive(:delete).with('/foo/bar')
|
193
|
+
subject.stub(:url => '/foo/bar')
|
194
|
+
end
|
195
|
+
|
196
|
+
it "flags itself as deleted" do
|
197
|
+
subject.deleted?.should be_false
|
198
|
+
subject.delete
|
199
|
+
subject.deleted?.should be_true
|
200
|
+
end
|
201
|
+
|
202
|
+
it "sends a DELETE request" do
|
203
|
+
subject.delete
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
|
208
|
+
describe "new_record?" do
|
209
|
+
|
210
|
+
it "returns true for new_record? when new object" do
|
211
|
+
subject.attrs.stub(:[]).with('id').and_return(nil)
|
212
|
+
subject.new_record?.should be_true
|
213
|
+
end
|
214
|
+
|
215
|
+
it "returns false for new_record? when id is set" do
|
216
|
+
subject.attrs.stub(:[]).with('id').and_return('123')
|
217
|
+
subject.new_record?.should be_false
|
218
|
+
end
|
219
|
+
|
220
|
+
end
|
221
|
+
|
222
|
+
describe 'url' do
|
223
|
+
it "returns self as the URL if set" do
|
224
|
+
attrs.stub(:[]).with('self').and_return('http://foo/bar')
|
225
|
+
subject.url.should == "http://foo/bar"
|
226
|
+
end
|
227
|
+
|
228
|
+
it "generates the URL from key if self not set" do
|
229
|
+
attrs.stub(:[]).with('self').and_return(nil)
|
230
|
+
attrs.stub(:[]).with('key').and_return('FOO')
|
231
|
+
subject.stub(:rest_base_path => 'http://foo/bar')
|
232
|
+
subject.url.should == "http://foo/bar/FOO"
|
233
|
+
end
|
234
|
+
|
235
|
+
it "generates the URL from rest_base_path if self and key not set" do
|
236
|
+
attrs.stub(:[]).with('self').and_return(nil)
|
237
|
+
attrs.stub(:[]).with('key').and_return(nil)
|
238
|
+
subject.stub(:rest_base_path => 'http://foo/bar')
|
239
|
+
subject.url.should == "http://foo/bar"
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
it "returns the formatted attrs from to_s" do
|
244
|
+
subject.attrs.stub(:[]).with('foo').and_return('bar')
|
245
|
+
subject.attrs.stub(:[]).with('dead').and_return('beef')
|
246
|
+
|
247
|
+
subject.to_s.should match(/#<Jira::Resource::Deadbeef:\d+ @attrs=#{attrs.inspect}>/)
|
248
|
+
end
|
249
|
+
|
250
|
+
it "returns the key attribute" do
|
251
|
+
subject.class.key_attribute.should == :key
|
252
|
+
end
|
253
|
+
|
254
|
+
it "converts to json" do
|
255
|
+
subject.attrs.stub(:to_json => '{"foo":"bar","dead":"beef"}')
|
256
|
+
|
257
|
+
subject.to_json.should == '{"foo":"bar","dead":"beef"}'
|
258
|
+
end
|
259
|
+
|
260
|
+
describe "extract attrs from response" do
|
261
|
+
|
262
|
+
subject { Jira::Resource::Deadbeef.new(client, :attrs => {}) }
|
263
|
+
|
264
|
+
it "sets the attrs from a response" do
|
265
|
+
response = mock()
|
266
|
+
response.stub(:body).and_return('{"foo":"bar"}')
|
267
|
+
|
268
|
+
subject.set_attrs_from_response(response).should == {'foo' => 'bar'}
|
269
|
+
subject.foo.should == "bar"
|
270
|
+
end
|
271
|
+
|
272
|
+
it "doesn't clobber existing attrs not in response" do
|
273
|
+
response = mock()
|
274
|
+
response.stub(:body).and_return('{"foo":"bar"}')
|
275
|
+
|
276
|
+
subject.attrs = {'flum' => 'flar'}
|
277
|
+
subject.set_attrs_from_response(response).should == {'foo' => 'bar'}
|
278
|
+
subject.foo.should == "bar"
|
279
|
+
subject.flum.should == "flar"
|
280
|
+
end
|
281
|
+
|
282
|
+
it "handles nil response body" do
|
283
|
+
response = mock()
|
284
|
+
response.stub(:body).and_return(nil)
|
285
|
+
|
286
|
+
subject.attrs = {'flum' => 'flar'}
|
287
|
+
subject.set_attrs_from_response(response).should be_nil
|
288
|
+
subject.flum.should == 'flar'
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Jira::Resource::HTTPError do
|
4
|
+
|
5
|
+
let(:response) {
|
6
|
+
response = mock("response")
|
7
|
+
response.stub(:code => 401)
|
8
|
+
response.stub(:message => "A MESSAGE WOO")
|
9
|
+
response
|
10
|
+
}
|
11
|
+
subject { described_class.new(response) }
|
12
|
+
|
13
|
+
it "takes the response object as an argument" do
|
14
|
+
subject.response.should == response
|
15
|
+
end
|
16
|
+
|
17
|
+
it "has a code method" do
|
18
|
+
subject.code.should == response.code
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns code and class from message" do
|
22
|
+
subject.message.should == response.message
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Jira::Resource::ProjectFactory do
|
4
|
+
|
5
|
+
let(:client) { mock() }
|
6
|
+
subject { Jira::Resource::ProjectFactory.new(client) }
|
7
|
+
|
8
|
+
it "initializes correctly" do
|
9
|
+
subject.class.should == Jira::Resource::ProjectFactory
|
10
|
+
subject.client.should == client
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
{
|
2
|
+
"self": "http://localhost:2990/jira/rest/api/2/component/10001",
|
3
|
+
"id": "10001",
|
4
|
+
"name": "Test component",
|
5
|
+
"assigneeType": "PROJECT_DEFAULT",
|
6
|
+
"assignee": {
|
7
|
+
"self": "http://localhost:2990/jira/rest/api/2/user?username=admin",
|
8
|
+
"name": "admin",
|
9
|
+
"avatarUrls": {
|
10
|
+
"16x16": "http://localhost:2990/jira/secure/useravatar?size=small&avatarId=10122",
|
11
|
+
"48x48": "http://localhost:2990/jira/secure/useravatar?avatarId=10122"
|
12
|
+
},
|
13
|
+
"displayName": "admin",
|
14
|
+
"active": true
|
15
|
+
},
|
16
|
+
"realAssigneeType": "PROJECT_DEFAULT",
|
17
|
+
"realAssignee": {
|
18
|
+
"self": "http://localhost:2990/jira/rest/api/2/user?username=admin",
|
19
|
+
"name": "admin",
|
20
|
+
"avatarUrls": {
|
21
|
+
"16x16": "http://localhost:2990/jira/secure/useravatar?size=small&avatarId=10122",
|
22
|
+
"48x48": "http://localhost:2990/jira/secure/useravatar?avatarId=10122"
|
23
|
+
},
|
24
|
+
"displayName": "admin",
|
25
|
+
"active": true
|
26
|
+
},
|
27
|
+
"isAssigneeTypeValid": true
|
28
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
{
|
2
|
+
"self": "http://localhost:2990/jira/rest/api/2/component/10000",
|
3
|
+
"id": "10000",
|
4
|
+
"name": "Cheesecake",
|
5
|
+
"description": "Description!",
|
6
|
+
"lead": {
|
7
|
+
"self": "http://localhost:2990/jira/rest/api/2/user?username=admin",
|
8
|
+
"name": "admin",
|
9
|
+
"avatarUrls": {
|
10
|
+
"16x16": "http://localhost:2990/jira/secure/useravatar?size=small&avatarId=10122",
|
11
|
+
"48x48": "http://localhost:2990/jira/secure/useravatar?avatarId=10122"
|
12
|
+
},
|
13
|
+
"displayName": "admin",
|
14
|
+
"active": true
|
15
|
+
},
|
16
|
+
"assigneeType": "PROJECT_DEFAULT",
|
17
|
+
"assignee": {
|
18
|
+
"self": "http://localhost:2990/jira/rest/api/2/user?username=admin",
|
19
|
+
"name": "admin",
|
20
|
+
"avatarUrls": {
|
21
|
+
"16x16": "http://localhost:2990/jira/secure/useravatar?size=small&avatarId=10122",
|
22
|
+
"48x48": "http://localhost:2990/jira/secure/useravatar?avatarId=10122"
|
23
|
+
},
|
24
|
+
"displayName": "admin",
|
25
|
+
"active": true
|
26
|
+
},
|
27
|
+
"realAssigneeType": "PROJECT_DEFAULT",
|
28
|
+
"realAssignee": {
|
29
|
+
"self": "http://localhost:2990/jira/rest/api/2/user?username=admin",
|
30
|
+
"name": "admin",
|
31
|
+
"avatarUrls": {
|
32
|
+
"16x16": "http://localhost:2990/jira/secure/useravatar?size=small&avatarId=10122",
|
33
|
+
"48x48": "http://localhost:2990/jira/secure/useravatar?avatarId=10122"
|
34
|
+
},
|
35
|
+
"displayName": "admin",
|
36
|
+
"active": true
|
37
|
+
},
|
38
|
+
"isAssigneeTypeValid": true
|
39
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
{
|
2
|
+
"self": "http://localhost:2990/jira/rest/api/2/component/10000",
|
3
|
+
"id": "10000",
|
4
|
+
"name": "Jammy",
|
5
|
+
"description": "Description!",
|
6
|
+
"lead": {
|
7
|
+
"self": "http://localhost:2990/jira/rest/api/2/user?username=admin",
|
8
|
+
"name": "admin",
|
9
|
+
"avatarUrls": {
|
10
|
+
"16x16": "http://localhost:2990/jira/secure/useravatar?size=small&avatarId=10122",
|
11
|
+
"48x48": "http://localhost:2990/jira/secure/useravatar?avatarId=10122"
|
12
|
+
},
|
13
|
+
"displayName": "admin",
|
14
|
+
"active": true
|
15
|
+
},
|
16
|
+
"assigneeType": "PROJECT_DEFAULT",
|
17
|
+
"assignee": {
|
18
|
+
"self": "http://localhost:2990/jira/rest/api/2/user?username=admin",
|
19
|
+
"name": "admin",
|
20
|
+
"avatarUrls": {
|
21
|
+
"16x16": "http://localhost:2990/jira/secure/useravatar?size=small&avatarId=10122",
|
22
|
+
"48x48": "http://localhost:2990/jira/secure/useravatar?avatarId=10122"
|
23
|
+
},
|
24
|
+
"displayName": "admin",
|
25
|
+
"active": true
|
26
|
+
},
|
27
|
+
"realAssigneeType": "PROJECT_DEFAULT",
|
28
|
+
"realAssignee": {
|
29
|
+
"self": "http://localhost:2990/jira/rest/api/2/user?username=admin",
|
30
|
+
"name": "admin",
|
31
|
+
"avatarUrls": {
|
32
|
+
"16x16": "http://localhost:2990/jira/secure/useravatar?size=small&avatarId=10122",
|
33
|
+
"48x48": "http://localhost:2990/jira/secure/useravatar?avatarId=10122"
|
34
|
+
},
|
35
|
+
"displayName": "admin",
|
36
|
+
"active": true
|
37
|
+
},
|
38
|
+
"isAssigneeTypeValid": true
|
39
|
+
}
|