jirarest2 0.0.11 → 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig CHANGED
Binary file
data/History.txt CHANGED
@@ -1,3 +1,15 @@
1
+ === 0.0.12 / 2012-08-07
2
+
3
+ * 1 major enhancement:
4
+
5
+ * Renamed Issue to NewIssue
6
+
7
+ * 2 minor enhancements:
8
+
9
+ * Added feature to see if we are really authenticated. Had to change credentials around a bit for that. Hoperfully fixes #23
10
+ * Added new Issue class to work with the issues themselves. Doesn't work and needs a lot of work yet.
11
+
12
+
1
13
  === 0.0.11 / 2012-08-05
2
14
 
3
15
  * 1 major enhancements:
data/Manifest.txt CHANGED
@@ -16,6 +16,7 @@ lib/jirarest2/credentials.rb
16
16
  lib/jirarest2/exceptions.rb
17
17
  lib/jirarest2/issue.rb
18
18
  lib/jirarest2/madbitconfig.rb
19
+ lib/jirarest2/newissue.rb
19
20
  lib/jirarest2/password_credentials.rb
20
21
  lib/jirarest2/result.rb
21
22
  lib/jirarest2/services.rb
@@ -40,6 +41,7 @@ test/test_issue.rb
40
41
  test/test_issuelink.rb
41
42
  test/test_issuelinktype.rb
42
43
  test/test_madbitconfig.rb
44
+ test/test_newissue.rb
43
45
  test/test_password_credentials.rb
44
46
  test/test_result.rb
45
47
  test/test_watcher.rb
data/README.txt CHANGED
@@ -16,7 +16,6 @@ There are scripts to create new issues with watchers and link those to existing
16
16
 
17
17
  *Ruby1.9.1 is needed. Ruby1.8 doesn't work!*
18
18
 
19
-
20
19
  == FEATURES/PROBLEMS:
21
20
 
22
21
  * Still in the alpha stages. The classes are still pretty volatile.
data/lib/jirarest2.rb CHANGED
@@ -17,10 +17,12 @@
17
17
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
18
  #
19
19
 
20
- VERSION = "0.0.11"
20
+ VERSION = "0.0.12"
21
+ Version = VERSION
21
22
 
22
23
  require_relative "jirarest2/connect"
23
24
  require_relative "jirarest2/issue"
25
+ require_relative "jirarest2/newissue"
24
26
  require_relative "jirarest2/credentials"
25
27
  require_relative "jirarest2/password_credentials"
26
28
  require_relative "jirarest2/cookie_credentials"
@@ -43,7 +43,14 @@ class Connect
43
43
  # @return [Jirarest2::Result]
44
44
  def execute(operation,uritail,data)
45
45
  uri = nil
