jira-ruby 0.1.17 → 0.1.18
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.
- checksums.yaml +4 -4
- data/Gemfile +7 -2
- data/Guardfile +14 -0
- data/README.rdoc +7 -2
- data/Rakefile +5 -1
- data/example.rb +23 -1
- data/lib/jira.rb +2 -0
- data/lib/jira/base.rb +5 -4
- data/lib/jira/base_factory.rb +2 -2
- data/lib/jira/client.rb +19 -2
- data/lib/jira/resource/createmeta.rb +52 -0
- data/lib/jira/resource/field.rb +74 -1
- data/lib/jira/resource/issue.rb +22 -5
- data/lib/jira/resource/webhook.rb +40 -0
- data/lib/jira/version.rb +1 -1
- data/spec/integration/webhook.rb +34 -0
- data/spec/jira/base_spec.rb +5 -2
- data/spec/jira/resource/createmeta_spec.rb +253 -0
- data/spec/jira/resource/field_spec.rb +132 -0
- data/spec/jira/resource/issue_spec.rb +21 -1
- data/spec/mock_responses/jira/rest/webhooks/1.0/webhook.json +11 -0
- data/spec/mock_responses/jira/rest/webhooks/1.0/webhook/2.json +11 -0
- data/spec/mock_responses/webhook.json +11 -0
- data/spec/mock_responses/webhook/webhook.json +11 -0
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a295ea67b7236d11b1696c74e9491f80f694c698
|
4
|
+
data.tar.gz: c00568c1bba25ed92d64531df36539ba8d7d3d31
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e4c24dffaa5d308386ab2698391a8c0c73de5ac67582360c15df32c99775b07495776b6ab87637b0b4ccdb7d47e80508f868c5073391946ea199858fef0a12c
|
7
|
+
data.tar.gz: 89f26829c1937b26846e6557b0265e693e65ff22e764ebdfd05e06209d15034d42ca865846fc048907f06844896fa7b197b7bdd082b1acb564f3e6a969c20eb0
|
data/Gemfile
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
source "http://rubygems.org"
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
group :development do
|
4
|
+
gem 'guard'
|
5
|
+
gem 'guard-rspec'
|
6
|
+
gem 'pry' # this was in the original Gemfile - but only needed in development
|
7
|
+
gem 'wdm', '>= 0.1.0' if Gem.win_platform?
|
8
|
+
end
|
9
|
+
|
5
10
|
# Specify your gem's dependencies in jira_api.gemspec
|
6
11
|
gemspec
|
data/Guardfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
gem 'wdm', '>= 0.1.0' if Gem.win_platform?
|
2
|
+
gem 'rspec', '~> 3.0.0'
|
3
|
+
|
4
|
+
guard 'rspec', cmd: 'bundle exec rspec --color --format doc' do
|
5
|
+
# watch /lib/ files
|
6
|
+
watch(%r{^lib/(.+).rb$}) do |m|
|
7
|
+
"spec/#{m[1]}_spec.rb"
|
8
|
+
end
|
9
|
+
|
10
|
+
# watch /spec/ files
|
11
|
+
watch(%r{^spec/(.+).rb$}) do |m|
|
12
|
+
"spec/#{m[1]}.rb"
|
13
|
+
end
|
14
|
+
end
|
data/README.rdoc
CHANGED
@@ -76,6 +76,10 @@ defaults to HTTP Basic Auth.
|
|
76
76
|
Using HTTP Basic Authentication, configure and connect a client to your instance
|
77
77
|
of JIRA.
|
78
78
|
|
79
|
+
Note: If your Jira install is hosted on {atlassian.net}[atlassian.net], it will have no context
|
80
|
+
path by default. If you're having issues connecting, try setting context_path
|
81
|
+
to an empty string in the options hash.
|
82
|
+
|
79
83
|
require 'rubygems'
|
80
84
|
require 'pp'
|
81
85
|
require 'jira'
|
@@ -273,7 +277,8 @@ Here's the same example as a Sinatra application:
|
|
273
277
|
# Initiates the OAuth dance by first requesting a token then redirecting to
|
274
278
|
# http://<yourserver>/auth to get the @access_token
|
275
279
|
get '/signin' do
|
276
|
-
|
280
|
+
callback_url = "#{request.base_url}/callback"
|
281
|
+
request_token = @jira_client.request_token(oauth_callback: callback_url)
|
277
282
|
session[:request_token] = request_token.token
|
278
283
|
session[:request_secret] = request_token.secret
|
279
284
|
|
@@ -283,7 +288,7 @@ Here's the same example as a Sinatra application:
|
|
283
288
|
# http://<yourserver>/callback
|
284
289
|
# Retrieves the @access_token then stores it inside a session cookie. In a real app,
|
285
290
|
# you'll want to persist the token in a datastore associated with the user.
|
286
|
-
get "/callback
|
291
|
+
get "/callback" do
|
287
292
|
request_token = @jira_client.set_request_token(
|
288
293
|
session[:request_token], session[:request_secret]
|
289
294
|
)
|
data/Rakefile
CHANGED
@@ -19,7 +19,11 @@ task :prepare do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
desc 'Run RSpec tests'
|
22
|
-
RSpec::Core::RakeTask.new(:spec)
|
22
|
+
#RSpec::Core::RakeTask.new(:spec)
|
23
|
+
RSpec::Core::RakeTask.new(:spec) do |task|
|
24
|
+
task.rspec_opts = ['--color', '--format', 'doc']
|
25
|
+
end
|
26
|
+
|
23
27
|
|
24
28
|
Rake::RDocTask.new(:doc) do |rd|
|
25
29
|
rd.main = 'README.rdoc'
|
data/example.rb
CHANGED
@@ -42,6 +42,28 @@ end
|
|
42
42
|
issue = client.Issue.find('SAMPLEPROJECT-1')
|
43
43
|
pp issue
|
44
44
|
|
45
|
+
# # Handling fields by name, rather than by id
|
46
|
+
# # ------------------------------------------
|
47
|
+
# Cache the Field list from the server
|
48
|
+
client.Field.map_fields
|
49
|
+
# This allows use of friendlier names for custom fields
|
50
|
+
# Say that 'Special Field' is customfield_12345
|
51
|
+
# It becomes mapped to Special_Field which is usable as a method call
|
52
|
+
#
|
53
|
+
# Say that there is a second 'Special Field' is customfield_54321
|
54
|
+
# Names are deduplicated so the second 'Special Field' becomes Special_Field_54321
|
55
|
+
#
|
56
|
+
# Names are massaged to get rid of special characters, and spaces
|
57
|
+
# So 'Special & @ Field' becomes Special_____Field - not perfect, but usable
|
58
|
+
old_way = issue.customfield_12345
|
59
|
+
new_way = issue.Special_Field
|
60
|
+
(old_way == new_way) && puts 'much easier'
|
61
|
+
#
|
62
|
+
# Can also use this to specify fields to be returned in the response
|
63
|
+
client.Issue.jql(a_normal_jql_search, fields:[:Special_Field])
|
64
|
+
# Or you could always do it the old way - if you can remember the numbers...
|
65
|
+
client.Issue.jql(a_normal_jql_search, fields:['customfield_12345'])
|
66
|
+
|
45
67
|
# # Find a specific project by key
|
46
68
|
# # ------------------------------
|
47
69
|
# project = client.Project.find('SAMPLEPROJECT')
|
@@ -173,4 +195,4 @@ remote_link.save(
|
|
173
195
|
:title => issue_1.key,
|
174
196
|
}
|
175
197
|
}
|
176
|
-
)
|
198
|
+
)
|
data/lib/jira.rb
CHANGED
@@ -30,6 +30,8 @@ require 'jira/resource/filter'
|
|
30
30
|
require 'jira/resource/field'
|
31
31
|
require 'jira/resource/rapidview'
|
32
32
|
require 'jira/resource/serverinfo'
|
33
|
+
require 'jira/resource/createmeta'
|
34
|
+
require 'jira/resource/webhook'
|
33
35
|
|
34
36
|
require 'jira/request_client'
|
35
37
|
require 'jira/oauth_client'
|
data/lib/jira/base.rb
CHANGED
@@ -348,7 +348,7 @@ module JIRA
|
|
348
348
|
# JIRA::HTTPError if the request fails (response is not HTTP 2xx).
|
349
349
|
def save!(attrs)
|
350
350
|
http_method = new_record? ? :post : :put
|
351
|
-
response = client.send(http_method, url, attrs.to_json)
|
351
|
+
response = client.send(http_method, new_record? ? url : patched_url, attrs.to_json)
|
352
352
|
set_attrs(attrs, false)
|
353
353
|
set_attrs_from_response(response)
|
354
354
|
@expanded = false
|
@@ -439,6 +439,7 @@ module JIRA
|
|
439
439
|
end
|
440
440
|
|
441
441
|
# This method fixes issue that there is no / prefix in url. It is happened when we call for instance
|
442
|
+
# Looks like this issue is actual only in case if you use atlassian sdk your app path is not root (like /jira in example below)
|
442
443
|
# issue.save() for existing resource.
|
443
444
|
# As a result we got error 400 from JIRA API:
|
444
445
|
# [07/Jun/2015:15:32:19 +0400] "PUT jira/rest/api/2/issue/10111 HTTP/1.1" 400 -
|
@@ -446,7 +447,7 @@ module JIRA
|
|
446
447
|
# [07/Jun/2015:15:17:18 +0400] "PUT /jira/rest/api/2/issue/10111 HTTP/1.1" 204 -
|
447
448
|
def patched_url
|
448
449
|
result = url
|
449
|
-
result if result.start_with?('/')
|
450
|
+
return result if result.start_with?('/')
|
450
451
|
"/#{result}"
|
451
452
|
end
|
452
453
|
|
@@ -455,8 +456,8 @@ module JIRA
|
|
455
456
|
end
|
456
457
|
|
457
458
|
# Returns a JSON representation of the current attributes hash.
|
458
|
-
def to_json
|
459
|
-
attrs.to_json
|
459
|
+
def to_json(options = {})
|
460
|
+
attrs.to_json(options)
|
460
461
|
end
|
461
462
|
|
462
463
|
# Determines if the resource is newly created by checking whether its
|
data/lib/jira/base_factory.rb
CHANGED
@@ -15,7 +15,7 @@ module JIRA
|
|
15
15
|
# Need to do a little bit of work here as Module.const_get doesn't work
|
16
16
|
# with nested class names, i.e. JIRA::Resource::Foo.
|
17
17
|
#
|
18
|
-
# So create a method chain from the class
|
18
|
+
# So create a method chain from the class components. This code will
|
19
19
|
# unroll to:
|
20
20
|
# Module.const_get('JIRA').const_get('Resource').const_get('Foo')
|
21
21
|
#
|
@@ -35,7 +35,7 @@ module JIRA
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
# The
|
38
|
+
# The principle purpose of this class is to delegate methods to the corresponding
|
39
39
|
# non-factory class and automatically prepend the client argument to the argument
|
40
40
|
# list.
|
41
41
|
delegate_to_target_class :all, :find, :collection_path, :singular_path, :jql
|
data/lib/jira/client.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'forwardable'
|
3
|
+
require 'ostruct'
|
3
4
|
|
4
5
|
module JIRA
|
5
6
|
|
@@ -37,7 +38,7 @@ module JIRA
|
|
37
38
|
#
|
38
39
|
# The authenticated client instance returned by the respective client type
|
39
40
|
# (Oauth, Basic)
|
40
|
-
attr_accessor :consumer, :request_client
|
41
|
+
attr_accessor :consumer, :request_client, :http_debug, :cache
|
41
42
|
|
42
43
|
# The configuration options for this client instance
|
43
44
|
attr_reader :options
|
@@ -50,7 +51,8 @@ module JIRA
|
|
50
51
|
:rest_base_path => "/rest/api/2",
|
51
52
|
:ssl_verify_mode => OpenSSL::SSL::VERIFY_PEER,
|
52
53
|
:use_ssl => true,
|
53
|
-
:auth_type => :oauth
|
54
|
+
:auth_type => :oauth,
|
55
|
+
:http_debug => false
|
54
56
|
}
|
55
57
|
|
56
58
|
def initialize(options={})
|
@@ -64,9 +66,15 @@ module JIRA
|
|
64
66
|
@consumer = @request_client.consumer
|
65
67
|
when :basic
|
66
68
|
@request_client = HttpClient.new(@options)
|
69
|
+
else
|
70
|
+
raise ArgumentError, 'Options: ":auth_type" must be ":oauth" or ":basic"'
|
67
71
|
end
|
68
72
|
|
73
|
+
@http_debug = @options[:http_debug]
|
74
|
+
|
69
75
|
@options.freeze
|
76
|
+
|
77
|
+
@cache = OpenStruct.new
|
70
78
|
end
|
71
79
|
|
72
80
|
def Project # :nodoc:
|
@@ -133,10 +141,18 @@ module JIRA
|
|
133
141
|
JIRA::Resource::ServerInfoFactory.new(self)
|
134
142
|
end
|
135
143
|
|
144
|
+
def Createmeta
|
145
|
+
JIRA::Resource::CreatemetaFactory.new(self)
|
146
|
+
end
|
147
|
+
|
136
148
|
def ApplicationLink
|
137
149
|
JIRA::Resource::ApplicationLinkFactory.new(self)
|
138
150
|
end
|
139
151
|
|
152
|
+
def Webhook
|
153
|
+
JIRA::Resource::WebhookFactory.new(self)
|
154
|
+
end
|
155
|
+
|
140
156
|
def Issuelink
|
141
157
|
JIRA::Resource::IssuelinkFactory.new(self)
|
142
158
|
end
|
@@ -176,6 +192,7 @@ module JIRA
|
|
176
192
|
# Sends the specified HTTP request to the REST API through the
|
177
193
|
# appropriate method (oauth, basic).
|
178
194
|
def request(http_method, path, body = '', headers={})
|
195
|
+
puts "#{http_method}: #{path} - [#{body}]" if @http_debug
|
179
196
|
@request_client.request(http_method, path, body, headers)
|
180
197
|
end
|
181
198
|
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module JIRA
|
2
|
+
module Resource
|
3
|
+
|
4
|
+
class CreatemetaFactory < JIRA::BaseFactory # :nodoc:
|
5
|
+
end
|
6
|
+
|
7
|
+
class Createmeta < JIRA::Base
|
8
|
+
def self.endpoint_name
|
9
|
+
'/issue/createmeta'
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.all(client, params={})
|
13
|
+
|
14
|
+
if params.has_key?(:projectKeys)
|
15
|
+
values = Array(params[:projectKeys]).map{|i| (i.is_a?(JIRA::Resource::Project) ? i.key : i)}
|
16
|
+
params[:projectKeys] = values.join(',')
|
17
|
+
end
|
18
|
+
|
19
|
+
if params.has_key?(:projectIds)
|
20
|
+
values = Array(params[:projectIds]).map{|i| (i.is_a?(JIRA::Resource::Project) ? i.id : i)}
|
21
|
+
params[:projectIds] = values.join(',')
|
22
|
+
end
|
23
|
+
|
24
|
+
if params.has_key?(:issuetypeNames)
|
25
|
+
values = Array(params[:issuetypeNames]).map{|i| (i.is_a?(JIRA::Resource::Issuetype) ? i.name : i)}
|
26
|
+
params[:issuetypeNames] = values.join(',')
|
27
|
+
end
|
28
|
+
|
29
|
+
if params.has_key?(:issuetypeIds)
|
30
|
+
values = Array(params[:issuetypeIds]).map{|i| (i.is_a?(JIRA::Resource::Issuetype) ? i.id : i)}
|
31
|
+
params[:issuetypeIds] = values.join(',')
|
32
|
+
end
|
33
|
+
|
34
|
+
create_meta_url = client.options[:rest_base_path] + self.endpoint_name
|
35
|
+
params = hash_to_query_string(params)
|
36
|
+
|
37
|
+
response = params.empty? ? client.get("#{create_meta_url}") : client.get("#{create_meta_url}?#{params}")
|
38
|
+
|
39
|
+
json = parse_json(response.body)
|
40
|
+
self.new(client, {:attrs => json['projects']})
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.hash_to_query_string(query_params)
|
44
|
+
query_params.map do |k,v|
|
45
|
+
CGI.escape(k.to_s) + '=' + CGI.escape(v.to_s)
|
46
|
+
end.join('&')
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
data/lib/jira/resource/field.rb
CHANGED
@@ -2,9 +2,82 @@ module JIRA
|
|
2
2
|
module Resource
|
3
3
|
|
4
4
|
class FieldFactory < JIRA::BaseFactory # :nodoc:
|
5
|
+
delegate_to_target_class :map_fields, :name_to_id, :field_map
|
5
6
|
end
|
6
7
|
|
7
|
-
class Field < JIRA::Base
|
8
|
+
class Field < JIRA::Base
|
8
9
|
|
10
|
+
#translate a custom field description to a method-safe name
|
11
|
+
def self.safe_name(description)
|
12
|
+
description.gsub(/[^a-zA-Z0-9]/,'_')
|
13
|
+
end
|
14
|
+
|
15
|
+
# safe_name plus disambiguation if it fails it uses the original jira id (customfield_#####)
|
16
|
+
def self.safer_name(description, jira_id)
|
17
|
+
"#{safe_name(description)}_#{jira_id.split('_')[1]}" rescue jira_id
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.map_fields(client)
|
21
|
+
field_map = {}
|
22
|
+
field_map_reverse = {}
|
23
|
+
fields = client.Field.all
|
24
|
+
|
25
|
+
# two pass approach, so that a custom field with the same name
|
26
|
+
# as a system field can't take precedence
|
27
|
+
fields.each do |f|
|
28
|
+
next if f.custom
|
29
|
+
name = safe_name(f.name)
|
30
|
+
field_map_reverse[f.id] = [f.name, name] # capture both the official name, and the mapped name
|
31
|
+
field_map[name] = f.id
|
32
|
+
end
|
33
|
+
|
34
|
+
fields.each do |f|
|
35
|
+
next unless f.custom
|
36
|
+
name = if field_map.key? f.name
|
37
|
+
renamed = safer_name(f.name, f.id)
|
38
|
+
warn "Duplicate Field name #{f.name} #{f.id} - renaming as #{renamed}"
|
39
|
+
renamed
|
40
|
+
else
|
41
|
+
safe_name(f.name)
|
42
|
+
end
|
43
|
+
field_map_reverse[f.id] = [f.name, name] # capture both the official name, and the mapped name
|
44
|
+
field_map[name] = f.id
|
45
|
+
end
|
46
|
+
|
47
|
+
client.cache.field_map_reverse = field_map_reverse # not sure where this will be used yet, but sure to be useful
|
48
|
+
client.cache.field_map = field_map
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.field_map(client)
|
52
|
+
client.cache.field_map
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.name_to_id(client, field_name)
|
56
|
+
field_name = field_name.to_s
|
57
|
+
return field_name unless client.cache.field_map && client.cache.field_map[field_name]
|
58
|
+
client.cache.field_map[field_name]
|
59
|
+
end
|
60
|
+
|
61
|
+
def respond_to?(method_name, include_all=false)
|
62
|
+
if [method_name.to_s, client.Field.name_to_id(method_name)].any? {|k| attrs.key?(k)}
|
63
|
+
true
|
64
|
+
else
|
65
|
+
super(method_name)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def method_missing(method_name, *args, &block)
|
70
|
+
if attrs.keys.include?(method_name.to_s)
|
71
|
+
attrs[method_name.to_s]
|
72
|
+
else
|
73
|
+
official_name=client.Field.name_to_id(method_name)
|
74
|
+
if attrs.keys.include?(official_name)
|
75
|
+
attrs[official_name]
|
76
|
+
else
|
77
|
+
super(method_name, *args, &block)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
9
82
|
end
|
10
83
|
end
|
data/lib/jira/resource/issue.rb
CHANGED
@@ -51,7 +51,7 @@ module JIRA
|
|
51
51
|
def self.jql(client, jql, options = {fields: nil, start_at: nil, max_results: nil, expand: nil})
|
52
52
|
url = client.options[:rest_base_path] + "/search?jql=" + CGI.escape(jql)
|
53
53
|
|
54
|
-
url << "&fields=#{options[:fields].map{ |value| CGI.escape(value
|
54
|
+
url << "&fields=#{options[:fields].map{ |value| CGI.escape(client.Field.name_to_id(value)) }.join(',')}" if options[:fields]
|
55
55
|
url << "&startAt=#{CGI.escape(options[:start_at].to_s)}" if options[:start_at]
|
56
56
|
url << "&maxResults=#{CGI.escape(options[:max_results].to_s)}" if options[:max_results]
|
57
57
|
|
@@ -67,8 +67,16 @@ module JIRA
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
+
def editmeta
|
71
|
+
editmeta_url = client.options[:rest_base_path] + "/#{self.class.endpoint_name}/#{key}/editmeta"
|
72
|
+
|
73
|
+
response = client.get(editmeta_url)
|
74
|
+
json = self.class.parse_json(response.body)
|
75
|
+
json['fields']
|
76
|
+
end
|
77
|
+
|
70
78
|
def respond_to?(method_name, include_all=false)
|
71
|
-
if attrs.keys.include?('fields') && attrs['fields'].
|
79
|
+
if attrs.keys.include?('fields') && [method_name.to_s, client.Field.name_to_id(method_name)].any? {|k| attrs['fields'].key?(k)}
|
72
80
|
true
|
73
81
|
else
|
74
82
|
super(method_name)
|
@@ -76,10 +84,19 @@ module JIRA
|
|
76
84
|
end
|
77
85
|
|
78
86
|
def method_missing(method_name, *args, &block)
|
79
|
-
if attrs.keys.include?('fields')
|
80
|
-
attrs['fields']
|
87
|
+
if attrs.keys.include?('fields')
|
88
|
+
if attrs['fields'].keys.include?(method_name.to_s)
|
89
|
+
attrs['fields'][method_name.to_s]
|
90
|
+
else
|
91
|
+
official_name=client.Field.name_to_id(method_name)
|
92
|
+
if attrs['fields'].keys.include?(official_name)
|
93
|
+
attrs['fields'][official_name]
|
94
|
+
else
|
95
|
+
super(method_name, *args, &block)
|
96
|
+
end
|
97
|
+
end
|
81
98
|
else
|
82
|
-
super(method_name)
|
99
|
+
super(method_name, *args, &block)
|
83
100
|
end
|
84
101
|
end
|
85
102
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module JIRA
|
2
|
+
module Resource
|
3
|
+
|
4
|
+
class WebhookFactory < JIRA::BaseFactory # :nodoc:
|
5
|
+
end
|
6
|
+
|
7
|
+
class Webhook < JIRA::Base
|
8
|
+
|
9
|
+
REST_BASE_PATH = '/rest/webhooks/1.0/'
|
10
|
+
|
11
|
+
def self.endpoint_name
|
12
|
+
'webhook'
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.full_url(client)
|
16
|
+
client.options[:context_path] + REST_BASE_PATH
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.collection_path(client, prefix = '/')
|
20
|
+
self.full_url(client) + prefix + self.endpoint_name
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.all(client, options = {})
|
24
|
+
response = client.get(collection_path(client))
|
25
|
+
json = parse_json(response.body)
|
26
|
+
json.map do |attrs|
|
27
|
+
self.new(client, {:attrs => attrs}.merge(options))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# def self.save(options={})
|
32
|
+
# end
|
33
|
+
|
34
|
+
# def self.delete(options={})
|
35
|
+
|
36
|
+
# end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/jira/version.rb
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe JIRA::Resource::Webhook do
|
4
|
+
|
5
|
+
with_each_client do |site_url, client|
|
6
|
+
let(:client) { client }
|
7
|
+
let(:site_url) { site_url }
|
8
|
+
|
9
|
+
|
10
|
+
let(:key) { "2" }
|
11
|
+
|
12
|
+
let(:expected_attributes) do
|
13
|
+
{"name"=>"from API", "url"=>"http://localhost:3000/webhooks/1", "excludeBody"=>false, "filters"=>{"issue-related-events-section"=>""}, "events"=>[], "enabled"=>true, "self"=>"http://localhost:2990/jira/rest/webhooks/1.0/webhook/2", "lastUpdatedUser"=>"admin", "lastUpdatedDisplayName"=>"admin", "lastUpdated"=>1453306520188}
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:expected_collection_length) { 1 }
|
17
|
+
|
18
|
+
it_should_behave_like "a resource"
|
19
|
+
it_should_behave_like "a resource with a collection GET endpoint"
|
20
|
+
it_should_behave_like "a resource with a singular GET endpoint"
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
it "returns a collection of components" do
|
25
|
+
|
26
|
+
stub_request(:get, site_url + described_class.singular_path(client, key)).
|
27
|
+
to_return(:status => 200, :body => get_mock_response('webhook/webhook.json'))
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/spec/jira/base_spec.rb
CHANGED
@@ -427,9 +427,12 @@ describe JIRA::Base do
|
|
427
427
|
end
|
428
428
|
|
429
429
|
it "converts to json" do
|
430
|
-
subject.attrs = {
|
431
|
-
|
430
|
+
subject.attrs = { 'foo' => 'bar', 'dead' => 'beef' }
|
432
431
|
expect(subject.to_json).to eq(subject.attrs.to_json)
|
432
|
+
|
433
|
+
h = { 'key' => subject }
|
434
|
+
h_attrs = { 'key' => subject.attrs }
|
435
|
+
expect(h.to_json).to eq(h_attrs.to_json)
|
433
436
|
end
|
434
437
|
|
435
438
|
describe "extract attrs from response" do
|
@@ -0,0 +1,253 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe JIRA::Resource::Createmeta do
|
4
|
+
let(:client) {
|
5
|
+
double(
|
6
|
+
'client',
|
7
|
+
:options => {
|
8
|
+
:rest_base_path => '/jira/rest/api/2'
|
9
|
+
}
|
10
|
+
)
|
11
|
+
}
|
12
|
+
|
13
|
+
let(:response) {
|
14
|
+
double(
|
15
|
+
'response',
|
16
|
+
:body => '{"expand":"projects","projects":[{"self":"http://localhost:2029/rest/api/2/project/TST"}]}'
|
17
|
+
)
|
18
|
+
}
|
19
|
+
|
20
|
+
describe 'general' do
|
21
|
+
it 'should query correct url without parameters' do
|
22
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta').and_return(response)
|
23
|
+
JIRA::Resource::Createmeta.all(client)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should query correct url with `expand` parameter' do
|
27
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?expand=projects.issuetypes.fields').and_return(response)
|
28
|
+
JIRA::Resource::Createmeta.all(client, :expand => 'projects.issuetypes.fields')
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should query correct url with `foo` parameter' do
|
32
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?foo=bar').and_return(response)
|
33
|
+
JIRA::Resource::Createmeta.all(client, :foo => 'bar')
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
describe 'projectKeys' do
|
40
|
+
it 'should query correct url when only one `projectKeys` given as string' do
|
41
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?projectKeys=PROJECT_1').and_return(response)
|
42
|
+
JIRA::Resource::Createmeta.all(
|
43
|
+
client,
|
44
|
+
:projectKeys => 'PROJECT_1',
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should query correct url when multiple `projectKeys` given as string' do
|
49
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?projectKeys=PROJECT_1%2CPROJECT_2').and_return(response)
|
50
|
+
JIRA::Resource::Createmeta.all(
|
51
|
+
client,
|
52
|
+
:projectKeys => ['PROJECT_1', 'PROJECT_2'],
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should query correct url when only one `projectKeys` given as Project' do
|
57
|
+
prj = JIRA::Resource::Project.new(client)
|
58
|
+
allow(prj).to receive(:key).and_return('PRJ')
|
59
|
+
|
60
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?projectKeys=PRJ').and_return(response)
|
61
|
+
JIRA::Resource::Createmeta.all(
|
62
|
+
client,
|
63
|
+
:projectKeys => prj,
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should query correct url when multiple `projectKeys` given as Project' do
|
68
|
+
prj_1 = JIRA::Resource::Project.new(client)
|
69
|
+
allow(prj_1).to receive(:key).and_return('PRJ_1')
|
70
|
+
prj_2 = JIRA::Resource::Project.new(client)
|
71
|
+
allow(prj_2).to receive(:key).and_return('PRJ_2')
|
72
|
+
|
73
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?projectKeys=PRJ_2%2CPRJ_1').and_return(response)
|
74
|
+
JIRA::Resource::Createmeta.all(
|
75
|
+
client,
|
76
|
+
:projectKeys => [prj_2, prj_1],
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should query correct url when multiple `projectKeys` given as different types' do
|
81
|
+
prj_5 = JIRA::Resource::Project.new(client)
|
82
|
+
allow(prj_5).to receive(:key).and_return('PRJ_5')
|
83
|
+
|
84
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?projectKeys=PROJECT_1%2CPRJ_5').and_return(response)
|
85
|
+
JIRA::Resource::Createmeta.all(
|
86
|
+
client,
|
87
|
+
:projectKeys => ['PROJECT_1', prj_5],
|
88
|
+
)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
describe 'projectIds' do
|
94
|
+
it 'should query correct url when only one `projectIds` given as string' do
|
95
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?projectIds=10101').and_return(response)
|
96
|
+
JIRA::Resource::Createmeta.all(
|
97
|
+
client,
|
98
|
+
:projectIds => '10101',
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'should query correct url when multiple `projectIds` given as string' do
|
103
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?projectIds=10101%2C20202').and_return(response)
|
104
|
+
JIRA::Resource::Createmeta.all(
|
105
|
+
client,
|
106
|
+
:projectIds => ['10101', '20202'],
|
107
|
+
)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should query correct url when only one `projectIds` given as Project' do
|
111
|
+
prj = JIRA::Resource::Project.new(client)
|
112
|
+
allow(prj).to receive(:id).and_return('30303')
|
113
|
+
|
114
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?projectIds=30303').and_return(response)
|
115
|
+
JIRA::Resource::Createmeta.all(
|
116
|
+
client,
|
117
|
+
:projectIds => prj,
|
118
|
+
)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should query correct url when multiple `projectIds` given as Project' do
|
122
|
+
prj_1 = JIRA::Resource::Project.new(client)
|
123
|
+
allow(prj_1).to receive(:id).and_return('30303')
|
124
|
+
prj_2 = JIRA::Resource::Project.new(client)
|
125
|
+
allow(prj_2).to receive(:id).and_return('50505')
|
126
|
+
|
127
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?projectIds=50505%2C30303').and_return(response)
|
128
|
+
JIRA::Resource::Createmeta.all(
|
129
|
+
client,
|
130
|
+
:projectIds => [prj_2, prj_1],
|
131
|
+
)
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'should query correct url when multiple `projectIds` given as different types' do
|
135
|
+
prj_5 = JIRA::Resource::Project.new(client)
|
136
|
+
allow(prj_5).to receive(:id).and_return('60606')
|
137
|
+
|
138
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?projectIds=10101%2C60606').and_return(response)
|
139
|
+
JIRA::Resource::Createmeta.all(
|
140
|
+
client,
|
141
|
+
:projectIds => ['10101', prj_5],
|
142
|
+
)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
describe 'issuetypeNames' do
|
148
|
+
it 'should query correct url when only one `issuetypeNames` given as string' do
|
149
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?issuetypeNames=Feature').and_return(response)
|
150
|
+
JIRA::Resource::Createmeta.all(
|
151
|
+
client,
|
152
|
+
:issuetypeNames => 'Feature',
|
153
|
+
)
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'should query correct url when multiple `issuetypeNames` given as string' do
|
157
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?issuetypeNames=Feature%2CBug').and_return(response)
|
158
|
+
JIRA::Resource::Createmeta.all(
|
159
|
+
client,
|
160
|
+
:issuetypeNames => ['Feature', 'Bug'],
|
161
|
+
)
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'should query correct url when only one `issuetypeNames` given as Issuetype' do
|
165
|
+
issue_type = JIRA::Resource::Issuetype.new(client)
|
166
|
+
allow(issue_type).to receive(:name).and_return('Epic')
|
167
|
+
|
168
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?issuetypeNames=Epic').and_return(response)
|
169
|
+
JIRA::Resource::Createmeta.all(
|
170
|
+
client,
|
171
|
+
:issuetypeNames => issue_type,
|
172
|
+
)
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'should query correct url when multiple `issuetypeNames` given as Issuetype' do
|
176
|
+
issue_type_1 = JIRA::Resource::Issuetype.new(client)
|
177
|
+
allow(issue_type_1).to receive(:name).and_return('Epic')
|
178
|
+
issue_type_2 = JIRA::Resource::Issuetype.new(client)
|
179
|
+
allow(issue_type_2).to receive(:name).and_return('Sub-Task')
|
180
|
+
|
181
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?issuetypeNames=Sub-Task%2CEpic').and_return(response)
|
182
|
+
JIRA::Resource::Createmeta.all(
|
183
|
+
client,
|
184
|
+
:issuetypeNames => [issue_type_2, issue_type_1],
|
185
|
+
)
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'should query correct url when multiple `issuetypeNames` given as different types' do
|
189
|
+
issue_type = JIRA::Resource::Issuetype.new(client)
|
190
|
+
allow(issue_type).to receive(:name).and_return('Epic')
|
191
|
+
|
192
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?issuetypeNames=Feature%2CEpic').and_return(response)
|
193
|
+
JIRA::Resource::Createmeta.all(
|
194
|
+
client,
|
195
|
+
:issuetypeNames => ['Feature', issue_type],
|
196
|
+
)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
describe 'issuetypeIds' do
|
202
|
+
it 'should query correct url when only one `issuetypeIds` given as string' do
|
203
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?issuetypeIds=10101').and_return(response)
|
204
|
+
JIRA::Resource::Createmeta.all(
|
205
|
+
client,
|
206
|
+
:issuetypeIds => '10101',
|
207
|
+
)
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'should query correct url when multiple `issuetypeIds` given as string' do
|
211
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?issuetypeIds=10101%2C20202').and_return(response)
|
212
|
+
JIRA::Resource::Createmeta.all(
|
213
|
+
client,
|
214
|
+
:issuetypeIds => ['10101', '20202'],
|
215
|
+
)
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'should query correct url when only one `issuetypeIds` given as Issuetype' do
|
219
|
+
issue_type = JIRA::Resource::Issuetype.new(client)
|
220
|
+
allow(issue_type).to receive(:id).and_return('30303')
|
221
|
+
|
222
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?issuetypeIds=30303').and_return(response)
|
223
|
+
JIRA::Resource::Createmeta.all(
|
224
|
+
client,
|
225
|
+
:issuetypeIds => issue_type,
|
226
|
+
)
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'should query correct url when multiple `issuetypeIds` given as Issuetype' do
|
230
|
+
issue_type_1 = JIRA::Resource::Issuetype.new(client)
|
231
|
+
allow(issue_type_1).to receive(:id).and_return('30303')
|
232
|
+
issue_type_2 = JIRA::Resource::Issuetype.new(client)
|
233
|
+
allow(issue_type_2).to receive(:id).and_return('50505')
|
234
|
+
|
235
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?issuetypeIds=50505%2C30303').and_return(response)
|
236
|
+
JIRA::Resource::Createmeta.all(
|
237
|
+
client,
|
238
|
+
:issuetypeIds => [issue_type_2, issue_type_1],
|
239
|
+
)
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'should query correct url when multiple `issuetypeIds` given as different types' do
|
243
|
+
issue_type = JIRA::Resource::Issuetype.new(client)
|
244
|
+
allow(issue_type).to receive(:id).and_return('30303')
|
245
|
+
|
246
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/issue/createmeta?issuetypeIds=10101%2C30303').and_return(response)
|
247
|
+
JIRA::Resource::Createmeta.all(
|
248
|
+
client,
|
249
|
+
:issuetypeIds => ['10101', issue_type],
|
250
|
+
)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe JIRA::Resource::Field do
|
4
|
+
|
5
|
+
let(:cache) { OpenStruct.new }
|
6
|
+
|
7
|
+
let(:client) do
|
8
|
+
client = double(options: {rest_base_path: '/jira/rest/api/2'} )
|
9
|
+
field = JIRA::Resource::FieldFactory.new(client)
|
10
|
+
allow(client).to receive(:Field).and_return(field)
|
11
|
+
allow(client).to receive(:cache).and_return(cache)
|
12
|
+
# info about all fields on the client
|
13
|
+
allow(client.Field).to receive(:all).and_return([
|
14
|
+
JIRA::Resource::Field.new(client, :attrs => {'id' =>"customfield_10666", "name" => "Priority", "custom" => true, "orderable" => true, "navigable" => true, "searchable" => true, "clauseNames" => ["cf[10666]","Priority"], "schema" =>{"type" => "string", "custom" => "com.atlassian.jira.plugin.system.customfieldtypes:select","customId" => 10666}}),
|
15
|
+
JIRA::Resource::Field.new(client, :attrs => {'id' =>"issuekey", "name" => "Key", "custom" => false, "orderable" => false, "navigable" => true, "searchable" => false, "clauseNames" => ["id","issue","issuekey","key"]}),
|
16
|
+
JIRA::Resource::Field.new(client, :attrs => {"id" =>"priority", "name" => "Priority", "custom" => false, "orderable" => true, "navigable" => true, "searchable" => true, "clauseNames" => ["priority"], "schema" =>{"type" => "priority", "system" => "priority"}}),
|
17
|
+
JIRA::Resource::Field.new(client, :attrs => {'id' =>"summary", "name" => "Summary", "custom" => false, "orderable" => true, "navigable" => true, "searchable" => true, "clauseNames" => ["summary"], "schema" =>{"type" => "string", "system" => "summary"}}),
|
18
|
+
JIRA::Resource::Field.new(client, :attrs => {'id' =>"issuetype", "name" => "Issue Type", "custom" => false, "orderable" => true, "navigable" => true, "searchable" => true, "clauseNames" => ["issuetype","type"], "schema" =>{"type" => "issuetype", "system" => "issuetype"}}),
|
19
|
+
JIRA::Resource::Field.new(client, :attrs => {'id' =>"customfield_10111", "name" => "SingleWord", "custom" => true, "orderable" => true, "navigable" => true, "searchable" => true, "clauseNames" => ["cf[10111]","SingleWord"], "schema" =>{"type" => "string", "custom" => "com.atlassian.jira.plugin.system.customfieldtypes:select","customId" => 10111}}),
|
20
|
+
JIRA::Resource::Field.new(client, :attrs => {'id' =>"customfield_10222", "name" => "Multi Word", "custom" => true, "orderable" => true, "navigable" => true, "searchable" => true, "clauseNames" => ["cf[10222]","Multi Word"], "schema" =>{"type" => "string", "custom" => "com.atlassian.jira.plugin.system.customfieldtypes:select","customId" => 10222}}),
|
21
|
+
JIRA::Resource::Field.new(client, :attrs => {'id' =>"customfield_10333", "name" => "Why/N@t", "custom" => true, "orderable" => true, "navigable" => true, "searchable" => true, "clauseNames" => ["cf[10333]","Why/N@t"], "schema" =>{"type" => "string", "custom" => "com.atlassian.jira.plugin.system.customfieldtypes:select","customId" => 10333}}),
|
22
|
+
JIRA::Resource::Field.new(client, :attrs => {'id' =>"customfield_10444", "name" => "SingleWord", "custom" => true, "orderable" => true, "navigable" => true, "searchable" => true, "clauseNames" => ["cf[10444]","SingleWord"], "schema" =>{"type" => "string", "custom" => "com.atlassian.jira.plugin.system.customfieldtypes:select","customId" => 10444}})
|
23
|
+
])
|
24
|
+
client
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "field_mappings" do
|
28
|
+
|
29
|
+
shared_context "mapped or not" do
|
30
|
+
|
31
|
+
subject {
|
32
|
+
JIRA::Resource::Field.new(client, :attrs => {
|
33
|
+
'priority' => 1,
|
34
|
+
'customfield_10111' => 'data_in_custom_field',
|
35
|
+
'customfield_10222' => 'multi word custom name',
|
36
|
+
'customfield_10333' => 'complex custom name',
|
37
|
+
'customfield_10444' => 'duplicated custom name',
|
38
|
+
'customfield_10666' => 'duplicate of a system name',
|
39
|
+
})
|
40
|
+
}
|
41
|
+
|
42
|
+
it "can find a standard field by id" do
|
43
|
+
expect(subject.priority).to eq(1)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "can find a custom field by customfield_##### name" do
|
47
|
+
expect(subject.customfield_10111).to eq('data_in_custom_field')
|
48
|
+
end
|
49
|
+
|
50
|
+
it "is not confused by common attribute keys" do
|
51
|
+
expect{subject.name}.to raise_error(NoMethodError)
|
52
|
+
expect{subject.custom}.to raise_error(NoMethodError)
|
53
|
+
expect(subject.id).to eq(nil) # picks up ID from the parent -
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "before fields are mapped" do
|
58
|
+
|
59
|
+
include_context "mapped or not"
|
60
|
+
|
61
|
+
it "can find a standard field by id" do
|
62
|
+
expect(subject.priority).to eq(1)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "cannot find a standard field by name before mapping" do
|
66
|
+
expect{subject.Priority}.to raise_error(NoMethodError)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "can find a custom field by customfield_##### name" do
|
70
|
+
expect(subject.customfield_10111).to eq('data_in_custom_field')
|
71
|
+
end
|
72
|
+
|
73
|
+
it "cannot find a mapped field before mapping and raises error" do
|
74
|
+
expect{subject.SingleWork}.to raise_error(NoMethodError)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "is not confused by common attribute keys and raises error" do
|
78
|
+
expect{subject.name}.to raise_error(NoMethodError)
|
79
|
+
expect{subject.custom}.to raise_error(NoMethodError)
|
80
|
+
expect(subject.id).to eq(nil) # picks up ID from the parent -
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "after fields are mapped" do
|
85
|
+
|
86
|
+
before do
|
87
|
+
silence_stream(STDERR) do
|
88
|
+
expect(client.Field.map_fields.class).to eq(Hash)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
include_context "mapped or not"
|
93
|
+
|
94
|
+
it "warns of duplicate fields" do
|
95
|
+
expect{client.Field.map_fields}.to output(/renaming as Priority_10666/).to_stderr
|
96
|
+
expect{client.Field.map_fields}.to output(/renaming as SingleWord_10444/).to_stderr
|
97
|
+
end
|
98
|
+
|
99
|
+
it "can find a mapped field after mapping and returns results" do
|
100
|
+
expect{subject.SingleWord}.to_not raise_error
|
101
|
+
expect(subject.SingleWord).to eq subject.customfield_10111
|
102
|
+
end
|
103
|
+
|
104
|
+
it "handles duplicate names in a safe fashion" do
|
105
|
+
expect{subject.Multi_Word}.to_not raise_error
|
106
|
+
expect(subject.Multi_Word).to eq subject.customfield_10222
|
107
|
+
end
|
108
|
+
|
109
|
+
it "handles special characters in a safe fashion" do
|
110
|
+
expect{subject.Why_N_t}.to_not raise_error
|
111
|
+
expect(subject.Why_N_t).to eq subject.customfield_10333
|
112
|
+
end
|
113
|
+
|
114
|
+
it "handles duplicates in custom names" do
|
115
|
+
expect{subject.SingleWord_10444}.to_not raise_error
|
116
|
+
expect(subject.SingleWord_10444).to eq subject.customfield_10444
|
117
|
+
end
|
118
|
+
|
119
|
+
it "keeps custom names from overwriting system names" do
|
120
|
+
#expect(client.Field.map_fields.class).to eq(Hash)
|
121
|
+
expect{subject.Priority_10666}.to_not raise_error
|
122
|
+
expect(subject.Priority_10666).to eq subject.customfield_10666
|
123
|
+
end
|
124
|
+
|
125
|
+
it "can find a standard field by an expanded name" do
|
126
|
+
#expect(client.Field.map_fields.class).to eq(Hash)
|
127
|
+
expect(subject.priority).to eq(1)
|
128
|
+
expect(subject.Priority).to eq(1)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -5,7 +5,12 @@ describe JIRA::Resource::Issue do
|
|
5
5
|
class JIRAResourceDelegation < SimpleDelegator # :nodoc:
|
6
6
|
end
|
7
7
|
|
8
|
-
let(:client)
|
8
|
+
let(:client) do
|
9
|
+
client = double(options: {rest_base_path: '/jira/rest/api/2'} )
|
10
|
+
allow(client).to receive(:Field).and_return(JIRA::Resource::FieldFactory.new(client))
|
11
|
+
allow(client).to receive(:cache).and_return(OpenStruct.new)
|
12
|
+
client
|
13
|
+
end
|
9
14
|
|
10
15
|
describe "#respond_to?" do
|
11
16
|
describe "when decorated by SimpleDelegator" do
|
@@ -128,6 +133,21 @@ describe JIRA::Resource::Issue do
|
|
128
133
|
expect(JIRA::Resource::Issue.jql(client,'foo bar', expand: %w(transitions))).to eq([''])
|
129
134
|
end
|
130
135
|
|
136
|
+
it 'should return meta data available for editing an issue' do
|
137
|
+
subject = JIRA::Resource::Issue.new(client, :attrs => {'fields' => {'key' =>'TST=123'}})
|
138
|
+
response = double()
|
139
|
+
|
140
|
+
allow(response).to receive(:body).and_return(
|
141
|
+
'{"fields":{"summary":{"required":true,"name":"Summary","operations":["set"]}}}'
|
142
|
+
)
|
143
|
+
expect(client).to receive(:get)
|
144
|
+
.with('/jira/rest/api/2/issue/TST=123/editmeta')
|
145
|
+
.and_return(response)
|
146
|
+
|
147
|
+
expect(subject.editmeta).to eq({'summary' => {'required' => true, 'name' => 'Summary', 'operations' => ['set']}})
|
148
|
+
end
|
149
|
+
|
150
|
+
|
131
151
|
it "provides direct accessors to the fields" do
|
132
152
|
subject = JIRA::Resource::Issue.new(client, :attrs => {'fields' => {'foo' =>'bar'}})
|
133
153
|
expect(subject).to respond_to(:foo)
|
@@ -0,0 +1,11 @@
|
|
1
|
+
[{"name":"from API",
|
2
|
+
"url":"http://localhost:3000/webhooks/1",
|
3
|
+
"excludeBody":false,
|
4
|
+
"filters":{"issue-related-events-section":""},
|
5
|
+
"events":[],
|
6
|
+
"enabled":true,
|
7
|
+
"self":"http://localhost:2990/jira/rest/webhooks/1.0/webhook/2",
|
8
|
+
"lastUpdatedUser":"admin",
|
9
|
+
"lastUpdatedDisplayName":"admin",
|
10
|
+
"lastUpdated":1453306520188
|
11
|
+
}]
|
@@ -0,0 +1,11 @@
|
|
1
|
+
{"name":"from API",
|
2
|
+
"url":"http://localhost:3000/webhooks/1",
|
3
|
+
"excludeBody":false,
|
4
|
+
"filters":{"issue-related-events-section":""},
|
5
|
+
"events":[],
|
6
|
+
"enabled":true,
|
7
|
+
"self":"http://localhost:2990/jira/rest/webhooks/1.0/webhook/2",
|
8
|
+
"lastUpdatedUser":"admin",
|
9
|
+
"lastUpdatedDisplayName":"admin",
|
10
|
+
"lastUpdated":1453306520188
|
11
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
[{"name":"from API",
|
2
|
+
"url":"http://localhost:3000/webhooks/1",
|
3
|
+
"excludeBody":false,
|
4
|
+
"filters":{"issue-related-events-section":""},
|
5
|
+
"events":[],
|
6
|
+
"enabled":true,
|
7
|
+
"self":"http://localhost:2990/jira/rest/webhooks/1.0/webhook/2",
|
8
|
+
"lastUpdatedUser":"admin",
|
9
|
+
"lastUpdatedDisplayName":"admin",
|
10
|
+
"lastUpdated":1453306520188}
|
11
|
+
]
|
@@ -0,0 +1,11 @@
|
|
1
|
+
{"name":"from API",
|
2
|
+
"url":"http://localhost:3000/webhooks/1",
|
3
|
+
"excludeBody":false,
|
4
|
+
"filters":{"issue-related-events-section":""},
|
5
|
+
"events":[],
|
6
|
+
"enabled":true,
|
7
|
+
"self":"http://localhost:2990/jira/rest/webhooks/1.0/webhook/2",
|
8
|
+
"lastUpdatedUser":"admin",
|
9
|
+
"lastUpdatedDisplayName":"admin",
|
10
|
+
"lastUpdated":1453306520188
|
11
|
+
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jira-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- SUMO Heavy Industries
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-04-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -103,6 +103,7 @@ files:
|
|
103
103
|
- ".gitignore"
|
104
104
|
- ".travis.yml"
|
105
105
|
- Gemfile
|
106
|
+
- Guardfile
|
106
107
|
- LICENSE.txt
|
107
108
|
- README.rdoc
|
108
109
|
- Rakefile
|
@@ -123,6 +124,7 @@ files:
|
|
123
124
|
- lib/jira/resource/attachment.rb
|
124
125
|
- lib/jira/resource/comment.rb
|
125
126
|
- lib/jira/resource/component.rb
|
127
|
+
- lib/jira/resource/createmeta.rb
|
126
128
|
- lib/jira/resource/field.rb
|
127
129
|
- lib/jira/resource/filter.rb
|
128
130
|
- lib/jira/resource/issue.rb
|
@@ -138,6 +140,7 @@ files:
|
|
138
140
|
- lib/jira/resource/transition.rb
|
139
141
|
- lib/jira/resource/user.rb
|
140
142
|
- lib/jira/resource/version.rb
|
143
|
+
- lib/jira/resource/webhook.rb
|
141
144
|
- lib/jira/resource/worklog.rb
|
142
145
|
- lib/jira/tasks.rb
|
143
146
|
- lib/jira/version.rb
|
@@ -156,6 +159,7 @@ files:
|
|
156
159
|
- spec/integration/transition_spec.rb
|
157
160
|
- spec/integration/user_spec.rb
|
158
161
|
- spec/integration/version_spec.rb
|
162
|
+
- spec/integration/webhook.rb
|
159
163
|
- spec/integration/worklog_spec.rb
|
160
164
|
- spec/jira/base_factory_spec.rb
|
161
165
|
- spec/jira/base_spec.rb
|
@@ -166,6 +170,8 @@ files:
|
|
166
170
|
- spec/jira/oauth_client_spec.rb
|
167
171
|
- spec/jira/request_client_spec.rb
|
168
172
|
- spec/jira/resource/attachment_spec.rb
|
173
|
+
- spec/jira/resource/createmeta_spec.rb
|
174
|
+
- spec/jira/resource/field_spec.rb
|
169
175
|
- spec/jira/resource/filter_spec.rb
|
170
176
|
- spec/jira/resource/issue_spec.rb
|
171
177
|
- spec/jira/resource/issuelink_spec.rb
|
@@ -198,6 +204,8 @@ files:
|
|
198
204
|
- spec/mock_responses/issueLinkType/10000.json
|
199
205
|
- spec/mock_responses/issuetype.json
|
200
206
|
- spec/mock_responses/issuetype/5.json
|
207
|
+
- spec/mock_responses/jira/rest/webhooks/1.0/webhook.json
|
208
|
+
- spec/mock_responses/jira/rest/webhooks/1.0/webhook/2.json
|
201
209
|
- spec/mock_responses/priority.json
|
202
210
|
- spec/mock_responses/priority/1.json
|
203
211
|
- spec/mock_responses/project.json
|
@@ -214,6 +222,8 @@ files:
|
|
214
222
|
- spec/mock_responses/version/10000.invalid.put.json
|
215
223
|
- spec/mock_responses/version/10000.json
|
216
224
|
- spec/mock_responses/version/10000.put.json
|
225
|
+
- spec/mock_responses/webhook.json
|
226
|
+
- spec/mock_responses/webhook/webhook.json
|
217
227
|
- spec/spec_helper.rb
|
218
228
|
- spec/support/clients_helper.rb
|
219
229
|
- spec/support/matchers/have_attributes.rb
|
@@ -259,6 +269,7 @@ test_files:
|
|
259
269
|
- spec/integration/transition_spec.rb
|
260
270
|
- spec/integration/user_spec.rb
|
261
271
|
- spec/integration/version_spec.rb
|
272
|
+
- spec/integration/webhook.rb
|
262
273
|
- spec/integration/worklog_spec.rb
|
263
274
|
- spec/jira/base_factory_spec.rb
|
264
275
|
- spec/jira/base_spec.rb
|
@@ -269,6 +280,8 @@ test_files:
|
|
269
280
|
- spec/jira/oauth_client_spec.rb
|
270
281
|
- spec/jira/request_client_spec.rb
|
271
282
|
- spec/jira/resource/attachment_spec.rb
|
283
|
+
- spec/jira/resource/createmeta_spec.rb
|
284
|
+
- spec/jira/resource/field_spec.rb
|
272
285
|
- spec/jira/resource/filter_spec.rb
|
273
286
|
- spec/jira/resource/issue_spec.rb
|
274
287
|
- spec/jira/resource/issuelink_spec.rb
|
@@ -301,6 +314,8 @@ test_files:
|
|
301
314
|
- spec/mock_responses/issueLinkType/10000.json
|
302
315
|
- spec/mock_responses/issuetype.json
|
303
316
|
- spec/mock_responses/issuetype/5.json
|
317
|
+
- spec/mock_responses/jira/rest/webhooks/1.0/webhook.json
|
318
|
+
- spec/mock_responses/jira/rest/webhooks/1.0/webhook/2.json
|
304
319
|
- spec/mock_responses/priority.json
|
305
320
|
- spec/mock_responses/priority/1.json
|
306
321
|
- spec/mock_responses/project.json
|
@@ -317,6 +332,8 @@ test_files:
|
|
317
332
|
- spec/mock_responses/version/10000.invalid.put.json
|
318
333
|
- spec/mock_responses/version/10000.json
|
319
334
|
- spec/mock_responses/version/10000.put.json
|
335
|
+
- spec/mock_responses/webhook.json
|
336
|
+
- spec/mock_responses/webhook/webhook.json
|
320
337
|
- spec/spec_helper.rb
|
321
338
|
- spec/support/clients_helper.rb
|
322
339
|
- spec/support/matchers/have_attributes.rb
|