jiraSOAP 0.5.3 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/ChangeLog +22 -0
  2. data/README.markdown +6 -2
  3. data/lib/jiraSOAP.rb +6 -2
  4. data/lib/jiraSOAP/JIRAservice.rb +29 -32
  5. data/lib/jiraSOAP/api.rb +220 -59
  6. data/lib/jiraSOAP/entities.rb +29 -19
  7. data/lib/jiraSOAP/entities/attachment_metadata.rb +27 -0
  8. data/lib/jiraSOAP/entities/avatar.rb +12 -19
  9. data/lib/jiraSOAP/entities/comment.rb +17 -26
  10. data/lib/jiraSOAP/entities/component.rb +5 -0
  11. data/lib/jiraSOAP/entities/custom_field_value.rb +33 -0
  12. data/lib/jiraSOAP/entities/described_entity.rb +7 -0
  13. data/lib/jiraSOAP/entities/dynamic_entity.rb +8 -0
  14. data/lib/jiraSOAP/entities/entity.rb +43 -0
  15. data/lib/jiraSOAP/entities/field.rb +4 -0
  16. data/lib/jiraSOAP/entities/field_value.rb +4 -49
  17. data/lib/jiraSOAP/entities/filter.rb +7 -16
  18. data/lib/jiraSOAP/entities/issue.rb +32 -43
  19. data/lib/jiraSOAP/entities/issue_property.rb +9 -0
  20. data/lib/jiraSOAP/entities/issue_security_scheme.rb +4 -0
  21. data/lib/jiraSOAP/entities/issue_type.rb +8 -0
  22. data/lib/jiraSOAP/entities/named_entity.rb +7 -0
  23. data/lib/jiraSOAP/entities/notification_scheme.rb +4 -0
  24. data/lib/jiraSOAP/entities/permission.rb +12 -0
  25. data/lib/jiraSOAP/entities/permission_mapping.rb +12 -0
  26. data/lib/jiraSOAP/entities/permission_scheme.rb +8 -0
  27. data/lib/jiraSOAP/entities/priority.rb +9 -0
  28. data/lib/jiraSOAP/entities/project.rb +14 -24
  29. data/lib/jiraSOAP/entities/project_role.rb +11 -0
  30. data/lib/jiraSOAP/entities/remote_entity.rb +7 -0
  31. data/lib/jiraSOAP/entities/resolution.rb +4 -0
  32. data/lib/jiraSOAP/entities/scheme.rb +9 -0
  33. data/lib/jiraSOAP/entities/server_configuration.rb +56 -0
  34. data/lib/jiraSOAP/entities/server_info.rb +30 -0
  35. data/lib/jiraSOAP/entities/status.rb +4 -0
  36. data/lib/jiraSOAP/entities/time_info.rb +15 -0
  37. data/lib/jiraSOAP/entities/user.rb +8 -13
  38. data/lib/jiraSOAP/entities/version.rb +8 -16
  39. data/lib/jiraSOAP/handsoap_extensions.rb +29 -42
  40. data/lib/jiraSOAP/url.rb +3 -2
  41. metadata +193 -33
  42. data/lib/jiraSOAP/entities/abstract.rb +0 -93
  43. data/lib/jiraSOAP/entities/attachments.rb +0 -35
  44. data/lib/jiraSOAP/entities/issue_properties.rb +0 -39
  45. data/lib/jiraSOAP/entities/read_only.rb +0 -120
  46. data/lib/jiraSOAP/entities/schemes.rb +0 -25
data/ChangeLog CHANGED
@@ -1,6 +1,28 @@
1
1
  Version 0.6
2
2
 
3
+ * Added RemoteAPI#get_projects_without_schemes
4
+ * Added RemoteAPI#delete_project_avatar_with_id
5
+ * Added RemoteAPI#delete_project_with_key
6
+ * Added RemoteAPI#set_project_avatar_for_project_with_key
7
+ * Added RemoteAPI#set_new_project_avatar_for_project_with_key
8
+ * Added RemoteAPI#get_resolution_date_for_issue_with_id
9
+ * Added RemoteAPI#get_resolution_date_for_issue_with_key
10
+ * Added RemoteAPI#get_project_roles and friends
11
+
12
+ * Changed parsing logic (1.5-2x faster)
3
13
  * Changed Scheme#type to return a Class constant
14
+ * Changed #color in JIRA::Priority to be formatted as an array
15
+ triple
16
+ * Alias #colour to #color in JIRA::Priority
17
+ * Changed instances of #lead to #lead_username
18
+ * Changed instances of #create_date to #create_time
19
+ * Changed instances of #last_updated to #last_updated_time
20
+ * Changed instances of #filename to #file_name
21
+ * Changed instances of #original_author to #author
22
+ * Changed instances of #reporter_name to #reporter_username
23
+ * Changed instances of #assignee_name to #assignee_username
24
+ * Consolidated Handsoap parsing extensions into NokogiriDriver
25
+ * Various documentation updates
4
26
 
5
27
  Version 0.5