46
- uri = URI(@credentials.connecturl+uritail)
46
+ if (uritail == "auth/latest/session" ) then # this is the exception regarding the base path
47
+ uristring = @credentials.baseurl+uritail
48
+ else
49
+ uristring = @credentials.connecturl+uritail
50
+ end
51
+
52
+ uristring.gsub!(/\/\//,"/").gsub!(/^(http[s]*:)/,'\1/')
53
+ uri = URI(uristring)
47
54
  if data != "" then
48
55
  if ! (operation == "Post" || operation == "Put") then # POST carries the payload in the body that's why we have to wait
49
56
  uri.query = URI.encode_www_form(data)
@@ -64,12 +71,15 @@ class Connect
64
71
  end
65
72
  end
66
73
 
67
-
68
74
  # Ask the server
69
75
  result = Net::HTTP.start(uri.host, uri.port) {|http|
70
76
  http.request(req)
71
77
  }
72
78
  # deal with output
79
+
80
+ if ((result["x-ausername"] != @credentials.username) && (uritail != "auth/latest/session" )) then # this is not the right authentication
81
+ verify_auth # make sure
82
+ end
73
83
  case result
74
84
  when Net::HTTPBadRequest # 400
75
85
  raise Jirarest2::BadRequestError, result.body
@@ -82,14 +92,15 @@ class Connect
82
92
  raise Jirarest2::AuthenticationError, result.body
83
93
  end
84
94
  when Net::HTTPForbidden # 403
85
- if result.get_fields("x-authentication-denied-reason")[0] =~ /.*login-url=(.*)/ then #Captcha-Time
86
- raise Jirarest2::AuthenticationCaptchaError, $1
95
+ if result.get_fields("x-authentication-denied-reason") && result.get_fields("x-authentication-denied-reason")[0] =~ /.*login-url=(.*)/ then #Captcha-Time
96
+ raise Jirarest2::AuthentificationCaptchaError, $1
87
97
  else
88
98
  raise Jirarest2::ForbiddenError, result.body
89
99
  end
90
100
  when Net::HTTPNotFound # 404
91
101
  raise Jirarest2::NotFoundError, result.body
92
-
102
+ when Net::HTTPMethodNotAllowed # 405
103
+ raise Jirarest2::MethodNotAllowedError, result.body
93
104
  end
94
105
  ret = Jirarest2::Result.new(result)
95
106
  @credentials.bake_cookies(ret.header["set.cookie"]) if @credentials.instance_of?(CookieCredentials) # Make sure cookies are always up to date if we use them.
@@ -116,7 +127,7 @@ class Connect
116
127
  def heal_uri(url = @credentials.connecturl)
117
128
  splitURI = URI.split(url) # [Scheme,Userinfo,Host,Port,Registry,Path,Opaque,Query,Fragment]
118
129
  splitURI[5].gsub!(/^(.*)2$/,'\12/')
119
- splitURI[5].gsub!(/\/+/,'/') # get rid of duplicate /
130
+ splitURI[5].gsub!(/[\/]+/,'/') # get rid of duplicate /
120
131
  splitURI[5].gsub!(/(rest\/api\/2\/)+/,'\1') # duplicate path to rest
121
132
  splitURI[5].gsub!(/^(.*)\/login.jsp(\/rest\/api\/2\/)$/,'\1\2') # dedicated login page
122
133
  splitURI[5].gsub!(/^(.*)\/secure\/Dashboard.jspa(\/rest\/api\/2\/)$/,'\1\2') # copied the dashboard URL (or the login Page)
@@ -142,6 +153,15 @@ class Connect
142
153
  end
143
154
  end
144
155
 
156
+ # Verify that we are authenticated
157
+ # @return [Boolean] true if the authentication seems to be valid (actually it checks if there is a session)
158
+ def verify_auth
159
+ ret = execute("Get","auth/latest/session","")
160
+ store_cookiejar if @credentials.instance_of?(CookieCredentials) && @credentials.autosave
161
+ return ret.code == "200"
162
+ end
163
+
164
+
145
165
  end # class
146
166
 
147
167
  =begin
@@ -29,8 +29,8 @@ class CookieCredentials < Credentials
29
29
 
30
30
  # @param [String] url URL to JIRA(tm) instance
31
31
  # @param [Boolean] autosave Save the cookie on the harddisk whenever something happens?
32
- def initialize(connecturl, autosave = false )
33
- super(connecturl)
32
+ def initialize(connecturl, username, autosave = false )
33
+ super(connecturl,username)
34
34
  @cookiejar = {}
35
35
  @autosave = autosave
36
36
  @cookiestore = "~/.jirarest2.cookie"
@@ -80,29 +80,20 @@ class CookieCredentials < Credentials
80
80
  # @param [String] username Username to use for login
81
81
  # @param [String] password Password to use for login
82
82
  def login(username,password)
83
- pconnecturl = @connecturl.gsub(/\/*rest\/api\/.+/,"/rest/") # Unfortunately the session information is not in the same tree as all the other rest calls
84
- pcred = PasswordCredentials.new(pconnecturl,username,password)
83
+ pcred = PasswordCredentials.new(@connecturl,username,password)
85
84
  pconnect = Connect.new(pcred)
86
85
  result = pconnect.execute("Post","auth/latest/session",{"username" => username, "password" => password})
87
- bake_cookies(result.header["set-cookie"]) # I already had them seperated into an Array.
86
+ bake_cookies(result.header["set-cookie"]) # I already had them seperated into an array.
88
87
  return @cookiejar["JSESSIONID"]
89
88
  end
90
89
 
91
90
  # Invalidates the current cookie
92
91
  # @return [Boolean] true if successful
93
92
  def logout
94
- originalConnectUrl = @connecturl
95
- begin
96
- @connecturl = @connecturl.gsub(/rest\/api\/.+/,"rest/") # Unfortunately the session information is not in the same tree as all the other rest calls
97
93
  con = Connect.new(self)
98
94
  ret = con.execute("Delete","auth/latest/session","").code
99
95
  store_cookiejar if @autosave
100
96
  return true if ret == "204"
101
- rescue
102
- raise
103
- ensure
104
- @connecturl = originalConnectUrl
105
- end
106
97
  end
107
98
 
108
99
  # Loads a cookiejar from disk
@@ -23,13 +23,18 @@ class Credentials
23
23
 
24
24
  # url to connect to the JIRA(tm) instance
25
25
  attr_reader :connecturl
26
-
26
+ # username to use
27
+ attr_accessor :username
28
+ # basepath for the REST methods
29
+ attr_reader :baseurl
27
30
 
28
31
  # @param [String] url URL to JIRA(tm) instance
29
- def initialize(url)
32
+ def initialize(url,username)
30
33
  uri = URI(url)
31
34
  if uri.instance_of?(URI::HTTP) || uri.instance_of?(URI::HTTPS) then
32
35
  @connecturl = url
36
+ @username = username
37
+ @baseurl = @connecturl.gsub(/rest\/api\/.+/,"rest/")
33
38
  else
34
39
  raise Jirarest2::NotAnURLError
35
40
  end
@@ -45,7 +50,7 @@ class Credentials
45
50
  raise Jirarest2::NotAnURLError
46
51
  end
47
52
  end
48
-
53
+
49
54
  # Get the auth header to send to the server
50
55
  # @param [Net:::HTTP::Post,Net:::HTTP::Put,Net:::HTTP::Get,Net:::HTTP::Delete] request Request object
51
56
  def get_auth_header(request)
@@ -33,6 +33,8 @@ module Jirarest2
33
33
  class ForbiddenError < StandardError ; end
34
34
  # 404 - Results in HTML body - not JSON
35
35
  class NotFoundError < StandardError ; end
36
+ # 405 - Method not allowed
37
+ class MethodNotAllowedError < StandardError ; end
36
38
  # Could not heal URI
37
39
  class CouldNotHealURIError < StandardError ; end
38
40
 
@@ -1,4 +1,3 @@
1
- # class to handle new issues (building them up, changing fields, persistence)
2
1
  # Copyright (C) 2012 Cyril Bitterich
3
2
  #
4
3
  # This program is free software: you can redistribute it and/or modify
@@ -15,233 +14,52 @@
15
14
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
15
  #
17
16
 
18
- =begin
19
- # An Issue object contains all the data of an issue
20
- =end
17
+ require "jirarest2/connect"
18
+
19
+ # represent an issue
21
20
  class Issue
22
-
23
- # issue type of the issue
24
- attr_reader :issuetype
25
- # project the issue belongs to
26
- attr_reader :project
27
- # The issue numer if we got it somehow
28
- attr_reader :issuekey
29
-
30
- # @param [String] project Key of the JIRA(tm) project the issue belongs to
31
- # @param [String] type Issuetype the issue belongs to
32
- # @param [Connection] connection
33
- def initialize (project,type,connection)
34
- query = {:projectKeys => project, :issuetypeNames => type, :expand => "projects.issuetypes.fields" }
35
- answer = connection.execute("Get","issue/createmeta/",query)
36
- jhash = answer.result
37
- parse_json(jhash)
38
- raise Jirarest2::WrongProjectException, project if @project == ""
39
- raise Jirarest2::WrongIssuetypeException, type if @issuetype == ""
40
- end
21
+ #Person the issue is assigned to
22
+ attr_reader :assignee
41
23
 
42
- # produces an instance-variable @issuefields that can be
43
- # @param [Hash] jhash Hashed version of the json-snippet JIRA(tm) returns
44
- def parse_json (jhash)
45
- @issuefields = Hash.new
46
- @project = ""
47
- @issuetype = ""
48
- jhash["projects"].each { |value|
49
- @project = value["key"]
50
- value["issuetypes"].each { |value1|
51
- @issuetype = value1["name"]
52
- value1["fields"].delete("project") #The project key is duplicate and will make our live harder afterwards. It is marked as required but nothing happens if this key is not set.
53
- value1["fields"].each { |key,value2|
54
- fields = Hash.new
55
- fields["id"] = key
56
- if value2["name"] then
57
- name = value2["name"]
58
- else
59
- name = key
60
- end
61
- # If the allowed reponses are limited we want to know them.
62
- if value2["allowedValues"] then
63
- # With custom fields the identifier is "value" with the built in ones it's "name"
64
- identifier = "name"
65
- if value2["schema"]["custom"] then
66
- identifier = "value"
67
- end
68
- allowedValues = Array.new
69
- value2["allowedValues"].each { |value3|
70
- allowedValues << value3[identifier]
71
- } # value3
72
- fields["allowedValuesIdentifier"] = identifier
73
- fields["allowedValues"] = allowedValues
74
- end
75
- fields["required"] = value2["required"]
76
- fields["type"] = value2["schema"]["type"]
77
- @issuefields[name] = fields if name != "Issue Type" # "Issue Type" is not really a required field as we have to assign it at another place anyway
78
- } # value1
79
- } # value
80
- } # jhash
24
+ # @param [String] issueid Key or ID of the issue
25
+ def initialize(issueid)
26
+ @issueid = issueid
81
27
  end
82
28
 
83
- # @param [String] field Name of the field
84
- # @return [String] type of the Field
85
- def fieldtype(field)
86
- # If the fieldname is wrong we want to tell this and stop execution (or maybe let the caller fix it)
87
- if @issuefields[field].nil? then
88
- raise Jirarest2::WrongFieldnameException, field
89
- else
90
- return @issuefields[field]["type"]
91
- end
92
- end
93
-
94
- # @return [Array] Names of required fields
95
- def get_requireds
96
- names = Array.new
97
- @issuefields.each {|key,value|
98
- if value["required"] then
99
- names << key
100
- end
101
- }
102
- return names
103
- end
104
-
105
- # @return [Array] Names of all fields
106
- def get_fieldnames
107
- names = Array.new
108
- @issuefields.each {|key,value|
109
- names << key
110
- }
111
- return names
112
- end
113
-
114
- # @param [String] name Name of a field
115
- # @return [String] id of the field
116
- protected
117
- def get_id(name)
118
- return @issuefields["name"]["id"]
119
- end
120
-
121
- =begin
122
- # query=
123
- # {"fields"=>
124
- # { "project"=>{"key"=>"MFTP"},
125
- # "environment"=>"REST ye merry gentlemen.",
126
- # "My own text"=>"Creating of an issue using project keys and issue type names using the REST API",
127
- # "issuetype"=> {"name"=>"My own type"}
128
- # }
129
- # }
130
- =end
131
-
132
- # @return [Hash] Hash to be sent to JIRA(tm) in a JSON representation
133
- public
134
- def jirahash
135
- h = Hash.new
136
- issuetype = {"issuetype" => {"name" => @issuetype}}
137
- project = {"key" => @project}
138
- fields = Hash.new
139
- fields["project"] = project
140
- # here we need to enter the relevant fields and their values
141
- @issuefields.each { |key,value|
142
- if key != "project" then
143
- id = value["id"]
144
- if ! value["value"].nil? then
145
- fields[id] = value["value"]
146
- end
147
- end
148
- }
149
- fields = fields.merge!(issuetype)
150
- h = {"fields" => fields}
151
- return h
152
- end
153
-
154
- # check if the value is allowed for this field
155
- # @param [String] key Name of the field
156
- # @param [String] value Value to be checked
157
- # @return [Boolean, Jirarest2::ValueNotAllowedException]
158
- protected
159
- def value_allowed?(key,value)
160
- if @issuefields[key]["allowedValues"].include?(value)
161
- return true
162
- else
163
- # puts "Value #{value} not allowed for field #{key}."
164
- raise Jirarest2::ValueNotAllowedException.new(key, @issuefields[key]["allowedValues"]), value
165
- end
29
+ # Receive an issue and all it's fields from jira
30
+ # @param [Connection] connection
31
+ def receive(connection)
32
+ uritail = "issue/#{@issueid}"
33
+ result = connection.execute("Get",uritail,{"expand" => "metadata"}) # get the issue AND the metadata because we already know how to parse that.
34
+ # TODO Many and more fields
166
35
  end
167
36
 
168
-
169
- # Special setter for fields that have a limited numer of allowed values.
170
- #
171
- # This setter might be included in set_field at a later date.
172
- # @param [String] key Name of the field
173
- # @param [String] value Value to be checked
174
- def set_allowed_value(key,value)
175
- if @issuefields[key]["type"] == "array" && value.instance_of?(Array) then
176
- array = Array.new
177
- value.each {|item|
178
- if value_allowed?(key,item) then
179
- array << {@issuefields[key]["allowedValuesIdentifier"] => item}
180
- end
181
- }
182
- @issuefields[key]["value"] = array
37
+ # Set an assignee to an issue
38
+ # @param [Connection] connection
39
+ # @param [String] name Username of the new Assignee, Defaultassignee if "-1" is given
40
+ # @param [Nil] name Deletes Assignee
41
+ # @return [Boolean] true if successfull, false if not
42
+ def set_assignee(connection, name)
43
+ uritail = "issue/#{@issueid}/assignee"
44
+ if ! name.nil? then
45
+ setname = {"name" => name}
183
46
  else
184
- if value_allowed?(key,value) then
185
- @issuefields[key]["value"] = {@issuefields[key]["allowedValuesIdentifier"] => value}
186
- end
47
+ setname = nil
187
48
  end
188
- end
189
-
190
-
191
- # TODO We are not yet able to work with "Cascading Select" fields ( "custom": "com.atlassian.jira.plugin.system.customfieldtypes:cascadingselect")
192
- # @param [String] key Name of the field
193
- # @param [String] value Value the field should be set to, this is either a String or an Array (don't know if numbers work too)
194
- public
195
- def set_field(key, value)
196
- if @issuefields.include?(key) then
197
- if @issuefields[key].include?("allowedValues") then
198
- set_allowed_value(key,value)
199
- else
200
- @issuefields[key]["value"] = value
201
- end
49
+ retcode = connection.execute("Put",uritail,setname).code
50
+ if retcode == "204" then
51
+ @assignee = name
52
+ return true
202
53
  else
203
- raise Jirarest2::WrongFieldnameException, key
204
- puts "Unknown Field: #{key}"
54
+ return false
205
55
  end
206
56
  end
207
57
 
208
- # @param [String] field Name of the field
209
- # @return [String] value of the field
210
- def get_field(field)
211
- @issuefields[field]["value"]
212
- end
213
-
214
- # persitence of this Issue object instance
58
+ # Deletes an assignee. It actually only calls set_assignee with name = nil .
215
59
  # @param [Connection] connection
216
- # @return [Jirarest2::Result]
217
- def persist(connection)
218
- get_requireds.each { |fieldname|
219
- if @issuefields[fieldname]["value"].nil? then
220
- raise Jirarest2::RequiredFieldNotSetException, fieldname
221
- end
222
- }
223
- hash = jirahash
224
- ret = connection.execute("Post","issue/",hash)
225
- if ret.code == "201" then # Ticket sucessfully created
226
- @issuekey = ret.result["key"]
227
- end
228
- return ret
60
+ def remove_assignee(connection)
61
+ set_assignee(connection, nil)
229
62
  end
230
63
 
231
64
 
232
-
233
- # Set the watchers for this Ticket
234
- # @param [Connection] connection
235
- # @param [Array] watchers Watchers to be added
236
- # @return [Boolean] True if successful for all
237
- def add_watchers(connection,watchers)
238
- success = false # Return whether we were successful with the watchers
239
- watch = Watcher.new(connection,@issuekey)
240
- watchers.each { |person|
241
- success = watch.add_watcher(person)
242
- }
243
- return success
244
- end
245
-
246
-
247
- end # class
65
+ end # Issue
@@ -74,9 +74,7 @@ require "json"
74
74
  end
75
75
  }
76
76
  end # JSON or not?
77
-
78
77
  return vars
79
- STDIN.reopen if config_file == "-" #TODO See if this really does what it is supposed to do
80
78
  end # read.configfile
81
79
 
82
80
 
@@ -0,0 +1,247 @@
1
+ # class to handle new issues (building them up, changing fields, persistence)
2
+ # Copyright (C) 2012 Cyril Bitterich
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ #
17
+
18
+ =begin
19
+ # An Issue object contains all the data of an issue
20
+ =end
21
+ class NewIssue
22
+
23
+ # issue type of the issue
24
+ attr_reader :issuetype
25
+ # project the issue belongs to
26
+ attr_reader :project
27
+ # The issue numer if we got it somehow
28
+ attr_reader :issuekey
29
+
30
+ # @param [String] project Key of the JIRA(tm) project the issue belongs to
31
+ # @param [String] type Issuetype the issue belongs to
32
+ # @param [Connection] connection
33
+ def initialize (project,type,connection)
34
+ query = {:projectKeys => project, :issuetypeNames => type, :expand => "projects.issuetypes.fields" }
35
+ answer = connection.execute("Get","issue/createmeta/",query)
36
+ jhash = answer.result
37
+ parse_json(jhash)
38
+ raise Jirarest2::WrongProjectException, project if @project == ""
39
+ raise Jirarest2::WrongIssuetypeException, type if @issuetype == ""
40
+ end
41
+
42
+ # produces an instance-variable @issuefields that can be
43
+ # @param [Hash] jhash Hashed version of the json-snippet JIRA(tm) returns
44
+ def parse_json (jhash)
45
+ @issuefields = Hash.new
46
+ @project = ""
47
+ @issuetype = ""
48
+ jhash["projects"].each { |value|
49
+ @project = value["key"]
50
+ value["issuetypes"].each { |value1|
51
+ @issuetype = value1["name"]
52
+ value1["fields"].delete("project") #The project key is duplicate and will make our live harder afterwards. It is marked as required but nothing happens if this key is not set.
53
+ value1["fields"].each { |key,value2|
54
+ fields = Hash.new
55
+ fields["id"] = key
56
+ if value2["name"] then
57
+ name = value2["name"]
58
+ else
59
+ name = key
60
+ end
61
+ # If the allowed reponses are limited we want to know them.
62
+ if value2["allowedValues"] then
63
+ # With custom fields the identifier is "value" with the built in ones it's "name"
64
+ identifier = "name"
65
+ if value2["schema"]["custom"] then
66
+ identifier = "value"
67
+ end
68
+ allowedValues = Array.new
69
+ value2["allowedValues"].each { |value3|
70
+ allowedValues << value3[identifier]
71
+ } # value3
72
+ fields["allowedValuesIdentifier"] = identifier
73
+ fields["allowedValues"] = allowedValues
74
+ end
75
+ fields["required"] = value2["required"]
76
+ fields["type"] = value2["schema"]["type"]
77
+ @issuefields[name] = fields if name != "Issue Type" # "Issue Type" is not really a required field as we have to assign it at another place anyway
78
+ } # value1
79
+ } # value
80
+ } # jhash
81
+ end
82
+
83
+ # @param [String] field Name of the field
84
+ # @return [String] type of the Field
85
+ def fieldtype(field)
86
+ # If the fieldname is wrong we want to tell this and stop execution (or maybe let the caller fix it)
87
+ if @issuefields[field].nil? then
88
+ raise Jirarest2::WrongFieldnameException, field
89
+ else
90
+ return @issuefields[field]["type"]
91
+ end
92
+ end
93
+
94
+ # @return [Array] Names of required fields
95
+ def get_requireds
96
+ names = Array.new
97
+ @issuefields.each {|key,value|
98
+ if value["required"] then
99
+ names << key
100
+ end
101
+ }
102
+ return names
103
+ end
104
+
105
+ # @return [Array] Names of all fields
106
+ def get_fieldnames
107
+ names = Array.new
108
+ @issuefields.each {|key,value|
109
+ names << key
110
+ }
111
+ return names
112
+ end
113
+
114
+ # @param [String] name Name of a field
115
+ # @return [String] id of the field
116
+ protected
117
+ def get_id(name)
118
+ return @issuefields["name"]["id"]
119
+ end
120
+
121
+ =begin
122
+ # query=
123
+ # {"fields"=>
124
+ # { "project"=>{"key"=>"MFTP"},
125
+ # "environment"=>"REST ye merry gentlemen.",
126
+ # "My own text"=>"Creating of an issue using project keys and issue type names using the REST API",
127
+ # "issuetype"=> {"name"=>"My own type"}
128
+ # }
129
+ # }
130
+ =end
131
+
132
+ # @return [Hash] Hash to be sent to JIRA(tm) in a JSON representation
133
+ public
134
+ def jirahash
135
+ h = Hash.new
136
+ issuetype = {"issuetype" => {"name" => @issuetype}}
137
+ project = {"key" => @project}
138
+ fields = Hash.new
139
+ fields["project"] = project
140
+ # here we need to enter the relevant fields and their values
141
+ @issuefields.each { |key,value|
142
+ if key != "project" then
143
+ id = value["id"]
144
+ if ! value["value"].nil? then
145
+ fields[id] = value["value"]
146
+ end
147
+ end
148
+ }
149
+ fields = fields.merge!(issuetype)
150
+ h = {"fields" => fields}
151
+ return h
152
+ end
153
+
154
+ # check if the value is allowed for this field
155
+ # @param [String] key Name of the field
156
+ # @param [String] value Value to be checked
157
+ # @return [Boolean, Jirarest2::ValueNotAllowedException]
158
+ protected
159
+ def value_allowed?(key,value)
160
+ if @issuefields[key]["allowedValues"].include?(value)
161
+ return true
162
+ else
163
+ # puts "Value #{value} not allowed for field #{key}."
164
+ raise Jirarest2::ValueNotAllowedException.new(key, @issuefields[key]["allowedValues"]), value
165
+ end
166
+ end
167
+
168
+
169
+ # Special setter for fields that have a limited numer of allowed values.
170
+ #
171
+ # This setter might be included in set_field at a later date.
172
+ # @param [String] key Name of the field
173
+ # @param [String] value Value to be checked
174
+ def set_allowed_value(key,value)
175
+ if @issuefields[key]["type"] == "array" && value.instance_of?(Array) then
176
+ array = Array.new
177
+ value.each {|item|
178
+ if value_allowed?(key,item) then
179
+ array << {@issuefields[key]["allowedValuesIdentifier"] => item}
180
+ end
181
+ }
182
+ @issuefields[key]["value"] = array
183
+ else
184
+ if value_allowed?(key,value) then
185
+ @issuefields[key]["value"] = {@issuefields[key]["allowedValuesIdentifier"] => value}
186
+ end
187
+ end
188
+ end
189
+
190
+
191
+ # TODO We are not yet able to work with "Cascading Select" fields ( "custom": "com.atlassian.jira.plugin.system.customfieldtypes:cascadingselect")
192
+ # @param [String] key Name of the field
193
+ # @param [String] value Value the field should be set to, this is either a String or an Array (don't know if numbers work too)
194
+ public
195
+ def set_field(key, value)
196
+ if @issuefields.include?(key) then
197
+ if @issuefields[key].include?("allowedValues") then
198
+ set_allowed_value(key,value)
199
+ else
200
+ @issuefields[key]["value"] = value
201
+ end
202
+ else
203
+ raise Jirarest2::WrongFieldnameException, key
204
+ puts "Unknown Field: #{key}"
205
+ end
206
+ end
207
+
208
+ # @param [String] field Name of the field
209
+ # @return [String] value of the field
210
+ def get_field(field)
211
+ @issuefields[field]["value"]
212
+ end
213
+
214
+ # persitence of this Issue object instance
215
+ # @param [Connection] connection
216
+ # @return [Jirarest2::Result]
217
+ def persist(connection)
218
+ get_requireds.each { |fieldname|
219
+ if @issuefields[fieldname]["value"].nil? then
220
+ raise Jirarest2::RequiredFieldNotSetException, fieldname
221
+ end
222
+ }
223
+ hash = jirahash
224
+ ret = connection.execute("Post","issue/",hash)
225
+ if ret.code == "201" then # Ticket sucessfully created
226
+ @issuekey = ret.result["key"]
227
+ end
228
+ return ret
229
+ end
230
+
231
+
232
+
233
+ # Set the watchers for this Ticket
234
+ # @param [Connection] connection
235
+ # @param [Array] watchers Watchers to be added
236
+ # @return [Boolean] True if successfull for all
237
+ def add_watchers(connection,watchers)
238
+ success = false # Return whether we were successful with the watchers
239
+ watch = Watcher.new(connection,@issuekey)
240
+ watchers.each { |person|
241
+ success = watch.add_watcher(person)
242
+ }
243
+ return success
244
+ end
245
+
246
+
247
+ end # class
@@ -21,8 +21,6 @@ require_relative "credentials"
21
21
  # A Credentials object contains the data required to connect to a JIRA(tm) instance.
22
22
  class PasswordCredentials < Credentials
23
23
 
24
- # username to use
25
- attr_accessor :username
26
24
  # password for the connection
27
25
  attr_accessor :password
28
26
 
@@ -30,30 +28,10 @@ class PasswordCredentials < Credentials
30
28
  # @param [String] username
31
29
  # @param [String] password
32
30
  def initialize(url,username,password)
33
- super(url)
34
- @username = username
31
+ super(url,username)
35
32
  @password = password
36
- =begin
37
- uri = URI(url)
38
- if uri.instance_of?(URI::HTTP) || uri.instance_of?(URI::HTTPS) then
39
- @connecturl = url
40
- else
41
- raise Jirarest2::NotAnURLError
42
- end
43
- =end
44
33
  end
45
- =begin
46
- # Throws an Jirarest2::NotAnURLError if the given String is not an URI.
47
- # @param [String] url
48
- def connecturl=(url)
49
- uri = URI(url)
50
- if uri.instance_of?(URI::HTTP) || uri.instance_of?(URI::HTTPS) then
51
- @connecturl = url
52
- else
53
- raise Jirarest2::NotAnURLError
54
- end
55
- end
56
- =end
34
+
57
35
  # Get the auth header to send to the server
58
36
  # @param [Net:::HTTP::Post,Net:::HTTP::Put,Net:::HTTP::Get,Net:::HTTP::Delete] request Request object
59
37
  def get_auth_header(request)
@@ -37,7 +37,7 @@ class IssueLink < Services
37
37
  # @param [String, Issue] issue
38
38
  # @return [String]
39
39
  def key(issue)
40
- if issue.instance_of?(Issue) then
40
+ if issue.instance_of?(NewIssue) then
41
41
  return issue.issuekey
42
42
  else
43
43
  return issue
data/lib/jirarest2bin.rb CHANGED
@@ -114,7 +114,7 @@ module Jirarest2Bin
114
114
  end
115
115
 
116
116
  if !scriptopts.nocookieauth then
117
- credentials = CookieCredentials.new(scriptopts.url,true)
117
+ credentials = CookieCredentials.new(scriptopts.url,scriptopts.username,true)
118
118
  credentials.load_cookiejar
119
119
  return credentials
120
120
  # TODO What to do if the cookie expired?
@@ -168,7 +168,7 @@ module Jirarest2Bin
168
168
  end
169
169
  case command
170
170
  when :issue
171
- return connection, Issue.new(args[0],args[1],connection)
171
+ return connection, NewIssue.new(args[0],args[1],connection)
172
172
  when :connection
173
173
  return connection
174
174
  end
@@ -234,7 +234,7 @@ module Jirarest2Bin
234
234
  end
235
235
 
236
236
  opts.on_tail("--version", "Show version") do
237
- puts OptionParser::Version.join(".")
237
+ puts opts.ver
238
238
  exit
239
239
  end
240
240
 
data/test/test_comment.rb CHANGED
@@ -8,6 +8,8 @@ class TestComment < MiniTest::Unit::TestCase
8
8
  def setup
9
9
  cred = PasswordCredentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
10
10
  @con = Connect.new(cred)
11
+ stub_request(:get, "http://test:1234@localhost:2990/jira/rest/auth/latest/session").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => "", :headers => {})
12
+
11
13
  end
12
14
 
13
15
  def test_get_comment_filled
@@ -43,7 +45,8 @@ class TestComment < MiniTest::Unit::TestCase
43
45
  stub_request(:post, "http://test:1234@localhost:2990/jira/rest/api/2/issue/SP-3/comment").with(:body => "{\"body\":\"Text for the long run\"}",:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 201, :body => '{"self":"http://localhost:2990/jira/rest/api/2/issue/10104/comment/10110","id":"10110","author":{"self":"http://localhost:2990/jira/rest/api/2/user?username=test","name":"test","emailAddress":"jira-test@localhost","avatarUrls":{"16x16":"http://localhost:2990/jira/secure/useravatar?size=small&avatarId=10122","48x48":"http://localhost:2990/jira/secure/useravatar?avatarId=10122"},"displayName":"Test User","active":true},"body":"Text for the long run","updateAuthor":{"self":"http://localhost:2990/jira/rest/api/2/user?username=test","name":"test","emailAddress":"jira-test@localhost","avatarUrls":{"16x16":"http://localhost:2990/jira/secure/useravatar?size=small&avatarId=10122","48x48":"http://localhost:2990/jira/secure/useravatar?avatarId=10122"},"displayName":"Test User","active":true},"created":"2012-07-27T20:36:07.832+0200","updated":"2012-07-27T20:36:07.832+0200"}', :headers => {})
44
46
 
45
47
  comment = Comment.new(@con,"SP-3")
46
- assert_match /,"body":"Text for the long run","updateAuthor"/, comment.add("Text for the long run").body
48
+ match = Regexp.new(',"body":"Text for the long run","updateAuthor"')
49
+ assert_match match, comment.add("Text for the long run").body
47
50
  assert_instance_of Jirarest2::Result, comment.add("Text for the long run")
48
51
  end
49
52
 
data/test/test_connect.rb CHANGED
@@ -8,6 +8,8 @@ class TestConnect < MiniTest::Unit::TestCase
8
8
  def setup
9
9
  cred = PasswordCredentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
10
10
  @con = Connect.new(cred)
11
+ stub_request(:get, "http://test:1234@localhost:2990/jira/rest/auth/latest/session").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => "", :headers => {})
12
+
11
13
  end
12
14
 
13
15
  def test_access
@@ -33,6 +35,8 @@ class TestConnect < MiniTest::Unit::TestCase
33
35
 
34
36
  def test_check_uri_false
35
37
  stub_request(:get, "http://test:1234@localhost:2990/rest/api/2/dashboard").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 400, :body => "", :headers => {})
38
+ stub_request(:get, "http://test:1234@localhost:2990/rest/auth/latest/session").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => "", :headers => {})
39
+
36
40
  cred = PasswordCredentials.new("http://localhost:2990/rest/api/2/","test","1234")
37
41
  con1 = Connect.new(cred)
38
42
  assert_equal false,con1.check_uri
@@ -56,11 +60,11 @@ class TestConnect < MiniTest::Unit::TestCase
56
60
  end
57
61
 
58
62
  def test_working_heal_uri!
59
-
60
- stub_request(:get, "http://test:1234@localhost:2990/jira//rest/api//2//dashboard").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 404, :body => '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><status><status-code>404</status-code><message>null for uri: http://localhost:2990/jira//rest/api//2//dashboard</message></status>', :headers => {"X-AUSERNAME" => "test" })
61
-
63
+ stub_request(:get, "http://test:1234@localhost:2990/jira/login.jsp/rest/auth/latest/session").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => "", :headers => {})
64
+
65
+ stub_request(:get, "http://test:1234@localhost:2990/jira/login.jsp/rest/api/2/dashboard").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 404, :body => '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><status><status-code>404</status-code><message>null for uri: http://localhost:2990/jira//rest/api//2//dashboard</message></status>', :headers => {"X-AUSERNAME" => "test" })
62
66
  ## First an URL we can fix
63
- cred = PasswordCredentials.new("http://localhost:2990/jira//rest/api//2//","test","1234")
67
+ cred = PasswordCredentials.new("http://localhost:2990/jira/login.jsp/rest/api//2//","test","1234")
64
68
  con = Connect.new(cred)
65
69
  assert_equal false,con.check_uri
66
70
 
@@ -71,6 +75,7 @@ class TestConnect < MiniTest::Unit::TestCase
71
75
 
72
76
  def test_notworking_heal_uri!
73
77
  stub_request(:get, "http://test:1234@localhost:2990/secure/Dashboard.jspadashboard").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 400, :body => "", :headers => {})
78
+ stub_request(:get, "http://test:1234@localhost:2990/secure/Dashboard.jspaauth/latest/session").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => "", :headers => {})
74
79
  ## And now one we cant't fix
75
80
  cred = PasswordCredentials.new("http://localhost:2990/secure/Dashboard.jspa","test","1234")
76
81
  con = Connect.new(cred)
@@ -78,5 +83,15 @@ class TestConnect < MiniTest::Unit::TestCase
78
83
  assert_raises(Jirarest2::CouldNotHealURIError){ con.heal_uri! }
79
84
  assert_equal false,con.check_uri
80
85
  end
81
-
86
+
87
+ #
88
+ # Missing tests
89
+ #
90
+ def test_verify_auth_session
91
+ # returncode 200
92
+ end
93
+
94
+ def test_verify_auth_nosession
95
+ # returncode 401
96
+ end
82
97
  end
@@ -7,7 +7,7 @@ require "deb"
7
7
  class TestCookieCredentials < MiniTest::Unit::TestCase
8
8
 
9
9
  def setup
10
- @cred = CookieCredentials.new("http://localhost:2990/jira/rest/api/2/")
10
+ @cred = CookieCredentials.new("http://localhost:2990/jira/rest/api/2/","test")
11
11
  @header = ["a.xsrf.token=BP8Q-WXN6-SKX3-NB5M|11ca22ad2bf3467bee711e5b912536d1fb046a4a|lout; Path=/myapp", "JSESSIONID=6C3AE9205FFC6E0DEC3353C2D10745D8; Path=/"]
12
12
  end
13
13
 
@@ -4,13 +4,13 @@ require "jirarest2/exceptions"
4
4
 
5
5
  class TestCredentials < MiniTest::Unit::TestCase
6
6
  def setup
7
- @cred = Credentials.new("https://localhost:2990")
7
+ @cred = Credentials.new("https://localhost:2990","test")
8
8
  end
9
9
 
10
10
  def testInitialize
11
- assert_instance_of(Credentials, Credentials.new("https://localhost:2990"))
11
+ assert_instance_of(Credentials, Credentials.new("https://localhost:2990","test"))
12
12
  assert_raises(Jirarest2::NotAnURLError) {
13
- Credentials.new("localhost:2990")
13
+ Credentials.new("localhost:2990","Minime")
14
14
  }
15
15
  assert_equal "https://localhost:2990", @cred.connecturl
16
16
  end
@@ -23,4 +23,9 @@ class TestCredentials < MiniTest::Unit::TestCase
23
23
  }
24
24
  end
25
25
 
26
+ def test_baseurl
27
+ cre = Credentials.new("https://localhost:2990/blah/blubb/rest/api/latest","test")
28
+ assert_equal "https://localhost:2990/blah/blubb/rest/",cre.baseurl
29
+ end
30
+
26
31
  end
data/test/test_issue.rb CHANGED
@@ -1,68 +1,50 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  require "minitest/autorun"
3
- require "jirarest2"
3
+ require "jirarest2/connect"
4
+ require "jirarest2/credentials"
5
+ require "jirarest2/password_credentials"
6
+ require "jirarest2/cookie_credentials"
7
+ require "jirarest2/issue"
8
+ require "pp"
4
9
  require "webmock/minitest"
5
10
 
6
11
  class TestIssue < MiniTest::Unit::TestCase
7
- def setup
8
- @credentials = PasswordCredentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
9
- @connect = Connect.new(@credentials)
10
- raw_response_file = File.new(File.dirname(__FILE__)+"/data/issuespec.txt")
11
- stub_request(:get, "http://test:1234@localhost:2990/jira/rest/api/2/issue/createmeta/?expand=projects.issuetypes.fields&issuetypeNames=My%20issue%20type&projectKeys=MFTP").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(raw_response_file)
12
- @existentIssue = Issue.new("MFTP","My issue type",@connect)
13
- end
14
12
 
15
- def testNonExistentProject
16
- stub_request(:get, "http://test:1234@localhost:2990/jira/rest/api/2/issue/createmeta/?expand=projects.issuetypes.fields&issuetypeNames=fasel&projectKeys=blubber").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => '{"expand":"projects","projects":[]}', :headers => {})
17
- assert_raises(Jirarest2::WrongProjectException) {
18
- nonexistentProject = Issue.new("blubber","fasel",@connect)
19
- }
20
- end
13
+ def setup
14
+ cred = PasswordCredentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
15
+ @con = Connect.new(cred)
16
+ stub_request(:get, "http://test:1234@localhost:2990/jira/rest/auth/latest/session").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => "", :headers => {})
21
17
 
22
- def testNonExistentIssuetype
23
- stub_request(:get, "http://test:1234@localhost:2990/jira/rest/api/2/issue/createmeta/?expand=projects.issuetypes.fields&issuetypeNames=fasel&projectKeys=MFTP").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => '{"expand":"projects","projects":[{"expand":"issuetypes","self":"http://localhost:2990/jira/rest/api/2/project/MFTP","id":"10000","key":"MFTP","name":"My first Test Project","avatarUrls":{"16x16":"http://localhost:2990/jira/secure/projectavatar?size=small&pid=10000&avatarId=10011","48x48":"http://localhost:2990/jira/secure/projectavatar?pid=10000&avatarId=10011"},"issuetypes":[]}]}', :headers => {})
24
- assert_raises(Jirarest2::WrongIssuetypeException) {
25
- nonexistentIssue = Issue.new("MFTP","fasel",@connect)
26
- }
27
18
  end
28
19
 
29
- def testExistent
30
- assert_equal "My issue type", @existentIssue.issuetype
31
- end
32
-
33
- def test_get_requireds
34
- req = @existentIssue.get_requireds
35
- assert_equal true, req.include?("Summary")
36
- end
37
-
38
- def test_get_fieldnames
39
- req = @existentIssue.get_fieldnames
40
- assert_equal true, req.include?("Priority")
20
+ def test_receive
21
+ issue = Issue.new("SP-2")
22
+ WebMock.disable!
23
+ # pp issue.receive(@con)
24
+ WebMock.enable!
25
+ end
26
+
27
+ def test_set_assignee_no_rights
28
+ stub_request(:put, "http://test:1234@localhost:2990/jira/rest/api/2/issue/SP-2/assignee").with(:body => "{\"name\":\"cebit\"}",:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 403, :body => "", :headers => {})
29
+ issue = Issue.new("SP-2")
30
+ assert_raises(Jirarest2::ForbiddenError) {
31
+ issue.set_assignee(@con,"cebit")
32
+ }
41
33
  end
42
34
 
43
- def test_jirahash
44
- issue = @existentIssue
45
- issue.set_field("Summary","Summary Text")
46
- issue.set_field("Großes Text","My own text as well")
47
- issue.set_field("Description","And a little bit for \n the big \n text field")
48
- issue.set_field("Priority","Trivial")
49
- issue.set_field("List select","Räuber")
50
- issue.set_field("Multi Select",["Glocke","Kabale und Liebe"])
51
- blankissue = issue.jirahash
52
- assert blankissue
53
- assert_equal "MFTP", blankissue["fields"]["project"]["key"]
54
- assert_equal "Summary Text", issue.get_field("Summary")
35
+ def test_set_assignee_with_rights
36
+ stub_request(:put, "http://test:1234@localhost:2990/jira/rest/api/2/issue/SP-2/assignee").with(:body => "{\"name\":\"cebit\"}",:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 204, :body => "", :headers => {})
37
+ issue = Issue.new("SP-2")
38
+ assert_equal true,issue.set_assignee(@con,"cebit")
55
39
  end
56
40
 
57
-
58
- def test_persist
59
- issue = @existentIssue
60
- issue.set_field("Summary","Summary Text")
61
- issue.set_field("Priority","Trivial")
62
- stub_request(:post, "http://test:1234@localhost:2990/jira/rest/api/2/issue/").with(:body => "{\"fields\":{\"project\":{\"key\":\"MFTP\"},\"summary\":\"Summary Text\",\"priority\":{\"name\":\"Trivial\"},\"issuetype\":{\"name\":\"My issue type\"}}}",:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 201, :body => '{"id":"10608","key":"MFTP-11","self":"http://localhost:2990/jira/rest/api/2/issue/10608"}', :headers => {})
63
-
64
- issue.persist(@connect)
41
+ def test_remove_assignee
42
+ stub_request(:get, "http://admin:admin@localhost:2990/jira/rest/auth/latest/session").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => "", :headers => {})
43
+ stub_request(:put, "http://admin:admin@localhost:2990/jira/rest/api/2/issue/SP-2/assignee").with(:body => "null",:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 204, :body => "", :headers => {})
44
+ cred = PasswordCredentials.new("http://localhost:2990/jira/rest/api/2/","admin","admin")
45
+ con = Connect.new(cred)
46
+ issue = Issue.new("SP-2")
47
+ assert_equal true,issue.remove_assignee(con)
65
48
  end
66
-
67
-
68
49
  end
50
+
@@ -11,6 +11,7 @@ class TestIssueLink < MiniTest::Unit::TestCase
11
11
  cred = PasswordCredentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
12
12
  @con = Connect.new(cred)
13
13
  stub_request(:get, "http://test:1234@localhost:2990/jira/rest/api/2/issueLinkType").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => '{"issueLinkTypes":[{"id":"10000","name":"Blocks","inward":"is blocked by","outward":"blocks","self":"http://localhost:2990/jira/rest/api/2/issueLinkType/10000"},{"id":"10001","name":"Cloners","inward":"is cloned by","outward":"clones","self":"http://localhost:2990/jira/rest/api/2/issueLinkType/10001"},{"id":"10002","name":"Duplicate","inward":"is duplicated by","outward":"duplicates","self":"http://localhost:2990/jira/rest/api/2/issueLinkType/10002"},{"id":"10003","name":"Relates","inward":"relates to","outward":"relates to","self":"http://localhost:2990/jira/rest/api/2/issueLinkType/10003"}]}', :headers => {})
14
+ stub_request(:get, "http://test:1234@localhost:2990/jira/rest/auth/latest/session").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => "", :headers => {})
14
15
  @link = IssueLink.new(@con)
15
16
  end
16
17
 
@@ -10,6 +10,7 @@ class TestIssueLinkType < MiniTest::Unit::TestCase
10
10
  def setup
11
11
  cred = PasswordCredentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
12
12
  @con = Connect.new(cred)
13
+ stub_request(:get, "http://test:1234@localhost:2990/jira/rest/auth/latest/session").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => "", :headers => {})
13
14
  end
14
15
 
15
16
  def test_single_name
@@ -0,0 +1,69 @@
1
+ # -*- coding: utf-8 -*-
2
+ require "minitest/autorun"
3
+ require "jirarest2"
4
+ require "webmock/minitest"
5
+
6
+ class TestNewIssue < MiniTest::Unit::TestCase
7
+ def setup
8
+ @credentials = PasswordCredentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
9
+ @connect = Connect.new(@credentials)
10
+ raw_response_file = File.new(File.dirname(__FILE__)+"/data/issuespec.txt")
11
+ stub_request(:get, "http://test:1234@localhost:2990/jira/rest/api/2/issue/createmeta/?expand=projects.issuetypes.fields&issuetypeNames=My%20issue%20type&projectKeys=MFTP").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(raw_response_file)
12
+ stub_request(:get, "http://test:1234@localhost:2990/jira/rest/auth/latest/session").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => "", :headers => {})
13
+ @existentIssue = NewIssue.new("MFTP","My issue type",@connect)
14
+ end
15
+
16
+ def testNonExistentProject
17
+ stub_request(:get, "http://test:1234@localhost:2990/jira/rest/api/2/issue/createmeta/?expand=projects.issuetypes.fields&issuetypeNames=fasel&projectKeys=blubber").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => '{"expand":"projects","projects":[]}', :headers => {})
18
+ assert_raises(Jirarest2::WrongProjectException) {
19
+ nonexistentProject = NewIssue.new("blubber","fasel",@connect)
20
+ }
21
+ end
22
+
23
+ def testNonExistentIssuetype
24
+ stub_request(:get, "http://test:1234@localhost:2990/jira/rest/api/2/issue/createmeta/?expand=projects.issuetypes.fields&issuetypeNames=fasel&projectKeys=MFTP").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => '{"expand":"projects","projects":[{"expand":"issuetypes","self":"http://localhost:2990/jira/rest/api/2/project/MFTP","id":"10000","key":"MFTP","name":"My first Test Project","avatarUrls":{"16x16":"http://localhost:2990/jira/secure/projectavatar?size=small&pid=10000&avatarId=10011","48x48":"http://localhost:2990/jira/secure/projectavatar?pid=10000&avatarId=10011"},"issuetypes":[]}]}', :headers => {})
25
+ assert_raises(Jirarest2::WrongIssuetypeException) {
26
+ nonexistentIssue = NewIssue.new("MFTP","fasel",@connect)
27
+ }
28
+ end
29
+
30
+ def testExistent
31
+ assert_equal "My issue type", @existentIssue.issuetype
32
+ end
33
+
34
+ def test_get_requireds
35
+ req = @existentIssue.get_requireds
36
+ assert_equal true, req.include?("Summary")
37
+ end
38
+
39
+ def test_get_fieldnames
40
+ req = @existentIssue.get_fieldnames
41
+ assert_equal true, req.include?("Priority")
42
+ end
43
+
44
+ def test_jirahash
45
+ issue = @existentIssue
46
+ issue.set_field("Summary","Summary Text")
47
+ issue.set_field("Großes Text","My own text as well")
48
+ issue.set_field("Description","And a little bit for \n the big \n text field")
49
+ issue.set_field("Priority","Trivial")
50
+ issue.set_field("List select","Räuber")
51
+ issue.set_field("Multi Select",["Glocke","Kabale und Liebe"])
52
+ blankissue = issue.jirahash
53
+ assert blankissue
54
+ assert_equal "MFTP", blankissue["fields"]["project"]["key"]
55
+ assert_equal "Summary Text", issue.get_field("Summary")
56
+ end
57
+
58
+
59
+ def test_persist
60
+ issue = @existentIssue
61
+ issue.set_field("Summary","Summary Text")
62
+ issue.set_field("Priority","Trivial")
63
+ stub_request(:post, "http://test:1234@localhost:2990/jira/rest/api/2/issue/").with(:body => "{\"fields\":{\"project\":{\"key\":\"MFTP\"},\"summary\":\"Summary Text\",\"priority\":{\"name\":\"Trivial\"},\"issuetype\":{\"name\":\"My issue type\"}}}",:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 201, :body => '{"id":"10608","key":"MFTP-11","self":"http://localhost:2990/jira/rest/api/2/issue/10608"}', :headers => {})
64
+
65
+ issue.persist(@connect)
66
+ end
67
+
68
+
69
+ end
data/test/test_result.rb CHANGED
@@ -8,6 +8,7 @@ class TestResult < MiniTest::Unit::TestCase
8
8
  def setup
9
9
  cred = PasswordCredentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
10
10
  @con = Connect.new(cred)
11
+ stub_request(:get, "http://test:1234@localhost:2990/jira/rest/auth/latest/session").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => "", :headers => {})
11
12
  end
12
13
 
13
14
  def test_code
data/test/test_watcher.rb CHANGED
@@ -9,10 +9,14 @@ class TestWatcher < MiniTest::Unit::TestCase
9
9
  def setup
10
10
  cred = PasswordCredentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
11
11
  @con = Connect.new(cred)
12
+ stub_request(:get, "http://test:1234@localhost:2990/jira/rest/auth/latest/session").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => "", :headers => {})
13
+
12
14
  end
13
15
 
14
16
  def test_get_watchers_filled
15
17
  stub_request(:get, "http://test:1234@localhost:2990/jira/rest/api/2/issue/MFTP-7/watchers").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => '{"self":"http://localhost:2990/jira/rest/api/2/issue/MFTP-7/watchers","isWatching":true,"watchCount":3,"watchers":[{"self":"http://localhost:2990/jira/rest/api/2/user?username=admin","name":"admin","avatarUrls":{"16x16":"http://localhost:2990/jira/secure/useravatar?size=small&avatarId=10122","48x48":"http://localhost:2990/jira/secure/useravatar?avatarId=10122"},"displayName":"admin","active":true},{"self":"http://localhost:2990/jira/rest/api/2/user?username=cebit","name":"cebit","avatarUrls":{"16x16":"http://localhost:2990/jira/secure/useravatar?size=small&avatarId=10122","48x48":"http://localhost:2990/jira/secure/useravatar?avatarId=10122"},"displayName":"Cyril Bitterich","active":true},{"self":"http://localhost:2990/jira/rest/api/2/user?username=test","name":"test","avatarUrls":{"16x16":"http://localhost:2990/jira/secure/useravatar?size=small&avatarId=10122","48x48":"http://localhost:2990/jira/secure/useravatar?avatarId=10122"},"displayName":"Test User","active":true}]}', :headers => {})
18
+ # stub_request(:get, "http://test:1234@localhost:2990/jira/rest/auth/latest/session").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => "", :headers => {})
19
+
16
20
  watchers = Watcher.new(@con,"MFTP-7")
17
21
  assert_equal ["admin","cebit","test"], watchers.get_watchers
18
22
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jirarest2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.0.12
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -50,7 +50,7 @@ cert_chain:
50
50
  -----END CERTIFICATE-----
51
51
 
52
52
  '
53
- date: 2012-08-05 00:00:00.000000000 Z
53
+ date: 2012-08-07 00:00:00.000000000 Z
54
54
  dependencies:
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: json
@@ -171,6 +171,7 @@ files:
171
171
  - lib/jirarest2/exceptions.rb
172
172
  - lib/jirarest2/issue.rb
173
173
  - lib/jirarest2/madbitconfig.rb
174
+ - lib/jirarest2/newissue.rb
174
175
  - lib/jirarest2/password_credentials.rb
175
176
  - lib/jirarest2/result.rb
176
177
  - lib/jirarest2/services.rb
@@ -195,6 +196,7 @@ files:
195
196
  - test/test_issuelink.rb
196
197
  - test/test_issuelinktype.rb
197
198
  - test/test_madbitconfig.rb
199
+ - test/test_newissue.rb
198
200
  - test/test_password_credentials.rb
199
201
  - test/test_result.rb
200
202
  - test/test_watcher.rb
@@ -236,6 +238,7 @@ test_files:
236
238
  - test/test_credentials.rb
237
239
  - test/test_issue.rb
238
240
  - test/test_password_credentials.rb
241
+ - test/test_newissue.rb
239
242
  - test/test_result.rb
240
243
  - test/test_issuelink.rb
241
244
  - test/test_watcher.rb
metadata.gz.sig CHANGED
Binary file