6
28
 
data/README.markdown CHANGED
@@ -26,13 +26,17 @@ Pick up where `jira4r` left off:
26
26
  Getting Started
27
27
  ---------------
28
28
 
29
- `jiraSOAP` should run on Ruby 1.9.2 and MacRuby 0.8. You can install it using `gem`, or build from source:
29
+ `jiraSOAP` should run on Ruby 1.9.2 and MacRuby 0.8 or newer. It is available through rubygems or you can build from source:
30
30
 
31
+ # Using rubygems
32
+ sudo gem install jiraSOAP
33
+
34
+ # Building from source
31
35
  git clone git://github.com/Marketcircle/jiraSOAP.git
32
36
  rake build
33
37
  rake install
34
38
 
35
- Once that ugliness is over with, you can run a quick demo (making appropriate substitutions):
39
+ Once installed, you can run a quick demo (making appropriate substitutions):
36
40
 
37
41
  require 'jiraSOAP'
38
42
 
data/lib/jiraSOAP.rb CHANGED
@@ -1,16 +1,20 @@
1
1
  require 'logger'
2
2
  require 'time'
3
3
  require 'uri'
4
+ require 'nokogiri'
4
5
 
5
6
  require 'handsoap'
6
7
  Handsoap.http_driver = :net_http
7
8
 
8
9
  require 'jiraSOAP/url.rb'
9
10
  require 'jiraSOAP/handsoap_extensions.rb'
11
+
12
+ # All the remote entities as well as the SOAP service client.
13
+ module JIRA
14
+ end
15
+
10
16
  require 'jiraSOAP/entities.rb'
11
17
  require 'jiraSOAP/api.rb'
12
-
13
18
  require 'jiraSOAP/JIRAservice.rb'
14
19
 
15
- #overrides and additions
16
20
  require 'jiraSOAP/macruby_bonuses.rb' if RUBY_ENGINE == 'macruby'
@@ -1,21 +1,15 @@
1
- # All the remote entities as well as the SOAP service client.
2
- module JIRA
3
-
4
- # Interface to the JIRA endpoint server; set at initialization.
1
+ # @todo consider adding a finalizer that will try to logout
2
+ # @note HTTPS is not supported in this version.
3
+ # Interface to the JIRA endpoint server.
5
4
  #
6
5
  # Due to limitations in Handsoap::Service, there can only be one endpoint.
7
6
  # You can have multiple instances of that one endpoint if you would
8
7
  # like; but if you try to set a differnt endpoint for a new instance you
9
8
  # will end up messing up any other instances currently being used.
10
9
  #
11
- # It is best to treat this class as a singleton. There should only be one.
12
- # However, this is not enforced, in case you want to be able to login as
13
- # multiple users to the same endpoint.
14
- #
15
- # HTTPS is not supported in this version.
16
- #
17
- # @todo consider adding a finalizer that will try to logout
18
- class JIRAService < Handsoap::Service
10
+ # It is best to treat this class as a singleton, but it is not enforced
11
+ # in case you want to be able to login as multiple users to the same endpoint.
12
+ class JIRA::JIRAService < Handsoap::Service
19
13
  include RemoteAPI
20
14
 
21
15
  # @return [String]
@@ -24,47 +18,50 @@ class JIRAService < Handsoap::Service
24
18
  # @return [String]
25
19
  attr_reader :user
26
20
 
27
- # @return [String]
21
+ # @return [URL]
28
22
  attr_reader :endpoint_url
29
23
 
30
- # Factory method to initialize and login.
31
- # @param [String] url URL for the JIRA server
24
+ # Initialize and log in.
25
+ # @param [String,URL] url URL for the JIRA server
32
26
  # @param [String] user JIRA user name to login with
33
27
  # @param [String] password
34
28
  # @return [JIRA::JIRAService]
35
- def self.instance_with_endpoint(url, user, password)
36
- jira = JIRAService.new url
29
+ def self.instance_with_endpoint url, user, password
30
+ jira = JIRA::JIRAService.new url
37
31
  jira.login user, password
38
32
  jira
39
33
  end
40
34
 
41
- # Slightly hacky in order to set the endpoint at the initialization.
42
- # @param endpoint_url URL for the JIRA server
43
- def initialize(endpoint_url)
35
+ # @param [String,URL] endpoint_url for the JIRA server
36
+ def initialize endpoint_url
44
37
  @endpoint_url = endpoint_url
45
- endpoint_data = {
46
- :uri => "#{endpoint_url}/rpc/soap/jirasoapservice-v2",
47
- :version => 2
48
- }
49
- self.class.endpoint endpoint_data
38
+ JIRA::JIRAService.endpoint({
39
+ uri:"#{endpoint_url.to_s}/rpc/soap/jirasoapservice-v2",
40
+ version:2
41
+ })
50
42
  end
51
43
 
52
- # Something to help users out until the rest of the API is implemented.
44
+ # An extra note for users when things break.
45
+ # @deprecated This will be removed in v1.0 when the API is stable.
53
46
  # @return [nil]
54
- def method_missing(method, *args)
47
+ def method_missing method, *args
55
48
  message = "#{method} is not a valid method. Check the documentation; the "
56
- message << 'method may not be implemented or has changed in recent '
57
- message << 'revisions. The API has not been stabilized yet.'
49
+ message << 'API is not stabale yet and the method name likely changed.'
58
50
  STDERR.puts message
59
51
  super method, *args
60
52
  end
61
53
 
54
+
62
55
  protected
63
- def on_create_document(doc)
56
+
57
+ # Makes sure the correct namespace is set
58
+ def on_create_document doc
64
59
  doc.alias 'soap', 'http://soap.rpc.jira.atlassian.com'
65
60
  end
66
- def on_response_document(doc)
61
+
62
+ # Make sure that the required namespace is added
63
+ def on_response_document doc
67
64
  doc.add_namespace 'jir', @endpoint_url
68
65
  end
69
- end
66
+
70
67
  end
data/lib/jiraSOAP/api.rb CHANGED
@@ -1,16 +1,15 @@
1
- # Contains the API defined by Atlassian for the JIRA SOAP service. The JavaDoc
2
- # for the SOAP API is located at http://docs.atlassian.com/software/jira/docs/api/rpc-jira-plugin/latest/com/atlassian/jira/rpc/soap/JiraSoapService.html.
3
- # @todo exception handling
1
+ # Contains the API defined by Atlassian for the [JIRA SOAP service](http://docs.atlassian.com/software/jira/docs/api/rpc-jira-plugin/latest/com/atlassian/jira/rpc/soap/JiraSoapService.html).
2
+ #
3
+ # There are several cases where this API diverges from the one defined by
4
+ # Atlassian; most notably, this API tries to be more idomatically Ruby by using
5
+ # snake case for method names.
4
6
  # @todo logging
5
7
  # @todo code refactoring and de-duplication
6
- # @todo break the API down by task, like Apple's developer documentation
7
- # @todo deleteProjectAvatar [target v0.5]
8
- # @todo setProjectAvatar (change to different existing) [target v0.5]
9
- # @todo setNewProjectAvatar (upload new and set it) [target v0.5]
10
- # @todo createProjectRole [v0.6]
11
- # @todo getAvailableActions [target v0.7]
12
- # @todo progressWorkflowAction [target v0.7]
8
+ # @todo break the API down by task, like Apple's developer documentation;
9
+ # I can break the tasks down by CRUD or by what they affect, or both
10
+ # @todo progressWorkflowAction and friends [target v0.7]
13
11
  module RemoteAPI
12
+
14
13
  # XPath constant to get a node containing a response array.
15
14
  # This could be used for all responses, but is only used in cases where we
16
15
  # cannot use a more blunt XPath expression.
@@ -19,7 +18,7 @@ module RemoteAPI
19
18
  # The first method to call; other methods will fail until you are logged in.
20
19
  # @param [String] user JIRA user name to login with
21
20
  # @param [String] password
22
- # @return [boolean] true if successful, otherwise an exception is thrown
21
+ # @return [true]
23
22
  def login(user, password)
24
23
  response = invoke('soap:login') { |msg|
25
24
  msg.add 'soap:in0', user
@@ -33,7 +32,7 @@ module RemoteAPI
33
32
 
34
33
  # You only need to call this to make an explicit logout; normally, a session
35
34
  # will automatically expire after a set time (configured on the server).
36
- # @return [boolean] true if successful, otherwise false
35
+ # @return [true,false] true if successful, otherwise false
37
36
  def logout
38
37
  response = invoke('soap:logout') { |msg|
39
38
  msg.add 'soap:in0', @auth_token
@@ -47,7 +46,7 @@ module RemoteAPI
47
46
  msg.add 'soap:in0', @auth_token
48
47
  }
49
48
  response.document.xpath("#{RESPONSE_XPATH}/getPrioritiesReturn").map {
50
- |frag| JIRA::Priority.new_with_xml_fragment frag
49
+ |frag| JIRA::Priority.new_with_xml frag
51
50
  }
52
51
  end
53
52
 
@@ -57,7 +56,7 @@ module RemoteAPI
57
56
  msg.add 'soap:in0', @auth_token
58
57
  }
59
58
  response.document.xpath("#{RESPONSE_XPATH}/getResolutionsReturn").map {
60
- |frag| JIRA::Resolution.new_with_xml_fragment frag
59
+ |frag| JIRA::Resolution.new_with_xml frag
61
60
  }
62
61
  end
63
62
 
@@ -67,7 +66,7 @@ module RemoteAPI
67
66
  msg.add 'soap:in0', @auth_token
68
67
  }
69
68
  response.document.xpath("#{RESPONSE_XPATH}/getCustomFieldsReturn").map {
70
- |frag| JIRA::Field.new_with_xml_fragment frag
69
+ |frag| JIRA::Field.new_with_xml frag
71
70
  }
72
71
  end
73
72
 
@@ -77,7 +76,7 @@ module RemoteAPI
77
76
  msg.add 'soap:in0', @auth_token
78
77
  }
79
78
  response.document.xpath("#{RESPONSE_XPATH}/getIssueTypesReturn").map {
80
- |frag| JIRA::IssueType.new_with_xml_fragment frag
79
+ |frag| JIRA::IssueType.new_with_xml frag
81
80
  }
82
81
  end
83
82
 
@@ -87,7 +86,7 @@ module RemoteAPI
87
86
  msg.add 'soap:in0', @auth_token
88
87
  }
89
88
  response.document.xpath("#{RESPONSE_XPATH}/getStatusesReturn").map {
90
- |frag| JIRA::Status.new_with_xml_fragment frag
89
+ |frag| JIRA::Status.new_with_xml frag
91
90
  }
92
91
  end
93
92
 
@@ -97,7 +96,7 @@ module RemoteAPI
97
96
  msg.add 'soap:in0', @auth_token
98
97
  }
99
98
  response.document.xpath("#{RESPONSE_XPATH}/getNotificationSchemesReturn").map {
100
- |frag| JIRA::NotificationScheme.new_with_xml_fragment frag
99
+ |frag| JIRA::NotificationScheme.new_with_xml frag
101
100
  }
102
101
  end
103
102
 
@@ -109,7 +108,7 @@ module RemoteAPI
109
108
  msg.add 'soap:in1', project_key
110
109
  }
111
110
  response.document.xpath("#{RESPONSE_XPATH}/getVersionsReturn").map {
112
- |frag| JIRA::Version.new_with_xml_fragment frag
111
+ |frag| JIRA::Version.new_with_xml frag
113
112
  }
114
113
  end
115
114
 
@@ -123,7 +122,7 @@ module RemoteAPI
123
122
  msg.add 'soap:in0', @auth_token
124
123
  msg.add 'soap:in1', project_key
125
124
  }
126
- JIRA::Project.new_with_xml_fragment response.document.xpath('//getProjectByKeyReturn').first
125
+ JIRA::Project.new_with_xml response.document.xpath('//getProjectByKeyReturn').first
127
126
  end
128
127
 
129
128
  # @param [String] user_name
@@ -133,7 +132,7 @@ module RemoteAPI
133
132
  msg.add 'soap:in0', @auth_token
134
133
  msg.add 'soap:in1', user_name
135
134
  }
136
- JIRA::User.new_with_xml_fragment response.document.xpath('//getUserReturn').first
135
+ JIRA::User.new_with_xml response.document.xpath('//getUserReturn').first
137
136
  end
138
137
 
139
138
  # Gets you the default avatar image for a project; if you want all
@@ -145,13 +144,13 @@ module RemoteAPI
145
144
  msg.add 'soap:in0', @auth_token
146
145
  msg.add 'soap:in1', project_key
147
146
  }
148
- JIRA::Avatar.new_with_xml_fragment response.document.xpath('//getProjectAvatarReturn').first
147
+ JIRA::Avatar.new_with_xml response.document.xpath('//getProjectAvatarReturn').first
149
148
  end
150
149
 
151
150
  # Gets ALL avatars for a given project with this method; if you
152
151
  # just want the project avatar, use {#get_project_avatar_for_key}.
153
152
  # @param [String] project_key
154
- # @param [boolean] include_default_avatars
153
+ # @param [true,false] include_default_avatars
155
154
  # @return [[JIRA::Avatar]]
156
155
  def get_project_avatars_for_key(project_key, include_default_avatars = false)
157
156
  response = invoke('soap:getProjectAvatars') { |msg|
@@ -160,7 +159,7 @@ module RemoteAPI
160
159
  msg.add 'soap:in2', include_default_avatars
161
160
  }
162
161
  response.document.xpath("#{RESPONSE_XPATH}/getProjectAvatarsReturn").map {
163
- |frag| JIRA::Avatar.new_with_xml_fragment frag
162
+ |frag| JIRA::Avatar.new_with_xml frag
164
163
  }
165
164
  end
166
165
 
@@ -183,7 +182,7 @@ module RemoteAPI
183
182
  msg.add 'soap:in2', max_results
184
183
  }
185
184
  response.document.xpath("#{RESPONSE_XPATH}/getIssuesFromJqlSearchReturn").map {
186
- |frag| JIRA::Issue.new_with_xml_fragment frag
185
+ |frag| JIRA::Issue.new_with_xml frag
187
186
  }
188
187
  end
189
188
 
@@ -217,7 +216,7 @@ module RemoteAPI
217
216
  field_values.each { |fv| fv.soapify_for submsg }
218
217
  end
219
218
  }
220
- JIRA::Issue.new_with_xml_fragment response.document.xpath('//updateIssueReturn').first
219
+ JIRA::Issue.new_with_xml response.document.xpath('//updateIssueReturn').first
221
220
  end
222
221
 
223
222
  # Some fields will be ignored when an issue is created.
@@ -237,7 +236,7 @@ module RemoteAPI
237
236
  issue.soapify_for submsg
238
237
  end
239
238
  }
240
- JIRA::Issue.new_with_xml_fragment response.document.xpath('//createIssueReturn').first
239
+ JIRA::Issue.new_with_xml response.document.xpath('//createIssueReturn').first
241
240
  end
242
241
 
243
242
  # @param [String] issue_key
@@ -247,7 +246,7 @@ module RemoteAPI
247
246
  msg.add 'soap:in0', @auth_token
248
247
  msg.add 'soap:in1', issue_key
249
248
  }
250
- JIRA::Issue.new_with_xml_fragment response.document.xpath('//getIssueReturn').first
249
+ JIRA::Issue.new_with_xml response.document.xpath('//getIssueReturn').first
251
250
  end
252
251
 
253
252
  # @param [String] issue_id
@@ -257,7 +256,7 @@ module RemoteAPI
257
256
  msg.add 'soap:in0', @auth_token
258
257
  msg.add 'soap:in1', issue_id
259
258
  }
260
- JIRA::Issue.new_with_xml_fragment response.document.xpath('//getIssueByIdReturn').first
259
+ JIRA::Issue.new_with_xml response.document.xpath('//getIssueByIdReturn').first
261
260
  end
262
261
 
263
262
  # @param [String] issue_key
@@ -268,7 +267,7 @@ module RemoteAPI
268
267
  msg.add 'soap:in1', issue_key
269
268
  }
270
269
  response.document.xpath("#{RESPONSE_XPATH}/getAttachmentsFromIssueReturn").map {
271
- |frag| JIRA::AttachmentMetadata.new_with_xml_fragment frag
270
+ |frag| JIRA::AttachmentMetadata.new_with_xml frag
272
271
  }
273
272
  end
274
273
 
@@ -290,17 +289,17 @@ module RemoteAPI
290
289
  msg.add 'soap:in1', project_key
291
290
  msg.add 'soap:in2' do |submsg| version.soapify_for submsg end
292
291
  }
293
- JIRA::Version.new_with_xml_fragment response.document.xpath('//addVersionReturn').first
292
+ JIRA::Version.new_with_xml response.document.xpath('//addVersionReturn').first
294
293
  end
295
294
 
296
295
  # The archive state can only be set to true for versions that have not been
297
296
  # released. However, this is not reflected by the return value of this method.
298
297
  # @param [String] project_key
299
298
  # @param [String] version_name
300
- # @param [boolean] state
301
- # @return [boolean] true if successful, otherwise an exception is thrown
299
+ # @param [true,false] state
300
+ # @return [true]
302
301
  def set_archive_state_for_version_for_project(project_key, version_name, state)
303
- response = invoke('soap:archiveVersion') { |msg|
302
+ invoke('soap:archiveVersion') { |msg|
304
303
  msg.add 'soap:in0', @auth_token
305
304
  msg.add 'soap:in1', project_key
306
305
  msg.add 'soap:in2', version_name
@@ -320,15 +319,15 @@ module RemoteAPI
320
319
  msg.add 'soap:in0', @auth_token
321
320
  msg.add 'soap:in1' do |submsg| project.soapify_for submsg end
322
321
  }
323
- JIRA::Project.new_with_xml_fragment response.document.xpath('//createProjectFromObjectReturn').first
322
+ JIRA::Project.new_with_xml response.document.xpath('//createProjectFromObjectReturn').first
324
323
  end
325
324
 
326
325
  # You can set the release state for a project with this method.
327
326
  # @param [String] project_name
328
327
  # @param [JIRA::Version] version
329
- # @return [boolean] true, throws an exception otherwise
328
+ # @return [true]
330
329
  def release_state_for_version_for_project(project_name, version)
331
- response = invoke('soap:releaseVersion') { |msg|
330
+ invoke('soap:releaseVersion') { |msg|
332
331
  msg.add 'soap:in0', @auth_token
333
332
  msg.add 'soap:in1', project_name
334
333
  msg.add 'soap:in2' do |submsg| version.soapify_for submsg end
@@ -345,7 +344,7 @@ module RemoteAPI
345
344
  msg.add 'soap:in0', @auth_token
346
345
  msg.add 'soap:in1' do |submsg| project.soapify_for submsg end
347
346
  }
348
- JIRA::Project.new_with_xml_fragment response.document.xpath('//updateProjectReturn').first
347
+ JIRA::Project.new_with_xml response.document.xpath('//updateProjectReturn').first
349
348
  end
350
349
 
351
350
  # It seems that creating a user without any permission groups will trigger
@@ -366,13 +365,13 @@ module RemoteAPI
366
365
  msg.add 'soap:in3', full_name
367
366
  msg.add 'soap:in4', email
368
367
  }
369
- JIRA::User.new_with_xml_fragment response.document.xpath('//createUserReturn').first
368
+ JIRA::User.new_with_xml response.document.xpath('//createUserReturn').first
370
369
  end
371
370
 
372
371
  # @param [String] username
373
- # @return [boolean] true if successful, throws an exception otherwise
372
+ # @return [true]
374
373
  def delete_user_with_name(username)
375
- response = invoke('soap:deleteUser') { |msg|
374
+ invoke('soap:deleteUser') { |msg|
376
375
  msg.add 'soap:in0', @auth_token
377
376
  msg.add 'soap:in1', username
378
377
  }
@@ -386,7 +385,7 @@ module RemoteAPI
386
385
  msg.add 'soap:in0', @auth_token
387
386
  msg.add 'soap:in1', project_id
388
387
  }
389
- JIRA::Project.new_with_xml_fragment response.document.xpath('//getProjectByIdReturn').first
388
+ JIRA::Project.new_with_xml response.document.xpath('//getProjectByIdReturn').first
390
389
  end
391
390
 
392
391
  # @todo parse the permission scheme
@@ -398,14 +397,14 @@ module RemoteAPI
398
397
  msg.add 'soap:in0', @auth_token
399
398
  msg.add 'soap:in1', project_id
400
399
  }
401
- JIRA::Project.new_with_xml_fragment response.document.xpath('//getProjectWithSchemesByIdReturn').first
400
+ JIRA::Project.new_with_xml response.document.xpath('//getProjectWithSchemesByIdReturn').first
402
401
  end
403
402
 
404
403
  # @param [String] issue_key
405
404
  # @param [JIRA::Comment] comment
406
- # @return [boolean] true if successful, throws an exception otherwise
405
+ # @return [true]
407
406
  def add_comment_to_issue_with_key(issue_key, comment)
408
- response = invoke('soap:addComment') { |msg|
407
+ invoke('soap:addComment') { |msg|
409
408
  msg.add 'soap:in0', @auth_token
410
409
  msg.add 'soap:in1', issue_key
411
410
  msg.add 'soap:in2' do |submsg| comment.soapify_for submsg end
@@ -420,7 +419,7 @@ module RemoteAPI
420
419
  msg.add 'soap:in0', @auth_token
421
420
  msg.add 'soap:in1', id
422
421
  }
423
- JIRA::Comment.new_with_xml_fragment response.document.xpath('//getCommentReturn').first
422
+ JIRA::Comment.new_with_xml response.document.xpath('//getCommentReturn').first
424
423
  end
425
424
 
426
425
  # @param [String] issue_key
@@ -431,7 +430,7 @@ module RemoteAPI
431
430
  msg.add 'soap:in1', issue_key
432
431
  }
433
432
  response.document.xpath("#{RESPONSE_XPATH}/getCommentsReturn").map {
434
- |frag| JIRA::Comment.new_with_xml_fragment frag
433
+ |frag| JIRA::Comment.new_with_xml frag
435
434
  }
436
435
  end
437
436
 
@@ -443,7 +442,7 @@ module RemoteAPI
443
442
  msg.add 'soap:in1', project_id
444
443
  }
445
444
  response.document.xpath("#{RESPONSE_XPATH}/getIssueTypesForProjectReturn").map {
446
- |frag| JIRA::IssueType.new_with_xml_fragment frag
445
+ |frag| JIRA::IssueType.new_with_xml frag
447
446
  }
448
447
  end
449
448
 
@@ -455,7 +454,7 @@ module RemoteAPI
455
454
  msg.add 'soap:in1' do |submsg| comment.soapify_for submsg end
456
455
  }
457
456
  frag = response.document.xpath('//editCommentReturn').first
458
- JIRA::Comment.new_with_xml_fragment frag
457
+ JIRA::Comment.new_with_xml frag
459
458
  end
460
459
 
461
460
  # @return [[JIRA::IssueType]]
@@ -464,7 +463,7 @@ module RemoteAPI
464
463
  msg.add 'soap:in0', @auth_token
465
464
  }
466
465
  response.document.xpath("#{RESPONSE_XPATH}/getSubTaskIssueTypesReturn").map {
467
- |frag| JIRA::IssueType.new_with_xml_fragment frag
466
+ |frag| JIRA::IssueType.new_with_xml frag
468
467
  }
469
468
  end
470
469
 
@@ -476,15 +475,15 @@ module RemoteAPI
476
475
  msg.add 'soap:in1', project_id
477
476
  }
478
477
  response.document.xpath("#{RESPONSE_XPATH}/getSubtaskIssueTypesForProjectReturn").map {
479
- |frag| JIRA::IssueType.new_with_xml_fragment frag
478
+ |frag| JIRA::IssueType.new_with_xml frag
480
479
  }
481
480
  end
482
481
 
483
482
  # I have no idea what this method does.
484
483
  # @todo find out what this method does
485
- # @return [boolean] true if successful, throws an exception otherwise
484
+ # @return [true]
486
485
  def refresh_custom_fields
487
- response = invoke('soap:refreshCustomFields') { |msg|
486
+ invoke('soap:refreshCustomFields') { |msg|
488
487
  msg.add 'soap:in0', @auth_token
489
488
  }
490
489
  true
@@ -497,7 +496,7 @@ module RemoteAPI
497
496
  msg.add 'soap:in0', @auth_token
498
497
  }
499
498
  response.document.xpath("#{RESPONSE_XPATH}/getFavouriteFiltersReturn").map {
500
- |frag| JIRA::Filter.new_with_xml_fragment frag
499
+ |frag| JIRA::Filter.new_with_xml frag
501
500
  }
502
501
  end
503
502
 
@@ -513,7 +512,7 @@ module RemoteAPI
513
512
  msg.add 'soap:in3', max_results
514
513
  }
515
514
  response.document.xpath("#{RESPONSE_XPATH}/getIssuesFromFilterWithLimitReturn").map {
516
- |frag| JIRA::Issue.new_with_xml_fragment frag
515
+ |frag| JIRA::Issue.new_with_xml frag
517
516
  }
518
517
  end
519
518
 
@@ -532,9 +531,9 @@ module RemoteAPI
532
531
  # @param [String] issue_key
533
532
  # @param [[String]] filenames names to put on the files
534
533
  # @param [[String]] data base64 encoded data
535
- # @return [boolean] true if successful, otherwise an exception is thrown
534
+ # @return [true]
536
535
  def add_base64_encoded_attachments_to_issue_with_key(issue_key, filenames, data)
537
- response = invoke('soap:addBase64EncodedAttachmentsToIssue') { |msg|
536
+ invoke('soap:addBase64EncodedAttachmentsToIssue') { |msg|
538
537
  msg.add 'soap:in0', @auth_token
539
538
  msg.add 'soap:in1', issue_key
540
539
  msg.add 'soap:in2' do |submsg|
@@ -553,7 +552,7 @@ module RemoteAPI
553
552
  response = invoke('soap:getServerInfo') { |msg|
554
553
  msg.add 'soap:in0', @auth_token
555
554
  }
556
- JIRA::ServerInfo.new_with_xml_fragment response.document.xpath('//getServerInfoReturn').first
555
+ JIRA::ServerInfo.new_with_xml response.document.xpath('//getServerInfoReturn').first
557
556
  end
558
557
 
559
558
  # @return [JIRA::ServerConfiguration]
@@ -561,6 +560,168 @@ module RemoteAPI
561
560
  response = invoke('soap:getConfiguration') { |msg|
562
561
  msg.add 'soap:in0', @auth_token
563
562
  }
564
- JIRA::ServerConfiguration.new_with_xml_fragment response.document.xpath('//getConfigurationReturn').first
563
+ JIRA::ServerConfiguration.new_with_xml response.document.xpath('//getConfigurationReturn').first
564
+ end
565
+
566
+ # @note This will not fill in JIRA::Scheme data for the projects.
567
+ # @return [[JIRA::Project]]
568
+ def get_projects_without_schemes
569
+ response = invoke('soap:getProjectsNoSchemes') { |msg|
570
+ msg.add 'soap:in0', @auth_token
571
+ }
572
+ response.document.xpath("#{RESPONSE_XPATH}/getProjectsNoSchemesReturn").map {
573
+ |frag| JIRA::Project.new_with_xml frag
574
+ }
575
+ end
576
+
577
+ # @param [#to_s] issue_id
578
+ # @return [Time]
579
+ def get_resolution_date_for_issue_with_id issue_id
580
+ response = invoke('soap:getResolutionDateById') { |msg|
581
+ msg.add 'soap:in0', @auth_token
582
+ msg.add 'soap:in1', issue_id
583
+ }
584
+ response.document.xpath('//getResolutionDateByIdReturn').to_date
585
+ end
586
+
587
+ # @param [String] issue_key
588
+ # @return [Time]
589
+ def get_resolution_date_for_issue_with_key issue_key
590
+ response = invoke('soap:getResolutionDateByKey') { |msg|
591
+ msg.add 'soap:in0', @auth_token
592
+ msg.add 'soap:in1', issue_key
593
+ }
594
+ response.document.xpath('//getResolutionDateByKeyReturn').to_date
595
+ end
596
+
597
+ # @param [String] project_key
598
+ # @return [true]
599
+ def delete_project_with_key project_key
600
+ invoke('soap:deleteProject') { |msg|
601
+ msg.add 'soap:in0', @auth_token
602
+ msg.add 'soap:in1', project_key
603
+ }
604
+ true
605
+ end
606
+
607
+ # @todo add tests for this method
608
+ # @note You cannot delete the system avatar
609
+ # @note You need project administration permissions to delete an avatar
610
+ # @param [#to_s] avatar_id
611
+ # @return [true]
612
+ def delete_project_avatar_with_id avatar_id
613
+ invoke('soap:deleteProjectAvatar') { |msg|
614
+ msg.add 'soap:in0', @auth_token
615
+ msg.add 'soap:in1', avatar_id
616
+ }
617
+ true
618
+ end
619
+
620
+ # @note You need project administration permissions to edit an avatar
621
+ # @note JIRA does not care if the avatar_id is valid
622
+ # Change the project avatar to another existing avatar. If you want to
623
+ # upload a new avatar and set it to be the new project avatar use
624
+ # {#set_new_project_avatar} instead.
625
+ # @return [true]
626
+ def set_project_avatar_for_project_with_key project_key, avatar_id
627
+ invoke('soap:setProjectAvatar') { |msg|
628
+ msg.add 'soap:in0', @auth_token
629
+ msg.add 'soap:in1', project_key
630
+ msg.add 'soap:in2', avatar_id
631
+ }
632
+ true
633
+ end
634
+
635
+ # @note You need project administration permissions to edit an avatar
636
+ # Use this method to create a new custom avatar for a project and set it
637
+ # to be current avatar for the project.
638
+ #
639
+ # The image, provided as base64 encoded data, should be a 48x48 pixel square.
640
+ # If the image is larger, the top left 48 pixels are taken, if it is smaller
641
+ # then it will be upscaled to 48 pixels.
642
+ # The small version of the avatar image (16 pixels) is generated
643
+ # automatically.
644
+ # If you want to switch a project avatar to an avatar that already exists on
645
+ # the system then use {#set_project_avatar_for_project_with_key} instead.
646
+ # @param [String] project_key
647
+ # @param [String] mime_type
648
+ # @param [#to_s] base64_image
649
+ # @return [true]
650
+ def set_new_project_avatar_for_project_with_key project_key, mime_type, base64_image
651
+ invoke('soap:setNewProjectAvatar') { |msg|
652
+ msg.add 'soap:in0', @auth_token
653
+ msg.add 'soap:in1', project_key
654
+ msg.add 'soap:in2', mime_type
655
+ msg.add 'soap:in3', base64_image
656
+ }
657
+ true
658
+ end
659
+
660
+ # @return [[JIRA::ProjectRole]]
661
+ def get_project_roles
662
+ response = invoke('soap:getProjectRoles') { |msg|
663
+ msg.add 'soap:in0', @auth_token
664
+ }
665
+ response.document.xpath("#{RESPONSE_XPATH}/getProjectRolesReturn").map {
666
+ |frag| JIRA::ProjectRole.new_with_xml frag
667
+ }
565
668
  end
669
+
670
+ # @param [#to_s] role_id
671
+ # @return [JIRA::ProjectRole]
672
+ def get_project_role_with_id role_id
673
+ response = invoke('soap:getProjectRole') { |msg|
674
+ msg.add 'soap:in0', @auth_token
675
+ msg.add 'soap:in1', role_id
676
+ }
677
+ JIRA::ProjectRole.new_with_xml response.document.xpath('//getProjectRoleReturn').first
678
+ end
679
+
680
+ # @param [JIRA::ProjectRole] project_role
681
+ # @return [JIRA::ProjectRole] the role that was created
682
+ def create_project_role_with_role project_role
683
+ response = invoke('soap:createProjectRole') { |msg|
684
+ msg.add 'soap:in0', @auth_token
685
+ msg.add 'soap:in1' do |submsg| project_role.soapify_for submsg end
686
+ }
687
+ JIRA::ProjectRole.new_with_xml response.document.xpath('//createProjectRoleReturn').first
688
+ end
689
+
690
+ # @note JIRA 4.0 returns an exception if the name already exists
691
+ # Returns true if the name does not exist.
692
+ # @param [String] project_role_name
693
+ # @return [true,false]
694
+ def project_role_name_unique? project_role_name
695
+ response = invoke('soap:isProjectRoleNameUnique') { |msg|
696
+ msg.add 'soap:in0', @auth_token
697
+ msg.add 'soap:in1', project_role_name
698
+ }
699
+ response.document.xpath('//isProjectRoleNameUniqueReturn').to_boolean
700
+ end
701
+
702
+ # @note the confirm argument appears to do nothing (at least on JIRA 4.0)
703
+ # @param [JIRA::ProjectRole] project_role
704
+ # @param [true,false] confirm
705
+ # @return [true]
706
+ def delete_project_role project_role, confirm = true
707
+ invoke('soap:deleteProjectRole') { |msg|
708
+ msg.add 'soap:in0', @auth_token
709
+ msg.add 'soap:in1' do |submsg| project_role.soapify_for submsg end
710
+ msg.add 'soap:in2', confirm
711
+ }
712
+ true
713
+ end
714
+
715
+ # @note JIRA 4.0 will not update project roles, it will instead throw
716
+ # an exception telling you that the project role already exists
717
+ # @param [JIRA::ProjectRole] project_role
718
+ # @return [JIRA::ProjectRole] the role after the update
719
+ def update_project_role_with_role project_role
720
+ response = invoke('soap:updateProjectRole') { |msg|
721
+ msg.add 'soap:in0', @auth_token
722
+ msg.add 'soap:in1' do |submsg| project_role.soapify_for submsg end
723
+ }
724
+ JIRA::ProjectRole.new_with_xml response.document.xpath('//updateProjectRoleReturn').first
725
+ end
726
+
566
727
  end